mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-25 15:19:58 -07:00
global: snapshot
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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!();
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
83
parser/src/structs/timestamp.rs
Normal file
83
parser/src/structs/timestamp.rs
Normal 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user