Make analytics granular - individual tools + selective analyze_report
**Granular Analytics Tools (8 new tools):** - analyze_monthly_pnl - Monthly profit/loss breakdown - analyze_drawdown_events - Drawdown events from balance curve - analyze_top_losses - Top N worst losses with grid depth - analyze_loss_sequences - Consecutive loss streaks analysis - analyze_position_pairs - Entry/exit position pairs - analyze_direction_bias - Long vs Short performance stats - analyze_streaks - Win/loss streaks with dates - analyze_concurrent_peak - Peak concurrent open positions **Updated analyze_report:** - Now supports selective analytics via 'analytics' array parameter - Runs all analytics by default (backward compatible) - Optional top_losses_limit parameter - Returns list of analytics that were run **Changes:** - analytics/analyze.rs: Made all analysis methods public - tools/definitions.rs: Added 8 new tool definitions + updated analyze_report schema - tools/handlers/mod.rs: Added dispatch for new tools - tools/handlers/analysis.rs: Added helper load_report_data() + 8 granular handlers + selective analyze_report logic
This commit is contained in:
@@ -34,7 +34,7 @@ impl DealAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
fn monthly_pnl(&self, deals: &[Deal]) -> Vec<MonthlyPnl> {
|
||||
pub fn monthly_pnl(&self, deals: &[Deal]) -> Vec<MonthlyPnl> {
|
||||
let mut monthly: HashMap<String, (f64, i32)> = HashMap::new();
|
||||
|
||||
for deal in deals {
|
||||
@@ -71,7 +71,7 @@ impl DealAnalyzer {
|
||||
result
|
||||
}
|
||||
|
||||
fn reconstruct_dd_events(&self, deals: &[Deal], _metrics: &Metrics) -> Vec<DrawdownEvent> {
|
||||
pub fn reconstruct_dd_events(&self, deals: &[Deal], _metrics: &Metrics) -> Vec<DrawdownEvent> {
|
||||
let mut balance_curve = Vec::new();
|
||||
let mut peak_balance: f64 = 0.0;
|
||||
let mut initial_balance: Option<f64> = None;
|
||||
@@ -178,7 +178,7 @@ impl DealAnalyzer {
|
||||
event
|
||||
}
|
||||
|
||||
fn top_losses(&self, deals: &[Deal], n: usize) -> Vec<LossEntry> {
|
||||
pub fn top_losses(&self, deals: &[Deal], n: usize) -> Vec<LossEntry> {
|
||||
let mut losses: Vec<LossEntry> = deals
|
||||
.iter()
|
||||
.filter(|d| d.profit < 0.0)
|
||||
@@ -196,7 +196,7 @@ impl DealAnalyzer {
|
||||
losses
|
||||
}
|
||||
|
||||
fn loss_sequences(&self, deals: &[Deal]) -> Vec<LossSequence> {
|
||||
pub fn loss_sequences(&self, deals: &[Deal]) -> Vec<LossSequence> {
|
||||
let closed: Vec<&Deal> = deals
|
||||
.iter()
|
||||
.filter(|d| d.entry.to_lowercase().contains("out") && d.profit != 0.0)
|
||||
@@ -241,7 +241,7 @@ impl DealAnalyzer {
|
||||
sequences
|
||||
}
|
||||
|
||||
fn position_pairs(&self, deals: &[Deal]) -> Vec<PositionPair> {
|
||||
pub fn position_pairs(&self, deals: &[Deal]) -> Vec<PositionPair> {
|
||||
let mut open_pos: HashMap<String, &Deal> = HashMap::new();
|
||||
let mut pairs = Vec::new();
|
||||
|
||||
@@ -278,7 +278,7 @@ impl DealAnalyzer {
|
||||
pairs
|
||||
}
|
||||
|
||||
fn direction_bias(&self, deals: &[Deal]) -> HashMap<String, DirectionStats> {
|
||||
pub fn direction_bias(&self, deals: &[Deal]) -> HashMap<String, DirectionStats> {
|
||||
let mut stats: HashMap<String, (i32, i32, f64)> = HashMap::new();
|
||||
stats.insert("buy".to_string(), (0, 0, 0.0));
|
||||
stats.insert("sell".to_string(), (0, 0, 0.0));
|
||||
@@ -314,7 +314,7 @@ impl DealAnalyzer {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn streak_analysis(&self, deals: &[Deal]) -> StreakAnalysis {
|
||||
pub fn streak_analysis(&self, deals: &[Deal]) -> StreakAnalysis {
|
||||
let closed: Vec<&Deal> = deals
|
||||
.iter()
|
||||
.filter(|d| d.entry.to_lowercase().contains("out") && d.profit != 0.0)
|
||||
@@ -372,7 +372,7 @@ impl DealAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
fn concurrent_peak(&self, deals: &[Deal]) -> ConcurrentPeak {
|
||||
pub fn concurrent_peak(&self, deals: &[Deal]) -> ConcurrentPeak {
|
||||
let mut events: Vec<(DateTime<chrono::Utc>, i32, &Deal)> = Vec::new();
|
||||
|
||||
for deal in deals {
|
||||
|
||||
Reference in New Issue
Block a user