Estratégia Fisher Org Sign
Esta estratégia utiliza o indicador Fisher Transform com níveis superior e inferior predefinidos. Uma posição comprada é aberta quando o valor Fisher cruza acima do nível inferior. Uma posição vendida é aberta quando o valor Fisher cruza abaixo do nível superior.
Detalhes
- Critérios de entrada:
- Comprado:
Fisher crosses above DownLevel - Vendido:
Fisher crosses below UpLevel
- Comprado:
- Comprado/Vendido: Ambos
- Critérios de saída:
- Sinal oposto aciona a reversão da posição
- Stops: Não
- Valores padrão:
Fisher Length= 7UpLevel= 1.5DownLevel= -1.5
- Filtros:
- Categoria: Seguidor de tendência
- Direção: Ambos
- Indicadores: Fisher Transform
- Stops: Não
- Complexidade: Baixo
- Período: Médio prazo (H4)
- Sazonalidade: Não
- Redes neurais: Não
- Divergência: Não
- Nível de risco: Médio
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>
/// Long on Fisher crossing upward over DownLevel, short on crossing downward under UpLevel.
/// Each reversal first closes the actual position volume, then opens the configured Volume.
/// </summary>
public class FisherOrgSignStrategy : Strategy
{
private readonly StrategyParam<int> _length;
private readonly StrategyParam<decimal> _upLevel;
private readonly StrategyParam<decimal> _downLevel;
private readonly StrategyParam<DataType> _candleType;
private decimal? _previousFisher;
public int Length { get => _length.Value; set => _length.Value = value; }
public decimal UpLevel { get => _upLevel.Value; set => _upLevel.Value = value; }
public decimal DownLevel { get => _downLevel.Value; set => _downLevel.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public FisherOrgSignStrategy()
{
_length = Param(nameof(Length), 7).SetGreaterThanZero()
.SetDisplay("Fisher Length", "Period for Fisher Transform", "General")
.SetOptimize(5, 20, 1);
_upLevel = Param(nameof(UpLevel), 1.5m)
.SetDisplay("Upper Level", "Sell signal level", "General");
_downLevel = Param(nameof(DownLevel), -1.5m)
.SetDisplay("Lower Level", "Buy signal level", "General");
_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();
_previousFisher = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_previousFisher = null;
var fisher = new EhlersFisherTransform { Length = Length };
SubscribeCandles(CandleType).BindEx(fisher, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue fisherValue)
{
if (candle.State != CandleStates.Finished)
return;
if (fisherValue is not IEhlersFisherTransformValue typed || typed.MainLine is not decimal current)
return;
var previous = _previousFisher;
_previousFisher = current;
if (previous is null || !IsFormedAndOnlineAndAllowTrading())
return;
var position = Position;
if (previous <= DownLevel && current > DownLevel && position <= 0m)
{
if (position < 0m)
BuyMarket(-position);
BuyMarket(Volume);
}
else if (previous >= UpLevel && current < UpLevel && position >= 0m)
{
if (position > 0m)
SellMarket(position);
SellMarket(Volume);
}
}
}
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 EhlersFisherTransform
from StockSharp.Algo.Strategies import Strategy
class fisher_org_sign_strategy(Strategy):
"""Fisher level crossings with documented defaults and exact-volume reversal."""
def __init__(self):
super(fisher_org_sign_strategy, self).__init__()
self._length = self.Param("Length", 7).SetDisplay("Fisher Length", "Period for Fisher Transform", "General")
self._up_level = self.Param("UpLevel", 1.5).SetDisplay("Upper Level", "Sell signal level", "General")
self._down_level = self.Param("DownLevel", -1.5).SetDisplay("Lower Level", "Buy signal level", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Type of candles", "General")
self._previous_fisher = None
@property
def Length(self):
return self._length.Value
@Length.setter
def Length(self, value):
self._length.Value = value
@property
def UpLevel(self):
return self._up_level.Value
@UpLevel.setter
def UpLevel(self, value):
self._up_level.Value = value
@property
def DownLevel(self):
return self._down_level.Value
@DownLevel.setter
def DownLevel(self, value):
self._down_level.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnReseted(self):
super(fisher_org_sign_strategy, self).OnReseted()
self._previous_fisher = None
def OnStarted2(self, time):
super(fisher_org_sign_strategy, self).OnStarted2(time)
self._previous_fisher = None
fisher = EhlersFisherTransform()
fisher.Length = self.Length
self.SubscribeCandles(self.CandleType).BindEx(fisher, self.process_candle).Start()
def process_candle(self, candle, fisher_value):
if candle.State != CandleStates.Finished:
return
current = fisher_value.MainLine
if current is None:
return
current = float(current)
previous = self._previous_fisher
self._previous_fisher = current
if previous is None or not self.IsFormedAndOnlineAndAllowTrading():
return
position = self.Position
if previous <= float(self.DownLevel) < current and position <= 0:
if position < 0:
self.BuyMarket(-position)
self.BuyMarket(self.Volume)
elif previous >= float(self.UpLevel) > current and position >= 0:
if position > 0:
self.SellMarket(position)
self.SellMarket(self.Volume)
def CreateClone(self):
return fisher_org_sign_strategy()