#![allow(
clippy::unreadable_literal,
clippy::match_same_arms,
clippy::unused_async
)]
use crate::FixedPoint;
use crate::processor::ExportOpenDeviationBarProcessor;
use crate::trade::Tick;
use crate::types::OpenDeviationBar;
pub fn create_test_trade(id: u64, price: f64, timestamp: u64) -> Tick {
let price_str = format!("{:.8}", price);
Tick {
ref_id: id as i64,
price: FixedPoint::from_str(&price_str).unwrap(),
volume: FixedPoint::from_str("1.0").unwrap(),
first_sub_id: id as i64,
last_sub_id: id as i64,
timestamp: timestamp as i64,
is_buyer_maker: false,
is_best_match: None,
best_bid: None,
best_ask: None,
}
}
pub fn process_batch_style(
trades: &[Tick],
threshold_decimal_bps: u32,
) -> Vec<OpenDeviationBar> {
let mut processor = ExportOpenDeviationBarProcessor::new(threshold_decimal_bps).unwrap();
processor.process_trades_continuously(trades);
let mut bars = processor.get_all_completed_bars();
if let Some(incomplete) = processor.get_incomplete_bar() {
bars.push(incomplete);
}
bars
}
pub async fn process_streaming_style(
trades: &[Tick],
threshold_decimal_bps: u32,
) -> Vec<OpenDeviationBar> {
let mut range_processor = ExportOpenDeviationBarProcessor::new(threshold_decimal_bps).unwrap();
let chunk_size = 10000; let mut all_bars = Vec::new();
for chunk in trades.chunks(chunk_size) {
range_processor.process_trades_continuously(chunk);
let chunk_bars = range_processor.get_all_completed_bars();
all_bars.extend(chunk_bars);
}
if let Some(incomplete) = range_processor.get_incomplete_bar() {
all_bars.push(incomplete);
}
all_bars
}
pub fn create_massive_realistic_dataset(count: usize) -> Vec<Tick> {
let mut trades = Vec::with_capacity(count);
let base_price = 23000.0;
let base_time = 1_659_312_000_000_i64;
for i in 0..count {
let time_progress = i as f64 / count as f64;
let trend = (time_progress * 2.0 * std::f64::consts::PI).sin() * 500.0; let volatility = ((i as f64 * 0.01).sin() * 50.0) + ((i as f64 * 0.001).cos() * 20.0); let noise = (i as f64 * 0.1).sin() * 5.0;
let price = base_price + trend + volatility + noise;
let timestamp = base_time + (i as i64 * 100);
trades.push(create_test_trade(
1_000_000 + i as u64,
price,
timestamp as u64,
));
}
trades
}
pub fn create_multi_day_boundary_dataset(days: usize) -> Vec<Tick> {
let mut trades = Vec::new();
let base_time = 1_659_312_000_000_i64; let day_ms = 24 * 60 * 60 * 1000;
for day in 0..days {
let day_start = base_time + (day as i64 * day_ms);
let daily_trades = match day % 3 {
0 => create_volatile_day_data(day_start, 100_000), 1 => create_stable_day_data(day_start, 80000), _ => create_trending_day_data(day_start, 120_000), };
trades.extend(daily_trades);
}
trades
}
pub fn create_volatile_day_data(start_time: i64, count: usize) -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
for i in 0..count {
let volatility = ((i as f64 * 0.02).sin() * 200.0) + ((i as f64 * 0.005).cos() * 100.0);
let price = base_price + volatility;
let timestamp = start_time + (i as i64 * 500);
trades.push(create_test_trade(
2_000_000 + i as u64,
price,
timestamp as u64,
));
}
trades
}
pub fn create_stable_day_data(start_time: i64, count: usize) -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
for i in 0..count {
let movement = (i as f64 * 0.001).sin() * 20.0;
let price = base_price + movement;
let timestamp = start_time + (i as i64 * 800);
trades.push(create_test_trade(
3_000_000 + i as u64,
price,
timestamp as u64,
));
}
trades
}
pub fn create_trending_day_data(start_time: i64, count: usize) -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
for i in 0..count {
let trend = (i as f64 / count as f64) * 800.0; let noise = (i as f64 * 0.01).sin() * 30.0;
let price = base_price + trend + noise;
let timestamp = start_time + (i as i64 * 600);
trades.push(create_test_trade(
4_000_000 + i as u64,
price,
timestamp as u64,
));
}
trades
}
pub fn create_asian_session_data() -> Vec<Tick> {
create_session_data(1_659_312_000_000, 50_000, 0.5, 0.8)
}
pub fn create_european_session_data() -> Vec<Tick> {
create_session_data(1_659_340_800_000, 80_000, 1.0, 1.2)
}
pub fn create_us_session_data() -> Vec<Tick> {
create_session_data(1_659_369_600_000, 120_000, 1.5, 2.0)
}
pub fn create_weekend_gap_data() -> Vec<Tick> {
create_session_data(1_659_484_800_000, 5_000, 0.2, 0.3)
}
fn create_session_data(
start_time: i64,
count: usize,
volatility_factor: f64,
activity_factor: f64,
) -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
for i in 0..count {
let volatility = ((i as f64 * 0.01).sin() * 100.0 * volatility_factor)
+ ((i as f64 * 0.003).cos() * 50.0 * volatility_factor);
let price = base_price + volatility;
let interval = (1000.0 / activity_factor) as i64; let timestamp = start_time + (i as i64 * interval);
trades.push(create_test_trade(
5000000 + i as u64,
price,
timestamp as u64,
));
}
trades
}
pub fn create_high_frequency_data(interval_ms: i64) -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
let base_time = 1659312000000i64;
for i in 0..10000 {
let micro_movement = (i as f64 * 0.1).sin() * 0.5; let price = base_price + micro_movement;
let timestamp = base_time + (i as i64 * interval_ms);
trades.push(create_test_trade(
6000000 + i as u64,
price,
timestamp as u64,
));
}
trades
}
pub fn create_medium_frequency_data(interval_ms: i64) -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
let base_time = 1659312000000i64;
for i in 0..5000 {
let movement = (i as f64 * 0.05).sin() * 10.0;
let price = base_price + movement;
let timestamp = base_time + (i as i64 * interval_ms);
trades.push(create_test_trade(
7000000 + i as u64,
price,
timestamp as u64,
));
}
trades
}
pub fn create_low_frequency_data(interval_ms: i64) -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
let base_time = 1659312000000i64;
for i in 0..1000 {
let movement = (i as f64 * 0.01).sin() * 50.0;
let price = base_price + movement;
let timestamp = base_time + (i as i64 * interval_ms);
trades.push(create_test_trade(
8000000 + i as u64,
price,
timestamp as u64,
));
}
trades
}
pub fn create_mixed_frequency_data() -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
let base_time = 1659312000000i64;
let mut current_time = base_time;
for i in 0..3000 {
let movement = (i as f64 * 0.02).sin() * 25.0;
let price = base_price + movement;
let interval = if i % 10 < 3 {
50 } else if i % 10 < 7 {
200 } else {
1000 };
current_time += interval;
trades.push(create_test_trade(
9000000 + i as u64,
price,
current_time as u64,
));
}
trades
}
pub fn create_rapid_threshold_hit_data() -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
let threshold = 0.0025; let base_time = 1659312000000i64;
for i in 0..1000 {
let phase = (i / 10) % 4;
let price = match phase {
0 => base_price, 1 => base_price * (1.0 + threshold * 1.1), 2 => base_price, _ => base_price * (1.0 - threshold * 1.1), };
trades.push(create_test_trade(
10000000 + i as u64,
price,
(base_time + i as i64 * 10) as u64,
));
}
trades
}
pub fn create_precision_limit_data() -> Vec<Tick> {
let mut trades = Vec::new();
let base_time = 1659312000000i64;
let precision_prices = [
23000.12345678, 23000.00000001, 99999999.99999999, 0.00000001, ];
for (i, price) in precision_prices.iter().enumerate() {
trades.push(create_test_trade(
11000000 + i as u64,
*price,
(base_time + i as i64 * 1000) as u64,
));
}
trades
}
pub fn create_volume_extreme_data() -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
let base_time = 1659312000000i64;
for i in 0..100 {
let price = base_price + (i as f64 * 0.1);
trades.push(create_test_trade(
12000000 + i as u64,
price,
(base_time + i as i64 * 100) as u64,
));
}
trades
}
pub fn create_timestamp_edge_data() -> Vec<Tick> {
let mut trades = Vec::new();
let base_price = 23000.0;
let edge_timestamps: Vec<i64> = vec![
1, 1659312000000, 9223372036854775807, ];
for (i, timestamp) in edge_timestamps.iter().enumerate() {
let price = base_price + (i as f64 * 10.0);
trades.push(create_test_trade(
13000000 + i as u64,
price,
*timestamp as u64,
));
}
trades
}
pub fn create_floating_point_stress_data() -> Vec<Tick> {
let mut trades = Vec::new();
let base_time = 1659312000000i64;
let stress_prices = [
23000.1 + 0.1, 23000.0 / 3.0, 23000.0 * 1.1, (23000.0_f64).sqrt(), ];
for (i, price) in stress_prices.iter().enumerate() {
trades.push(create_test_trade(
14000000 + i as u64,
*price,
(base_time + i as i64 * 100) as u64,
));
}
trades
}