SiddharthVenba's picture
Initial commit for HF Space
75d9b3c
Raw
History Blame Contribute Delete
2.53 kB
"""
Monte Carlo Simulation — Stress testing the strategy by shuffling trade sequences.
"""
import numpy as np
import pandas as pd
from typing import List
def run_monte_carlo(trades: List[dict], initial_capital: float, iterations: int = 1000):
"""
Run Monte Carlo simulation on a list of historical trades.
Args:
trades: List of trade dictionaries with 'pnl' and 'entry_price'.
initial_capital: Starting capital.
iterations: Number of simulations.
"""
if not trades:
return {"error": "No trades to simulate"}
pnls = [t["pnl"] for t in trades]
results = []
for _ in range(iterations):
# Shuffle the order of trades
shuffled_pnls = np.random.choice(pnls, size=len(pnls), replace=True)
equity = initial_capital
equity_curve = [initial_capital]
max_dd = 0
peak = initial_capital
for pnl in shuffled_pnls:
equity += pnl
equity_curve.append(equity)
if equity > peak:
peak = equity
dd = (peak - equity) / peak
if dd > max_dd:
max_dd = dd
results.append({
"final_equity": equity,
"max_drawdown": max_dd * 100,
"return_pct": (equity / initial_capital - 1) * 100
})
df_results = pd.DataFrame(results)
stats = {
"avg_return": df_results["return_pct"].mean(),
"median_return": df_results["return_pct"].median(),
"worst_case_return": df_results["return_pct"].min(),
"best_case_return": df_results["return_pct"].max(),
"avg_drawdown": df_results["max_drawdown"].mean(),
"max_drawdown_95th": df_results["max_drawdown"].quantile(0.95), # Risk at 95% confidence
"ruin_probability": (df_results["final_equity"] < initial_capital * 0.5).mean() * 100 # Prob of losing 50%
}
return stats, df_results
def print_mc_report(stats):
print("\n" + "="*40)
print(" MONTE CARLO STRESS TEST")
print("="*40)
print(f"Avg Return: {stats['avg_return']:.2f}%")
print(f"Median Return: {stats['median_return']:.2f}%")
print(f"Best Case: {stats['best_case_return']:.2f}%")
print(f"Worst Case: {stats['worst_case_return']:.2f}%")
print(f"Avg Drawdown: {stats['avg_drawdown']:.2f}%")
print(f"Max DD (95% CI): {stats['max_drawdown_95th']:.2f}%")
print(f"Prob. of Ruin: {stats['ruin_probability']:.1f}%")
print("="*40)