"""Hypothetical daily delta-hedging ledger, not market data or a backtest.
Python 3.10+ standard library. Writes CSVs for a moving and a quiet path.
European BSM straddle, fixed 20% IV, zero rates/dividends, fractional stock hedges.
"""
import csv
import math
from datetime import date, timedelta
from pathlib import Path


def straddle(spot, days, strike=100, sigma=0.20):
    t = days / 365
    d1 = (math.log(spot / strike) + 0.5 * sigma ** 2 * t) / (sigma * math.sqrt(t))
    d2 = d1 - sigma * math.sqrt(t)
    cdf = lambda x: 0.5 * (1 + math.erf(x / math.sqrt(2)))
    call = spot * cdf(d1) - strike * cdf(d2)
    put = strike * cdf(-d2) - spot * cdf(-d1)
    return call + put, 2 * cdf(d1) - 1


def ledger(prices, stock_cost=0.01, option_fee=1.00):
    multiplier = 100
    option0, delta0 = straddle(prices[0], 30)
    shares = -multiplier * delta0
    entry_cost = 2 * option_fee + abs(shares) * stock_cost
    rows = [{"date": "2026-10-12", "spot": prices[0], "delta": delta0,
             "hedge_before": 0, "stock_trade": shares, "hedge_after": shares,
             "option_pnl": 0, "stock_pnl": 0, "cost": entry_cost,
             "net_step": -entry_cost, "net_total": -entry_cost}]
    total, prev_option = -entry_cost, option0
    for i, spot in enumerate(prices[1:], 1):
        option, delta = straddle(spot, 30 - i)
        option_pnl = multiplier * (option - prev_option)
        stock_pnl = shares * (spot - prices[i - 1])
        # Liquidate the straddle and hedge on the final observation.
        closing = i == len(prices) - 1
        target = 0 if closing else -multiplier * delta
        trade = target - shares
        cost = abs(trade) * stock_cost + (2 * option_fee if closing else 0)
        net = option_pnl + stock_pnl - cost
        total += net
        rows.append({"date": str(date(2026, 10, 12) + timedelta(days=i)), "spot": spot,
                     "delta": delta, "hedge_before": shares, "stock_trade": trade,
                     "hedge_after": target, "option_pnl": option_pnl, "stock_pnl": stock_pnl,
                     "cost": cost, "net_step": net, "net_total": total})
        shares, prev_option = target, option
    return rows


def main():
    for name, prices in {"moving": [100, 103, 99, 102, 100],
                         "quiet": [100, 100.1, 99.9, 100.05, 100]}.items():
        rows = ledger(prices)
        path = Path(f"gamma-scalping-{name}.csv")
        with path.open("w", newline="", encoding="utf-8") as stream:
            writer = csv.DictWriter(stream, fieldnames=rows[0])
            writer.writeheader()
            writer.writerows(rows)
        print(f"{name}: net ${rows[-1]['net_total']:.2f}; costs ${sum(r['cost'] for r in rows):.2f}; {path}")


if __name__ == "__main__":
    main()
