global: snapshot

This commit is contained in:
k
2024-10-04 19:09:09 +02:00
parent 1c9d118ba2
commit 068bb07d6e
57 changed files with 1799 additions and 295 deletions

View File

@@ -1,4 +1,4 @@
use super::{AddressData, Amount, Price};
use super::{AddressData, Amount, Price, Timestamp};
#[derive(Debug)]
pub struct AddressRealizedData {
@@ -8,7 +8,9 @@ pub struct AddressRealizedData {
pub profit: Price,
pub loss: Price,
pub value_created: Price,
pub adjusted_value_created: Price,
pub value_destroyed: Price,
pub adjusted_value_destroyed: Price,
pub utxos_created: u32,
pub utxos_destroyed: u32,
}
@@ -23,7 +25,9 @@ impl AddressRealizedData {
utxos_created: 0,
utxos_destroyed: 0,
value_created: Price::ZERO,
adjusted_value_created: Price::ZERO,
value_destroyed: Price::ZERO,
adjusted_value_destroyed: Price::ZERO,
initial_address_data: *initial_address_data,
}
}
@@ -33,7 +37,14 @@ impl AddressRealizedData {
self.utxos_created += 1;
}
pub fn send(&mut self, amount: Amount, current_price: Price, previous_price: Price) {
pub fn send(
&mut self,
amount: Amount,
current_price: Price,
previous_price: Price,
current_timestamp: Timestamp,
previous_timestamp: Timestamp,
) {
self.sent += amount;
self.utxos_destroyed += 1;
@@ -44,6 +55,11 @@ impl AddressRealizedData {
self.value_created += current_value;
self.value_destroyed += previous_value;
if previous_timestamp.older_by_1h_plus_than(current_timestamp) {
self.adjusted_value_created += current_value;
self.adjusted_value_destroyed += previous_value;
}
if current_value >= previous_value {
self.profit += current_value - previous_value;
} else {

View File

@@ -36,6 +36,7 @@ direct_repr!(Amount);
impl Amount {
pub const ZERO: Self = Self(BitcoinAmount::ZERO);
pub const ONE_BTC_F32: f32 = 100_000_000.0;
pub const ONE_BTC_F64: f64 = 100_000_000.0;
#[inline(always)]

View File

@@ -299,6 +299,18 @@ where
self.date
.multi_insert_percentile(dates, date_map_and_percentiles, days);
}
pub fn multi_insert_max(
&mut self,
heights: &[Height],
dates: &[Date],
source: &mut BiMap<Value>,
) where
Value: PartialOrd,
{
self.height.multi_insert_max(heights, &mut source.height);
self.date.multi_insert_max(dates, &mut source.date);
}
}
pub trait AnyBiMap {

View File

@@ -2,19 +2,19 @@ use allocative::Allocative;
use bincode::{Decode, Encode};
use serde::{Deserialize, Serialize};
use super::{Amount, Height, Price};
use super::{Amount, Height, Price, Timestamp};
#[derive(Debug, Serialize, Deserialize, Encode, Decode, Allocative)]
pub struct BlockData {
pub height: Height,
pub price: Price,
pub timestamp: u32,
pub timestamp: Timestamp,
pub amount: Amount,
pub utxos: u32,
}
impl BlockData {
pub fn new(height: Height, price: Price, timestamp: u32) -> Self {
pub fn new(height: Height, price: Price, timestamp: Timestamp) -> Self {
Self {
height,
price,

View File

@@ -33,20 +33,21 @@ pub struct Config {
pub delay: Option<u64>,
/// Start a dry run, default: false, not saved
#[arg(long, default_value_t = false)]
pub dry_run: bool,
#[arg(long, value_name = "BOOL")]
dry_run: Option<bool>,
/// Record ram usage, default: false, not saved
#[arg(long, default_value_t = false)]
pub record_ram_usage: bool,
#[arg(long, value_name = "BOOL")]
record_ram_usage: Option<bool>,
}
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| {
let mut config_saved =
fs::read_to_string(Self::PATH).map_or(Config::default(), |contents| {
dbg!(&contents);
toml::from_str(&contents).unwrap_or_default()
});
@@ -92,8 +93,8 @@ impl Config {
log(&format!("rpcuser: {:?}", config.rpcuser));
log(&format!("rpcpassword: {:?}", config.rpcpassword));
log(&format!("delay: {:?}", config.delay));
log(&format!("dry_run: {}", config.dry_run));
log(&format!("record_ram_usage: {}", config.record_ram_usage));
log(&format!("dry_run: {:?}", config.dry_run));
log(&format!("record_ram_usage: {:?}", config.record_ram_usage));
log("---");
Ok(config)
@@ -124,4 +125,12 @@ impl Config {
fn write(&self) -> std::io::Result<()> {
fs::write(Self::PATH, toml::to_string(self).unwrap())
}
pub fn dry_run(&self) -> bool {
self.dry_run.is_some_and(|b| b)
}
pub fn record_ram_usage(&self) -> bool {
self.record_ram_usage.is_some_and(|b| b)
}
}

View File

@@ -7,7 +7,7 @@ use bincode::{
error::{DecodeError, EncodeError},
BorrowDecode, Decode, Encode,
};
use chrono::{Datelike, Days, NaiveDate, TimeZone, Utc};
use chrono::{Datelike, Days, NaiveDate};
use derive_deref::{Deref, DerefMut};
use serde::{Deserialize, Serialize};
@@ -38,14 +38,6 @@ impl Date {
Self(date)
}
pub fn from_timestamp(timestamp: u32) -> Self {
Self(
Utc.timestamp_opt(i64::from(timestamp), 0)
.unwrap()
.date_naive(),
)
}
pub fn today() -> Self {
Self(chrono::offset::Utc::now().date_naive())
}

View File

@@ -818,4 +818,36 @@ where
ControlFlow::Continue(())
});
}
pub fn multi_insert_max(&mut self, keys: &[Key], source: &mut Self)
where
Value: Default + PartialOrd,
{
let mut max = None;
keys.iter().for_each(|key| {
let previous_max = max.unwrap_or_else(|| {
key.checked_sub(1)
.and_then(|previous_max_key| self.get(&previous_max_key))
.unwrap_or_default()
});
let last_value = source.get_or_import(key).unwrap_or_else(|| {
dbg!(key);
panic!()
});
if max.is_none() || last_value > previous_max {
max.replace(last_value);
}
self.insert(
*key,
max.unwrap_or_else(|| {
dbg!(previous_max, last_value, max);
panic!();
}),
);
});
}
}

View File

@@ -6,7 +6,7 @@ use serde::{de::DeserializeOwned, Serialize};
use crate::datasets::OHLC;
use super::{Date, Height};
use super::{Date, Height, Timestamp};
pub trait MapValue:
Clone
@@ -32,3 +32,4 @@ impl MapValue for f64 {}
impl MapValue for Date {}
impl MapValue for OHLC {}
impl MapValue for Height {}
impl MapValue for Timestamp {}

View File

@@ -29,6 +29,7 @@ mod price;
mod sent_data;
mod serialized_btreemap;
mod serialized_vec;
mod timestamp;
mod tx_data;
mod txout_index;
@@ -63,5 +64,6 @@ pub use price::*;
pub use sent_data::*;
pub use serialized_btreemap::*;
pub use serialized_vec::*;
pub use timestamp::*;
pub use tx_data::*;
pub use txout_index::*;

View File

@@ -0,0 +1,83 @@
use std::ops::Sub;
use allocative::Allocative;
use bincode::{Decode, Encode};
use chrono::{Datelike, NaiveDateTime, NaiveTime, TimeZone, Timelike, Utc};
use derive_deref::{Deref, DerefMut};
use serde::{Deserialize, Serialize};
use crate::utils::{ONE_DAY_IN_S, ONE_HOUR_IN_S};
use super::Date;
#[derive(
Debug,
Default,
Clone,
Copy,
Allocative,
Serialize,
Deserialize,
Deref,
DerefMut,
PartialEq,
Eq,
PartialOrd,
Ord,
Encode,
Decode,
)]
pub struct Timestamp(u32);
impl Timestamp {
pub const ZERO: Self = Self(0);
pub fn wrap(timestamp: u32) -> Self {
Self(timestamp)
}
pub fn to_date(self) -> Date {
Date::wrap(
Utc.timestamp_opt(i64::from(self.0), 0)
.unwrap()
.date_naive(),
)
}
pub fn to_year(self) -> u32 {
self.to_date().year() as u32
}
pub fn to_floored_seconds(self) -> Self {
let date_time = Utc.timestamp_opt(i64::from(self.0), 0).unwrap();
Self::wrap(
NaiveDateTime::new(
date_time.date_naive(),
NaiveTime::from_hms_opt(date_time.hour(), date_time.minute(), 0).unwrap(),
)
.and_utc()
.timestamp() as u32,
)
}
pub fn difference_in_days_between(older: Self, younger: Self) -> u32 {
if younger <= older {
0
} else {
*(younger - older) / ONE_DAY_IN_S as u32
}
}
pub fn older_by_1h_plus_than(&self, younger: Self) -> bool {
younger.checked_sub(**self).unwrap_or_default() > ONE_HOUR_IN_S as u32
}
}
impl Sub for Timestamp {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self::wrap(self.0 - rhs.0)
}
}