43 lines
1.4 KiB
Python
43 lines
1.4 KiB
Python
"""MACD 金叉死叉策略。"""
|
|
from __future__ import annotations
|
|
|
|
import pandas as pd
|
|
|
|
from ...indicators import macd
|
|
from ..broker import PaperBroker
|
|
from .base import Strategy
|
|
|
|
|
|
class MACDCrossStrategy(Strategy):
|
|
def __init__(self, fast: float = 12, slow: float = 26, signal: float = 9):
|
|
self.fast = int(fast)
|
|
self.slow = int(slow)
|
|
self.signal = int(signal)
|
|
self._ind: pd.DataFrame | None = None
|
|
self._prev_dif: float | None = None
|
|
self._prev_dea: float | None = None
|
|
|
|
def compute(self, close: pd.Series, high: pd.Series, low: pd.Series) -> pd.DataFrame:
|
|
self._ind = macd(close, self.fast, self.slow, self.signal)
|
|
return self._ind
|
|
|
|
def on_bar(self, i: int, row: pd.Series, broker: PaperBroker) -> None:
|
|
dif = float(self._ind["macd"].iloc[i])
|
|
dea = float(self._ind["signal"].iloc[i])
|
|
|
|
if self._prev_dif is None:
|
|
self._prev_dif, self._prev_dea = dif, dea
|
|
return
|
|
|
|
golden = self._prev_dif <= self._prev_dea and dif > dea # 金叉
|
|
death = self._prev_dif >= self._prev_dea and dif < dea # 死叉
|
|
|
|
price = float(row["close"])
|
|
ts = row["ts"]
|
|
if golden and pd.notna(dif):
|
|
broker.buy_max(ts, price)
|
|
elif death and broker.position > 0 and pd.notna(dif):
|
|
broker.sell_all(ts, price)
|
|
|
|
self._prev_dif, self._prev_dea = dif, dea
|