#!/usr/bin/env python3
"""
generate_sample_trades.py
Generates a synthetic trade-level CSV that matches the schema expected
by robustness_testing.py. Use this to test the robustness battery end
to end without needing a live MetaTrader 5 export.

It produces several indicator variants with deliberately different
statistical profiles so the three robustness modules each have
something meaningful to detect:

  SMA   : weak, near-random edge        -> expect high permutation p-value
  EMA   : moderate genuine edge         -> expect low p-value, stable CI
  KAMA  : strong but volatile edge      -> expect low p-value, wide CI
  SAMA  : strong, consistent edge       -> expect very low p-value, tight CI

Usage:
    python generate_sample_trades.py
    # writes exports/trade_level_results.csv
"""

import os
import numpy as np
import pandas as pd
from datetime import datetime, timedelta

OUTPUT_DIR  = "exports"
OUTPUT_FILE = os.path.join(OUTPUT_DIR, "trade_level_results.csv")
RANDOM_SEED = 7
SYMBOL      = "EURUSD"
TIMEFRAME   = "H1"

# (indicator, n_trades, win_rate, avg_win, avg_loss, noise_sd)
PROFILES = [
    ("SMA",  120, 0.50,  18.0, -17.5, 12.0),   # near break-even, noisy
    ("EMA",  140, 0.55,  22.0, -16.0,  8.0),   # modest real edge
    ("KAMA", 110, 0.58,  40.0, -28.0, 22.0),   # strong but very volatile
    ("SAMA", 160, 0.60,  26.0, -15.0,  6.0),   # strong, consistent edge
]


def generate_trades_for_profile(rng, indicator, n, win_rate,
                                 avg_win, avg_loss, noise_sd,
                                 start_time):
    rows  = []
    t     = start_time
    for k in range(n):
        is_win = rng.random() < win_rate
        base   = avg_win if is_win else avg_loss
        # Add Gaussian noise; a win can still post a small loss and vice versa
        profit = base + rng.normal(0.0, noise_sd)
        dur_h  = float(max(0.5, rng.exponential(6.0)))
        entry  = t
        exit_  = t + timedelta(hours=dur_h)
        slip   = round(abs(rng.normal(1.2, 0.6)), 1)
        rows.append({
            "Trade_ID"          : k + 1,
            "Symbol"            : SYMBOL,
            "Timeframe"         : TIMEFRAME,
            "Indicator_Name"    : indicator,
            "Entry_Time"        : entry.strftime("%Y.%m.%d %H:%M"),
            "Exit_Time"         : exit_.strftime("%Y.%m.%d %H:%M"),
            "Trade_Profit_USD"  : round(profit, 2),
            "Trade_Duration_Hrs": round(dur_h, 2),
            "Entry_Slippage_Pts": slip,
        })
        # Space trades a few hours apart on average
        t = exit_ + timedelta(hours=float(rng.exponential(4.0)))
    return rows


def main():
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    rng        = np.random.default_rng(RANDOM_SEED)
    start_time = datetime(2024, 1, 2, 8, 0, 0)
    all_rows   = []

    for (indicator, n, wr, aw, al, sd) in PROFILES:
        all_rows.extend(
            generate_trades_for_profile(rng, indicator, n, wr, aw, al, sd,
                                        start_time)
        )

    df = pd.DataFrame(all_rows)
    df.to_csv(OUTPUT_FILE, index=False, encoding="utf-8")

    print(f"[Generator] Wrote {len(df):,} synthetic trades to {OUTPUT_FILE}")
    print("\nPer-indicator summary:")
    summary = (df.groupby("Indicator_Name")["Trade_Profit_USD"]
                 .agg(["count", "mean", "sum"])
                 .round(2))
    print(summary.to_string())


if __name__ == "__main__":
    main()
