#![feature(drain_filter)] #![feature(bool_to_option)] use std::env; use fern::colors::{Color, ColoredLevelConfig}; use log::error; use log::LevelFilter::Info; use tokio::time::Duration; use crate::bot::BfxBot; use crate::connectors::ExchangeDetails; use crate::currency::Symbol; mod bot; mod connectors; mod currency; mod events; mod frontend; mod managers; mod models; mod strategy; mod ticker; mod tests; mod sounds; pub type BoxError = Box; #[tokio::main] async fn main() -> Result<(), BoxError> { if let Err(e) = setup_logger() { error!("Could not setup logger: {}", e); return Err(e.into()); } if let Err(e) = dotenv::dotenv() { error!("Could not open .env file: {}", e); return Err(e.into()); } let api_key = env::vars() .find(|(k, _v)| k == "API_KEY") .map(|(_k, v)| v) .ok_or("API_KEY not set!")?; let api_secret = env::vars() .find(|(k, _v)| k == "API_SECRET") .map(|(_k, v)| v) .ok_or("API_SECRET not set!")?; let bitfinex = ExchangeDetails::Bitfinex { api_key: api_key.into(), api_secret: api_secret.into(), }; let mut bot = BfxBot::new( vec![bitfinex], vec![Symbol::DERIV_ETH, Symbol::DERIV_BTC], Symbol::DERIV_USDT, Duration::new(10, 0), ); Ok(bot.start_loop().await?) } fn setup_logger() -> Result<(), fern::InitError> { let colors = ColoredLevelConfig::new() .info(Color::Green) .error(Color::Red) .trace(Color::Blue) .debug(Color::Cyan) .warn(Color::Yellow); fern::Dispatch::new() .format(move |out, message, record| { out.finish(format_args!( "{} | [{}][{}] | {}", chrono::Local::now().format("[%d/%m/%Y][%H:%M:%S]"), record.target().strip_prefix("rustico::").unwrap_or("rustico"), colors.color(record.level()), message )) }) .level(Info) .filter(|metadata| metadata.target().contains("rustico")) .chain(std::io::stdout()) .chain(fern::log_file("rustico.log")?) .apply()?; Ok(()) }