Estratégia de Máximos e Mínimos
Estratégia que opera nos pontos médios das velas em relação ao intervalo de máximos e mínimos.
Compra quando o ponto médio da vela atual está abaixo da média dos valores mais altos e mais baixos e a distância normalizada está abaixo de LowThreshold. Fecha a posição comprada quando o ponto médio sobe acima da média e a distância normalizada está acima de HighThreshold.
Detalhes
- Critérios de entrada: Ponto médio abaixo da média e distância normalizada abaixo de LowThreshold.
- Comprado/Vendido: Somente comprado.
- Critérios de saída: Ponto médio acima da média e distância normalizada acima de HighThreshold.
- Stops: Não.
- Valores padrão:
Range= 100LowThreshold= 15mHighThreshold= 85mCandleType= TimeSpan.FromMinutes(240)
- Filtros:
- Categoria: Range
- Direção: Comprado
- Indicadores: Highest, Lowest
- Stops: Não
- Complexidade: Básico
- Período: Intradiário (240m)
- 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>
/// Highs Lows strategy.
/// Tracks the highest high and lowest low of the last Range candles. The candle midpoint is compared with the average of
/// these extremes, and their distance is normalized by half the range (0 at the average, 100 at an extreme). A long opens when the midpoint is
/// below the average and the normalized distance is below LowThreshold, and closes when the midpoint is above the average
/// and the normalized distance is above HighThreshold.
/// </summary>
public class HighsLowsStrategy : Strategy
{
private readonly StrategyParam<int> _range;
private readonly StrategyParam<decimal> _lowThreshold;
private readonly StrategyParam<decimal> _highThreshold;
private readonly StrategyParam<DataType> _candleType;
private Highest _highest;
private Lowest _lowest;
/// <summary>
/// Number of candles for the highest and lowest values.
/// </summary>
public int Range
{
get => _range.Value;
set => _range.Value = value;
}
/// <summary>
/// Normalized distance below which a long opens.
/// </summary>
public decimal LowThreshold
{
get => _lowThreshold.Value;
set => _lowThreshold.Value = value;
}
/// <summary>
/// Normalized distance above which the long closes.
/// </summary>
public decimal HighThreshold
{
get => _highThreshold.Value;
set => _highThreshold.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public HighsLowsStrategy()
{
_range = Param(nameof(Range), 100)
.SetGreaterThanZero()
.SetDisplay("Range", "Number of candles for highest and lowest values", "Indicators");
_lowThreshold = Param(nameof(LowThreshold), 15m)
.SetDisplay("Low Threshold", "Normalized distance below which a long opens", "Signals");
_highThreshold = Param(nameof(HighThreshold), 85m)
.SetDisplay("High Threshold", "Normalized distance above which the long closes", "Signals");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(240).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();
_highest = null;
_lowest = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_highest = new Highest { Length = Range };
_lowest = new Lowest { Length = Range };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _highest);
DrawIndicator(area, _lowest);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
var highest = _highest.Process(candle.HighPrice, candle.OpenTime, true).ToDecimal();
var lowest = _lowest.Process(candle.LowPrice, candle.OpenTime, true).ToDecimal();
if (!_highest.IsFormed || !_lowest.IsFormed)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var width = highest - lowest;
if (width <= 0)
return;
var midpoint = (candle.HighPrice + candle.LowPrice) / 2;
var average = (highest + lowest) / 2;
// Distance from the average as a percentage of the half range: 0 at the average, 100 at an extreme.
var distance = Math.Abs(midpoint - average) / (width / 2) * 100m;
if (Position <= 0 && midpoint < average && distance < LowThreshold)
BuyMarket(Volume + Math.Abs(Position));
else if (Position > 0 && midpoint > average && distance > HighThreshold)
SellMarket(Position);
}
}
import clr
clr.AddReference("StockSharp.Messages")
clr.AddReference("StockSharp.Algo")
clr.AddReference("StockSharp.Algo.Indicators")
clr.AddReference("StockSharp.Algo.Strategies")
from System import TimeSpan, Decimal
from StockSharp.Messages import DataType, CandleStates
from StockSharp.Algo.Indicators import Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
from indicator_extensions import *
class highs_lows_strategy(Strategy):
"""
Highs Lows strategy.
Tracks the highest high and lowest low of the last Range candles. The candle midpoint is compared with the average of
these extremes, and their distance is normalized by half the range (0 at the average, 100 at an extreme). A long opens when the midpoint is
below the average and the normalized distance is below LowThreshold, and closes when the midpoint is above the average
and the normalized distance is above HighThreshold.
"""
def __init__(self):
super(highs_lows_strategy, self).__init__()
self._range = self.Param("Range", 100).SetGreaterThanZero().SetDisplay("Range", "Number of candles for highest and lowest values", "Indicators")
self._low_threshold = self.Param("LowThreshold", 15.0).SetDisplay("Low Threshold", "Normalized distance below which a long opens", "Signals")
self._high_threshold = self.Param("HighThreshold", 85.0).SetDisplay("High Threshold", "Normalized distance above which the long closes", "Signals")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(240))).SetDisplay("Candle Type", "Type of candles to use", "General")
self._highest = None
self._lowest = None
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(highs_lows_strategy, self).OnReseted()
self._highest = None
self._lowest = None
def OnStarted2(self, time):
super(highs_lows_strategy, self).OnStarted2(time)
self._highest = Highest()
self._highest.Length = self._range.Value
self._lowest = Lowest()
self._lowest.Length = self._range.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, self._highest)
self.DrawIndicator(area, self._lowest)
self.DrawOwnTrades(area)
def _process_candle(self, candle):
if candle.State != CandleStates.Finished:
return
highest = process_float(self._highest, candle.HighPrice, candle.OpenTime, True).GetValue[Decimal](None)
lowest = process_float(self._lowest, candle.LowPrice, candle.OpenTime, True).GetValue[Decimal](None)
if not self._highest.IsFormed or not self._lowest.IsFormed:
return
if not self.IsFormedAndOnlineAndAllowTrading():
return
width = highest - lowest
if width <= 0:
return
midpoint = (candle.HighPrice + candle.LowPrice) / Decimal(2)
average = (highest + lowest) / Decimal(2)
# Distance from the average as a percentage of the half range: 0 at the average, 100 at an extreme.
distance = abs(midpoint - average) / (width / Decimal(2)) * Decimal(100)
if self.Position <= 0 and midpoint < average and distance < Decimal(self._low_threshold.Value):
self.BuyMarket(self.Volume + abs(self.Position))
elif self.Position > 0 and midpoint > average and distance > Decimal(self._high_threshold.Value):
self.SellMarket(self.Position)
def CreateClone(self):
return highs_lows_strategy()