#!/usr/bin/env python3
"""
6-month segmented run — processes one month at a time to avoid OOM.
Carries equity forward between segments.

Usage:
    python3 run_6month_segmented.py
    python3 run_6month_segmented.py --max-rows=2000000  # sample per month
"""

import sys, os, json, time, gc
from datetime import datetime

os.chdir(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, ".")

try:
    os.nice(10)
except OSError:
    pass

import settings
from run_btc_backtest import load_ticks_to_candles
from backtest import BacktestEngine
from utils import setup_logging

PROGRESS_FILE = "backtest_progress.json"
RESULTS_DIR = "results"

# Aug 2025 through Jan 2026 (6 months)
MONTHS = ["202508", "202509", "202510", "202511", "202512", "202601"]

def write_progress(data):
    tmp = PROGRESS_FILE + ".tmp"
    try:
        with open(tmp, "w") as f:
            json.dump(data, f, indent=2, default=str)
        os.replace(tmp, PROGRESS_FILE)
    except Exception:
        pass


def load_month(month_code, max_rows=None):
    """Load a single monthly CSV."""
    csv_path = f"data/monthly/BTCUSD_{month_code}.csv"
    if not os.path.exists(csv_path):
        print(f"WARNING: {csv_path} not found, skipping")
        return None
    return load_ticks_to_candles(csv_path, timeframe="5min", max_rows=max_rows)


def run_month(data, starting_balance):
    """Run backtest on one month's data with given starting balance."""
    settings.INITIAL_BALANCE = starting_balance
    engine = BacktestEngine(
        symbol=settings.SYMBOL,
        initial_balance=starting_balance,
        commission_percent=settings.COMMISSION_PERCENT,
        slippage_pips=settings.SLIPPAGE_PIPS,
    )
    return engine.run(data, progress_callback=None)


