use std::sync::Arc;
use trading_maid::prelude::*;
struct MyStrategy {
ema_cache144: EMACache,
ema_cache169: EMACache,
count: usize,
}
impl MyStrategy {
pub fn new() -> Self {
MyStrategy {
ema_cache144: EMACache::with_ema(144, 80871.2),
ema_cache169: EMACache::with_ema(169, 78705.2),
count: 0,
}
}
}
#[async_trait(?Send)]
impl Strategy for MyStrategy {
async fn next(&mut self, cx: &Context) -> anyhow::Result<()> {
let ema144 = self.ema_cache144.update(cx.close);
let ema169 = self.ema_cache169.update(cx.close);
if self.count >= 50
&& (cx.close >= ema144 || cx.close >= ema169)
&& cx.get_position("BTCUSDT").await?.is_none()
{
println!("place_order: {}", t2s(cx.time));
cx.cancel_all_order("BTCUSDT").await?;
cx.sell("BTCUSDT", 0.01).await?;
cx.buy_limit_reduce_only("BTCUSDT", cx.close - 1000.0, 0.01)
.await?;
cx.buy_trigger_market_reduce_only("BTCUSDT", cx.close + 1000.0, 0.01)
.await?;
}
if cx.close <= ema144 && cx.close <= ema169 {
self.count += 1;
} else {
self.count = 0;
}
Ok(())
}
}
async fn my_hook(_: KLine, exchange: Arc<dyn Exchange + 'static>) -> anyhow::Result<()> {
if let Some(v) = exchange
.get_history_order_list("BTCUSDT")
.await?
.iter()
.find(|v| v.status == Status::Rejected || v.kind == Kind::Liquidation)
{
anyhow::bail!(
"rejected/liquidation {}: cash: {}",
t2s(v.update_time),
exchange.get_cash().await?
);
}
Ok(())
}
#[tokio::main]
async fn main() {
let path = get_or_download("BTCUSDT/1m", 12).await.unwrap();
let data_source_1m = DataSource::from_file_metadata(
path,
Metadata {
symbol: "BTCUSDT".to_string(),
level: Level::Minute1,
min_size: 0.01,
min_notional: 0.0,
tick_size: 0.1,
maker_fee: 0.0002,
taker_fee: 0.0005,
maintenance: 0.004,
},
)
.unwrap();
let exchange = LocalExchange::new(data_source_1m.clone())
.cash(10000.0)
.leverage(10)
.slippage(0.0);
let mut engine = Engine::new(exchange.clone(), MyStrategy::new());
engine.hook(my_hook);
if let Err(v) = engine.run("BTCUSDT", Level::Minute5).await {
println!("{:#?}", v);
}
let history_position = exchange.get_history_position_list("BTCUSDT").await.unwrap();
let history_order = exchange.get_history_order_list("BTCUSDT").await.unwrap();
let summary = summarize(&history_position);
println!("history summary: {:#?}", summary);
let data_source_5m = data_source_1m.resample(Level::Minute5).unwrap();
let data_source_1h = data_source_1m.resample(Level::Hour1).unwrap();
open_in_browser(
[data_source_5m, data_source_1m, data_source_1h],
history_position,
history_order,
)
.unwrap();
}