MADX-07 ADX MA 策略
该策略由 MQL4 平台的 MADX-07 EA 转换而来,使用 H4 K 线,将两条移动平均线与平均趋向指数 (ADX) 结合作为过滤器。
逻辑
- 做多:价格高于慢速 MA,快速 MA 高于慢速 MA,最近两根 K 线的价格至少比快速 MA 高
MaDifference点,ADX 上升并高于AdxMainLevel,+DI 上升,-DI 下降。 - 做空:条件相反。
- 当盈利达到
CloseProfit点或挂单在TakeProfit距离被执行时,仓位将平仓。
参数
BigMaPeriod(25) – 慢速 MA 的周期。BigMaType– 慢速 MA 的类型。SmallMaPeriod(5) – 快速 MA 的周期。SmallMaType– 快速 MA 的类型。MaDifference(5) – 价格与快速 MA 之间的最小距离(点)。AdxPeriod(11) – ADX 计算周期。AdxMainLevel(13) – ADX 的最小值。AdxPlusLevel(13) – +DI 的最小值。AdxMinusLevel(14) – -DI 的最小值。TakeProfit(299) – 止盈距离(点)。CloseProfit(13) – 提前平仓的利润点数。Volume(0.1) – 交易量。CandleType– K 线时间框(默认 H4)。
using System;
using System.Collections.Generic;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Strategy combining EMA crossover for trend following.
/// </summary>
public class Madx07AdxMaStrategy : Strategy
{
private readonly StrategyParam<int> _bigMaPeriod;
private readonly StrategyParam<int> _smallMaPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevSmall;
private decimal _prevBig;
private bool _hasPrev;
public int BigMaPeriod { get => _bigMaPeriod.Value; set => _bigMaPeriod.Value = value; }
public int SmallMaPeriod { get => _smallMaPeriod.Value; set => _smallMaPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Madx07AdxMaStrategy()
{
_bigMaPeriod = Param(nameof(BigMaPeriod), 25)
.SetGreaterThanZero()
.SetDisplay("Big MA Period", "Period of the slower MA", "MA");
_smallMaPeriod = Param(nameof(SmallMaPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Small MA Period", "Period of the faster MA", "MA");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Candle type", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevSmall = 0;
_prevBig = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var bigMa = new ExponentialMovingAverage { Length = BigMaPeriod };
var smallMa = new ExponentialMovingAverage { Length = SmallMaPeriod };
SubscribeCandles(CandleType)
.Bind(bigMa, smallMa, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal bigMaVal, decimal smallMaVal)
{
if (candle.State != CandleStates.Finished) return;
if (!_hasPrev)
{
_prevSmall = smallMaVal;
_prevBig = bigMaVal;
_hasPrev = true;
return;
}
var crossUp = _prevSmall <= _prevBig && smallMaVal > bigMaVal;
var crossDown = _prevSmall >= _prevBig && smallMaVal < bigMaVal;
if (crossUp && Position <= 0)
{
if (Position < 0) BuyMarket();
BuyMarket();
}
else if (crossDown && Position >= 0)
{
if (Position > 0) SellMarket();
SellMarket();
}
_prevSmall = smallMaVal;
_prevBig = bigMaVal;
}
}
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 ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class madx07_adx_ma_strategy(Strategy):
def __init__(self):
super(madx07_adx_ma_strategy, self).__init__()
self._big_ma_period = self.Param("BigMaPeriod", 25) \
.SetDisplay("Big MA Period", "Period of the slower MA", "MA")
self._small_ma_period = self.Param("SmallMaPeriod", 10) \
.SetDisplay("Small MA Period", "Period of the faster MA", "MA")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Candle type", "General")
self._prev_small = 0.0
self._prev_big = 0.0
self._has_prev = False
@property
def big_ma_period(self):
return self._big_ma_period.Value
@property
def small_ma_period(self):
return self._small_ma_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(madx07_adx_ma_strategy, self).OnReseted()
self._prev_small = 0.0
self._prev_big = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(madx07_adx_ma_strategy, self).OnStarted2(time)
big_ma = ExponentialMovingAverage()
big_ma.Length = self.big_ma_period
small_ma = ExponentialMovingAverage()
small_ma.Length = self.small_ma_period
self.SubscribeCandles(self.candle_type).Bind(big_ma, small_ma, self.process_candle).Start()
def process_candle(self, candle, big_ma_val, small_ma_val):
if candle.State != CandleStates.Finished:
return
bv = float(big_ma_val)
sv = float(small_ma_val)
if not self._has_prev:
self._prev_small = sv
self._prev_big = bv
self._has_prev = True
return
cross_up = self._prev_small <= self._prev_big and sv > bv
cross_down = self._prev_small >= self._prev_big and sv < bv
if cross_up and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif cross_down and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_small = sv
self._prev_big = bv
def CreateClone(self):
return madx07_adx_ma_strategy()