Estrategia Fisher Org v1
Esta estrategia utiliza el indicador Fisher Transform para capturar reversiones de tendencia. Se abre una posición larga cuando el indicador forma un mínimo local, mientras que se abre una posición corta cuando aparece un máximo local. Las señales opuestas cierran cualquier posición existente.
Reglas
- Largo:
Fisher[t-2] > Fisher[t-1]yFisher[t-1] <= Fisher[t] - Corto:
Fisher[t-2] < Fisher[t-1]yFisher[t-1] >= Fisher[t]
Parámetros
Fisher Length– período del Fisher Transform (por defecto 7)Candle Type– marco temporal de las velas utilizadas para los cálculos
Indicadores
- Fisher Transform
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>
/// Fisher Org v1 strategy.
/// Detects local minima and maxima of the Fisher Transform indicator.
/// Buys on local minima and sells on local maxima.
/// </summary>
public class FisherOrgV1Strategy : Strategy
{
private readonly StrategyParam<int> _length;
private readonly StrategyParam<DataType> _candleType;
private EhlersFisherTransform _fisher;
private decimal _prev;
private decimal _prevPrev;
private int _valueCount;
/// <summary>
/// Fisher transform period length.
/// </summary>
public int Length
{
get => _length.Value;
set => _length.Value = value;
}
/// <summary>
/// The type of candles to use for strategy calculation.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Initializes a new instance of <see cref="FisherOrgV1Strategy"/>.
/// </summary>
public FisherOrgV1Strategy()
{
_length = Param(nameof(Length), 7)
.SetGreaterThanZero()
.SetDisplay("Fisher Length", "Period for Fisher Transform", "General")
.SetOptimize(5, 20, 1);
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prev = 0m;
_prevPrev = 0m;
_valueCount = 0;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_fisher = new EhlersFisherTransform
{
Length = Length
};
var subscription = SubscribeCandles(CandleType);
subscription.BindEx(_fisher, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _fisher);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue fisherVal)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
if (fisherVal is not IEhlersFisherTransformValue typed || typed.MainLine is not decimal fisherValue)
return;
if (_valueCount < 2)
{
if (_valueCount == 0)
_prev = fisherValue;
else
{
_prevPrev = _prev;
_prev = fisherValue;
}
_valueCount++;
return;
}
var isLongSignal = _prevPrev > _prev && _prev <= fisherValue;
var isShortSignal = _prevPrev < _prev && _prev >= fisherValue;
if (isLongSignal && Position <= 0)
BuyMarket();
if (isShortSignal && Position >= 0)
SellMarket();
_prevPrev = _prev;
_prev = fisherValue;
}
}
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_v1_strategy(Strategy):
def __init__(self):
super(fisher_org_v1_strategy, self).__init__()
self._length = self.Param("Length", 7) \
.SetDisplay("Fisher Length", "Period for Fisher Transform", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._prev = 0.0
self._prev_prev = 0.0
self._value_count = 0
@property
def length(self):
return self._length.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(fisher_org_v1_strategy, self).OnReseted()
self._prev = 0.0
self._prev_prev = 0.0
self._value_count = 0
def OnStarted2(self, time):
super(fisher_org_v1_strategy, self).OnStarted2(time)
self._prev = 0.0
self._prev_prev = 0.0
self._value_count = 0
fisher = EhlersFisherTransform()
fisher.Length = self.length
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(fisher, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, fisher)
self.DrawOwnTrades(area)
def process_candle(self, candle, fisher_val):
if candle.State != CandleStates.Finished:
return
main_line = fisher_val.MainLine
if main_line is None:
return
fisher_value = float(main_line)
if self._value_count < 2:
if self._value_count == 0:
self._prev = fisher_value
else:
self._prev_prev = self._prev
self._prev = fisher_value
self._value_count += 1
return
is_long_signal = self._prev_prev > self._prev and self._prev <= fisher_value
is_short_signal = self._prev_prev < self._prev and self._prev >= fisher_value
if is_long_signal and self.Position <= 0:
self.BuyMarket()
if is_short_signal and self.Position >= 0:
self.SellMarket()
self._prev_prev = self._prev
self._prev = fisher_value
def CreateClone(self):
return fisher_org_v1_strategy()