Momentum Alligator 4h Bitcoin 策略
Momentum Alligator 4h Bitcoin 策略将 Awesome 振荡器与日线级别的 Alligator 指标结合使用。当振荡器上穿其 5 周期 SMA 且价格位于日线 Alligator 三条线之上时开多。动态止损在入场价按百分比下移和 Alligator 下颚线之间取较高值。盈利平仓后策略会跳过接下来的两个信号。
细节
- 入场条件:AO 上穿其 5 周期 SMA 且收盘价高于日线 Alligator 各线。
- 多空方向:仅做多。
- 出场条件:动态止损,取百分比止损与 Alligator 下颚的较大者。
- 止损:有。
- 默认值:
StopLossPercent= 0.02mCandleType= TimeSpan.FromHours(4)TradeStart= 2023-01-01TradeStop= 2025-01-01
- 过滤器:
- 类别:Momentum
- 方向:Long
- 指标:Awesome Oscillator, Alligator
- 止损:有
- 复杂度:基础
- 时间框架:中期
- 季节性:无
- 神经网络:无
- 背离:无
- 风险等级:中等
using System;
using System.Linq;
using Ecng.Common;
using StockSharp.Algo;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Momentum Alligator strategy for Bitcoin.
/// </summary>
public class MomentumAlligator4hBitcoinStrategy : Strategy
{
private readonly StrategyParam<decimal> _stopLossPercent;
private readonly StrategyParam<int> _signalCooldownBars;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevAo;
private bool _hasPrev;
private decimal _entryPrice;
private int _barsFromSignal;
public decimal StopLossPercent { get => _stopLossPercent.Value; set => _stopLossPercent.Value = value; }
public int SignalCooldownBars { get => _signalCooldownBars.Value; set => _signalCooldownBars.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public MomentumAlligator4hBitcoinStrategy()
{
_stopLossPercent = Param(nameof(StopLossPercent), 0.02m).SetGreaterThanZero();
_signalCooldownBars = Param(nameof(SignalCooldownBars), 2).SetGreaterThanZero();
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(15).TimeFrame());
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevAo = 0m;
_hasPrev = false;
_entryPrice = 0m;
_barsFromSignal = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevAo = 0;
_hasPrev = false;
_entryPrice = 0;
_barsFromSignal = SignalCooldownBars;
var jaw = new SmoothedMovingAverage { Length = 13 };
var teeth = new SmoothedMovingAverage { Length = 8 };
var lips = new SmoothedMovingAverage { Length = 5 };
var ao = new AwesomeOscillator { ShortMa = { Length = 5 }, LongMa = { Length = 34 } };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ao, jaw, teeth, lips, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal ao, decimal jaw, decimal teeth, decimal lips)
{
if (candle.State != CandleStates.Finished)
return;
var close = candle.ClosePrice;
_barsFromSignal++;
if (_hasPrev)
{
var aoCrossUp = _prevAo <= 0m && ao > 0m;
var aoCrossDown = _prevAo >= 0m && ao < 0m;
var alligatorBull = lips > teeth && close > jaw;
var alligatorBear = lips < teeth && close < jaw;
if (_barsFromSignal >= SignalCooldownBars && aoCrossUp && alligatorBull && Position <= 0)
{
BuyMarket();
_entryPrice = close;
_barsFromSignal = 0;
}
if (_barsFromSignal >= SignalCooldownBars && aoCrossDown && alligatorBear && Position >= 0)
{
SellMarket();
_entryPrice = close;
_barsFromSignal = 0;
}
}
if (Position > 0 && _entryPrice > 0)
{
var percentStop = _entryPrice * (1m - StopLossPercent);
if (close < percentStop || close < teeth)
{
SellMarket();
}
}
else if (Position < 0 && _entryPrice > 0)
{
var percentStop = _entryPrice * (1m + StopLossPercent);
if (close > percentStop || close > teeth)
{
BuyMarket();
}
}
_prevAo = ao;
_hasPrev = true;
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import SmoothedMovingAverage, AwesomeOscillator
from StockSharp.Algo.Strategies import Strategy
class momentum_alligator_4h_bitcoin_strategy(Strategy):
"""
Momentum Alligator 4h Bitcoin: AO zero-line cross with Alligator alignment and stop-loss.
"""
def __init__(self):
super(momentum_alligator_4h_bitcoin_strategy, self).__init__()
self._stop_loss_pct = self.Param("StopLossPercent", 0.02).SetDisplay("SL %", "Stop loss percent", "Risk")
self._cooldown_bars = self.Param("SignalCooldownBars", 2).SetDisplay("Cooldown", "Min bars between entries", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(15))).SetDisplay("Candle Type", "Candles", "General")
self._prev_ao = 0.0
self._has_prev = False
self._entry_price = 0.0
self._bars_from_signal = 2
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(momentum_alligator_4h_bitcoin_strategy, self).OnReseted()
self._prev_ao = 0.0
self._has_prev = False
self._entry_price = 0.0
self._bars_from_signal = self._cooldown_bars.Value
def OnStarted2(self, time):
super(momentum_alligator_4h_bitcoin_strategy, self).OnStarted2(time)
jaw = SmoothedMovingAverage()
jaw.Length = 13
teeth = SmoothedMovingAverage()
teeth.Length = 8
lips = SmoothedMovingAverage()
lips.Length = 5
ao = AwesomeOscillator()
ao.ShortMa.Length = 5
ao.LongMa.Length = 34
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ao, jaw, teeth, lips, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ao_val, jaw_val, teeth_val, lips_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
ao = float(ao_val)
jaw = float(jaw_val)
teeth = float(teeth_val)
lips = float(lips_val)
self._bars_from_signal += 1
if self._has_prev:
ao_cross_up = self._prev_ao <= 0.0 and ao > 0.0
ao_cross_down = self._prev_ao >= 0.0 and ao < 0.0
alligator_bull = lips > teeth and close > jaw
alligator_bear = lips < teeth and close < jaw
if self._bars_from_signal >= self._cooldown_bars.Value and ao_cross_up and alligator_bull and self.Position <= 0:
self.BuyMarket()
self._entry_price = close
self._bars_from_signal = 0
if self._bars_from_signal >= self._cooldown_bars.Value and ao_cross_down and alligator_bear and self.Position >= 0:
self.SellMarket()
self._entry_price = close
self._bars_from_signal = 0
sl_pct = float(self._stop_loss_pct.Value)
if self.Position > 0 and self._entry_price > 0:
if close < self._entry_price * (1.0 - sl_pct) or close < teeth:
self.SellMarket()
elif self.Position < 0 and self._entry_price > 0:
if close > self._entry_price * (1.0 + sl_pct) or close > teeth:
self.BuyMarket()
self._prev_ao = ao
self._has_prev = True
def CreateClone(self):
return momentum_alligator_4h_bitcoin_strategy()