Estratégia de Rompimento para Iniciantes
Usa os preços mais altos e mais baixos das últimas Period velas para formar um canal. Quando o fechamento se aproxima do limite superior, a estratégia vai comprada. Quando o fechamento se aproxima do limite inferior, vai vendida.
Regras de Entrada
- Comprado: Close >= highest - (highest - lowest) *
ShiftPercent/ 100 e a tendência ainda não está em alta. - Vendido: Close <= lowest + (highest - lowest) *
ShiftPercent/ 100 e a tendência ainda não está em baixa.
Regras de Saída
- O sinal oposto fecha a posição atual e abre uma nova na outra direção.
Parâmetros
Period– barras para olhar para trás no cálculo do canal.ShiftPercent– deslocamento percentual das bordas do canal.CandleType– período das velas de trabalho.Volume– volume de negociação.StopLoss– stop loss em unidades de preço.TakeProfit– take profit em unidades de preço.
Indicadores
- Highest
- Lowest
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>
/// Strategy based on Beginner indicator breakout.
/// Opens a long position when price closes near the recent high.
/// Opens a short position when price closes near the recent low.
/// </summary>
public class BeginnerBreakoutStrategy : Strategy
{
private readonly StrategyParam<int> _period;
private readonly StrategyParam<decimal> _shiftPercent;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<decimal> _takeProfit;
private Highest _highest = null!;
private Lowest _lowest = null!;
private TrendDirections _trend = TrendDirections.None;
/// <summary>
/// Lookback period for highest/highest calculation.
/// </summary>
public int Period
{
get => _period.Value;
set => _period.Value = value;
}
/// <summary>
/// Percentage shift from the channel borders.
/// </summary>
public decimal ShiftPercent
{
get => _shiftPercent.Value;
set => _shiftPercent.Value = value;
}
/// <summary>
/// Candle type to work on.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// Stop loss in price units.
/// </summary>
public decimal StopLoss
{
get => _stopLoss.Value;
set => _stopLoss.Value = value;
}
/// <summary>
/// Take profit in price units.
/// </summary>
public decimal TakeProfit
{
get => _takeProfit.Value;
set => _takeProfit.Value = value;
}
/// <summary>
/// Initializes a new instance of the <see cref="BeginnerBreakoutStrategy"/> class.
/// </summary>
public BeginnerBreakoutStrategy()
{
_period = Param(nameof(Period), 9)
.SetDisplay("Period", "Lookback period for highs/lows", "General")
.SetGreaterThanZero()
;
_shiftPercent = Param(nameof(ShiftPercent), 30m)
.SetDisplay("Shift %", "Percentage shift from channel", "General")
.SetGreaterThanZero()
;
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Timeframe for strategy", "General");
_stopLoss = Param(nameof(StopLoss), 2m)
.SetDisplay("Stop Loss", "Stop loss in percent", "Risk")
.SetGreaterThanZero();
_takeProfit = Param(nameof(TakeProfit), 4m)
.SetDisplay("Take Profit", "Take profit in percent", "Risk")
.SetGreaterThanZero();
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_trend = TrendDirections.None;
_highest = null!;
_lowest = null!;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_highest = new Highest { Length = Period };
_lowest = new Lowest { Length = Period };
StartProtection(new Unit(TakeProfit, UnitTypes.Percent), new Unit(StopLoss, UnitTypes.Percent));
var subscription = SubscribeCandles(CandleType);
subscription.Bind(_highest, _lowest, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _highest);
DrawIndicator(area, _lowest);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal highValue, decimal lowValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_highest.IsFormed || !_lowest.IsFormed)
return;
var range = (highValue - lowValue) * ShiftPercent / 100m;
var close = candle.ClosePrice;
if (_trend != TrendDirections.Down && close <= lowValue + range)
{
if (Position > 0)
SellMarket();
if (Position >= 0)
{
SellMarket();
_trend = TrendDirections.Down;
}
}
else if (_trend != TrendDirections.Up && close >= highValue - range)
{
if (Position < 0)
BuyMarket();
if (Position <= 0)
{
BuyMarket();
_trend = TrendDirections.Up;
}
}
}
private enum TrendDirections
{
None,
Up,
Down
}
}
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, Unit, UnitTypes
from StockSharp.Algo.Indicators import Highest, Lowest
from StockSharp.Algo.Strategies import Strategy
class beginner_breakout_strategy(Strategy):
# TrendDirections: 0=None, 1=Up, 2=Down
def __init__(self):
super(beginner_breakout_strategy, self).__init__()
self._period = self.Param("Period", 9) \
.SetDisplay("Period", "Lookback period for highs/lows", "General")
self._shift_percent = self.Param("ShiftPercent", 30.0) \
.SetDisplay("Shift %", "Percentage shift from channel", "General")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe for strategy", "General")
self._stop_loss = self.Param("StopLoss", 2.0) \
.SetDisplay("Stop Loss", "Stop loss in percent", "Risk")
self._take_profit = self.Param("TakeProfit", 4.0) \
.SetDisplay("Take Profit", "Take profit in percent", "Risk")
self._trend = 0 # 0=None, 1=Up, 2=Down
@property
def period(self):
return self._period.Value
@property
def shift_percent(self):
return self._shift_percent.Value
@property
def candle_type(self):
return self._candle_type.Value
@property
def stop_loss(self):
return self._stop_loss.Value
@property
def take_profit(self):
return self._take_profit.Value
def OnReseted(self):
super(beginner_breakout_strategy, self).OnReseted()
self._trend = 0
def OnStarted2(self, time):
super(beginner_breakout_strategy, self).OnStarted2(time)
highest = Highest()
highest.Length = self.period
lowest = Lowest()
lowest.Length = self.period
self.StartProtection(
takeProfit=Unit(float(self.take_profit), UnitTypes.Percent),
stopLoss=Unit(float(self.stop_loss), UnitTypes.Percent))
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(highest, lowest, self.process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, highest)
self.DrawIndicator(area, lowest)
self.DrawOwnTrades(area)
def process_candle(self, candle, high_value, low_value):
if candle.State != CandleStates.Finished:
return
high_value = float(high_value)
low_value = float(low_value)
shift = float(self.shift_percent)
rng = (high_value - low_value) * shift / 100.0
close = float(candle.ClosePrice)
if self._trend != 2 and close <= low_value + rng:
if self.Position > 0:
self.SellMarket()
if self.Position >= 0:
self.SellMarket()
self._trend = 2
elif self._trend != 1 and close >= high_value - rng:
if self.Position < 0:
self.BuyMarket()
if self.Position <= 0:
self.BuyMarket()
self._trend = 1
def CreateClone(self):
return beginner_breakout_strategy()