use async_trait::async_trait;
use serde::{Serialize, Deserialize};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MarketState {
pub prices: Vec<f32>,
pub volatility: Vec<f32>,
pub agent_capital: f32,
pub scar_count: u32,
pub win_loss_ratio: f32,
pub timestamp: u64,
}
impl MarketState {
pub fn to_features(&self) -> Vec<f32> {
vec![
self.prices.iter().sum::<f32>() / self.prices.len().max(1) as f32,
self.volatility.iter().sum::<f32>() / self.volatility.len().max(1) as f32,
self.agent_capital,
(1.0 - (self.scar_count as f32 / 10.0).min(1.0)),
self.win_loss_ratio,
]
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum TradeAction {
Buy,
Sell,
Hold,
}
impl TradeAction {
pub fn to_index(&self) -> usize {
match self {
TradeAction::Buy => 0,
TradeAction::Sell => 1,
TradeAction::Hold => 2,
}
}
pub fn from_index(idx: usize) -> Self {
match idx {
0 => TradeAction::Buy,
1 => TradeAction::Sell,
_ => TradeAction::Hold,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TradeDecision {
pub action: TradeAction,
pub confidence: f32,
pub amount: u64,
pub model_id: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ModelMetadata {
pub name: String,
pub version: String,
pub parent_id: Option<String>,
pub mutation_count: u32,
pub generations: u32,
}
#[async_trait]
pub trait MlStrategy: Send + Sync {
async fn predict(&self, state: &MarketState) -> Result<TradeDecision, crate::finance::ml::errors::MlError>;
fn update_weights(&mut self, gradients: &[f32]) -> Result<(), crate::finance::ml::errors::MlError>;
fn serialize(&self) -> Result<Vec<u8>, crate::finance::ml::errors::MlError>;
fn deserialize(&mut self, data: &[u8]) -> Result<(), crate::finance::ml::errors::MlError>;
fn metadata(&self) -> ModelMetadata;
fn mutate(&mut self, mutation_rate: f32, mutation_strength: f32) -> Result<(), crate::finance::ml::errors::MlError>;
fn clone_box(&self) -> Box<dyn MlStrategy>;
}