server: add support for .json .csv and ?all=true

This commit is contained in:
k
2024-10-16 18:38:43 +02:00
parent 4cdc9ef9b3
commit 608ccafc70
66 changed files with 12150 additions and 11014 deletions
+8 -5
View File
@@ -27,12 +27,12 @@
## Website
- Added dashboards
- Added a Home option
- Added a library of PDFs viewable inside the app
- Added a dashboard
- Added a library of PDFs
- Fixed service worker not passing 304 (not modified) response and instead serving cached responses
- Fixed history not being properly registered
- Fixed window being moveable on iOS when in standalone mode when it shouldn't be
- Split `index.html` and `script.js` into multiple js and css files to load only what's necessary at a given time
## Parser
@@ -40,13 +40,16 @@
- Added `--rpcconnect` parameter to the config
- Added handling of SIGINT and SIGTERM terminal signals which menas you can now safely CTRL+C or kill the parser while it's exporting
- Added config print at the start of the program
- Compressed `empty_address_data` struct to save space (should shave of between 25 and 50% of the `address_index_to_empty_address_data` database)
- Compressed `empty_address_data` struct to save space (should shave of between up to 50% of the `address_index_to_empty_address_data` database)
- Doubled the number of `txid_to_tx_data` databases from 4096 to 8192
## Server
- Fixed links in several places missing the `/api` part and thus not working
- Fixed broken last values routes
- Add support for the `/datasets/last` file via the `/api/last` route
- Added support for the `/datasets/last` file via the `/api/last` route
- Added support for `.json` (won't change anything) and `.csv` (will download a csv file) extension at the end of datasets routes
- Added `all=true` query parameter to dataset routes to get to full history
## Biter
+1 -1
View File
@@ -114,7 +114,7 @@ impl TxidToTxData {
}
fn db_index(txid: &Txid) -> u16 {
((txid[0] as u16) << 4) + ((txid[1] as u16) >> 4)
((txid[0] as u16) << 5) + ((txid[1] as u16) >> 3)
}
}
+18 -8
View File
@@ -2,7 +2,8 @@ use allocative::Allocative;
use crate::{
datasets::AnyDataset,
structs::{AnyBiMap, BiMap},
structs::{AnyDateMap, AnyHeightMap},
DateMap, HeightMap,
};
use super::{InsertData, MinInitialStates};
@@ -12,7 +13,8 @@ pub struct CoindaysDataset {
min_initial_states: MinInitialStates,
// Inserted
pub coindays_destroyed: BiMap<f32>,
pub coindays_destroyed: HeightMap<f32>,
pub coindays_destroyed_1d_sum: DateMap<f32>,
}
impl CoindaysDataset {
@@ -22,7 +24,8 @@ impl CoindaysDataset {
let mut s = Self {
min_initial_states: MinInitialStates::default(),
coindays_destroyed: BiMap::new_bin(1, &f("coindays_destroyed")),
coindays_destroyed: HeightMap::new_bin(1, &f("coindays_destroyed")),
coindays_destroyed_1d_sum: DateMap::new_bin(1, &f("coindays_destroyed_1d_sum")),
};
s.min_initial_states
@@ -43,25 +46,32 @@ impl CoindaysDataset {
}: &InsertData,
) {
self.coindays_destroyed
.height
.insert(height, satdays_destroyed.to_btc() as f32);
if is_date_last_block {
self.coindays_destroyed
.date_insert_sum_range(date, date_blocks_range)
self.coindays_destroyed_1d_sum
.insert(date, self.coindays_destroyed.sum_range(date_blocks_range));
}
}
}
impl AnyDataset for CoindaysDataset {
fn to_inserted_bi_map_vec(&self) -> Vec<&(dyn AnyBiMap + Send + Sync)> {
fn to_inserted_height_map_vec(&self) -> Vec<&(dyn AnyHeightMap + Send + Sync)> {
vec![&self.coindays_destroyed]
}
fn to_inserted_mut_bi_map_vec(&mut self) -> Vec<&mut dyn AnyBiMap> {
fn to_inserted_date_map_vec(&self) -> Vec<&(dyn AnyDateMap + Send + Sync)> {
vec![&self.coindays_destroyed_1d_sum]
}
fn to_inserted_mut_height_map_vec(&mut self) -> Vec<&mut dyn AnyHeightMap> {
vec![&mut self.coindays_destroyed]
}
fn to_inserted_mut_date_map_vec(&mut self) -> Vec<&mut dyn AnyDateMap> {
vec![&mut self.coindays_destroyed_1d_sum]
}
fn get_min_initial_states(&self) -> &MinInitialStates {
&self.min_initial_states
}
+182 -104
View File
@@ -1,8 +1,9 @@
use allocative::Allocative;
use crate::{
structs::{AnyBiMap, BiMap, DateMap, Height},
structs::{AnyBiMap, AnyDateMap, AnyHeightMap, BiMap, DateMap, Height},
utils::{ONE_DAY_IN_DAYS, ONE_YEAR_IN_DAYS, THREE_MONTHS_IN_DAYS, TWO_WEEK_IN_DAYS},
HeightMap,
};
use super::{AnyDataset, ComputeData, InsertData, MinInitialStates, RatioDataset};
@@ -12,7 +13,8 @@ pub struct CointimeDataset {
min_initial_states: MinInitialStates,
// Inserted
pub coinblocks_destroyed: BiMap<f32>,
pub coinblocks_destroyed: HeightMap<f32>,
pub coinblocks_destroyed_1d_sum: DateMap<f32>,
// Computed
pub active_cap: BiMap<f32>,
@@ -22,18 +24,24 @@ pub struct CointimeDataset {
pub active_supply_3m_net_change: BiMap<f32>,
pub active_supply_net_change: BiMap<f32>,
pub activity_to_vaultedness_ratio: BiMap<f32>,
pub coinblocks_created: BiMap<f32>,
pub coinblocks_stored: BiMap<f32>,
pub cointime_adjusted_velocity: BiMap<f32>,
pub cointime_adjusted_yearly_inflation_rate: BiMap<f32>,
pub coinblocks_created: HeightMap<f32>,
pub coinblocks_created_1d_sum: DateMap<f32>,
pub coinblocks_stored: HeightMap<f32>,
pub coinblocks_stored_1d_sum: DateMap<f32>,
pub cointime_adjusted_velocity: DateMap<f32>,
pub cointime_adjusted_inflation_rate: DateMap<f32>,
pub cointime_adjusted_yearly_inflation_rate: DateMap<f32>,
pub cointime_cap: BiMap<f32>,
pub cointime_price: BiMap<f32>,
pub cointime_price_ratio: RatioDataset,
pub cointime_value_created: BiMap<f32>,
pub cointime_value_destroyed: BiMap<f32>,
pub cointime_value_stored: BiMap<f32>,
pub concurrent_liveliness: BiMap<f32>,
pub concurrent_liveliness_2w_median: BiMap<f32>,
pub cointime_value_created: HeightMap<f32>,
pub cointime_value_created_1d_sum: DateMap<f32>,
pub cointime_value_destroyed: HeightMap<f32>,
pub cointime_value_destroyed_1d_sum: DateMap<f32>,
pub cointime_value_stored: HeightMap<f32>,
pub cointime_value_stored_1d_sum: DateMap<f32>,
pub concurrent_liveliness: DateMap<f32>,
pub concurrent_liveliness_2w_median: DateMap<f32>,
pub cumulative_coinblocks_created: BiMap<f32>,
pub cumulative_coinblocks_destroyed: BiMap<f32>,
pub cumulative_coinblocks_stored: BiMap<f32>,
@@ -76,22 +84,35 @@ impl CointimeDataset {
active_supply_3m_net_change: BiMap::new_bin(1, &f("active_supply_3m_net_change")),
active_supply_net_change: BiMap::new_bin(1, &f("active_supply_net_change")),
activity_to_vaultedness_ratio: BiMap::new_bin(2, &f("activity_to_vaultedness_ratio")),
coinblocks_created: BiMap::new_bin(1, &f("coinblocks_created")),
coinblocks_destroyed: BiMap::new_bin(1, &f("coinblocks_destroyed")),
coinblocks_stored: BiMap::new_bin(1, &f("coinblocks_stored")),
cointime_adjusted_velocity: BiMap::new_bin(1, &f("cointime_adjusted_velocity")),
cointime_adjusted_yearly_inflation_rate: BiMap::new_bin(
coinblocks_created: HeightMap::new_bin(1, &f("coinblocks_created")),
coinblocks_created_1d_sum: DateMap::new_bin(1, &f("coinblocks_created_1d_sum")),
coinblocks_destroyed: HeightMap::new_bin(1, &f("coinblocks_destroyed")),
coinblocks_destroyed_1d_sum: DateMap::new_bin(1, &f("coinblocks_destroyed_1d_sum")),
coinblocks_stored: HeightMap::new_bin(1, &f("coinblocks_stored")),
coinblocks_stored_1d_sum: DateMap::new_bin(1, &f("coinblocks_stored_1d_sum")),
cointime_adjusted_velocity: DateMap::new_bin(1, &f("cointime_adjusted_velocity")),
cointime_adjusted_inflation_rate: DateMap::new_bin(
1,
&f("cointime_adjusted_inflation_rate"),
),
cointime_adjusted_yearly_inflation_rate: DateMap::new_bin(
1,
&f("cointime_adjusted_yearly_inflation_rate"),
),
cointime_cap: BiMap::new_bin(1, &f("cointime_cap")),
cointime_price: BiMap::new_bin(1, &f("cointime_price")),
cointime_price_ratio: RatioDataset::import(parent_path, "cointime_price")?,
cointime_value_created: BiMap::new_bin(1, &f("cointime_value_created")),
cointime_value_destroyed: BiMap::new_bin(1, &f("cointime_value_destroyed")),
cointime_value_stored: BiMap::new_bin(1, &f("cointime_value_stored")),
concurrent_liveliness: BiMap::new_bin(1, &f("concurrent_liveliness")),
concurrent_liveliness_2w_median: BiMap::new_bin(
cointime_value_created: HeightMap::new_bin(1, &f("cointime_value_created")),
cointime_value_created_1d_sum: DateMap::new_bin(1, &f("cointime_value_created_1d_sum")),
cointime_value_destroyed: HeightMap::new_bin(1, &f("cointime_value_destroyed")),
cointime_value_destroyed_1d_sum: DateMap::new_bin(
1,
&f("cointime_value_destroyed_1d_sum"),
),
cointime_value_stored: HeightMap::new_bin(1, &f("cointime_value_stored")),
cointime_value_stored_1d_sum: DateMap::new_bin(1, &f("cointime_value_stored_1d_sum")),
concurrent_liveliness: DateMap::new_bin(1, &f("concurrent_liveliness")),
concurrent_liveliness_2w_median: DateMap::new_bin(
2,
&f("concurrent_liveliness_2w_median"),
),
@@ -153,12 +174,11 @@ impl CointimeDataset {
}: &InsertData,
) {
self.coinblocks_destroyed
.height
.insert(height, satblocks_destroyed.to_btc() as f32);
if is_date_last_block {
self.coinblocks_destroyed
.date_insert_sum_range(date, date_blocks_range);
self.coinblocks_destroyed_1d_sum
.insert(date, self.coinblocks_destroyed.sum_range(date_blocks_range));
}
}
@@ -172,45 +192,58 @@ impl CointimeDataset {
circulating_supply: &mut BiMap<f64>,
realized_cap: &mut BiMap<f32>,
realized_price: &mut BiMap<f32>,
yearly_inflation_rate: &mut BiMap<f64>,
annualized_transaction_volume: &mut BiMap<f32>,
inflation_rate: &mut DateMap<f64>,
yearly_inflation_rate: &mut DateMap<f64>,
annualized_transaction_volume: &mut DateMap<f32>,
cumulative_subsidy_in_dollars: &mut BiMap<f32>,
) {
let &ComputeData { heights, dates, .. } = compute_data;
self.cumulative_coinblocks_destroyed
.multi_insert_cumulative(heights, dates, &mut self.coinblocks_destroyed);
self.coinblocks_created
.height
.multi_insert_simple_transform(
heights,
&mut circulating_supply.height,
|circulating_supply, _| circulating_supply as f32,
);
self.coinblocks_created
.multi_date_insert_sum_range(dates, first_height, last_height);
.multi_insert_cumulative(heights, &mut self.coinblocks_destroyed);
self.cumulative_coinblocks_destroyed
.date
.multi_insert_cumulative(dates, &mut self.coinblocks_destroyed_1d_sum);
self.cumulative_coinblocks_created.multi_insert_cumulative(
self.coinblocks_created.multi_insert_simple_transform(
heights,
&mut circulating_supply.height,
|circulating_supply, _| circulating_supply as f32,
);
self.coinblocks_created_1d_sum.multi_insert_sum_range(
dates,
&self.coinblocks_created,
first_height,
last_height,
);
self.cumulative_coinblocks_created
.height
.multi_insert_cumulative(heights, &mut self.coinblocks_created);
self.cumulative_coinblocks_created
.date
.multi_insert_cumulative(dates, &mut self.coinblocks_created_1d_sum);
self.coinblocks_stored.multi_insert_subtract(
heights,
&mut self.coinblocks_created,
&mut self.coinblocks_destroyed,
);
self.coinblocks_stored.height.multi_insert_subtract(
heights,
&mut self.coinblocks_created.height,
&mut self.coinblocks_destroyed.height,
);
self.coinblocks_stored
.multi_date_insert_sum_range(dates, first_height, last_height);
self.cumulative_coinblocks_stored.multi_insert_cumulative(
heights,
self.coinblocks_stored_1d_sum.multi_insert_sum_range(
dates,
&mut self.coinblocks_stored,
&self.coinblocks_stored,
first_height,
last_height,
);
self.cumulative_coinblocks_stored
.height
.multi_insert_cumulative(heights, &mut self.coinblocks_stored);
self.cumulative_coinblocks_stored
.date
.multi_insert_cumulative(dates, &mut self.coinblocks_stored_1d_sum);
self.liveliness.multi_insert_divide(
heights,
dates,
@@ -233,14 +266,12 @@ impl CointimeDataset {
);
self.concurrent_liveliness.multi_insert_divide(
heights,
dates,
&mut self.coinblocks_destroyed,
&mut self.coinblocks_created,
&mut self.coinblocks_destroyed_1d_sum,
&mut self.coinblocks_created_1d_sum,
);
self.concurrent_liveliness_2w_median.multi_insert_median(
heights,
dates,
&mut self.concurrent_liveliness,
Some(TWO_WEEK_IN_DAYS),
@@ -309,19 +340,23 @@ impl CointimeDataset {
// let min_vaulted_supply = ;
// let max_active_supply = ;
self.cointime_adjusted_inflation_rate.multi_insert_multiply(
dates,
&mut self.activity_to_vaultedness_ratio.date,
inflation_rate,
);
self.cointime_adjusted_yearly_inflation_rate
.multi_insert_multiply(
heights,
dates,
&mut self.activity_to_vaultedness_ratio,
&mut self.activity_to_vaultedness_ratio.date,
yearly_inflation_rate,
);
self.cointime_adjusted_velocity.multi_insert_divide(
heights,
dates,
annualized_transaction_volume,
&mut self.active_supply,
&mut self.active_supply.date,
);
// TODO:
@@ -426,56 +461,59 @@ impl CointimeDataset {
self.producerness
.multi_insert_divide(heights, dates, &mut self.thermo_cap, realized_cap);
self.cointime_value_destroyed.height.multi_insert_multiply(
self.cointime_value_destroyed.multi_insert_multiply(
heights,
&mut self.coinblocks_destroyed.height,
&mut self.coinblocks_destroyed,
&mut closes.height,
);
self.cointime_value_destroyed.date.multi_insert_multiply(
self.cointime_value_destroyed_1d_sum.multi_insert_multiply(
dates,
&mut self.coinblocks_destroyed.date,
&mut self.coinblocks_destroyed_1d_sum,
&mut closes.date,
);
self.cointime_value_created.height.multi_insert_multiply(
self.cointime_value_created.multi_insert_multiply(
heights,
&mut self.coinblocks_created.height,
&mut self.coinblocks_created,
&mut closes.height,
);
self.cointime_value_created.date.multi_insert_multiply(
self.cointime_value_created_1d_sum.multi_insert_multiply(
dates,
&mut self.coinblocks_created.date,
&mut self.coinblocks_created_1d_sum,
&mut closes.date,
);
self.cointime_value_stored.height.multi_insert_multiply(
self.cointime_value_stored.multi_insert_multiply(
heights,
&mut self.coinblocks_stored.height,
&mut self.coinblocks_stored,
&mut closes.height,
);
self.cointime_value_stored.date.multi_insert_multiply(
self.cointime_value_stored_1d_sum.multi_insert_multiply(
dates,
&mut self.coinblocks_stored.date,
&mut self.coinblocks_stored_1d_sum,
&mut closes.date,
);
self.total_cointime_value_created.multi_insert_cumulative(
heights,
dates,
&mut self.cointime_value_created,
);
self.total_cointime_value_created
.height
.multi_insert_cumulative(heights, &mut self.cointime_value_created);
self.total_cointime_value_created
.date
.multi_insert_cumulative(dates, &mut self.cointime_value_created_1d_sum);
self.total_cointime_value_destroyed.multi_insert_cumulative(
heights,
dates,
&mut self.cointime_value_destroyed,
);
self.total_cointime_value_destroyed
.height
.multi_insert_cumulative(heights, &mut self.cointime_value_destroyed);
self.total_cointime_value_destroyed
.date
.multi_insert_cumulative(dates, &mut self.cointime_value_destroyed_1d_sum);
self.total_cointime_value_stored.multi_insert_cumulative(
heights,
dates,
&mut self.cointime_value_stored,
);
self.total_cointime_value_stored
.height
.multi_insert_cumulative(heights, &mut self.cointime_value_stored);
self.total_cointime_value_stored
.date
.multi_insert_cumulative(dates, &mut self.cointime_value_stored_1d_sum);
self.cointime_price.multi_insert_divide(
heights,
@@ -506,14 +544,72 @@ impl CointimeDataset {
}
impl AnyDataset for CointimeDataset {
fn to_inserted_bi_map_vec(&self) -> Vec<&(dyn AnyBiMap + Send + Sync)> {
fn to_inserted_height_map_vec(&self) -> Vec<&(dyn AnyHeightMap + Send + Sync)> {
vec![&self.coinblocks_destroyed]
}
fn to_inserted_mut_bi_map_vec(&mut self) -> Vec<&mut dyn AnyBiMap> {
fn to_inserted_mut_height_map_vec(&mut self) -> Vec<&mut dyn AnyHeightMap> {
vec![&mut self.coinblocks_destroyed]
}
fn to_inserted_date_map_vec(&self) -> Vec<&(dyn AnyDateMap + Send + Sync)> {
vec![&self.coinblocks_destroyed_1d_sum]
}
fn to_inserted_mut_date_map_vec(&mut self) -> Vec<&mut dyn AnyDateMap> {
vec![&mut self.coinblocks_destroyed_1d_sum]
}
fn to_computed_height_map_vec(&self) -> Vec<&(dyn AnyHeightMap + Send + Sync)> {
vec![
&self.coinblocks_created,
&self.coinblocks_stored,
&self.cointime_value_created,
&self.cointime_value_destroyed,
&self.cointime_value_stored,
]
}
fn to_computed_mut_height_map_vec(&mut self) -> Vec<&mut dyn AnyHeightMap> {
vec![
&mut self.coinblocks_created,
&mut self.coinblocks_stored,
&mut self.cointime_value_created,
&mut self.cointime_value_destroyed,
&mut self.cointime_value_stored,
]
}
fn to_computed_date_map_vec(&self) -> Vec<&(dyn AnyDateMap + Send + Sync)> {
vec![
&self.coinblocks_created_1d_sum,
&self.coinblocks_stored_1d_sum,
&self.concurrent_liveliness,
&self.concurrent_liveliness_2w_median,
&self.cointime_adjusted_velocity,
&self.cointime_value_created_1d_sum,
&self.cointime_value_destroyed_1d_sum,
&self.cointime_value_stored_1d_sum,
&self.cointime_adjusted_inflation_rate,
&self.cointime_adjusted_yearly_inflation_rate,
]
}
fn to_computed_mut_date_map_vec(&mut self) -> Vec<&mut dyn AnyDateMap> {
vec![
&mut self.coinblocks_created_1d_sum,
&mut self.coinblocks_stored_1d_sum,
&mut self.concurrent_liveliness,
&mut self.concurrent_liveliness_2w_median,
&mut self.cointime_adjusted_velocity,
&mut self.cointime_value_created_1d_sum,
&mut self.cointime_value_destroyed_1d_sum,
&mut self.cointime_value_stored_1d_sum,
&mut self.cointime_adjusted_inflation_rate,
&mut self.cointime_adjusted_yearly_inflation_rate,
]
}
fn to_computed_bi_map_vec(&self) -> Vec<&(dyn AnyBiMap + Send + Sync)> {
let mut v = vec![
&self.active_cap as &(dyn AnyBiMap + Send + Sync),
@@ -522,17 +618,8 @@ impl AnyDataset for CointimeDataset {
&self.active_supply_3m_net_change,
&self.active_supply_net_change,
&self.activity_to_vaultedness_ratio,
&self.coinblocks_created,
&self.coinblocks_stored,
&self.cointime_adjusted_velocity,
&self.cointime_adjusted_yearly_inflation_rate,
&self.cointime_cap,
&self.cointime_price,
&self.cointime_value_created,
&self.cointime_value_destroyed,
&self.cointime_value_stored,
&self.concurrent_liveliness,
&self.concurrent_liveliness_2w_median,
&self.cumulative_coinblocks_created,
&self.cumulative_coinblocks_destroyed,
&self.cumulative_coinblocks_stored,
@@ -575,17 +662,8 @@ impl AnyDataset for CointimeDataset {
&mut self.active_supply_3m_net_change,
&mut self.active_supply_net_change,
&mut self.activity_to_vaultedness_ratio,
&mut self.coinblocks_created,
&mut self.coinblocks_stored,
&mut self.cointime_adjusted_velocity,
&mut self.cointime_adjusted_yearly_inflation_rate,
&mut self.cointime_cap,
&mut self.cointime_price,
&mut self.cointime_value_created,
&mut self.cointime_value_destroyed,
&mut self.cointime_value_stored,
&mut self.concurrent_liveliness,
&mut self.concurrent_liveliness_2w_median,
&mut self.cumulative_coinblocks_created,
&mut self.cumulative_coinblocks_destroyed,
&mut self.cumulative_coinblocks_stored,
+193 -124
View File
@@ -25,10 +25,14 @@ pub struct MiningDataset {
// Inserted
pub blocks_mined: DateMap<usize>,
pub total_blocks_mined: DateMap<usize>,
pub coinbase: BiMap<f64>,
pub coinbase_in_dollars: BiMap<f32>,
pub fees: BiMap<f64>,
pub fees_in_dollars: BiMap<f32>,
pub coinbase: HeightMap<f64>,
pub coinbase_1d_sum: DateMap<f64>,
pub coinbase_in_dollars: HeightMap<f32>,
pub coinbase_in_dollars_1d_sum: DateMap<f32>,
pub fees: HeightMap<f64>,
pub fees_1d_sum: DateMap<f64>,
pub fees_in_dollars: HeightMap<f32>,
pub fees_in_dollars_1d_sum: DateMap<f32>,
// Raw
// pub average_fee_paid: BiMap<f32>,
// pub max_fee_paid: BiMap<f32>,
@@ -48,8 +52,10 @@ pub struct MiningDataset {
// pub _10th_percentile_fee_price: BiMap<f32>,
// pub min_fee_price: BiMap<f32>,
// -
pub subsidy: BiMap<f64>,
pub subsidy_in_dollars: BiMap<f32>,
pub subsidy: HeightMap<f64>,
pub subsidy_1d_sum: DateMap<f64>,
pub subsidy_in_dollars: HeightMap<f32>,
pub subsidy_in_dollars_1d_sum: DateMap<f32>,
pub last_coinbase: DateMap<f64>,
pub last_coinbase_in_dollars: DateMap<f32>,
pub last_fees: DateMap<f64>,
@@ -57,17 +63,13 @@ pub struct MiningDataset {
pub last_subsidy: DateMap<f64>,
pub last_subsidy_in_dollars: DateMap<f32>,
pub difficulty: BiMap<f64>,
pub block_size: HeightMap<f32>, // in MB
pub block_size_recap: DateRecapDataset<f32>, // in MB
pub block_weight: HeightMap<f32>, // in MB
pub block_weight_recap: DateRecapDataset<f32>, // in MB
pub block_size: HeightMap<f32>, // in MB
pub block_weight: HeightMap<f32>, // in MB
pub block_vbytes: HeightMap<u64>,
pub block_vbytes_recap: DateRecapDataset<u64>,
pub block_interval: HeightMap<u32>, // in s
pub block_interval_recap: DateRecapDataset<u32>, // in s
pub block_interval: HeightMap<u32>, // in s
// Computed
pub annualized_issuance: BiMap<f64>, // Same as subsidy_1y_sum
pub annualized_issuance: DateMap<f64>, // Same as subsidy_1y_sum
pub blocks_mined_1d_target: DateMap<usize>,
pub blocks_mined_1m_sma: DateMap<f32>,
pub blocks_mined_1m_sum: DateMap<usize>,
@@ -84,38 +86,30 @@ pub struct MiningDataset {
pub cumulative_subsidy_in_dollars: BiMap<f32>,
pub coinbase_1y_sum: DateMap<f64>,
pub coinbase_in_dollars_1y_sum: DateMap<f64>,
pub coinbase_in_dollars_1y_sma: DateMap<f32>,
pub coinbase_in_dollars_1d_sum_1y_sma: DateMap<f32>,
pub cumulative_coinbase: BiMap<f64>,
pub cumulative_coinbase_in_dollars: BiMap<f32>,
pub fees_1y_sum: DateMap<f64>,
pub fees_in_dollars_1y_sum: DateMap<f64>,
pub cumulative_fees: BiMap<f64>,
pub cumulative_fees_in_dollars: BiMap<f32>,
pub yearly_inflation_rate: BiMap<f64>,
pub subsidy_to_coinbase_ratio: BiMap<f64>,
pub fees_to_coinbase_ratio: BiMap<f64>,
pub inflation_rate: DateMap<f64>,
pub yearly_inflation_rate: DateMap<f64>,
pub subsidy_to_coinbase_ratio: HeightMap<f64>,
pub subsidy_to_coinbase_1d_ratio: DateMap<f64>,
pub fees_to_coinbase_ratio: HeightMap<f64>,
pub fees_to_coinbase_1d_ratio: DateMap<f64>,
pub hash_rate: DateMap<f64>,
pub hash_rate_1w_sma: DateMap<f32>,
pub hash_rate_1m_sma: DateMap<f32>,
pub hash_rate_2m_sma: DateMap<f32>,
pub hash_price: DateMap<f64>,
pub difficulty_adjustment: DateMap<f64>,
pub block_size_recap: DateRecapDataset<f32>, // in MB
pub block_weight_recap: DateRecapDataset<f32>, // in MB
pub block_vbytes_recap: DateRecapDataset<u64>,
pub block_interval_recap: DateRecapDataset<u32>, // in s
pub puell_multiple: DateMap<f32>,
// pub block_size_1d_sma: DateMap<f32>, // in MB
// pub block_weight_1d_sma: DateMap<f32>, // in MB
// pub block_vbytes_1d_sma: DateMap<u64>,
// pub block_interval_1d_sma: DateMap<u32>, // in s
// pub block_size_1d_median: DateMap<f32>, // in MB
// pub block_weight_1d_median: DateMap<f32>, // in MB
// pub block_vbytes_1d_median: DateMap<u64>,
// pub block_interval_1d_median: DateMap<u32>,
// pub blocks_size: DateMap<f32>,
// pub average_block_size: DateMap<f32>,
// pub median_block_size: DateMap<f32>,
// pub average_block_weight: DateMap<f32>,
// pub median_block_weight: DateMap<f32>,
// pub average_block_interval: DateMap<u32>,
// pub median_block_interval: DateMap<u32>,
// pub hash_price_in_dollars: DateMap<f64>,
// pub hash_price_30d_volatility: BiMap<f32>,
// difficulty_adjustment
@@ -136,31 +130,43 @@ impl MiningDataset {
total_blocks_mined: DateMap::new_bin(1, &f("total_blocks_mined")),
blocks_mined: DateMap::new_bin(1, &f("blocks_mined")),
coinbase: BiMap::new_bin(1, &f("coinbase")),
coinbase_in_dollars: BiMap::new_bin(1, &f("coinbase_in_dollars")),
coinbase: HeightMap::new_bin(1, &f("coinbase")),
coinbase_1d_sum: DateMap::new_bin(1, &f("coinbase_1d_sum")),
coinbase_in_dollars: HeightMap::new_bin(1, &f("coinbase_in_dollars")),
coinbase_in_dollars_1d_sum: DateMap::new_bin(1, &f("coinbase_in_dollars_1d_sum")),
coinbase_1y_sum: DateMap::new_bin(1, &f("coinbase_1y_sum")),
coinbase_in_dollars_1y_sum: DateMap::new_bin(1, &f("coinbase_in_dollars_1y_sum")),
coinbase_in_dollars_1y_sma: DateMap::new_bin(1, &f("coinbase_in_dollars_1y_sma")),
coinbase_in_dollars_1d_sum_1y_sma: DateMap::new_bin(
1,
&f("coinbase_in_dollars_1d_sum_1y_sma"),
),
cumulative_coinbase: BiMap::new_bin(1, &f("cumulative_coinbase")),
cumulative_coinbase_in_dollars: BiMap::new_bin(1, &f("cumulative_coinbase_in_dollars")),
fees: BiMap::new_bin(1, &f("fees")),
fees_in_dollars: BiMap::new_bin(1, &f("fees_in_dollars")),
fees: HeightMap::new_bin(1, &f("fees")),
fees_1d_sum: DateMap::new_bin(1, &f("fees_1d_sum")),
fees_in_dollars: HeightMap::new_bin(1, &f("fees_in_dollars")),
fees_in_dollars_1d_sum: DateMap::new_bin(1, &f("fees_in_dollars_1d_sum")),
fees_1y_sum: DateMap::new_bin(1, &f("fees_1y_sum")),
fees_in_dollars_1y_sum: DateMap::new_bin(1, &f("fees_in_dollars_1y_sum")),
cumulative_fees: BiMap::new_bin(1, &f("cumulative_fees")),
cumulative_fees_in_dollars: BiMap::new_bin(1, &f("cumulative_fees_in_dollars")),
subsidy: BiMap::new_bin(1, &f("subsidy")),
subsidy_in_dollars: BiMap::new_bin(1, &f("subsidy_in_dollars")),
subsidy: HeightMap::new_bin(1, &f("subsidy")),
subsidy_1d_sum: DateMap::new_bin(1, &f("subsidy_1d_sum")),
subsidy_in_dollars: HeightMap::new_bin(1, &f("subsidy_in_dollars")),
subsidy_in_dollars_1d_sum: DateMap::new_bin(1, &f("subsidy_in_dollars_1d_sum")),
subsidy_1y_sum: DateMap::new_bin(1, &f("subsidy_1y_sum")),
subsidy_in_dollars_1y_sum: DateMap::new_bin(1, &f("subsidy_in_dollars_1y_sum")),
cumulative_subsidy: BiMap::new_bin(1, &f("cumulative_subsidy")),
cumulative_subsidy_in_dollars: BiMap::new_bin(1, &f("cumulative_subsidy_in_dollars")),
subsidy_to_coinbase_ratio: BiMap::new_bin(1, &f("subsidy_to_coinbase_ratio")),
fees_to_coinbase_ratio: BiMap::new_bin(1, &f("fees_to_coinbase_ratio")),
subsidy_to_coinbase_ratio: HeightMap::new_bin(1, &f("subsidy_to_coinbase_ratio")),
subsidy_to_coinbase_1d_ratio: DateMap::new_bin(1, &f("subsidy_to_coinbase_1d_ratio")),
fees_to_coinbase_ratio: HeightMap::new_bin(1, &f("fees_to_coinbase_ratio")),
fees_to_coinbase_1d_ratio: DateMap::new_bin(1, &f("fees_to_coinbase_1d_ratio")),
annualized_issuance: BiMap::new_bin(1, &f("annualized_issuance")),
yearly_inflation_rate: BiMap::new_bin(1, &f("yearly_inflation_rate")),
annualized_issuance: DateMap::new_bin(1, &f("annualized_issuance")),
inflation_rate: DateMap::new_bin(2, &f("inflation_rate")),
yearly_inflation_rate: DateMap::new_bin(1, &f("yearly_inflation_rate")),
last_subsidy: DateMap::new_bin(1, &f("last_subsidy")),
last_subsidy_in_dollars: DateMap::new_bin(1, &f("last_subsidy_in_dollars")),
@@ -271,28 +277,25 @@ impl MiningDataset {
..
}: &InsertData,
) {
self.coinbase.height.insert(height, coinbase.to_btc());
self.coinbase.insert(height, coinbase.to_btc());
let coinbase_in_dollars = self
.coinbase_in_dollars
.height
.insert(height, (block_price * coinbase).to_dollar() as f32);
let sumed_fees = Amount::from_sat(fees.iter().map(|amount| amount.to_sat()).sum());
self.fees.height.insert(height, sumed_fees.to_btc());
self.fees.insert(height, sumed_fees.to_btc());
let sumed_fees_in_dollars = self
.fees_in_dollars
.height
.insert(height, (block_price * sumed_fees).to_dollar() as f32);
let subsidy = coinbase - sumed_fees;
self.subsidy.height.insert(height, subsidy.to_btc());
self.subsidy.insert(height, subsidy.to_btc());
let subsidy_in_dollars = self
.subsidy_in_dollars
.height
.insert(height, (block_price * subsidy).to_dollar() as f32);
self.difficulty.height.insert(height, difficulty);
@@ -305,20 +308,23 @@ impl MiningDataset {
self.block_interval.insert(height, *block_interval);
if is_date_last_block {
self.coinbase.date_insert_sum_range(date, date_blocks_range);
self.coinbase_1d_sum
.insert(date, self.coinbase.sum_range(date_blocks_range));
self.coinbase_in_dollars
.date_insert_sum_range(date, date_blocks_range);
self.coinbase_in_dollars_1d_sum
.insert(date, self.coinbase_in_dollars.sum_range(date_blocks_range));
self.fees.date_insert_sum_range(date, date_blocks_range);
self.fees_1d_sum
.insert(date, self.fees.sum_range(date_blocks_range));
self.fees_in_dollars
.date_insert_sum_range(date, date_blocks_range);
self.fees_in_dollars_1d_sum
.insert(date, self.fees_in_dollars.sum_range(date_blocks_range));
self.subsidy.date_insert_sum_range(date, date_blocks_range);
self.subsidy_1d_sum
.insert(date, self.subsidy.sum_range(date_blocks_range));
self.subsidy_in_dollars
.date_insert_sum_range(date, date_blocks_range);
self.subsidy_in_dollars_1d_sum
.insert(date, self.subsidy_in_dollars.sum_range(date_blocks_range));
self.last_coinbase.insert(date, coinbase.to_btc());
@@ -370,96 +376,128 @@ impl MiningDataset {
self.subsidy_1y_sum.multi_insert_last_x_sum(
dates,
&mut self.subsidy.date,
&mut self.subsidy_1d_sum,
ONE_YEAR_IN_DAYS,
);
self.subsidy_in_dollars_1y_sum.multi_insert_last_x_sum(
dates,
&mut self.subsidy_in_dollars.date,
&mut self.subsidy_in_dollars_1d_sum,
ONE_YEAR_IN_DAYS,
);
self.cumulative_subsidy
.multi_insert_cumulative(heights, dates, &mut self.subsidy);
.height
.multi_insert_cumulative(heights, &mut self.subsidy);
self.cumulative_subsidy
.date
.multi_insert_cumulative(dates, &mut self.subsidy_1d_sum);
self.cumulative_subsidy_in_dollars.multi_insert_cumulative(
heights,
dates,
&mut self.subsidy_in_dollars,
);
self.cumulative_subsidy_in_dollars
.height
.multi_insert_cumulative(heights, &mut self.subsidy_in_dollars);
self.cumulative_subsidy_in_dollars
.date
.multi_insert_cumulative(dates, &mut self.subsidy_in_dollars_1d_sum);
self.fees_1y_sum
.multi_insert_last_x_sum(dates, &mut self.fees.date, ONE_YEAR_IN_DAYS);
.multi_insert_last_x_sum(dates, &mut self.fees_1d_sum, ONE_YEAR_IN_DAYS);
self.fees_in_dollars_1y_sum.multi_insert_last_x_sum(
dates,
&mut self.fees_in_dollars.date,
&mut self.fees_in_dollars_1d_sum,
ONE_YEAR_IN_DAYS,
);
self.cumulative_fees
.multi_insert_cumulative(heights, dates, &mut self.fees);
.height
.multi_insert_cumulative(heights, &mut self.fees);
self.cumulative_fees
.date
.multi_insert_cumulative(dates, &mut self.fees_1d_sum);
self.cumulative_fees_in_dollars.multi_insert_cumulative(
heights,
dates,
&mut self.fees_in_dollars,
);
self.cumulative_fees_in_dollars
.height
.multi_insert_cumulative(heights, &mut self.fees_in_dollars);
self.cumulative_fees_in_dollars
.date
.multi_insert_cumulative(dates, &mut self.fees_in_dollars_1d_sum);
self.coinbase_1y_sum.multi_insert_last_x_sum(
dates,
&mut self.coinbase.date,
&mut self.coinbase_1d_sum,
ONE_YEAR_IN_DAYS,
);
self.coinbase_in_dollars_1y_sum.multi_insert_last_x_sum(
dates,
&mut self.coinbase_in_dollars.date,
&mut self.coinbase_in_dollars_1d_sum,
ONE_YEAR_IN_DAYS,
);
self.coinbase_in_dollars_1y_sma.multi_insert_simple_average(
dates,
&mut self.coinbase_in_dollars.date,
ONE_YEAR_IN_DAYS,
);
self.coinbase_in_dollars_1d_sum_1y_sma
.multi_insert_simple_average(
dates,
&mut self.coinbase_in_dollars_1d_sum,
ONE_YEAR_IN_DAYS,
);
self.cumulative_coinbase
.multi_insert_cumulative(heights, dates, &mut self.coinbase);
.height
.multi_insert_cumulative(heights, &mut self.coinbase);
self.cumulative_coinbase
.date
.multi_insert_cumulative(dates, &mut self.coinbase_1d_sum);
self.cumulative_coinbase_in_dollars.multi_insert_cumulative(
heights,
dates,
&mut self.coinbase_in_dollars,
);
self.cumulative_coinbase_in_dollars
.height
.multi_insert_cumulative(heights, &mut self.coinbase_in_dollars);
self.cumulative_coinbase_in_dollars
.date
.multi_insert_cumulative(dates, &mut self.coinbase_in_dollars_1d_sum);
self.subsidy_to_coinbase_ratio.multi_insert_percentage(
heights,
dates,
&mut self.subsidy,
&mut self.coinbase,
);
self.subsidy_to_coinbase_1d_ratio.multi_insert_percentage(
dates,
&mut self.subsidy_1d_sum,
&mut self.coinbase_1d_sum,
);
self.fees_to_coinbase_ratio.multi_insert_percentage(
heights,
dates,
&mut self.fees,
&mut self.coinbase,
);
self.fees_to_coinbase_1d_ratio.multi_insert_percentage(
dates,
&mut self.fees_1d_sum,
&mut self.coinbase_1d_sum,
);
self.annualized_issuance.multi_insert_last_x_sum(
heights,
dates,
&mut self.subsidy,
&mut self.subsidy_1d_sum,
ONE_YEAR_IN_DAYS,
);
self.inflation_rate.multi_insert_simple_transform(
dates,
&mut self.subsidy_1d_sum,
|subsidy_1d_sum, date| {
subsidy_1d_sum * ONE_YEAR_IN_DAYS as f64
/ self.cumulative_subsidy.date.get_or_import(date).unwrap()
* 100.0
},
);
self.yearly_inflation_rate.multi_insert_percentage(
heights,
dates,
&mut self.annualized_issuance,
&mut self.cumulative_subsidy,
&mut self.cumulative_subsidy.date,
);
self.blocks_mined_1d_target
@@ -502,7 +540,9 @@ impl MiningDataset {
let difficulty = self.difficulty.date.get_or_import(date).unwrap();
((blocks_mined as f64 / TARGET_BLOCKS_PER_DAY as f64) * difficulty * 2.0_f64.powi(32))
((blocks_mined as f64 / date.get_day_completion() * TARGET_BLOCKS_PER_DAY as f64)
* difficulty
* 2.0_f64.powi(32))
/ 600.0
/ 1_000_000_000_000_000_000.0
});
@@ -526,7 +566,7 @@ impl MiningDataset {
);
self.hash_price.multi_insert(dates, |date| {
let coinbase_in_dollars = self.coinbase_in_dollars.date.get_or_import(date).unwrap();
let coinbase_in_dollars = self.coinbase_in_dollars_1d_sum.get_or_import(date).unwrap();
let hashrate = self.hash_rate.get_or_import(date).unwrap();
@@ -535,8 +575,13 @@ impl MiningDataset {
self.puell_multiple.multi_insert_divide(
dates,
&mut self.coinbase_in_dollars.date,
&mut self.coinbase_in_dollars_1y_sma,
&mut self.coinbase_in_dollars_1d_sum,
&mut self.coinbase_in_dollars_1d_sum_1y_sma,
);
self.puell_multiple.multi_insert_divide(
dates,
&mut self.coinbase_in_dollars_1d_sum,
&mut self.coinbase_in_dollars_1d_sum_1y_sma,
);
self.difficulty_adjustment.multi_insert_percentage_change(
@@ -590,31 +635,21 @@ impl AnyDataset for MiningDataset {
}
fn to_inserted_bi_map_vec(&self) -> Vec<&(dyn AnyBiMap + Send + Sync)> {
vec![
&self.coinbase,
&self.coinbase_in_dollars,
&self.fees,
&self.fees_in_dollars,
&self.subsidy,
&self.subsidy_in_dollars,
&self.difficulty,
]
vec![&self.difficulty]
}
fn to_inserted_mut_bi_map_vec(&mut self) -> Vec<&mut dyn AnyBiMap> {
vec![
&mut self.coinbase,
&mut self.coinbase_in_dollars,
&mut self.fees,
&mut self.fees_in_dollars,
&mut self.subsidy,
&mut self.subsidy_in_dollars,
&mut self.difficulty,
]
vec![&mut self.difficulty]
}
fn to_inserted_date_map_vec(&self) -> Vec<&(dyn AnyDateMap + Send + Sync)> {
vec![
&self.coinbase_1d_sum,
&self.coinbase_in_dollars_1d_sum,
&self.fees_1d_sum,
&self.fees_in_dollars_1d_sum,
&self.subsidy_1d_sum,
&self.subsidy_in_dollars_1d_sum,
&self.total_blocks_mined,
&self.blocks_mined,
&self.last_subsidy,
@@ -628,6 +663,12 @@ impl AnyDataset for MiningDataset {
fn to_inserted_mut_date_map_vec(&mut self) -> Vec<&mut dyn AnyDateMap> {
vec![
&mut self.coinbase_1d_sum,
&mut self.coinbase_in_dollars_1d_sum,
&mut self.fees_1d_sum,
&mut self.fees_in_dollars_1d_sum,
&mut self.subsidy_1d_sum,
&mut self.subsidy_in_dollars_1d_sum,
&mut self.total_blocks_mined,
&mut self.blocks_mined,
&mut self.last_subsidy,
@@ -641,6 +682,12 @@ impl AnyDataset for MiningDataset {
fn to_inserted_height_map_vec(&self) -> Vec<&(dyn AnyHeightMap + Send + Sync)> {
vec![
&self.coinbase,
&self.coinbase_in_dollars,
&self.fees,
&self.fees_in_dollars,
&self.subsidy,
&self.subsidy_in_dollars,
&self.block_size,
&self.block_weight,
&self.block_vbytes,
@@ -650,6 +697,12 @@ impl AnyDataset for MiningDataset {
fn to_inserted_mut_height_map_vec(&mut self) -> Vec<&mut dyn AnyHeightMap> {
vec![
&mut self.coinbase,
&mut self.coinbase_in_dollars,
&mut self.fees,
&mut self.fees_in_dollars,
&mut self.subsidy,
&mut self.subsidy_in_dollars,
&mut self.block_size,
&mut self.block_weight,
&mut self.block_vbytes,
@@ -665,11 +718,7 @@ impl AnyDataset for MiningDataset {
&self.cumulative_fees_in_dollars,
&self.cumulative_subsidy,
&self.cumulative_subsidy_in_dollars,
&self.annualized_issuance,
&self.yearly_inflation_rate,
&self.cumulative_block_size,
&self.subsidy_to_coinbase_ratio,
&self.fees_to_coinbase_ratio,
]
}
@@ -681,9 +730,19 @@ impl AnyDataset for MiningDataset {
&mut self.cumulative_fees_in_dollars,
&mut self.cumulative_subsidy,
&mut self.cumulative_subsidy_in_dollars,
&mut self.annualized_issuance,
&mut self.yearly_inflation_rate,
&mut self.cumulative_block_size,
]
}
fn to_computed_height_map_vec(&self) -> Vec<&(dyn AnyHeightMap + Send + Sync)> {
vec![
&self.subsidy_to_coinbase_ratio,
&self.fees_to_coinbase_ratio,
]
}
fn to_computed_mut_height_map_vec(&mut self) -> Vec<&mut dyn AnyHeightMap> {
vec![
&mut self.subsidy_to_coinbase_ratio,
&mut self.fees_to_coinbase_ratio,
]
@@ -704,9 +763,14 @@ impl AnyDataset for MiningDataset {
&self.subsidy_in_dollars_1y_sum,
&self.coinbase_1y_sum,
&self.coinbase_in_dollars_1y_sum,
&self.coinbase_in_dollars_1y_sma,
&self.coinbase_in_dollars_1d_sum_1y_sma,
&self.fees_to_coinbase_1d_ratio,
&self.annualized_issuance,
&self.fees_1y_sum,
&self.fees_in_dollars_1y_sum,
&self.inflation_rate,
&self.yearly_inflation_rate,
&self.subsidy_to_coinbase_1d_ratio,
&self.hash_rate,
&self.hash_rate_1w_sma,
&self.hash_rate_1m_sma,
@@ -742,11 +806,16 @@ impl AnyDataset for MiningDataset {
&mut self.blocks_mined_1w_target,
&mut self.blocks_mined_1m_target,
&mut self.blocks_mined_1y_target,
&mut self.annualized_issuance,
&mut self.subsidy_1y_sum,
&mut self.subsidy_in_dollars_1y_sum,
&mut self.fees_to_coinbase_1d_ratio,
&mut self.inflation_rate,
&mut self.yearly_inflation_rate,
&mut self.subsidy_to_coinbase_1d_ratio,
&mut self.coinbase_1y_sum,
&mut self.coinbase_in_dollars_1y_sum,
&mut self.coinbase_in_dollars_1y_sma,
&mut self.coinbase_in_dollars_1d_sum_1y_sma,
&mut self.fees_1y_sum,
&mut self.fees_in_dollars_1y_sum,
&mut self.hash_rate,
+1
View File
@@ -259,6 +259,7 @@ impl AllDatasets {
&mut self.mining.cumulative_subsidy,
&mut self.address.cohorts.all.subs.capitalization.realized_cap,
&mut self.address.cohorts.all.subs.capitalization.realized_price,
&mut self.mining.inflation_rate,
&mut self.mining.yearly_inflation_rate,
&mut self.transaction.annualized_volume,
&mut self.mining.cumulative_subsidy_in_dollars,
+27 -7
View File
@@ -3,7 +3,8 @@ use allocative::Allocative;
use crate::{
datasets::{AnyDataset, InsertData, MinInitialStates},
states::InputState,
structs::{AnyBiMap, BiMap},
structs::{AnyBiMap, AnyDateMap, AnyHeightMap, BiMap},
DateMap, HeightMap,
};
#[derive(Default, Allocative)]
@@ -12,7 +13,8 @@ pub struct InputSubDataset {
// Inserted
pub count: BiMap<u64>,
pub volume: BiMap<f64>,
pub volume: HeightMap<f64>,
pub volume_1d_sum: DateMap<f64>,
// Computed
// add inputs_per_second
}
@@ -31,7 +33,8 @@ impl InputSubDataset {
min_initial_states: MinInitialStates::default(),
count: BiMap::new_bin(1, &f("input_count")),
volume: BiMap::new_bin(1, &f("input_volume")),
volume: HeightMap::new_bin(1, &f("input_volume")),
volume_1d_sum: DateMap::new_bin(1, &f("input_volume_1d_sum")),
};
s.min_initial_states
@@ -56,12 +59,13 @@ impl InputSubDataset {
.height
.insert(height, state.count().round() as u64);
self.volume.height.insert(height, state.volume().to_btc());
self.volume.insert(height, state.volume().to_btc());
if is_date_last_block {
self.count.date.insert(date, count);
self.volume.date_insert_sum_range(date, date_blocks_range);
self.volume_1d_sum
.insert(date, self.volume.sum_range(date_blocks_range));
}
}
}
@@ -72,10 +76,26 @@ impl AnyDataset for InputSubDataset {
}
fn to_inserted_bi_map_vec(&self) -> Vec<&(dyn AnyBiMap + Send + Sync)> {
vec![&self.count, &self.volume]
vec![&self.count]
}
fn to_inserted_mut_bi_map_vec(&mut self) -> Vec<&mut dyn AnyBiMap> {
vec![&mut self.count, &mut self.volume]
vec![&mut self.count]
}
fn to_inserted_height_map_vec(&self) -> Vec<&(dyn AnyHeightMap + Send + Sync)> {
vec![&self.volume]
}
fn to_inserted_mut_height_map_vec(&mut self) -> Vec<&mut dyn AnyHeightMap> {
vec![&mut self.volume]
}
fn to_inserted_date_map_vec(&self) -> Vec<&(dyn AnyDateMap + Send + Sync)> {
vec![&self.volume_1d_sum]
}
fn to_inserted_mut_date_map_vec(&mut self) -> Vec<&mut dyn AnyDateMap> {
vec![&mut self.volume_1d_sum]
}
}
+202 -99
View File
@@ -3,9 +3,9 @@ use allocative::Allocative;
use crate::{
datasets::{AnyDataset, ComputeData, InsertData, MinInitialStates},
states::RealizedState,
structs::{AnyBiMap, AnyDateMap, BiMap, Price},
structs::{AnyBiMap, AnyDateMap, AnyHeightMap, BiMap, Price},
utils::ONE_MONTH_IN_DAYS,
DateMap,
DateMap, HeightMap,
};
#[derive(Default, Allocative)]
@@ -13,26 +13,36 @@ pub struct RealizedSubDataset {
min_initial_states: MinInitialStates,
// Inserted
realized_profit: BiMap<f32>,
realized_loss: BiMap<f32>,
value_created: BiMap<f32>,
adjusted_value_created: BiMap<f32>,
value_destroyed: BiMap<f32>,
adjusted_value_destroyed: BiMap<f32>,
realized_profit: HeightMap<f32>,
realized_loss: HeightMap<f32>,
value_created: HeightMap<f32>,
adjusted_value_created: HeightMap<f32>,
value_destroyed: HeightMap<f32>,
adjusted_value_destroyed: HeightMap<f32>,
realized_profit_1d_sum: DateMap<f32>,
realized_loss_1d_sum: DateMap<f32>,
value_created_1d_sum: DateMap<f32>,
adjusted_value_created_1d_sum: DateMap<f32>,
value_destroyed_1d_sum: DateMap<f32>,
adjusted_value_destroyed_1d_sum: DateMap<f32>,
spent_output_profit_ratio: BiMap<f32>,
adjusted_spent_output_profit_ratio: BiMap<f32>,
// Computed
negative_realized_loss: BiMap<f32>,
net_realized_profit_and_loss: BiMap<f32>,
net_realized_profit_and_loss_to_market_cap_ratio: BiMap<f32>,
negative_realized_loss: HeightMap<f32>,
negative_realized_loss_1d_sum: DateMap<f32>,
net_realized_profit_and_loss: HeightMap<f32>,
net_realized_profit_and_loss_1d_sum: DateMap<f32>,
net_realized_profit_and_loss_1d_sum_to_market_cap_ratio: DateMap<f32>,
cumulative_realized_profit: BiMap<f32>,
cumulative_realized_loss: BiMap<f32>,
cumulative_net_realized_profit_and_loss: BiMap<f32>,
cumulative_net_realized_profit_and_loss_1m_net_change: BiMap<f32>,
realized_value: BiMap<f32>,
realized_value: HeightMap<f32>,
realized_value_1d_sum: DateMap<f32>,
sell_side_risk_ratio: DateMap<f32>,
realized_profit_to_loss_ratio: BiMap<f32>,
realized_profit_to_loss_ratio: HeightMap<f32>,
realized_profit_to_loss_1d_sum_ratio: DateMap<f32>,
}
impl RealizedSubDataset {
@@ -48,21 +58,35 @@ impl RealizedSubDataset {
let mut s = Self {
min_initial_states: MinInitialStates::default(),
realized_profit: BiMap::new_bin(1, &f("realized_profit")),
realized_loss: BiMap::new_bin(1, &f("realized_loss")),
value_created: BiMap::new_bin(1, &f("value_created")),
adjusted_value_created: BiMap::new_bin(1, &f("adjusted_value_created")),
value_destroyed: BiMap::new_bin(1, &f("value_destroyed")),
adjusted_value_destroyed: BiMap::new_bin(1, &f("adjusted_value_destroyed")),
realized_profit: HeightMap::new_bin(1, &f("realized_profit")),
realized_loss: HeightMap::new_bin(1, &f("realized_loss")),
value_created: HeightMap::new_bin(1, &f("value_created")),
adjusted_value_created: HeightMap::new_bin(1, &f("adjusted_value_created")),
value_destroyed: HeightMap::new_bin(1, &f("value_destroyed")),
adjusted_value_destroyed: HeightMap::new_bin(1, &f("adjusted_value_destroyed")),
realized_profit_1d_sum: DateMap::new_bin(1, &f("realized_profit_1d_sum")),
realized_loss_1d_sum: DateMap::new_bin(1, &f("realized_loss_1d_sum")),
value_created_1d_sum: DateMap::new_bin(1, &f("value_created_1d_sum")),
adjusted_value_created_1d_sum: DateMap::new_bin(1, &f("adjusted_value_created_1d_sum")),
value_destroyed_1d_sum: DateMap::new_bin(1, &f("value_destroyed_1d_sum")),
adjusted_value_destroyed_1d_sum: DateMap::new_bin(
1,
&f("adjusted_value_destroyed_1d_sum"),
),
spent_output_profit_ratio: BiMap::new_bin(2, &f("spent_output_profit_ratio")),
adjusted_spent_output_profit_ratio: BiMap::new_bin(
2,
&f("adjusted_spent_output_profit_ratio"),
),
negative_realized_loss: BiMap::new_bin(2, &f("negative_realized_loss")),
net_realized_profit_and_loss: BiMap::new_bin(1, &f("net_realized_profit_and_loss")),
net_realized_profit_and_loss_to_market_cap_ratio: BiMap::new_bin(
negative_realized_loss: HeightMap::new_bin(2, &f("negative_realized_loss")),
negative_realized_loss_1d_sum: DateMap::new_bin(2, &f("negative_realized_loss_1d_sum")),
net_realized_profit_and_loss: HeightMap::new_bin(1, &f("net_realized_profit_and_loss")),
net_realized_profit_and_loss_1d_sum: DateMap::new_bin(
1,
&f("net_realized_profit_and_loss_1d_sum"),
),
net_realized_profit_and_loss_1d_sum_to_market_cap_ratio: DateMap::new_bin(
2,
&f("net_realized_profit_and_loss_to_market_cap_ratio"),
),
@@ -76,9 +100,17 @@ impl RealizedSubDataset {
1,
&f("cumulative_net_realized_profit_and_loss_1m_net_change"),
),
realized_value: BiMap::new_bin(1, &f("realized_value")),
realized_value: HeightMap::new_bin(1, &f("realized_value")),
realized_value_1d_sum: DateMap::new_bin(1, &f("realized_value_1d_sum")),
sell_side_risk_ratio: DateMap::new_bin(1, &f("sell_side_risk_ratio")),
realized_profit_to_loss_ratio: BiMap::new_bin(1, &f("realized_profit_to_loss_ratio")),
realized_profit_to_loss_ratio: HeightMap::new_bin(
1,
&f("realized_profit_to_loss_ratio"),
),
realized_profit_to_loss_1d_sum_ratio: DateMap::new_bin(
1,
&f("realized_profit_to_loss_1d_sum_ratio"),
),
};
s.min_initial_states
@@ -99,27 +131,23 @@ impl RealizedSubDataset {
height_state: &RealizedState,
) {
self.realized_profit
.height
.insert(height, height_state.realized_profit().to_dollar() as f32);
self.realized_loss
.height
.insert(height, height_state.realized_loss().to_dollar() as f32);
self.value_created
.height
.insert(height, height_state.value_created().to_dollar() as f32);
self.adjusted_value_created.height.insert(
self.adjusted_value_created.insert(
height,
height_state.adjusted_value_created().to_dollar() as f32,
);
self.value_destroyed
.height
.insert(height, height_state.value_destroyed().to_dollar() as f32);
self.adjusted_value_destroyed.height.insert(
self.adjusted_value_destroyed.insert(
height,
height_state.adjusted_value_destroyed().to_dollar() as f32,
);
@@ -146,39 +174,37 @@ impl RealizedSubDataset {
});
if is_date_last_block {
self.realized_profit
.date_insert_sum_range(date, date_blocks_range);
self.realized_profit_1d_sum
.insert(date, self.realized_profit.sum_range(date_blocks_range));
self.realized_loss
.date_insert_sum_range(date, date_blocks_range);
self.realized_loss_1d_sum
.insert(date, self.realized_loss.sum_range(date_blocks_range));
self.value_created
.date_insert_sum_range(date, date_blocks_range);
let value_created_1d_sum = self
.value_created_1d_sum
.insert(date, self.value_created.sum_range(date_blocks_range));
self.adjusted_value_created
.date_insert_sum_range(date, date_blocks_range);
self.value_destroyed
.date_insert_sum_range(date, date_blocks_range);
self.adjusted_value_destroyed
.date_insert_sum_range(date, date_blocks_range);
self.spent_output_profit_ratio.date.insert(
let adjusted_value_created_1d_sum = self.adjusted_value_created_1d_sum.insert(
date,
self.value_created.height.sum_range(date_blocks_range)
/ self.value_destroyed.height.sum_range(date_blocks_range),
self.adjusted_value_created.sum_range(date_blocks_range),
);
let value_destroyed_1d_sum = self
.value_destroyed_1d_sum
.insert(date, self.value_destroyed.sum_range(date_blocks_range));
let adjusted_value_destroyed_1d_sum = self.adjusted_value_destroyed_1d_sum.insert(
date,
self.adjusted_value_destroyed.sum_range(date_blocks_range),
);
self.spent_output_profit_ratio
.date
.insert(date, value_created_1d_sum / value_destroyed_1d_sum);
self.adjusted_spent_output_profit_ratio.date.insert(
date,
self.adjusted_value_created
.height
.sum_range(date_blocks_range)
/ self
.adjusted_value_destroyed
.height
.sum_range(date_blocks_range),
adjusted_value_created_1d_sum / adjusted_value_destroyed_1d_sum,
);
}
}
@@ -190,40 +216,53 @@ impl RealizedSubDataset {
) {
self.negative_realized_loss.multi_insert_simple_transform(
heights,
dates,
&mut self.realized_loss,
&|v| v * -1.0,
|v, _| v * -1.0,
);
self.negative_realized_loss_1d_sum
.multi_insert_simple_transform(dates, &mut self.realized_loss_1d_sum, |v, _| v * -1.0);
self.net_realized_profit_and_loss.multi_insert_subtract(
heights,
dates,
&mut self.realized_profit,
&mut self.realized_loss,
);
self.net_realized_profit_and_loss_to_market_cap_ratio
.multi_insert_percentage(
heights,
self.net_realized_profit_and_loss_1d_sum
.multi_insert_subtract(
dates,
&mut self.net_realized_profit_and_loss,
market_cap,
&mut self.realized_profit_1d_sum,
&mut self.realized_loss_1d_sum,
);
self.cumulative_realized_profit.multi_insert_cumulative(
heights,
dates,
&mut self.realized_profit,
);
self.net_realized_profit_and_loss_1d_sum_to_market_cap_ratio
.multi_insert_percentage(
dates,
&mut self.net_realized_profit_and_loss_1d_sum,
&mut market_cap.date,
);
self.cumulative_realized_loss.multi_insert_cumulative(
heights,
dates,
&mut self.realized_loss,
);
self.cumulative_realized_profit
.height
.multi_insert_cumulative(heights, &mut self.realized_profit);
self.cumulative_realized_profit
.date
.multi_insert_cumulative(dates, &mut self.realized_profit_1d_sum);
self.cumulative_realized_loss
.height
.multi_insert_cumulative(heights, &mut self.realized_loss);
self.cumulative_realized_loss
.date
.multi_insert_cumulative(dates, &mut self.realized_loss_1d_sum);
self.cumulative_net_realized_profit_and_loss
.multi_insert_cumulative(heights, dates, &mut self.net_realized_profit_and_loss);
.height
.multi_insert_cumulative(heights, &mut self.net_realized_profit_and_loss);
self.cumulative_net_realized_profit_and_loss
.date
.multi_insert_cumulative(dates, &mut self.net_realized_profit_and_loss_1d_sum);
self.cumulative_net_realized_profit_and_loss_1m_net_change
.multi_insert_net_change(
@@ -235,23 +274,33 @@ impl RealizedSubDataset {
self.realized_value.multi_insert_add(
heights,
dates,
&mut self.realized_profit,
&mut self.realized_loss,
);
self.realized_value_1d_sum.multi_insert_add(
dates,
&mut self.realized_profit_1d_sum,
&mut self.realized_loss_1d_sum,
);
self.sell_side_risk_ratio.multi_insert_percentage(
dates,
&mut self.realized_value.date,
&mut self.realized_value_1d_sum,
&mut market_cap.date,
);
self.realized_profit_to_loss_ratio.multi_insert_divide(
heights,
dates,
&mut self.realized_profit,
&mut self.realized_loss,
);
self.realized_profit_to_loss_1d_sum_ratio
.multi_insert_divide(
dates,
&mut self.realized_profit_1d_sum,
&mut self.realized_loss_1d_sum,
);
}
}
@@ -262,18 +311,30 @@ impl AnyDataset for RealizedSubDataset {
fn to_inserted_bi_map_vec(&self) -> Vec<&(dyn AnyBiMap + Send + Sync)> {
vec![
&self.realized_loss,
&self.realized_profit,
&self.value_created,
&self.adjusted_value_created,
&self.value_destroyed,
&self.adjusted_value_destroyed,
&self.spent_output_profit_ratio,
&self.adjusted_spent_output_profit_ratio,
]
}
fn to_inserted_mut_bi_map_vec(&mut self) -> Vec<&mut dyn AnyBiMap> {
vec![
&mut self.spent_output_profit_ratio,
&mut self.adjusted_spent_output_profit_ratio,
]
}
fn to_inserted_height_map_vec(&self) -> Vec<&(dyn AnyHeightMap + Send + Sync)> {
vec![
&self.realized_loss,
&self.realized_profit,
&self.value_created,
&self.adjusted_value_created,
&self.value_destroyed,
&self.adjusted_value_destroyed,
]
}
fn to_inserted_mut_height_map_vec(&mut self) -> Vec<&mut dyn AnyHeightMap> {
vec![
&mut self.realized_loss,
&mut self.realized_profit,
@@ -281,44 +342,86 @@ impl AnyDataset for RealizedSubDataset {
&mut self.adjusted_value_created,
&mut self.value_destroyed,
&mut self.adjusted_value_destroyed,
&mut self.spent_output_profit_ratio,
&mut self.adjusted_spent_output_profit_ratio,
]
}
fn to_inserted_date_map_vec(&self) -> Vec<&(dyn AnyDateMap + Send + Sync)> {
vec![
&self.realized_loss_1d_sum,
&self.realized_profit_1d_sum,
&self.value_created_1d_sum,
&self.adjusted_value_created_1d_sum,
&self.value_destroyed_1d_sum,
&self.adjusted_value_destroyed_1d_sum,
]
}
fn to_inserted_mut_date_map_vec(&mut self) -> Vec<&mut dyn AnyDateMap> {
vec![
&mut self.realized_loss_1d_sum,
&mut self.realized_profit_1d_sum,
&mut self.value_created_1d_sum,
&mut self.adjusted_value_created_1d_sum,
&mut self.value_destroyed_1d_sum,
&mut self.adjusted_value_destroyed_1d_sum,
]
}
fn to_computed_bi_map_vec(&self) -> Vec<&(dyn AnyBiMap + Send + Sync)> {
vec![
&self.negative_realized_loss,
&self.net_realized_profit_and_loss,
&self.net_realized_profit_and_loss_to_market_cap_ratio,
&self.cumulative_realized_profit,
&self.cumulative_realized_loss,
&self.cumulative_net_realized_profit_and_loss,
&self.cumulative_net_realized_profit_and_loss_1m_net_change,
]
}
fn to_computed_mut_bi_map_vec(&mut self) -> Vec<&mut dyn AnyBiMap> {
vec![
&mut self.cumulative_realized_profit,
&mut self.cumulative_realized_loss,
&mut self.cumulative_net_realized_profit_and_loss,
&mut self.cumulative_net_realized_profit_and_loss_1m_net_change,
]
}
fn to_computed_height_map_vec(&self) -> Vec<&(dyn AnyHeightMap + Send + Sync)> {
vec![
&self.negative_realized_loss,
&self.net_realized_profit_and_loss,
&self.realized_value,
&self.realized_profit_to_loss_ratio,
]
}
fn to_computed_date_map_vec(&self) -> Vec<&(dyn AnyDateMap + Send + Sync)> {
vec![&self.sell_side_risk_ratio]
}
fn to_computed_mut_bi_map_vec(&mut self) -> Vec<&mut dyn AnyBiMap> {
fn to_computed_mut_height_map_vec(&mut self) -> Vec<&mut dyn AnyHeightMap> {
vec![
&mut self.negative_realized_loss,
&mut self.net_realized_profit_and_loss,
&mut self.net_realized_profit_and_loss_to_market_cap_ratio,
&mut self.cumulative_realized_profit,
&mut self.cumulative_realized_loss,
&mut self.cumulative_net_realized_profit_and_loss,
&mut self.cumulative_net_realized_profit_and_loss_1m_net_change,
&mut self.realized_value,
&mut self.realized_profit_to_loss_ratio,
]
}
fn to_computed_date_map_vec(&self) -> Vec<&(dyn AnyDateMap + Send + Sync)> {
vec![
&self.sell_side_risk_ratio,
&self.negative_realized_loss_1d_sum,
&self.net_realized_profit_and_loss_1d_sum,
&self.net_realized_profit_and_loss_1d_sum_to_market_cap_ratio,
&self.realized_value_1d_sum,
&self.realized_profit_to_loss_1d_sum_ratio,
]
}
fn to_computed_mut_date_map_vec(&mut self) -> Vec<&mut dyn AnyDateMap> {
vec![&mut self.sell_side_risk_ratio]
vec![
&mut self.sell_side_risk_ratio,
&mut self.negative_realized_loss_1d_sum,
&mut self.net_realized_profit_and_loss_1d_sum,
&mut self.net_realized_profit_and_loss_1d_sum_to_market_cap_ratio,
&mut self.realized_value_1d_sum,
&mut self.realized_profit_to_loss_1d_sum_ratio,
]
}
}
+172 -64
View File
@@ -2,8 +2,11 @@ use allocative::Allocative;
use crate::{
datasets::InsertData,
structs::{AnyBiMap, BiMap, HeightMap},
utils::{ONE_DAY_IN_S, ONE_MONTH_IN_DAYS, ONE_WEEK_IN_DAYS, ONE_YEAR_IN_DAYS},
structs::{AnyBiMap, AnyDateMap, AnyHeightMap, BiMap, HeightMap},
utils::{
ONE_DAY_IN_S, ONE_MONTH_IN_DAYS, ONE_WEEK_IN_DAYS, ONE_YEAR_IN_DAYS, TARGET_BLOCKS_PER_DAY,
},
DateMap,
};
use super::{AnyDataset, ComputeData, MinInitialStates};
@@ -13,9 +16,12 @@ pub struct TransactionDataset {
min_initial_states: MinInitialStates,
// Inserted
pub count: BiMap<usize>,
pub volume: BiMap<f64>,
pub volume_in_dollars: BiMap<f32>,
pub count: HeightMap<usize>,
pub count_1d_sum: DateMap<usize>,
pub volume: HeightMap<f64>,
pub volume_1d_sum: DateMap<f64>,
pub volume_in_dollars: HeightMap<f32>,
pub volume_in_dollars_1d_sum: DateMap<f32>,
// Average sent
// Average sent in dollars
// Median sent
@@ -27,15 +33,21 @@ pub struct TransactionDataset {
// version
// Computed
pub count_1w_sma: BiMap<f32>,
pub count_1m_sma: BiMap<f32>,
pub volume_1w_sma: BiMap<f32>,
pub volume_1m_sma: BiMap<f32>,
pub volume_in_dollars_1w_sma: BiMap<f32>,
pub volume_in_dollars_1m_sma: BiMap<f32>,
pub annualized_volume: BiMap<f32>,
pub annualized_volume_in_dollars: BiMap<f32>,
pub velocity: BiMap<f32>,
pub count_1w_sma: HeightMap<f32>,
pub count_1d_sum_1w_sma: DateMap<f32>,
pub count_1m_sma: HeightMap<f32>,
pub count_1d_sum_1m_sma: DateMap<f32>,
pub volume_1w_sma: HeightMap<f32>,
pub volume_1d_sum_1w_sma: DateMap<f32>,
pub volume_1m_sma: HeightMap<f32>,
pub volume_1d_sum_1m_sma: DateMap<f32>,
pub volume_in_dollars_1w_sma: HeightMap<f32>,
pub volume_in_dollars_1d_sum_1w_sma: DateMap<f32>,
pub volume_in_dollars_1m_sma: HeightMap<f32>,
pub volume_in_dollars_1d_sum_1m_sma: DateMap<f32>,
pub annualized_volume: DateMap<f32>,
pub annualized_volume_in_dollars: DateMap<f32>,
pub velocity: DateMap<f32>,
pub transactions_per_second: BiMap<f32>,
pub transactions_per_second_1w_sma: BiMap<f32>,
pub transactions_per_second_1m_sma: BiMap<f32>,
@@ -48,21 +60,45 @@ impl TransactionDataset {
let mut s = Self {
min_initial_states: MinInitialStates::default(),
count: BiMap::new_bin(1, &f("transaction_count")),
count_1w_sma: BiMap::new_bin(1, &f("transaction_count_1w_sma")),
count_1m_sma: BiMap::new_bin(1, &f("transaction_count_1m_sma")),
volume: BiMap::new_bin(1, &f("transaction_volume")),
volume_1w_sma: BiMap::new_bin(1, &f("transaction_volume_1w_sma")),
volume_1m_sma: BiMap::new_bin(1, &f("transaction_volume_1m_sma")),
volume_in_dollars: BiMap::new_bin(1, &f("transaction_volume_in_dollars")),
volume_in_dollars_1w_sma: BiMap::new_bin(1, &f("transaction_volume_in_dollars_1w_sma")),
volume_in_dollars_1m_sma: BiMap::new_bin(1, &f("transaction_volume_in_dollars_1m_sma")),
annualized_volume: BiMap::new_bin(1, &f("annualized_transaction_volume")),
annualized_volume_in_dollars: BiMap::new_bin(
count: HeightMap::new_bin(1, &f("transaction_count")),
count_1d_sum: DateMap::new_bin(1, &f("transaction_count_1d_sum")),
count_1w_sma: HeightMap::new_bin(1, &f("transaction_count_1w_sma")),
count_1d_sum_1w_sma: DateMap::new_bin(1, &f("transaction_count_1d_sum_1w_sma")),
count_1m_sma: HeightMap::new_bin(1, &f("transaction_count_1m_sma")),
count_1d_sum_1m_sma: DateMap::new_bin(1, &f("transaction_count_1d_sum_1m_sma")),
volume: HeightMap::new_bin(1, &f("transaction_volume")),
volume_1d_sum: DateMap::new_bin(1, &f("transaction_volume_1d_sum")),
volume_1w_sma: HeightMap::new_bin(1, &f("transaction_volume_1w_sma")),
volume_1d_sum_1w_sma: DateMap::new_bin(1, &f("transaction_volume_1d_sum_1w_sma")),
volume_1m_sma: HeightMap::new_bin(1, &f("transaction_volume_1m_sma")),
volume_1d_sum_1m_sma: DateMap::new_bin(1, &f("transaction_volume_1d_sum_1m_sma")),
volume_in_dollars: HeightMap::new_bin(1, &f("transaction_volume_in_dollars")),
volume_in_dollars_1d_sum: DateMap::new_bin(
1,
&f("transaction_volume_in_dollars_1d_sum"),
),
volume_in_dollars_1w_sma: HeightMap::new_bin(
1,
&f("transaction_volume_in_dollars_1w_sma"),
),
volume_in_dollars_1d_sum_1w_sma: DateMap::new_bin(
1,
&f("transaction_volume_in_dollars_1d_sum_1w_sma"),
),
volume_in_dollars_1m_sma: HeightMap::new_bin(
1,
&f("transaction_volume_in_dollars_1m_sma"),
),
volume_in_dollars_1d_sum_1m_sma: DateMap::new_bin(
1,
&f("transaction_volume_in_dollars_1d_sum_1m_sma"),
),
annualized_volume: DateMap::new_bin(1, &f("annualized_transaction_volume")),
annualized_volume_in_dollars: DateMap::new_bin(
2,
&f("annualized_transaction_volume_in_dollars"),
),
velocity: BiMap::new_bin(1, &f("transaction_velocity")),
velocity: DateMap::new_bin(1, &f("transaction_velocity")),
transactions_per_second: BiMap::new_bin(1, &f("transactions_per_second")),
transactions_per_second_1w_sma: BiMap::new_bin(1, &f("transactions_per_second_1w_sma")),
transactions_per_second_1m_sma: BiMap::new_bin(1, &f("transactions_per_second_1m_sma")),
@@ -87,21 +123,22 @@ impl TransactionDataset {
..
}: &InsertData,
) {
self.count.height.insert(height, transaction_count);
self.count.insert(height, transaction_count);
self.volume.height.insert(height, amount_sent.to_btc());
self.volume.insert(height, amount_sent.to_btc());
self.volume_in_dollars
.height
.insert(height, (block_price * amount_sent).to_dollar() as f32);
if is_date_last_block {
self.count.date_insert_sum_range(date, date_blocks_range);
self.count_1d_sum
.insert(date, self.count.sum_range(date_blocks_range));
self.volume.date_insert_sum_range(date, date_blocks_range);
self.volume_1d_sum
.insert(date, self.volume.sum_range(date_blocks_range));
self.volume_in_dollars
.date_insert_sum_range(date, date_blocks_range);
self.volume_in_dollars_1d_sum
.insert(date, self.volume_in_dollars.sum_range(date_blocks_range));
}
}
@@ -113,77 +150,100 @@ impl TransactionDataset {
) {
self.count_1w_sma.multi_insert_simple_average(
heights,
dates,
&mut self.count,
TARGET_BLOCKS_PER_DAY * ONE_WEEK_IN_DAYS,
);
self.count_1d_sum_1w_sma.multi_insert_simple_average(
dates,
&mut self.count_1d_sum,
ONE_WEEK_IN_DAYS,
);
self.count_1m_sma.multi_insert_simple_average(
heights,
dates,
&mut self.count,
TARGET_BLOCKS_PER_DAY * ONE_MONTH_IN_DAYS,
);
self.count_1d_sum_1m_sma.multi_insert_simple_average(
dates,
&mut self.count_1d_sum,
ONE_MONTH_IN_DAYS,
);
self.volume_1w_sma.multi_insert_simple_average(
heights,
dates,
&mut self.volume,
TARGET_BLOCKS_PER_DAY * ONE_WEEK_IN_DAYS,
);
self.volume_1d_sum_1w_sma.multi_insert_simple_average(
dates,
&mut self.volume_1d_sum,
ONE_WEEK_IN_DAYS,
);
self.volume_1m_sma.multi_insert_simple_average(
heights,
dates,
&mut self.volume,
TARGET_BLOCKS_PER_DAY * ONE_MONTH_IN_DAYS,
);
self.volume_1d_sum_1m_sma.multi_insert_simple_average(
dates,
&mut self.volume_1d_sum,
ONE_MONTH_IN_DAYS,
);
self.volume_in_dollars_1w_sma.multi_insert_simple_average(
heights,
dates,
&mut self.volume_in_dollars,
ONE_WEEK_IN_DAYS,
TARGET_BLOCKS_PER_DAY * ONE_WEEK_IN_DAYS,
);
self.volume_in_dollars_1d_sum_1w_sma
.multi_insert_simple_average(
dates,
&mut self.volume_in_dollars_1d_sum,
ONE_WEEK_IN_DAYS,
);
self.volume_in_dollars_1m_sma.multi_insert_simple_average(
heights,
dates,
&mut self.volume_in_dollars,
ONE_MONTH_IN_DAYS,
TARGET_BLOCKS_PER_DAY * ONE_MONTH_IN_DAYS,
);
self.volume_in_dollars_1d_sum_1m_sma
.multi_insert_simple_average(
dates,
&mut self.volume_in_dollars_1d_sum,
ONE_MONTH_IN_DAYS,
);
self.annualized_volume.multi_insert_last_x_sum(
heights,
dates,
&mut self.volume,
&mut self.volume_1d_sum,
ONE_YEAR_IN_DAYS,
);
self.annualized_volume_in_dollars.multi_insert_last_x_sum(
heights,
dates,
&mut self.volume_in_dollars,
&mut self.volume_in_dollars_1d_sum,
ONE_YEAR_IN_DAYS,
);
self.velocity.multi_insert_divide(
heights,
dates,
&mut self.annualized_volume,
circulating_supply,
&mut circulating_supply.date,
);
self.transactions_per_second.height.multi_insert_divide(
heights,
&mut self.count.height,
&mut self.count,
block_interval,
);
self.transactions_per_second
.date
.multi_insert_simple_transform(dates, &mut self.count.date, |count, _| {
count as f32 / ONE_DAY_IN_S as f32
.multi_insert_simple_transform(dates, &mut self.count_1d_sum, |count, date| {
count as f32 / (date.get_day_completion() as f32 * ONE_DAY_IN_S as f32)
});
self.transactions_per_second_1w_sma
@@ -209,11 +269,11 @@ impl AnyDataset for TransactionDataset {
&self.min_initial_states
}
fn to_inserted_bi_map_vec(&self) -> Vec<&(dyn AnyBiMap + Send + Sync)> {
fn to_inserted_height_map_vec(&self) -> Vec<&(dyn AnyHeightMap + Send + Sync)> {
vec![&self.count, &self.volume, &self.volume_in_dollars]
}
fn to_inserted_mut_bi_map_vec(&mut self) -> Vec<&mut dyn AnyBiMap> {
fn to_inserted_mut_height_map_vec(&mut self) -> Vec<&mut dyn AnyHeightMap> {
vec![
&mut self.count,
&mut self.volume,
@@ -221,17 +281,24 @@ impl AnyDataset for TransactionDataset {
]
}
fn to_inserted_date_map_vec(&self) -> Vec<&(dyn AnyDateMap + Send + Sync)> {
vec![
&self.count_1d_sum,
&self.volume_1d_sum,
&self.volume_in_dollars_1d_sum,
]
}
fn to_inserted_mut_date_map_vec(&mut self) -> Vec<&mut dyn AnyDateMap> {
vec![
&mut self.count_1d_sum,
&mut self.volume_1d_sum,
&mut self.volume_in_dollars_1d_sum,
]
}
fn to_computed_bi_map_vec(&self) -> Vec<&(dyn AnyBiMap + Send + Sync)> {
vec![
&self.count_1w_sma,
&self.count_1m_sma,
&self.volume_1w_sma,
&self.volume_1m_sma,
&self.volume_in_dollars_1w_sma,
&self.volume_in_dollars_1m_sma,
&self.annualized_volume,
&self.annualized_volume_in_dollars,
&self.velocity,
&self.transactions_per_second,
&self.transactions_per_second_1w_sma,
&self.transactions_per_second_1m_sma,
@@ -239,6 +306,25 @@ impl AnyDataset for TransactionDataset {
}
fn to_computed_mut_bi_map_vec(&mut self) -> Vec<&mut dyn AnyBiMap> {
vec![
&mut self.transactions_per_second,
&mut self.transactions_per_second_1w_sma,
&mut self.transactions_per_second_1m_sma,
]
}
fn to_computed_height_map_vec(&self) -> Vec<&(dyn AnyHeightMap + Send + Sync)> {
vec![
&self.count_1w_sma,
&self.count_1m_sma,
&self.volume_1w_sma,
&self.volume_1m_sma,
&self.volume_in_dollars_1w_sma,
&self.volume_in_dollars_1m_sma,
]
}
fn to_computed_mut_height_map_vec(&mut self) -> Vec<&mut dyn AnyHeightMap> {
vec![
&mut self.count_1w_sma,
&mut self.count_1m_sma,
@@ -246,12 +332,34 @@ impl AnyDataset for TransactionDataset {
&mut self.volume_1m_sma,
&mut self.volume_in_dollars_1w_sma,
&mut self.volume_in_dollars_1m_sma,
]
}
fn to_computed_date_map_vec(&self) -> Vec<&(dyn AnyDateMap + Send + Sync)> {
vec![
&self.count_1d_sum_1w_sma,
&self.count_1d_sum_1m_sma,
&self.volume_1d_sum_1w_sma,
&self.volume_1d_sum_1m_sma,
&self.volume_in_dollars_1d_sum_1w_sma,
&self.volume_in_dollars_1d_sum_1m_sma,
&self.annualized_volume,
&self.annualized_volume_in_dollars,
&self.velocity,
]
}
fn to_computed_mut_date_map_vec(&mut self) -> Vec<&mut dyn AnyDateMap> {
vec![
&mut self.count_1d_sum_1w_sma,
&mut self.count_1d_sum_1m_sma,
&mut self.volume_1d_sum_1w_sma,
&mut self.volume_1d_sum_1m_sma,
&mut self.volume_in_dollars_1d_sum_1w_sma,
&mut self.volume_in_dollars_1d_sum_1m_sma,
&mut self.annualized_volume,
&mut self.annualized_volume_in_dollars,
&mut self.velocity,
&mut self.transactions_per_second,
&mut self.transactions_per_second_1w_sma,
&mut self.transactions_per_second_1m_sma,
]
}
}
+1 -1
View File
@@ -12,7 +12,7 @@ pub use crate::{
datasets::OHLC,
io::{Binary, Json, Serialization, COMPRESSED_BIN_EXTENSION, JSON_EXTENSION},
structs::{
Config, Date, DateMap, Exit, Height, HeightMap, MapChunkId, SerializedBTreeMap,
Config, Date, DateMap, Exit, Height, HeightMap, MapChunkId, MapValue, SerializedBTreeMap,
SerializedVec, HEIGHT_MAP_CHUNK_SIZE,
},
utils::{create_rpc, log, reset_logs},
+25 -44
View File
@@ -1,6 +1,6 @@
use std::{
iter::Sum,
ops::{Add, Div, Mul, RangeInclusive, Sub},
ops::{Add, Div, Mul, Sub},
};
use allocative::Allocative;
@@ -36,30 +36,30 @@ where
}
}
pub fn date_insert_sum_range(&mut self, date: Date, date_blocks_range: &RangeInclusive<u32>)
where
Value: Sum,
{
self.date
.insert(date, self.height.sum_range(date_blocks_range));
}
// pub fn date_insert_sum_range(&mut self, date: Date, date_blocks_range: &RangeInclusive<u32>)
// where
// Value: Sum,
// {
// self.date
// .insert(date, self.height.sum_range(date_blocks_range));
// }
pub fn multi_date_insert_sum_range(
&mut self,
dates: &[Date],
first_height: &mut DateMap<Height>,
last_height: &mut DateMap<Height>,
) where
Value: Sum,
{
dates.iter().for_each(|date| {
let first_height = first_height.get_or_import(date).unwrap();
let last_height = last_height.get_or_import(date).unwrap();
let range = (*first_height)..=(*last_height);
// pub fn multi_date_insert_sum_range(
// &mut self,
// dates: &[Date],
// first_height: &mut DateMap<Height>,
// last_height: &mut DateMap<Height>,
// ) where
// Value: Sum,
// {
// dates.iter().for_each(|date| {
// let first_height = first_height.get_or_import(date).unwrap();
// let last_height = last_height.get_or_import(date).unwrap();
// let range = (*first_height)..=(*last_height);
self.date.insert(*date, self.height.sum_range(&range));
})
}
// self.date.insert(*date, self.height.sum_range(&range));
// })
// }
pub fn multi_insert_const(&mut self, heights: &[Height], dates: &[Date], constant: Value) {
self.height.multi_insert_const(heights, constant);
@@ -176,6 +176,7 @@ where
.multi_insert_percentage(dates, &mut divided.date, &mut divider.date);
}
#[allow(unused)]
pub fn multi_insert_cumulative<K>(
&mut self,
heights: &[Height],
@@ -192,27 +193,6 @@ where
self.date.multi_insert_cumulative(dates, &mut source.date);
}
pub fn multi_insert_last_x_sum<K>(
&mut self,
heights: &[Height],
dates: &[Date],
source: &mut BiMap<K>,
days: usize,
) where
K: MapValue,
Value: LossyFrom<K>,
Value: Add<Output = Value> + Sub<Output = Value>,
{
self.height.multi_insert_last_x_sum(
heights,
&mut source.height,
TARGET_BLOCKS_PER_DAY * days,
);
self.date
.multi_insert_last_x_sum(dates, &mut source.date, days);
}
pub fn multi_insert_simple_average<K>(
&mut self,
heights: &[Height],
@@ -251,6 +231,7 @@ where
.multi_insert_net_change(dates, &mut source.date, days);
}
#[allow(unused)]
pub fn multi_insert_median(
&mut self,
heights: &[Height],
+2 -3
View File
@@ -45,9 +45,8 @@ impl Config {
const PATH: &'static str = "./config.toml";
pub fn import() -> color_eyre::Result<Self> {
let mut config_saved =
fs::read_to_string(Self::PATH).map_or(Config::default(), |contents| {
dbg!(&contents);
let mut config_saved = fs::read_to_string(Self::PATH)
.map_or(Config::default(), |contents| {
toml::from_str(&contents).unwrap_or_default()
});
+27 -3
View File
@@ -1,4 +1,4 @@
use std::{fmt, str::FromStr};
use std::{cmp::Ordering, fmt, str::FromStr};
use allocative::{Allocative, Visitor};
use bincode::{
@@ -7,11 +7,13 @@ use bincode::{
error::{DecodeError, EncodeError},
BorrowDecode, Decode, Encode,
};
use chrono::{Datelike, Days, NaiveDate};
use chrono::{Datelike, Days, NaiveDate, NaiveDateTime};
use derive_deref::{Deref, DerefMut};
use serde::{Deserialize, Serialize};
use super::{DateMapChunkId, MapKey};
use crate::utils::ONE_DAY_IN_S;
use super::{DateMapChunkId, MapKey, Timestamp};
const NUMBER_OF_UNSAFE_DATES: usize = 2;
const MIN_YEAR: i32 = 2009;
@@ -49,6 +51,28 @@ impl Date {
pub fn difference_in_days_between(&self, older: Self) -> u32 {
(**self - *older).num_days() as u32
}
pub fn to_timestamp(self) -> Timestamp {
Timestamp::wrap(NaiveDateTime::from(*self).and_utc().timestamp() as u32)
}
/// Returns value between 0.0 and 1.0 depending on its completion
///
/// Any date before today (utc) will return 1.0
///
/// Any date after today (utc) will panic even though it should return 0.0, as it shouldn't happen in the code
///
/// Any date equal to today will have a completion between 0.0 and 1.0
pub fn get_day_completion(self) -> f64 {
let now = Timestamp::now();
let today = Date::today();
match self.cmp(&today) {
Ordering::Less => 1.0,
Ordering::Equal => *(now - self.to_timestamp()) as f64 / ONE_DAY_IN_S as f64,
Ordering::Greater => unreachable!("0.0 but shouldn't be called"),
}
}
}
impl MapKey<DateMapChunkId> for Date {
+23 -3
View File
@@ -1,17 +1,19 @@
use std::iter::Sum;
use crate::{Date, HeightMap};
use super::{AnyMap, DateMapChunkId, GenericMap, Height, MapValue, SerializedBTreeMap};
pub type DateMap<Value> = GenericMap<Date, Value, DateMapChunkId, SerializedBTreeMap<Date, Value>>;
impl<T> DateMap<T>
impl<Value> DateMap<Value>
where
T: MapValue,
Value: MapValue,
{
pub fn multi_insert_last(
&mut self,
dates: &[Date],
source: &mut HeightMap<T>,
source: &mut HeightMap<Value>,
last_height: &mut DateMap<Height>,
) {
dates.iter().for_each(|date| {
@@ -23,6 +25,24 @@ where
);
});
}
pub fn multi_insert_sum_range(
&mut self,
dates: &[Date],
height_map: &HeightMap<Value>,
first_height: &mut DateMap<Height>,
last_height: &mut DateMap<Height>,
) where
Value: Sum,
{
dates.iter().for_each(|date| {
let first_height = first_height.get_or_import(date).unwrap();
let last_height = last_height.get_or_import(date).unwrap();
let range = (*first_height)..=(*last_height);
self.insert(*date, height_map.sum_range(&range));
})
}
}
pub trait AnyDateMap: AnyMap {
+2 -2
View File
@@ -413,11 +413,11 @@ where
&mut self,
keys: &[Key],
source: &mut GenericMap<Key, SourceValue, ChunkId, SourceSerialized>,
transform: F,
mut transform: F,
) where
SourceValue: MapValue,
SourceSerialized: MapSerialized<Key, SourceValue, ChunkId>,
F: Fn(SourceValue, &Key) -> Value,
F: FnMut(SourceValue, &Key) -> Value,
{
keys.iter().for_each(|key| {
self.insert(*key, transform(source.get_or_import(key).unwrap(), key));
+1
View File
@@ -23,6 +23,7 @@ pub trait MapValue:
{
}
impl MapValue for u8 {}
impl MapValue for u16 {}
impl MapValue for u32 {}
impl MapValue for u64 {}
+35 -3
View File
@@ -1,10 +1,12 @@
use std::{collections::BTreeMap, fmt::Debug};
use std::{collections::BTreeMap, fmt::Debug, path::Path};
use allocative::Allocative;
use bincode::{Decode, Encode};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use super::{MapChunkId, MapKey, MapSerialized, MapValue};
use crate::Serialization;
use super::{DateMap, MapChunkId, MapKey, MapSerialized, MapValue};
#[derive(Debug, Default, Serialize, Deserialize, Encode, Decode, Allocative)]
pub struct SerializedBTreeMap<Key, Value>
@@ -12,7 +14,37 @@ where
Key: Ord,
{
version: u32,
map: BTreeMap<Key, Value>,
pub map: BTreeMap<Key, Value>,
}
impl<Key, Value> SerializedBTreeMap<Key, Value>
where
Key: Ord,
{
pub fn import_all<ChunkId>(path: &Path, serialization: &Serialization) -> Self
where
Self: Debug + Serialize + DeserializeOwned + Encode + Decode,
ChunkId: MapChunkId,
Key: MapKey<ChunkId>,
Value: MapValue,
{
let mut s = None;
DateMap::<usize>::_read_dir(path, serialization)
.iter()
.for_each(|(_, path)| {
let map = serialization.import::<Self>(path).unwrap();
if s.is_none() {
s.replace(map);
} else {
#[allow(clippy::unnecessary_unwrap)]
s.as_mut().unwrap().map.extend(map.map);
}
});
s.unwrap()
}
}
impl<Key, Value, ChunkId> MapSerialized<Key, Value, ChunkId> for SerializedBTreeMap<Key, Value>
+30 -3
View File
@@ -1,15 +1,42 @@
use std::{cmp::Ordering, collections::BTreeMap, fmt::Debug};
use std::{cmp::Ordering, collections::BTreeMap, fmt::Debug, path::Path};
use allocative::Allocative;
use bincode::{Decode, Encode};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use super::{MapChunkId, MapKey, MapSerialized, MapValue};
use crate::Serialization;
use super::{HeightMap, MapChunkId, MapKey, MapSerialized, MapValue};
#[derive(Debug, Default, Serialize, Deserialize, Encode, Decode, Allocative)]
pub struct SerializedVec<Value> {
version: u32,
map: Vec<Value>,
pub map: Vec<Value>,
}
impl<Value> SerializedVec<Value> {
pub fn import_all(path: &Path, serialization: &Serialization) -> Self
where
Self: Debug + Serialize + DeserializeOwned + Encode + Decode,
Value: MapValue,
{
let mut s = None;
HeightMap::<usize>::_read_dir(path, serialization)
.iter()
.for_each(|(_, path)| {
let mut map = serialization.import::<Self>(path).unwrap();
if s.is_none() {
s.replace(map);
} else {
#[allow(clippy::unnecessary_unwrap)]
s.as_mut().unwrap().map.append(&mut map.map);
}
});
s.unwrap()
}
}
impl<Key, Value, ChunkId> MapSerialized<Key, Value, ChunkId> for SerializedVec<Value>
+4
View File
@@ -36,6 +36,10 @@ impl Timestamp {
Self(timestamp)
}
pub fn now() -> Self {
Self(chrono::offset::Utc::now().timestamp() as u32)
}
pub fn to_date(self) -> Date {
Date::wrap(
Utc.timestamp_opt(i64::from(self.0), 0)
+63 -52
View File
@@ -20,11 +20,15 @@ use crate::{
AppState,
};
use super::response::{typed_value_to_response, value_to_response};
use super::{
extension::Extension,
response::{typed_value_to_response, value_to_response},
};
#[derive(Deserialize)]
pub struct Params {
chunk: Option<usize>,
all: Option<bool>,
}
pub async fn dataset_handler(
@@ -46,43 +50,44 @@ pub async fn dataset_handler(
}
}
const DATE_PREFIX: &str = "date-to-";
const HEIGHT_PREFIX: &str = "height-to-";
fn _dataset_handler(
headers: HeaderMap,
Path(path): Path<String>,
query: Query<Params>,
AppState { routes }: AppState,
) -> color_eyre::Result<Response> {
if query.chunk.is_some() && query.all.is_some() {
return Err(eyre!("chunk and all are exclusive"));
}
log(&format!(
"{}{}",
"{}{}{}",
path,
query.chunk.map_or("".to_string(), |chunk| format!(
"{}{chunk}",
"?chunk=".bright_black()
)),
query.all.map_or("".to_string(), |all| format!(
"{}{all}",
"?all=".bright_black()
))
));
let date_prefix = "date-to-";
let height_prefix = "height-to-";
let (kind, route) = if path.starts_with(date_prefix) {
(
Kind::Date,
routes.date.get(&replace_dash_by_underscore(
path.strip_prefix(date_prefix).unwrap(),
)),
)
} else if path.starts_with(height_prefix) {
(
Kind::Height,
routes.height.get(&replace_dash_by_underscore(
path.strip_prefix(height_prefix).unwrap(),
)),
)
let (kind, id, route) = if path.starts_with(DATE_PREFIX) {
let id = convert_path_to_id(path.strip_prefix(DATE_PREFIX).unwrap());
let route = routes.date.get(&id);
(Kind::Date, id, route)
} else if path.starts_with(HEIGHT_PREFIX) {
let id = convert_path_to_id(path.strip_prefix(HEIGHT_PREFIX).unwrap());
let route = routes.height.get(&id);
(Kind::Height, id, route)
} else {
(
Kind::Last,
routes.last.get(&replace_dash_by_underscore(&path)),
)
let id = convert_path_to_id(&path);
let route = routes.last.get(&id);
(Kind::Last, id, route)
};
if route.is_none() {
@@ -93,25 +98,28 @@ fn _dataset_handler(
let mut chunk = None;
match kind {
Kind::Date => {
let datasets = DateMap::<usize>::_read_dir(&route.file_path, &route.serialization);
if query.all.map_or(true, |b| !b) {
match kind {
Kind::Date => {
let datasets = DateMap::<usize>::_read_dir(&route.file_path, &route.serialization);
process_datasets(&headers, kind, &mut chunk, &mut route, query, datasets)?;
}
Kind::Height => {
let datasets = HeightMap::<usize>::_read_dir(&route.file_path, &route.serialization);
process_datasets(&headers, kind, &mut chunk, &mut route, query, datasets)?;
}
Kind::Height => {
let datasets =
HeightMap::<usize>::_read_dir(&route.file_path, &route.serialization);
process_datasets(&headers, kind, &mut chunk, &mut route, query, datasets)?;
}
Kind::Last => {
if !route.values_type.ends_with("Value") {
route.file_path.set_extension(COMPRESSED_BIN_EXTENSION);
} else {
route.file_path.set_extension(JSON_EXTENSION);
process_datasets(&headers, kind, &mut chunk, &mut route, query, datasets)?;
}
Kind::Last => {
if !route.values_type.ends_with("Value") {
route.file_path.set_extension(COMPRESSED_BIN_EXTENSION);
} else {
route.file_path.set_extension(JSON_EXTENSION);
}
}
}
};
}
let (date, response) = headers.check_if_modified_since(&route.file_path).unwrap();
@@ -121,18 +129,22 @@ fn _dataset_handler(
let type_name = route.values_type.split("::").last().unwrap();
let extension = Extension::from(&std::path::PathBuf::from(&path));
let mut response = match type_name {
"u8" => typed_value_to_response::<u8>(kind, &route, chunk)?,
"u16" => typed_value_to_response::<u16>(kind, &route, chunk)?,
"u32" => typed_value_to_response::<u32>(kind, &route, chunk)?,
"u64" => typed_value_to_response::<u64>(kind, &route, chunk)?,
"usize" => typed_value_to_response::<usize>(kind, &route, chunk)?,
"f32" => typed_value_to_response::<f32>(kind, &route, chunk)?,
"f64" => typed_value_to_response::<f64>(kind, &route, chunk)?,
"OHLC" => typed_value_to_response::<OHLC>(kind, &route, chunk)?,
"Date" => typed_value_to_response::<Date>(kind, &route, chunk)?,
"Height" => typed_value_to_response::<Height>(kind, &route, chunk)?,
"Value" => value_to_response::<serde_json::Value>(Json::import(&route.file_path)?),
"u8" => typed_value_to_response::<u8>(kind, &route, chunk, id, extension)?,
"u16" => typed_value_to_response::<u16>(kind, &route, chunk, id, extension)?,
"u32" => typed_value_to_response::<u32>(kind, &route, chunk, id, extension)?,
"u64" => typed_value_to_response::<u64>(kind, &route, chunk, id, extension)?,
"usize" => typed_value_to_response::<usize>(kind, &route, chunk, id, extension)?,
"f32" => typed_value_to_response::<f32>(kind, &route, chunk, id, extension)?,
"f64" => typed_value_to_response::<f64>(kind, &route, chunk, id, extension)?,
"OHLC" => typed_value_to_response::<OHLC>(kind, &route, chunk, id, extension)?,
"Date" => typed_value_to_response::<Date>(kind, &route, chunk, id, extension)?,
"Height" => typed_value_to_response::<Height>(kind, &route, chunk, id, extension)?,
"Value" => {
value_to_response::<serde_json::Value>(Json::import(&route.file_path)?, extension)
}
_ => panic!("Incompatible type: {type_name}"),
};
@@ -142,8 +154,8 @@ fn _dataset_handler(
Ok(response)
}
fn replace_dash_by_underscore(s: &str) -> String {
s.replace('-', "_")
fn convert_path_to_id(s: &str) -> String {
Extension::remove_extension(s).replace('-', "_")
}
fn process_datasets<ChunkId>(
@@ -174,7 +186,6 @@ where
}
let path = path.unwrap();
route.file_path = path.clone();
let offset = match kind {
+41
View File
@@ -0,0 +1,41 @@
use std::path::Path;
#[derive(PartialEq, Eq)]
pub enum Extension {
CSV,
JSON,
}
impl Extension {
pub fn from(path: &Path) -> Option<Self> {
if let Some(extension) = path.extension() {
let extension = extension.to_str().unwrap();
if extension == Self::CSV.to_str() {
Some(Self::CSV)
} else if extension == Self::JSON.to_str() {
Some(Self::JSON)
} else {
None
}
} else {
None
}
}
pub fn to_str(&self) -> &str {
match self {
Extension::CSV => "csv",
Extension::JSON => "json",
}
}
pub fn to_dot_str(&self) -> String {
format!(".{}", self.to_str())
}
pub fn remove_extension(s: &str) -> String {
s.replace(&Self::CSV.to_dot_str(), "")
.replace(&Self::JSON.to_dot_str(), "")
}
}
+9 -6
View File
@@ -3,14 +3,17 @@ use reqwest::header::HOST;
use crate::AppState;
use super::response::generic_to_reponse;
use super::response::{generic_to_reponse, update_reponse_headers};
pub async fn fallback(headers: HeaderMap, State(app_state): State<AppState>) -> Response {
generic_to_reponse(
app_state
.routes
.to_full_paths(headers[HOST].to_str().unwrap().to_string()),
None,
update_reponse_headers(
generic_to_reponse(
app_state
.routes
.to_full_paths(headers[HOST].to_str().unwrap().to_string()),
None,
),
60,
None,
)
}
+2
View File
@@ -1,5 +1,7 @@
mod dataset;
mod extension;
mod fallback;
mod response;
pub use dataset::*;
+90 -39
View File
@@ -1,8 +1,8 @@
use std::{fmt::Debug, path::Path};
use std::fmt::Debug;
use axum::response::{IntoResponse, Json, Response};
use bincode::Decode;
use parser::{Date, SerializedBTreeMap, SerializedVec};
use parser::{Date, MapValue, SerializedBTreeMap, SerializedVec};
use serde::de::DeserializeOwned;
use serde::Serialize;
@@ -11,6 +11,8 @@ use crate::{
header_map::HeaderMapUtils,
};
use super::extension::Extension;
#[derive(Serialize)]
struct WrappedDataset<'a, T>
where
@@ -25,70 +27,119 @@ pub fn typed_value_to_response<T>(
kind: Kind,
route: &Route,
chunk: Option<Chunk>,
id: String,
extension: Option<Extension>,
) -> color_eyre::Result<Response>
where
T: Serialize + Debug + DeserializeOwned + Decode,
T: Serialize + Debug + DeserializeOwned + Decode + MapValue,
{
Ok(match kind {
Kind::Date => dataset_to_response(
route
.serialization
.import::<SerializedBTreeMap<Date, T>>(Path::new(&route.file_path))?,
chunk.unwrap(),
),
Kind::Height => dataset_to_response(
route
.serialization
.import::<SerializedVec<T>>(Path::new(&route.file_path))?,
chunk.unwrap(),
),
Kind::Date => {
let dataset = if chunk.is_some() {
route
.serialization
.import::<SerializedBTreeMap<Date, T>>(&route.file_path)?
} else {
SerializedBTreeMap::<Date, T>::import_all(&route.file_path, &route.serialization)
};
if extension == Some(Extension::CSV) {
let mut csv = format!("date,{}\n", id);
dataset.map.iter().for_each(|(k, v)| {
csv += &format!("{},{:?}\n", k, v);
});
string_to_response(csv, extension)
} else {
dataset_to_response(dataset, chunk, extension)
}
}
Kind::Height => {
let dataset = if chunk.is_some() {
route
.serialization
.import::<SerializedVec<T>>(&route.file_path)?
} else {
SerializedVec::<T>::import_all(&route.file_path, &route.serialization)
};
if extension == Some(Extension::CSV) {
let mut csv = format!("height,{}\n", id);
let starting_height = chunk.map_or(0, |chunk| chunk.id);
dataset.map.iter().enumerate().for_each(|(k, v)| {
csv += &format!("{},{:?}\n", starting_height + k, v);
});
string_to_response(csv, extension)
} else {
dataset_to_response(dataset, chunk, extension)
}
}
Kind::Last => value_to_response(
route
.serialization
.import::<T>(Path::new(&route.file_path))?,
route.serialization.import::<T>(&route.file_path)?,
extension,
),
})
}
pub fn value_to_response<T>(value: T) -> Response
where
T: Serialize,
{
generic_to_reponse(value, None, 1)
pub fn string_to_response(s: String, extension: Option<Extension>) -> Response {
update_reponse_headers(s.into_response(), 5, extension)
}
fn dataset_to_response<T>(dataset: T, chunk: Chunk) -> Response
pub fn value_to_response<T>(value: T, extension: Option<Extension>) -> Response
where
T: Serialize,
{
generic_to_reponse(dataset, Some(chunk), 5)
update_reponse_headers(generic_to_reponse(value, None), 1, extension)
}
pub fn generic_to_reponse<T>(generic: T, chunk: Option<Chunk>, cache_time: u64) -> Response
fn dataset_to_response<T>(
dataset: T,
chunk: Option<Chunk>,
extension: Option<Extension>,
) -> Response
where
T: Serialize,
{
let mut response = {
if let Some(chunk) = chunk {
Json(WrappedDataset {
source: "https://kibo.money",
chunk,
dataset: generic,
})
.into_response()
} else {
Json(generic).into_response()
}
};
update_reponse_headers(generic_to_reponse(dataset, chunk), 5, extension)
}
pub fn generic_to_reponse<T>(generic: T, chunk: Option<Chunk>) -> Response
where
T: Serialize,
{
if let Some(chunk) = chunk {
Json(WrappedDataset {
source: "https://kibo.money",
chunk,
dataset: generic,
})
.into_response()
} else {
Json(generic).into_response()
}
}
pub fn update_reponse_headers(
mut response: Response,
cache_time: u64,
extension: Option<Extension>,
) -> Response {
let headers = response.headers_mut();
let max_age = cache_time;
let stale_while_revalidate = 2 * max_age;
headers.insert_cors();
headers.insert_content_type_application_json();
headers.insert_cache_control_revalidate(max_age, stale_while_revalidate);
match extension {
Some(Extension::CSV) => headers.insert_content_type_text_csv(),
_ => headers.insert_content_type_application_json(),
}
response
}
+1 -1
View File
@@ -24,7 +24,7 @@ pub struct Route {
pub struct Routes(pub Grouped<HashMap<String, Route>>);
const INPUTS_PATH: &str = "./in";
const WEBSITE_TYPES_PATH: &str = "../website/types";
const WEBSITE_TYPES_PATH: &str = "../website/scripts/types";
impl Routes {
pub fn build() -> Self {
+11
View File
@@ -34,6 +34,8 @@ pub trait HeaderMapUtils {
fn insert_cache_control_revalidate(&mut self, max_age: u64, stale_while_revalidate: u64);
fn insert_last_modified(&mut self, date: DateTime<Utc>);
fn insert_content_disposition_attachment(&mut self);
fn insert_content_type(&mut self, path: &Path);
fn insert_content_type_image_icon(&mut self);
fn insert_content_type_image_jpeg(&mut self);
@@ -43,6 +45,7 @@ pub trait HeaderMapUtils {
fn insert_content_type_application_manifest_json(&mut self);
fn insert_content_type_application_pdf(&mut self);
fn insert_content_type_text_css(&mut self);
fn insert_content_type_text_csv(&mut self);
fn insert_content_type_text_html(&mut self);
fn insert_content_type_text_plain(&mut self);
fn insert_content_type_font_woff2(&mut self);
@@ -181,6 +184,10 @@ impl HeaderMapUtils for HeaderMap {
);
}
fn insert_content_disposition_attachment(&mut self) {
self.insert(header::CONTENT_DISPOSITION, "attachment".parse().unwrap());
}
fn insert_content_type_application_json(&mut self) {
self.insert(header::CONTENT_TYPE, "application/json".parse().unwrap());
}
@@ -200,6 +207,10 @@ impl HeaderMapUtils for HeaderMap {
self.insert(header::CONTENT_TYPE, "text/css".parse().unwrap());
}
fn insert_content_type_text_csv(&mut self) {
self.insert(header::CONTENT_TYPE, "text/csv".parse().unwrap());
}
fn insert_content_type_text_html(&mut self) {
self.insert(header::CONTENT_TYPE, "text/html".parse().unwrap());
}
+8 -228
View File
@@ -13,7 +13,7 @@
/>
<link rel="manifest" href="/manifest.webmanifest" />
<meta name="mobile-web-app-capable" content="yes" />
<script type="module" crossorigin src="./script.js"></script>
<script type="module" crossorigin src="/scripts/main.js"></script>
<!-- ------ -->
<!-- Styles -->
@@ -395,6 +395,11 @@
}
}
details {
/* content-visibility: auto;
contain-intrinsic-size: auto none; */
}
fieldset {
> div.field {
display: flex;
@@ -1028,231 +1033,6 @@
max-width: 32rem;
}
}
> #dashboards {
z-index: 50;
margin: -0.5px calc(-1.5rem - 1px);
display: flex;
> details {
/* border: 1px; */
> summary {
margin: -0.5px;
display: block;
padding: 0.5rem 1.5rem;
text-align: left;
border: 1px;
details[open] > & {
border-bottom-style: dashed !important;
border-bottom-width: 1px;
}
}
> table {
border: 1px;
border-top-width: 0px;
margin: -0.5px;
width: calc(100% + 1px);
border-collapse: separate;
table-layout: auto;
padding: 0.375rem 1.5rem;
tr {
/* border: 1px; */
&:hover,
&:hover * {
color: var(--orange) !important;
}
td {
padding: 0.125rem 0;
text-align: right;
&:first-child {
text-align: left;
color: var(--off-color);
}
> i {
color: var(--off-color);
}
}
}
}
}
}
> #charts {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
> #legend {
display: flex;
align-items: center;
gap: 1.5rem;
margin: -1rem -1.5rem;
padding: 1rem 1.5rem;
overflow-x: auto;
min-width: 0;
> div {
flex: 0;
display: flex;
align-items: center;
> label {
margin: -0.375rem 0;
color: var(--color);
&:has(input:not(:checked)) {
color: var(--off-color);
> span.main > span.name {
text-decoration-style: wavy;
text-decoration-thickness: 1.5px;
text-decoration-color: var(--color);
text-decoration-line: line-through;
}
&:hover {
* {
color: var(--off-color) !important;
}
> span.main > span.name {
text-decoration-color: var(--orange) !important;
}
}
}
}
> a {
padding: 0.375rem;
margin: -0.375rem;
> svg {
/* padding: 0.375rem; */
margin: 0rem;
width: 1rem;
height: 1rem;
}
}
}
}
> #chart-list {
margin-top: 1rem;
position: relative;
margin-left: -1.5rem /* -24px */;
margin-right: -2rem /* -32px */;
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
z-index: 20;
> .chart-wrapper {
height: 100%;
position: relative;
min-height: 0px;
width: 100%;
cursor: crosshair;
&:has(+ .chart-wrapper:not([hidden])) {
height: calc(100% - 62px);
}
> fieldset {
pointer-events: none;
position: absolute;
left: 0px;
top: 0px;
z-index: 10;
display: flex;
align-items: center;
padding-left: 1.5rem /* 24px */;
padding-right: 1.5rem /* 24px */;
font-size: var(--font-size-xs);
line-height: var(--line-height-xs);
> * + * {
margin-left: 0.5rem; /* 8px */
}
> * + span {
color: var(--off-color);
}
}
> .chart-div {
width: 100%;
height: 100%;
}
}
}
> #timescale {
margin-top: 1rem;
display: flex;
overflow: hidden;
z-index: 50;
@media (max-width: 767px) {
margin-bottom: -1.5rem;
border-top: 1px;
margin-left: -1.5rem;
margin-right: -1.5rem;
}
@media (min-width: 768px) {
border-radius: 9999px;
border: 1px;
}
> button {
flex: 0;
}
> div {
min-width: 0;
flex: 1;
display: flex;
position: relative;
> #timescale-date-buttons,
> #timescale-height-buttons {
display: flex;
overflow-x: auto;
> button {
color: var(--off-color);
flex-shrink: 0;
flex-grow: 1;
padding: 0.5rem;
white-space: nowrap;
min-width: 5rem;
}
}
}
> *:not(:first-child):not(:last-child) {
border-left: 1px;
border-right: 1px;
}
}
}
> object {
margin: -1.5rem;
flex: 1;
z-index: 100;
}
}
#share-div {
@@ -1600,7 +1380,7 @@
}
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/service-worker.js");
navigator.serviceWorker.register("/scripts/service-worker.js");
}
</script>
@@ -2444,7 +2224,7 @@
</button>
</div>
</div>
<div id="dashboards" hidden></div>
<div id="dashboard" hidden></div>
</section>
</aside>
<div id="share-div" hidden>
-10199
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+309
View File
@@ -0,0 +1,309 @@
/**
* @import {Options} from './options';
*/
/**
* @param {Object} args
* @param {Flexmasonry} args.flexmasonry
* @param {Signal<Record<LastPath, number> | null>} args.lastValues
* @param {Options} args.options
* @param {Accessor<DashboardOption>} args.selected
* @param {Signals} args.signals
* @param {Elements} args.elements
* @param {Utilities} args.utils
*/
export function initDashboardElement({
elements,
flexmasonry,
lastValues,
options,
selected,
signals,
utils,
}) {
flexmasonry.destroyAll();
const element = elements.dashboard;
element.innerHTML = "";
/**
* @param {HTMLElement} parent
* @param {string} name
* @param {boolean} [defaultOpen]
*/
function createDetails(parent, name, defaultOpen) {
const details = window.document.createElement("details");
details.open = defaultOpen || false;
parent.append(details);
const summary = window.document.createElement("summary");
summary.innerHTML = name;
details.append(summary);
const div = window.document.createElement("div");
details.append(div);
return div;
}
/**
* @param {HTMLElement} parent
* @param {string} name
*/
function createTable(parent, name) {
const table = window.document.createElement("table");
parent.append(table);
const tbody = window.document.createElement("tbody");
table.append(tbody);
return tbody;
}
/**
* @param {Object} args
* @param {HTMLTableSectionElement} args.tbody
* @param {string} args.name
* @param {Unit} [args.unit]
* @param {string} args.path
* @param {boolean} [args.formatNumber]
*/
function createRow({ tbody, unit, name, path, formatNumber }) {
path = path.replace("date-to-", "").replace("height-to-", "");
const tr = window.document.createElement("tr");
tbody.append(tr);
const tdName = window.document.createElement("td");
tr.append(tdName);
const a = window.document.createElement("a");
a.href = path;
a.innerHTML = name;
tdName.append(a);
const tdValue = window.document.createElement("td");
const preSmall = window.document.createElement("small");
tdValue.append(preSmall);
const valueSpan = window.document.createElement("span");
tdValue.append(valueSpan);
const postSmall = window.document.createElement("small");
tdValue.append(postSmall);
signals.createEffect(() => {
const _lastValues = lastValues();
if (!_lastValues || !(path in _lastValues)) return;
const value = _lastValues[/** @type {LastPath} */ (path)] ?? 0;
tdValue.title = `${utils.locale.numberToUSFormat(value ?? 0)}`;
const formattedValue =
formatNumber ?? unit !== "Count"
? utils.locale.numberToShortUSFormat(value)
: utils.locale.numberToUSFormat(
value,
unit === "Count" ? 0 : undefined,
);
if (unit === "Date") {
valueSpan.innerHTML = String(value);
postSmall.innerHTML = ` UTC`;
return;
}
valueSpan.innerHTML = formattedValue;
switch (unit) {
case "US Dollars": {
preSmall.innerHTML = `$`;
break;
}
case "Bitcoin": {
preSmall.innerHTML = ``;
break;
}
case "Percentage": {
postSmall.innerHTML = `%`;
break;
}
case "Seconds": {
postSmall.innerHTML = ` sec`;
break;
}
case "Megabytes": {
postSmall.innerHTML = ` MB`;
break;
}
}
});
tr.append(tdValue);
}
// selected().groups.forEach(({ name, values, unit: groupUnit }) => {
// const tbody = createTable(name);
// values.forEach(({ name, path, unit: valueUnit, formatNumber }) => {
// const unit = groupUnit ?? valueUnit;
// createRow({
// name,
// tbody,
// path,
// unit,
// formatNumber,
// });
// });
// });
//
/** @type {HTMLTableSectionElement | null} */
let currentTbody = null;
const separator = " · ";
/**
* @param {Object} args
* @param {OptionsTree} args.tree
* @param {{group: OptionsGroup; element: HTMLElement} | null} args.parent
* @param {string[]} [args.namePre]
*/
function recursiveOptionConverter({ tree, parent, namePre }) {
tree.forEach((anyOption) => {
if ("tree" in anyOption) {
currentTbody = null;
const group = anyOption;
if (!group.tree.length || group.dashboard?.skip) return;
if (!parent || group.dashboard?.separate) {
recursiveOptionConverter({
tree: group.tree,
parent: {
group,
element: createDetails(
element,
group.name,
group.dashboard?.defaultOpen,
),
},
namePre,
});
} else {
const pre = group.dashboard?.flatten
? [...(namePre || []), group.name]
: [];
let element = parent.element;
if (!group.dashboard?.flatten) {
element = createDetails(
parent.element,
group.name,
group.dashboard?.defaultOpen,
);
}
recursiveOptionConverter({
tree: group.tree,
parent: {
group,
element,
},
namePre: pre,
});
}
} else if (anyOption.kind === "chart" && parent) {
currentTbody ||= createTable(
parent.element,
(namePre || []).join(separator),
);
if (!currentTbody) throw "Shouldn't be possible";
const tbody = currentTbody;
const option = anyOption;
if (option.dashboard?.skip) return;
const { top, bottom } = option;
const topLength = top?.length ?? 0;
const bottomLength = bottom?.length ?? 0;
/**
* @param {SeriesBlueprint[]} array
*/
function createRowFromBlueprint(array) {
const searchArray = array.filter(
(blueprint) =>
blueprint.options?.lastValueVisible !== false &&
/** @type {LineStyleOptions | undefined} */ (blueprint.options)
?.lineStyle === undefined,
);
const blueprint =
searchArray.length === 1
? searchArray[0]
: searchArray.find((blueprint) => blueprint.main);
if (!blueprint) return;
let name = namePre?.join(separator) || "";
if (!option.dashboard?.ignoreName) {
if (name) {
name += separator;
}
name += option.name;
}
createRow({
name,
tbody,
path: blueprint.datasetPath,
unit: option.unit,
formatNumber: blueprint.formatNumber,
});
}
if (!topLength && !bottomLength) {
createRow({
name: option.name,
tbody,
path: "close",
unit: option.unit,
formatNumber: false,
});
} else if (top && bottomLength === 0) {
createRowFromBlueprint(top);
} else if (bottom) {
createRowFromBlueprint(bottom);
}
} else if (parent && "unit" in anyOption) {
createRow({
name: anyOption.name,
tbody: currentTbody,
path: anyOption.path,
unit: anyOption.unit,
formatNumber: false,
});
}
});
currentTbody = null;
}
recursiveOptionConverter({
tree: /** @type {OptionsGroup} */ (
/** @type {OptionsGroup} */ (options.tree[1]).tree[0]
).tree,
parent: null,
});
flexmasonry.init([element]);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -12,12 +12,18 @@ self.addEventListener("install", (_event) => {
return cache.addAll([
"/",
"/index.html",
"/script.js",
"/packages/solid-signals/2024-04-17/script.js",
"/packages/ufuzzy/v1.0.14/script.js",
"/packages/lean-qr/v2.3.4/script.js",
"/packages/lightweight-charts/v4.2.0/script.js",
"/assets/fonts/satoshi/2024-09/font.var.woff2",
"/scripts/main.js",
"/scripts/dashboard.js",
"/styles/dashboard.css",
"/scripts/chart.js",
"/styles/chart.css",
"/scripts/packages/flexmasonry/v0.2.3-modified/script.js",
"/scripts/packages/flexmasonry/v0.2.3-modified/style.css",
"/scripts/packages/lean-qr/v2.3.4/script.js",
"/scripts/packages/lightweight-charts/v4.2.0/script.js",
"/scripts/packages/solid-signals/2024-04-17/script.js",
"/scripts/packages/ufuzzy/v1.0.14/script.js",
]);
}),
);
File diff suppressed because one or more lines are too long
+18 -2
View File
@@ -40,6 +40,8 @@ type DatasetPath<Scale extends TimeScale> = Scale extends "date"
type AnyDatasetPath = import("./paths").DatePath | import("./paths").HeightPath;
type AnyPath = AnyDatasetPath | LastPath;
type Color = () => string;
interface BaselineSpecificSeriesBlueprint {
@@ -74,6 +76,8 @@ type SeriesBlueprint = {
datasetPath: AnyDatasetPath;
title: string;
defaultActive?: boolean;
main?: boolean;
formatNumber?: false;
} & AnySpecificSeriesBlueprint;
type Unit =
@@ -115,9 +119,9 @@ interface PartialDashboardOption extends PartialOption {
unit?: Unit;
values: {
name: string;
path?: LastPath;
path: LastPath;
unit?: Unit;
long?: true;
formatNumber?: false;
}[];
}[];
}
@@ -125,10 +129,15 @@ interface PartialDashboardOption extends PartialOption {
interface PartialChartOption extends PartialOption {
scale: TimeScale;
title: string;
shortTitle?: string;
unit: Unit;
description: string;
top?: SeriesBlueprint[];
bottom?: SeriesBlueprint[];
dashboard?: {
ignoreName?: boolean;
skip?: boolean;
};
}
interface PartialPdfOption extends PartialOption {
@@ -138,6 +147,13 @@ interface PartialPdfOption extends PartialOption {
interface PartialOptionsGroup {
name: string;
tree: PartialOptionsTree;
dashboard?: {
skip?: true;
flatten?: true;
hopOver?: true;
separate?: true;
defaultOpen?: true;
};
}
type AnyPartialOption =
+161
View File
@@ -0,0 +1,161 @@
#charts {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
> #legend {
display: flex;
align-items: center;
gap: 1.5rem;
margin: -1rem -1.5rem;
padding: 1rem 1.5rem;
overflow-x: auto;
min-width: 0;
> div {
flex: 0;
display: flex;
align-items: center;
> label {
margin: -0.375rem 0;
color: var(--color);
&:has(input:not(:checked)) {
color: var(--off-color);
> span.main > span.name {
text-decoration-style: wavy;
text-decoration-thickness: 1.5px;
text-decoration-color: var(--color);
text-decoration-line: line-through;
}
&:hover {
* {
color: var(--off-color) !important;
}
> span.main > span.name {
text-decoration-color: var(--orange) !important;
}
}
}
}
> a {
padding: 0.375rem;
margin: -0.375rem;
> svg {
/* padding: 0.375rem; */
margin: 0rem;
width: 1rem;
height: 1rem;
}
}
}
}
> #chart-list {
margin-top: 1rem;
position: relative;
margin-left: -1.5rem /* -24px */;
margin-right: -2rem /* -32px */;
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
z-index: 20;
> .chart-wrapper {
height: 100%;
position: relative;
min-height: 0px;
width: 100%;
cursor: crosshair;
&:has(+ .chart-wrapper:not([hidden])) {
height: calc(100% - 62px);
}
> fieldset {
pointer-events: none;
position: absolute;
left: 0px;
top: 0px;
z-index: 10;
display: flex;
align-items: center;
padding-left: 1.5rem /* 24px */;
padding-right: 1.5rem /* 24px */;
font-size: var(--font-size-xs);
line-height: var(--line-height-xs);
> * + * {
margin-left: 0.5rem; /* 8px */
}
> * + span {
color: var(--off-color);
}
}
> .chart-div {
width: 100%;
height: 100%;
}
}
}
> #timescale {
margin-top: 1rem;
display: flex;
overflow: hidden;
z-index: 50;
@media (max-width: 767px) {
margin-bottom: -1.5rem;
border-top: 1px;
margin-left: -1.5rem;
margin-right: -1.5rem;
}
@media (min-width: 768px) {
border-radius: 9999px;
border: 1px;
}
> button {
flex: 0;
}
> div {
min-width: 0;
flex: 1;
display: flex;
position: relative;
> #timescale-date-buttons,
> #timescale-height-buttons {
display: flex;
overflow-x: auto;
> button {
color: var(--off-color);
flex-shrink: 0;
flex-grow: 1;
padding: 0.5rem;
white-space: nowrap;
min-width: 5rem;
}
}
}
> *:not(:first-child):not(:last-child) {
border-left: 1px;
border-right: 1px;
}
}
}
+83
View File
@@ -0,0 +1,83 @@
#dashboard {
z-index: 50;
margin: -0.5px calc(-1.5rem - 1px);
display: flex;
> details {
> summary {
margin: -0.5px;
display: block;
padding: 0.5rem 1.5rem;
text-align: left;
border: 1px;
details[open] > & {
border-bottom-style: dashed !important;
border-bottom-width: 1px;
}
}
> div {
border: 1px;
border-top-width: 0px;
margin: -0.5px;
width: calc(100% + 1px);
padding: 0.375rem 1.5rem;
summary,
td {
padding: 0.125rem 0;
}
details {
summary {
color: var(--off-color);
&:hover {
color: var(--orange);
}
}
div {
width: 100%;
padding-left: 0.75rem;
border-left-width: 1px;
border-left-style: dashed !important;
}
}
table {
width: 100%;
table-layout: auto;
tr {
width: 100%;
&:not(:has(details)) {
&:hover,
&:hover * {
color: var(--orange) !important;
}
}
td {
text-align: right;
&:first-child {
text-align: left;
color: var(--off-color);
}
> a {
color: var(--off-color);
}
> i {
color: var(--off-color);
}
}
}
}
}
}
}
+1
View File
@@ -6,5 +6,6 @@
"module": "ESNext",
"outDir": "/tmp/kibo"
},
// "include": ["scripts"],
"exclude": ["assets", "packages", "ignore"]
}
-8
View File
File diff suppressed because one or more lines are too long