work on new engine
This commit is contained in:
parent
44476da13f
commit
a1e5a21847
126 changed files with 3425 additions and 6695 deletions
100
apps/stock/engine/src/backtest/strategy.rs
Normal file
100
apps/stock/engine/src/backtest/strategy.rs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
use chrono::{DateTime, Utc};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use crate::MarketData;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum SignalType {
|
||||
Buy,
|
||||
Sell,
|
||||
Close,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Signal {
|
||||
pub symbol: String,
|
||||
pub signal_type: SignalType,
|
||||
pub strength: f64, // -1.0 to 1.0
|
||||
pub quantity: Option<f64>,
|
||||
pub reason: Option<String>,
|
||||
pub metadata: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
// This trait will be implemented by Rust strategies
|
||||
// TypeScript strategies will communicate through FFI
|
||||
pub trait Strategy: Send + Sync {
|
||||
fn on_market_data(&mut self, data: &MarketData) -> Vec<Signal>;
|
||||
fn on_fill(&mut self, symbol: &str, quantity: f64, price: f64, side: &str);
|
||||
fn get_name(&self) -> &str;
|
||||
fn get_parameters(&self) -> serde_json::Value;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct StrategyCall {
|
||||
pub method: String,
|
||||
pub data: serde_json::Value,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct StrategyResponse {
|
||||
pub signals: Vec<Signal>,
|
||||
}
|
||||
|
||||
// Bridge for TypeScript strategies
|
||||
|
||||
// This will be used to wrap TypeScript strategies
|
||||
pub struct TypeScriptStrategy {
|
||||
pub name: String,
|
||||
pub id: String,
|
||||
pub parameters: serde_json::Value,
|
||||
// Callback function will be injected from TypeScript
|
||||
pub callback: Option<Box<dyn Fn(StrategyCall) -> StrategyResponse + Send + Sync>>,
|
||||
}
|
||||
|
||||
impl TypeScriptStrategy {
|
||||
pub fn new(name: String, id: String, parameters: serde_json::Value) -> Self {
|
||||
Self {
|
||||
name,
|
||||
id,
|
||||
parameters,
|
||||
callback: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Strategy for TypeScriptStrategy {
|
||||
fn on_market_data(&mut self, data: &MarketData) -> Vec<Signal> {
|
||||
if let Some(callback) = &self.callback {
|
||||
let call = StrategyCall {
|
||||
method: "on_market_data".to_string(),
|
||||
data: serde_json::to_value(data).unwrap_or_default(),
|
||||
};
|
||||
let response = callback(call);
|
||||
response.signals
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn on_fill(&mut self, symbol: &str, quantity: f64, price: f64, side: &str) {
|
||||
if let Some(callback) = &self.callback {
|
||||
let call = StrategyCall {
|
||||
method: "on_fill".to_string(),
|
||||
data: serde_json::json!({
|
||||
"symbol": symbol,
|
||||
"quantity": quantity,
|
||||
"price": price,
|
||||
"side": side
|
||||
}),
|
||||
};
|
||||
callback(call);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
fn get_parameters(&self) -> serde_json::Value {
|
||||
self.parameters.clone()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue