Estratégia de Compra Personalizada BID
A estratégia Custom Buy BID usa o indicador Supertrend para identificar reversões altistas. Abre uma posição comprada quando o preço cruza acima da linha Supertrend e aplica alvos de lucro e perda configuráveis para gestão de risco.
Detalhes
- Critérios de entrada: O preço cruza acima do Supertrend.
- Comprado/Vendido: Somente comprado.
- Critérios de saída: Take Profit ou Stop Loss.
- Stops: Sim.
- Valores padrão:
SupertrendPeriod= 10SupertrendMultiplier= 3mTakeProfitPercent= 5mStopLossPercent= 2mCandleType= TimeSpan.FromMinutes(5)StartDate= 2018-09-01EndDate= 9999-01-01
- Filtros:
- Categoria: Seguidor de tendência
- Direção: Somente comprado
- Indicadores: Supertrend
- Stops: Sim
- Complexidade: Básico
- Período: Curto prazo
- 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>
/// Custom Buy BID strategy.
/// Goes long when the close crosses above the Supertrend line inside the StartDate..EndDate window.
/// The position is closed only by the percent take profit or stop loss.
/// </summary>
public class CustomBuyBidStrategy : Strategy
{
private readonly StrategyParam<int> _supertrendPeriod;
private readonly StrategyParam<decimal> _supertrendMultiplier;
private readonly StrategyParam<decimal> _takeProfitPercent;
private readonly StrategyParam<decimal> _stopLossPercent;
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<DateTimeOffset> _startDate;
private readonly StrategyParam<DateTimeOffset> _endDate;
private decimal? _prevClose;
private decimal? _prevSupertrend;
/// <summary>
/// ATR period of Supertrend.
/// </summary>
public int SupertrendPeriod
{
get => _supertrendPeriod.Value;
set => _supertrendPeriod.Value = value;
}
/// <summary>
/// ATR multiplier of Supertrend.
/// </summary>
public decimal SupertrendMultiplier
{
get => _supertrendMultiplier.Value;
set => _supertrendMultiplier.Value = value;
}
/// <summary>
/// Take profit percentage from entry price.
/// </summary>
public decimal TakeProfitPercent
{
get => _takeProfitPercent.Value;
set => _takeProfitPercent.Value = value;
}
/// <summary>
/// Stop loss percentage from entry price.
/// </summary>
public decimal StopLossPercent
{
get => _stopLossPercent.Value;
set => _stopLossPercent.Value = value;
}
/// <summary>
/// Candle type.
/// </summary>
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
/// <summary>
/// First date when entries are allowed.
/// </summary>
public DateTimeOffset StartDate
{
get => _startDate.Value;
set => _startDate.Value = value;
}
/// <summary>
/// Date after which no entries are made.
/// </summary>
public DateTimeOffset EndDate
{
get => _endDate.Value;
set => _endDate.Value = value;
}
/// <summary>
/// Constructor.
/// </summary>
public CustomBuyBidStrategy()
{
_supertrendPeriod = Param(nameof(SupertrendPeriod), 10)
.SetGreaterThanZero()
.SetDisplay("Supertrend Period", "ATR period of Supertrend", "Indicators");
_supertrendMultiplier = Param(nameof(SupertrendMultiplier), 3m)
.SetGreaterThanZero()
.SetDisplay("Supertrend Multiplier", "ATR multiplier of Supertrend", "Indicators");
_takeProfitPercent = Param(nameof(TakeProfitPercent), 5m)
.SetNotNegative()
.SetDisplay("Take Profit %", "Take profit percentage from entry price", "Risk");
_stopLossPercent = Param(nameof(StopLossPercent), 2m)
.SetNotNegative()
.SetDisplay("Stop Loss %", "Stop loss percentage from entry price", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Type of candles to use", "General");
_startDate = Param(nameof(StartDate), new DateTimeOffset(2018, 9, 1, 0, 0, 0, TimeSpan.Zero))
.SetDisplay("Start Date", "First date when entries are allowed", "General");
_endDate = Param(nameof(EndDate), new DateTimeOffset(9999, 1, 1, 0, 0, 0, TimeSpan.Zero))
.SetDisplay("End Date", "Date after which no entries are made", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevClose = null;
_prevSupertrend = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevClose = null;
_prevSupertrend = null;
var supertrend = new SuperTrend { Length = SupertrendPeriod, Multiplier = SupertrendMultiplier };
var subscription = SubscribeCandles(CandleType);
subscription
.BindEx(supertrend, ProcessCandle)
.Start();
StartProtection(
new Unit(TakeProfitPercent, UnitTypes.Percent),
new Unit(StopLossPercent, UnitTypes.Percent),
useMarketOrders: true);
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, supertrend);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, IIndicatorValue supertrendValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!supertrendValue.IsFormed)
return;
var line = supertrendValue.GetValue<decimal>();
var close = candle.ClosePrice;
var crossedUp = _prevClose is decimal prevClose && _prevSupertrend is decimal prevLine
&& prevClose <= prevLine && close > line;
_prevClose = close;
_prevSupertrend = line;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var time = candle.OpenTime;
var inWindow = time >= StartDate.UtcDateTime && time <= EndDate.UtcDateTime;
if (crossedUp && inWindow && Position == 0)
BuyMarket();
}
}
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, DateTimeOffset
from StockSharp.Messages import DataType, CandleStates, Unit, UnitTypes
from StockSharp.Algo.Indicators import SuperTrend
from StockSharp.Algo.Strategies import Strategy
class custom_buy_bid_strategy(Strategy):
"""
Custom Buy BID strategy.
Goes long when the close crosses above the Supertrend line inside the StartDate..EndDate window.
The position is closed only by the percent take profit or stop loss.
"""
def __init__(self):
super(custom_buy_bid_strategy, self).__init__()
self._supertrend_period = self.Param("SupertrendPeriod", 10) \
.SetGreaterThanZero() \
.SetDisplay("Supertrend Period", "ATR period of Supertrend", "Indicators")
self._supertrend_multiplier = self.Param("SupertrendMultiplier", 3.0) \
.SetGreaterThanZero() \
.SetDisplay("Supertrend Multiplier", "ATR multiplier of Supertrend", "Indicators")
self._take_profit_percent = self.Param("TakeProfitPercent", 5.0) \
.SetNotNegative() \
.SetDisplay("Take Profit %", "Take profit percentage from entry price", "Risk")
self._stop_loss_percent = self.Param("StopLossPercent", 2.0) \
.SetNotNegative() \
.SetDisplay("Stop Loss %", "Stop loss percentage from entry price", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Type of candles to use", "General")
self._start_date = self.Param("StartDate", DateTimeOffset(2018, 9, 1, 0, 0, 0, TimeSpan.Zero)) \
.SetDisplay("Start Date", "First date when entries are allowed", "General")
self._end_date = self.Param("EndDate", DateTimeOffset(9999, 1, 1, 0, 0, 0, TimeSpan.Zero)) \
.SetDisplay("End Date", "Date after which no entries are made", "General")
self._reset_state()
@property
def candle_type(self):
return self._candle_type.Value
def GetWorkingSecurities(self):
return [(self.Security, self.candle_type)]
def _reset_state(self):
self._prev_close = None
self._prev_supertrend = None
def OnReseted(self):
super(custom_buy_bid_strategy, self).OnReseted()
self._reset_state()
def OnStarted2(self, time):
super(custom_buy_bid_strategy, self).OnStarted2(time)
self._reset_state()
supertrend = SuperTrend()
supertrend.Length = self._supertrend_period.Value
supertrend.Multiplier = Decimal(self._supertrend_multiplier.Value)
subscription = self.SubscribeCandles(self.candle_type)
subscription.BindEx(supertrend, self._process_candle).Start()
self.StartProtection(
Unit(Decimal(self._take_profit_percent.Value), UnitTypes.Percent),
Unit(Decimal(self._stop_loss_percent.Value), UnitTypes.Percent),
useMarketOrders=True)
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, supertrend)
self.DrawOwnTrades(area)
def _process_candle(self, candle, supertrend_value):
if candle.State != CandleStates.Finished:
return
if not supertrend_value.IsFormed:
return
line = supertrend_value.GetValue[Decimal](None)
close = candle.ClosePrice
crossed_up = (self._prev_close is not None and self._prev_supertrend is not None
and self._prev_close <= self._prev_supertrend and close > line)
self._prev_close = close
self._prev_supertrend = line
if not self.IsFormedAndOnlineAndAllowTrading():
return
open_time = candle.OpenTime
in_window = open_time >= self._start_date.Value.UtcDateTime and open_time <= self._end_date.Value.UtcDateTime
if crossed_up and in_window and self.Position == 0:
self.BuyMarket()
def CreateClone(self):
return custom_buy_bid_strategy()