# -*- coding: utf-8 -*-
"""RandomWinRate sim

Automatically generated by Colab.

Original file is located at
    https://colab.research.google.com/drive/1rp0RkDeipF0SG2nhy6I_IWaaBPps3RbK
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import display

# Initial parameters
initial_equity = 1000
risk_per_trade = 0.01  # 1% risk
trades_per_run = 100

# Step 1: Generate 5 random win-rates (10%-95%) and 5 random RRR (0.1 - 5)
np.random.seed(82)
win_rates = np.random.uniform(0.10, 0.80, 5)
rrr = np.random.uniform(0.1, 3, 5)

# Sort win-rates ascending and RRR descending
win_rates = np.sort(win_rates)
rrr = np.sort(rrr)[::-1]

# Align each win-rate to corresponding RRR
pairs = list(zip(win_rates, rrr))

# Step 2: Calculate Expectancy: E = (P * RRR) - ((1-P) * 1)
expectancy = [(p * r) - ((1 - p) * 1) for p, r in pairs]

# Store results
df = pd.DataFrame({
    'Win Rate%': win_rates*100,
    'RRR': rrr,
    'Expectancy': expectancy
})

# Monte Carlo simulation function
def monte_carlo_sim(win_rate, rrr, trades=100, initial_equity=1000, risk_per_trade=0.01, sims=1):
    results = []
    for _ in range(sims):
        balance = initial_equity
        equity_curve = [balance]
        peak = balance
        for _ in range(trades):
            if np.random.rand() < win_rate:
                balance += balance * risk_per_trade * rrr
            else:
                balance -= balance * risk_per_trade
            equity_curve.append(balance)
        results.append((equity_curve))
    return results

print('\n\n')
# Step 2a: Monte Carlo for each win-rate/RRR pair (100 trades, 1 simulation)
plt.figure(figsize=(10,6))
stats_list = []
for p, r in pairs:
    sims = monte_carlo_sim(p, r, trades_per_run, sims=1)
    eq_curve = sims[0]
    plt.plot(eq_curve, label=f'WR={p*100:.2f}%, RRR={r:.2f}')

plt.title(f'Monte Carlo Equity Curves ({trades_per_run} trades, 1 sim each)')
plt.xlabel('Trades')
plt.ylabel('Equity')
plt.legend()
plt.grid(True)
plt.show()

display(df)

print('\n\n')

# Step 3: Monte Carlo simulation
def monte_carlo_equity(win_rate, rrr, trades, initial_equity, risk_per_trade, simulations=100):
    final_equities = []
    drawdowns = []
    equity_curves = []

    for _ in range(simulations):
        equity = initial_equity
        peak_equity = initial_equity
        curve = [equity]

        for _ in range(trades):
            risk_amount = equity * risk_per_trade
            if np.random.rand() < win_rate:
                equity += risk_amount * rrr
            else:
                equity -= risk_amount

            peak_equity = max(peak_equity, equity)
            dd = (peak_equity - equity) / peak_equity * 100
            curve.append(equity)

        final_equities.append(equity)
        drawdowns.append(max((np.array(curve).max() - np.array(curve)) / np.array(curve).max() * 100))
        equity_curves.append(curve)

    return np.array(final_equities), np.array(drawdowns), equity_curves

results = []
for w, r in pairs:
    eq, dd, curves = monte_carlo_equity(w, r, trades_per_run, initial_equity, risk_per_trade, simulations=100)
    results.append((w*100, r, eq, dd, curves))


sns.set(style="whitegrid")
# Get a color palette matching the number of boxes
colors = sns.color_palette("Set1", len(results))

# Step 2b: Box plot for drawdown % distribution
plt.figure(figsize=(8, 5))
boxprops = dict(linewidth=1.5)
bp = plt.boxplot(
    [dd for _, _, _, dd, _ in results],
    labels=[f"{w:.2f}%/{r:.2f}" for w, r, _, _, _ in results],
    patch_artist=True,
    boxprops=boxprops
)
for patch, color in zip(bp['boxes'], colors):
    patch.set_facecolor(color)

plt.title(f"Drawdown % Distribution({trades_per_run} trades, 100 sim each)")
plt.xlabel("WinRate%/RRR")
plt.ylabel("Drawdown %")
plt.grid(True)
plt.show()

print('\n\n')
# Step 2c: Box plot for equity curve distribution
plt.figure(figsize=(8, 5))
bp = plt.boxplot(
    [eq for _, _, eq, _, _ in results],
    labels=[f"{w:.2f}%/{r:.2f}" for w, r, _, _, _ in results],
    patch_artist=True,
    boxprops=boxprops
)
for patch, color in zip(bp['boxes'], colors):
    patch.set_facecolor(color)

plt.title(f"Equity Curve Final Distribution({trades_per_run} trades, 100 sim each)")
plt.xlabel("WinRate%/RRR")
plt.ylabel("Final Equity ($)")
plt.grid(True)
plt.show()

print('\n\n')
# Step 2d: Tabulate statistics
stats_df = pd.DataFrame({
    "Win Rate%": [w for w, _, _, _, _ in results],
    "RRR": [r for _, r, _, _, _ in results],
    "Mean Equity": [np.mean(eq) for _, _, eq, _, _ in results],
    "Median Equity": [np.median(eq) for _, _, eq, _, _ in results],
    "Median Drawdown %": [np.median(dd) for _, _, _, dd, _ in results]
})
display(stats_df)

print('\n\n')
# Step 3: 500 Monte Carlo simulations, randomly picking one pair each run
simulations_total = 500
chosen_pairs = np.random.choice(len(pairs), size=simulations_total, replace=True)
final_equities_total = []
drawdownsT = []
pair_counts = np.zeros(len(pairs), dtype=int)

for idx in chosen_pairs:
    w, r = pairs[idx]
    eq, dd, _ = monte_carlo_equity(w, r, trades_per_run, initial_equity, risk_per_trade, simulations=100)
    final_equities_total.append(eq[0])
    drawdownsT.append(dd[0])
    pair_counts[idx] += 1

final_equities_total = np.array(final_equities_total)
drawdownsT = np.array(drawdownsT)

# Step 3a: Pie chart for pair usage
plt.figure(figsize=(6, 6))
plt.pie(pair_counts, labels=[f"{w*100:.2f}%/{r:.2f}" for w, r in pairs], autopct='%1.1f%%', startangle=140)
plt.title("Usage Frequency of Win Rate / RRR Pairs")
plt.show()

print('\n\n')
# Step 3b: Box plot for drawdown % distribution (500 simulations)
plt.figure(figsize=(8, 5))
bp = plt.boxplot(drawdownsT, patch_artist=True, boxprops=boxprops)
for patch in bp['boxes']:
    patch.set_facecolor('lightblue')

plt.title(f"Drawdown % Distribution - {simulations_total} Simulations per {trades_per_run} trades")
plt.ylabel("Drawdown %")
plt.grid(True)
plt.show()

print('\n\n')
# Step 3c: Box plot for equity curve distribution (500 simulations)
plt.figure(figsize=(8, 5))
bp = plt.boxplot(final_equities_total, patch_artist=True, boxprops=boxprops)
for patch in bp['boxes']:
    patch.set_facecolor('lightgreen')

plt.title(f"Final Equity Distribution - {simulations_total} Simulations per {trades_per_run} trades")
plt.ylabel("Final Equity ($)")
plt.grid(True)
plt.show()

print('\n\n')
# Step 3d: Tabulate statistics
stats_total_df = pd.DataFrame({
    "Mean Equity": [np.mean(final_equities_total)],
    "Median Equity": [np.median(final_equities_total)],
    "Median Drawdown %": [np.median(drawdownsT)]
})

display(stats_total_df)