use anyhow::Error;
use chrono::{DateTime, TimeZone as _, Utc};
use scuriolus::{
app::App,
clock::{CheatClockFactory as _, RunningCheatClockFactory},
core::Core,
market::mexc_base::TestWithMexc,
order::{Amount, Crypto},
strategy::{strict_buy::StrictBuyFactory, StrategyFactory as _},
};
const QUOTE: Crypto = Crypto::USDT;
const ASSET: Crypto = Crypto::BTC;
const AMOUNT: Amount = Amount::from_parts(1000, 0, 0, false, 0);
const SECS_PER_YEAR: Amount = Amount::from_parts(60 * 60 * 24 * 365, 0, 0, false, 0);
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let start = Utc.with_ymd_and_hms(2024, 1, 1, 0, 0, 0).unwrap();
let end = Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap();
let earning = test_perf(start, end).await.unwrap();
let ratio =
earning * SECS_PER_YEAR / (Amount::from(end.timestamp() - start.timestamp()) * AMOUNT);
println!("APY: {}%", ratio.round_dp(2));
Ok(())
}
async fn test_perf(start: DateTime<Utc>, end: DateTime<Utc>) -> Result<Amount, Error> {
let (remote, clock) = RunningCheatClockFactory {}.get_clock(start).unwrap();
let market = TestWithMexc::new(clock).await;
let core = Core::new("perfo".to_string(), market).await.unwrap();
let mut strat_factory = Box::new(StrictBuyFactory::<TestWithMexc>::new(QUOTE, AMOUNT, ASSET));
strat_factory.as_mut().set_core(core);
let mut app = App::new(strat_factory, Some(remote)).await;
let early_stat = app.get_stats().await?;
app.run();
app.advance_toward(end);
app.wait_for_the_bot().await;
let final_stat = app.terminate().await?;
Ok(final_stat.quote.free - early_stat.quote.free)
}