Inicio
/
Ejemplos de estrategias
Ver en GitHub
Fibo Average MA Crossover Strategy
Overview
This strategy converts the MetaTrader expert advisor EA_Fibo_Avg_001a into the StockSharp framework.
It uses two smoothed moving averages. The slow average length is the sum of the base period and a Fibonacci-based offset.
A long position is opened when the fast average crosses above the slow average, while a short position is opened on the opposite crossover.
Positions are managed with stop loss, take profit and a trailing stop. Optional money management can calculate the order volume from the portfolio size.
Parameters
CandleType – candle data type.
FiboNumPeriod – additional length added to the slow moving average.
MaPeriod – base period of the moving averages.
TrailingStop – trailing distance in price steps.
TakeProfit – take profit distance in price steps.
StopLoss – stop loss distance in price steps.
UseMoneyManagement – enable simple money management.
PercentMm – portfolio percentage used when money management is enabled.
LotSize – default order volume when money management is disabled.
Logic
Subscribe to candles and calculate two smoothed moving averages.
When the fast average crosses above the slow average, buy. When it crosses below, sell.
After entering a position set stop loss, take profit and trailing levels.
Update trailing stop as price moves in favor and close positions when protective levels are hit or the opposite crossover occurs.
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 based on crossover of two smoothed moving averages with Fibonacci offset.
/// </summary>
public class FiboAvg001aStrategy : Strategy
{
private readonly StrategyParam<int> _fiboNumPeriod;
private readonly StrategyParam<int> _maPeriod;
private readonly StrategyParam<DataType> _candleType;
private decimal _prevFast;
private decimal _prevSlow;
private bool _hasPrev;
public int FiboNumPeriod { get => _fiboNumPeriod.Value; set => _fiboNumPeriod.Value = value; }
public int MaPeriod { get => _maPeriod.Value; set => _maPeriod.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public FiboAvg001aStrategy()
{
_fiboNumPeriod = Param(nameof(FiboNumPeriod), 11)
.SetGreaterThanZero()
.SetDisplay("Fibo Period", "Additional length for slow MA", "Indicators");
_maPeriod = Param(nameof(MaPeriod), 21)
.SetGreaterThanZero()
.SetDisplay("MA Period", "Base moving average period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
=> [(Security, CandleType)];
protected override void OnReseted()
{
base.OnReseted();
_prevFast = 0;
_prevSlow = 0;
_hasPrev = false;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var fastMa = new SmoothedMovingAverage { Length = MaPeriod };
var slowMa = new SmoothedMovingAverage { Length = MaPeriod + FiboNumPeriod };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(fastMa, slowMa, ProcessCandle)
.Start();
}
private void ProcessCandle(ICandleMessage candle, decimal fast, decimal slow)
{
if (candle.State != CandleStates.Finished)
return;
if (!_hasPrev)
{
_prevFast = fast;
_prevSlow = slow;
_hasPrev = true;
return;
}
// Fast crosses above slow -> buy
if (_prevFast <= _prevSlow && fast > slow)
{
if (Position < 0)
BuyMarket();
if (Position <= 0)
BuyMarket();
}
// Fast crosses below slow -> sell
else if (_prevFast >= _prevSlow && fast < slow)
{
if (Position > 0)
SellMarket();
if (Position >= 0)
SellMarket();
}
_prevFast = fast;
_prevSlow = slow;
}
}
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
from StockSharp.Algo.Strategies import Strategy
class fibo_avg001a_strategy(Strategy):
def __init__(self):
super(fibo_avg001a_strategy, self).__init__()
self._fibo_num_period = self.Param("FiboNumPeriod", 11) \
.SetDisplay("Fibo Period", "Additional length for slow MA", "Indicators")
self._ma_period = self.Param("MaPeriod", 21) \
.SetDisplay("MA Period", "Base moving average period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
@property
def fibo_num_period(self):
return self._fibo_num_period.Value
@property
def ma_period(self):
return self._ma_period.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(fibo_avg001a_strategy, self).OnReseted()
self._prev_fast = 0.0
self._prev_slow = 0.0
self._has_prev = False
def OnStarted2(self, time):
super(fibo_avg001a_strategy, self).OnStarted2(time)
fast_ma = SmoothedMovingAverage()
fast_ma.Length = self.ma_period
slow_ma = SmoothedMovingAverage()
slow_ma.Length = self.ma_period + self.fibo_num_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(fast_ma, slow_ma, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, fast, slow):
if candle.State != CandleStates.Finished:
return
if not self._has_prev:
self._prev_fast = fast
self._prev_slow = slow
self._has_prev = True
return
# Fast crosses above slow -> buy
if self._prev_fast <= self._prev_slow and fast > slow:
if self.Position < 0:
self.BuyMarket()
if self.Position <= 0:
self.BuyMarket()
# Fast crosses below slow -> sell
elif self._prev_fast >= self._prev_slow and fast < slow:
if self.Position > 0:
self.SellMarket()
if self.Position >= 0:
self.SellMarket()
self._prev_fast = fast
self._prev_slow = slow
def CreateClone(self):
return fibo_avg001a_strategy()