"""
Vibe-Trading → vnpy export: MA crossover strategy template.

This file is the reference implementation for the vnpy-export skill.
Copy it to your vnpy project's strategies/ folder and adjust parameters.

Requirements:
    pip install vnpy vnpy_ctp  (or vnpy_tts for paper trading)

Usage in vnpy Trader:
    CTA Strategy App → Add Strategy → MaCrossStrategy
    Set vt_symbol, e.g. "IF2406.CFFEX" (futures) or "000001.SZSE" (A-share)
"""

from vnpy.app.cta_strategy import (
    CtaTemplate,
    StopOrder,
    TickData,
    BarData,
    TradeData,
    OrderData,
    BarGenerator,
    ArrayManager,
)


class MaCrossStrategy(CtaTemplate):
    """
    Dual moving-average crossover — generated by Vibe-Trading.

    Signals:
        Long entry  : fast MA crosses above slow MA (golden cross)
        Long exit   : fast MA crosses below slow MA (death cross)
        Short entry : fast MA crosses below slow MA (futures / crypto only)
        Short exit  : fast MA crosses above slow MA

    Supports equity (long-only) and futures/crypto (long + short).
    Set `trade_long_only = True` for A-share stocks.
    """

    author = "Vibe-Trading"

    # ── Parameters (editable in the vnpy UI) ─────────────────────────────
    fast_window: int = 10
    slow_window: int = 30
    trade_long_only: bool = False   # True for A-share stocks (no short selling)

    parameters = ["fast_window", "slow_window", "trade_long_only"]

    # ── Variables (live state displayed in the vnpy UI) ───────────────────
    fast_ma0: float = 0.0    # fast MA, current bar
    fast_ma1: float = 0.0    # fast MA, previous bar
    slow_ma0: float = 0.0    # slow MA, current bar
    slow_ma1: float = 0.0    # slow MA, previous bar

    variables = ["fast_ma0", "fast_ma1", "slow_ma0", "slow_ma1"]

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.bg = BarGenerator(self.on_bar)
        self.am = ArrayManager()

        self.fast_ma0 = 0.0
        self.fast_ma1 = 0.0
        self.slow_ma0 = 0.0
        self.slow_ma1 = 0.0

    def on_init(self):
        self.write_log("Strategy initialised")
        self.load_bar(self.slow_window + 2)

    def on_start(self):
        self.write_log("Strategy started")
        self.put_event()

    def on_stop(self):
        self.write_log("Strategy stopped")

    def on_tick(self, tick: TickData):
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        self.cancel_all()

        am = self.am
        am.update_bar(bar)
        if not am.inited:
            return

        # ── Indicators ───────────────────────────────────────────────────
        fast_ma = am.sma(self.fast_window, array=True)
        slow_ma = am.sma(self.slow_window, array=True)

        self.fast_ma0 = fast_ma[-1]
        self.fast_ma1 = fast_ma[-2]
        self.slow_ma0 = slow_ma[-1]
        self.slow_ma1 = slow_ma[-2]

        # ── Crossover detection ──────────────────────────────────────────
        cross_over = self.fast_ma0 > self.slow_ma0 and self.fast_ma1 <= self.slow_ma1
        cross_under = self.fast_ma0 < self.slow_ma0 and self.fast_ma1 >= self.slow_ma1

        # ── Order execution ──────────────────────────────────────────────
        if cross_over:
            if self.pos == 0:
                self.buy(bar.close_price, 1)
            elif self.pos < 0:
                self.cover(bar.close_price, 1)
                self.buy(bar.close_price, 1)

        elif cross_under:
            if self.trade_long_only:
                if self.pos > 0:
                    self.sell(bar.close_price, 1)
            else:
                if self.pos == 0:
                    self.short(bar.close_price, 1)
                elif self.pos > 0:
                    self.sell(bar.close_price, 1)
                    self.short(bar.close_price, 1)

        self.put_event()

    def on_order(self, order: OrderData):
        pass

    def on_trade(self, trade: TradeData):
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        pass
