"""Small deterministic configuration test, NOT a trading strategy benchmark.

No network or account credentials. All prices are artificial.
"""
from pathlib import Path
import hashlib
import importlib.metadata
import json
import platform
import sys

import akquant as aq
import pandas as pd

ROOT = Path(__file__).resolve().parent
SYMBOL = "SYNTH"
CALENDAR = ["2026-10-26", "2026-10-27"]
FEES = dict(commission_rate=0.001, min_commission=0.0,
            stamp_tax_rate=0.0, transfer_fee_rate=0.0)
CASES = {"A_default": {}, "B_fees_only": FEES,
         "C_t1_only": {"t_plus_one": True},
         "D_fees_t1": {**FEES, "t_plus_one": True}}


def fixture():
    times = [f"{day} 09:{minute}:00" for day in CALENDAR for minute in range(31, 35)]
    prices = [9.8, 10.0, 10.7, 11.0, 9.7, 9.5, 9.6, 9.7]
    return pd.DataFrame({
        "date": pd.DatetimeIndex(times).tz_localize("Asia/Shanghai"),
        "open": prices, "high": [p + .2 for p in prices],
        "low": [p - .1 for p in prices], "close": [p + .1 for p in prices],
        "volume": [10000] * 8, "symbol": [SYMBOL] * 8,
    })


class Probe(aq.Strategy):
    def on_start(self):
        self.bar_number = 0
        self.observations = []

    def on_bar(self, bar):
        i = self.bar_number
        row = {"bar": i, "time": bar.timestamp_iso,
               "position_before": self.get_position(SYMBOL), "action": "none"}
        if i == 0:
            row["action"] = "buy_100"
            row["receipt"] = str(self.buy(symbol=SYMBOL, quantity=100))
        elif i in (2, 4) and self.get_position(SYMBOL) > 0:
            row["action"] = "sell_100"
            row["receipt"] = str(self.sell(symbol=SYMBOL, quantity=100))
        self.observations.append(row)
        self.bar_number += 1


def records(frame):
    return json.loads(frame.to_json(orient="records", date_format="iso"))


def run_case(name, options, data):
    strategy = Probe()
    result = aq.run_backtest(
        data=data.copy(), strategy=strategy, symbols=SYMBOL,
        initial_cash=10000.0, timezone="Asia/Shanghai",
        trading_calendar=CALENDAR, lot_size=100,
        show_progress=False, **options,
    )
    return {"name": name, "options": options,
            "observations": strategy.observations,
            "orders": records(result.orders_df),
            "executions": records(result.executions_df),
            "metrics": records(result.metrics_df.reset_index()),
            "positions": records(result.positions_df.reset_index())}


def main():
    data = fixture()
    data.to_csv(ROOT / "fixture.csv", index=False)
    packages = sorted(f"{d.metadata['Name']}=={d.version}" for d in importlib.metadata.distributions())
    (ROOT / "requirements.lock.txt").write_text("\n".join(packages) + "\n")
    report = {
        "purpose": "Synthetic configuration experiment; not real market data or investment performance",
        "environment": {"python": sys.version, "platform": platform.platform(),
                        "akquant": importlib.metadata.version("akquant"), "packages": packages},
        "common": {"symbol": SYMBOL, "calendar": CALENDAR, "timezone": "Asia/Shanghai",
                   "initial_cash": 10000, "lot_size": 100, "fill_policy": "omitted (library default)"},
        "fixture_sha256": hashlib.sha256((ROOT / "fixture.csv").read_bytes()).hexdigest(),
        "cases": [run_case(n, v, data) for n, v in CASES.items()],
    }
    (ROOT / "results.json").write_text(json.dumps(report, ensure_ascii=False, indent=2)+"\n")
    manifest = {name: hashlib.sha256((ROOT / name).read_bytes()).hexdigest()
                for name in ["fixture.csv", "results.json", "experiment.py", "requirements.lock.txt"]}
    (ROOT / "manifest.json").write_text(json.dumps(manifest, indent=2)+"\n")
    for case in report["cases"]:
        metrics = {m["name"]: m["value"] for m in case["metrics"]}
        print(json.dumps({"case": case["name"], "fills": len(case["executions"]),
                          "rejections": len([o for o in case["orders"] if o["status"] == "rejected"]),
                          "fees": metrics["total_commission"],
                          "end_value": metrics["end_market_value"]}, ensure_ascii=False))


if __name__ == "__main__":
    main()
