WODIsMA Triple MA Crossover Strategy
Strategy based on three moving averages for trend confirmation. It enters long when the fast average is above the middle and slow ones, and enters short on the opposite alignment.
using System;
using System.Linq;
using System.Collections.Generic;
using Ecng.Common;
using Ecng.Collections;
using Ecng.Serialization;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Triple moving average crossover strategy with trend confirmation.
/// Enters long when fast > middle > slow and short on the opposite order.
/// </summary>
public class WodismaTripleMaCrossoverStrategy : Strategy
{
private readonly StrategyParam<int> _fastLength;
private readonly StrategyParam<int> _midLength;
private readonly StrategyParam<int> _slowLength;
private readonly StrategyParam<DataType> _candleType;
/// <summary>
/// Fast MA period.
/// </summary>
public int FastLength
{
get => _fastLength.Value;
set => _fastLength.Value = value;
}
/// <summary>
/// Middle MA period.
/// </summary>
public int MidLength
{
get => _midLength.Value;
set => _midLength.Value = value;
}
/// <summary>
/// Slow MA period.
/// </summary>
public int SlowLength
{
get => _slowLength.Value;
set => _slowLength.Value = value;
}
/// <summary>
/// Candle type used by the strategy.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes <see cref="WodismaTripleMaCrossoverStrategy"/>.
/// </summary>
public WodismaTripleMaCrossoverStrategy()
{
_fastLength = Param(nameof(FastLength), 5)
.SetGreaterThanZero()
.SetDisplay("Fast MA", "Fast MA period", "MA");
_midLength = Param(nameof(MidLength), 20)
.SetGreaterThanZero()
.SetDisplay("Mid MA", "Middle MA period", "MA");
_slowLength = Param(nameof(SlowLength), 50)
.SetGreaterThanZero()
.SetDisplay("Slow MA", "Slow MA period", "MA");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fast = new SimpleMovingAverage { Length = FastLength };
var mid = new SimpleMovingAverage { Length = MidLength };
var slow = new SimpleMovingAverage { Length = SlowLength };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(fast, mid, slow, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, fast);
DrawIndicator(area, mid);
DrawIndicator(area, slow);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal mid, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (fast > mid && mid > slow && Position <= 0)
{
BuyMarket();
}
else if (fast < mid && mid < slow && Position >= 0)
{
SellMarket();
}
}
}
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 SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class wodisma_triple_ma_crossover_strategy(Strategy):
def __init__(self):
super(wodisma_triple_ma_crossover_strategy, self).__init__()
self._fast_length = self.Param("FastLength", 5) \
.SetDisplay("Fast MA", "Fast MA period", "MA")
self._mid_length = self.Param("MidLength", 20) \
.SetDisplay("Mid MA", "Middle MA period", "MA")
self._slow_length = self.Param("SlowLength", 50) \
.SetDisplay("Slow MA", "Slow MA period", "MA")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
@property
def fast_length(self):
return self._fast_length.Value
@property
def mid_length(self):
return self._mid_length.Value
@property
def slow_length(self):
return self._slow_length.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnStarted2(self, time):
super(wodisma_triple_ma_crossover_strategy, self).OnStarted2(time)
fast = SimpleMovingAverage()
fast.Length = self.fast_length
mid = SimpleMovingAverage()
mid.Length = self.mid_length
slow = SimpleMovingAverage()
slow.Length = self.slow_length
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast, mid, slow, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fast)
self.DrawIndicator(area, mid)
self.DrawIndicator(area, slow)
self.DrawOwnTrades(area)
def on_process(self, candle, fast, mid, slow):
if candle.State != CandleStates.Finished:
return
if fast > mid and mid > slow and self.Position <= 0:
self.BuyMarket()
elif fast < mid and mid < slow and self.Position >= 0:
self.SellMarket()
def CreateClone(self):
return wodisma_triple_ma_crossover_strategy()