def main():
    setup_logging(console=False, file=True)

    max_rows = None
    for arg in sys.argv[1:]:
        if arg.startswith("--max-rows="):
            max_rows = int(arg.split("=")[1])

    print("=" * 70)
    print("  6-MONTH SEGMENTED RUN — TIER 1 WINNER CONFIG")
    print(f"  LOT={settings.LOT_SIZE} | ThreadTP=${settings.THREAD_PROFIT_TARGET}")
    print(f"  RecTP=${settings.RECOVERY_PROFIT_TARGET} | MaxOrd={settings.MAX_INITIAL_ORDERS}")
    print(f"  Months: {', '.join(MONTHS)}")
    print("=" * 70)

    equity = 20000.0
    original_equity = equity
    total_trades = 0
    total_commission = 0.0
    total_gross_profit = 0.0
    total_gross_loss = 0.0
    worst_dd = 0.0
    monthly_results = []

    for i, month in enumerate(MONTHS):
        print(f"\n{'─' * 50}")
        print(f"  SEGMENT {i+1}/{len(MONTHS)}: {month}")
        print(f"  Starting equity: ${equity:,.2f}")
        print(f"{'─' * 50}")

        write_progress({
            "status": "running",
            "segment": f"{i+1}/{len(MONTHS)}",
            "month": month,
            "equity": equity,
            "updated_at": datetime.now().isoformat(),
        })

        t0 = time.time()
        data = load_month(month, max_rows)
        if data is None:
            print(f"  SKIPPED (no data)")
            monthly_results.append({
                "month": month, "start": equity, "end": equity,
                "return_pct": 0, "dd": 0, "trades": 0, "skipped": True
            })
            continue

        print(f"  Loaded {len(data)} candles in {time.time()-t0:.1f}s")

        t1 = time.time()
        result = run_month(data, equity)
        elapsed = time.time() - t1

        end_equity = result.final_balance
        ret_pct = ((end_equity - equity) / equity) * 100
        dd = result.max_drawdown_percent

        mr = {
            "month": month,
            "start": equity,
            "end": end_equity,
            "return_pct": ret_pct,
            "dd": dd,
            "trades": result.total_trades,
            "pf": result.gross_profit / result.gross_loss if result.gross_loss > 0 else 999,
            "commission": result.total_commission,
            "gross_profit": result.gross_profit,
            "gross_loss": result.gross_loss,
            "elapsed": elapsed,
        }
        monthly_results.append(mr)

        total_trades += result.total_trades
        total_commission += result.total_commission
        total_gross_profit += result.gross_profit
        total_gross_loss += result.gross_loss
        if dd > worst_dd:
            worst_dd = dd

        print(f"  ${equity:,.0f} → ${end_equity:,.0f} ({ret_pct:+.1f}%)")
        print(f"  DD: {dd:.2f}% | PF: {mr['pf']:.2f} | Trades: {result.total_trades:,}")
        print(f"  Commission: ${result.total_commission:,.0f} | Time: {elapsed:.0f}s")

        equity = end_equity

        # Free memory
        del data, result
        gc.collect()
        time.sleep(1)

    # Final summary
    total_return_pct = ((equity - original_equity) / original_equity) * 100
    overall_pf = total_gross_profit / total_gross_loss if total_gross_loss > 0 else 999
    rar = total_return_pct / worst_dd if worst_dd > 0 else 0

    print(f"\n\n{'═' * 70}")
    print(f"  6-MONTH FULL RESULTS — TIER 1 WINNER")
    print(f"  LOT={settings.LOT_SIZE} | TTP=${settings.THREAD_PROFIT_TARGET} | RTP=${settings.RECOVERY_PROFIT_TARGET} | MO={settings.MAX_INITIAL_ORDERS}")
    print(f"{'═' * 70}")
    print(f"  ${original_equity:,.0f} → ${equity:,.0f} ({total_return_pct:+,.1f}%)")
    print(f"  Worst DD: {worst_dd:.2f}%")
    print(f"  PF: {overall_pf:.2f}")
    print(f"  RAR: {rar:.1f}")
    print(f"  Trades: {total_trades:,}")
    print(f"  Commission: ${total_commission:,.0f}")
    print(f"  Gross Profit: ${total_gross_profit:,.0f}")
    print(f"  Gross Loss: ${total_gross_loss:,.0f}")
    print(f"{'═' * 70}")

    print(f"\n  Monthly Breakdown:")
    print(f"  {'Month':<8} {'Start':>12} {'End':>12} {'Return':>8} {'DD':>6} {'PF':>6} {'Trades':>7}")
    print(f"  {'-'*65}")
    for mr in monthly_results:
        if mr.get("skipped"):
            print(f"  {mr['month']:<8} {'SKIPPED':>12}")
        else:
            print(f"  {mr['month']:<8} ${mr['start']:>10,.0f} ${mr['end']:>10,.0f} {mr['return_pct']:>+7.1f}% {mr['dd']:>5.2f}% {mr['pf']:>5.2f} {mr['trades']:>7,}")

    # Save
    os.makedirs(RESULTS_DIR, exist_ok=True)
    result_path = os.path.join(RESULTS_DIR, f"6month_tier1_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json")
    save_data = {
        "config": {
            "LOT_SIZE": settings.LOT_SIZE,
            "THREAD_PROFIT_TARGET": settings.THREAD_PROFIT_TARGET,
            "RECOVERY_PROFIT_TARGET": settings.RECOVERY_PROFIT_TARGET,
            "MAX_INITIAL_ORDERS": settings.MAX_INITIAL_ORDERS,
        },
        "summary": {
            "start_equity": original_equity,
            "end_equity": equity,
            "total_return_pct": total_return_pct,
            "worst_dd": worst_dd,
            "pf": overall_pf,
            "rar": rar,
            "total_trades": total_trades,
            "total_commission": total_commission,
            "gross_profit": total_gross_profit,
            "gross_loss": total_gross_loss,
        },
        "monthly": monthly_results,
        "timestamp": datetime.now().isoformat(),
    }
    with open(result_path, "w") as f:
        json.dump(save_data, f, indent=2)
    print(f"\n  Saved to {result_path}")

    write_progress({
        "status": "completed",
        "final_equity": equity,
        "return_pct": total_return_pct,
        "worst_dd": worst_dd,
        "updated_at": datetime.now().isoformat(),
    })


if __name__ == "__main__":
    main()
