Estratégia Expert AutoLot 20/200
Esta estratégia abre no máximo uma posição por dia em uma hora definida pelo usuário. Ela compara o preço de abertura de duas barras passadas (T1 e T2). Se a barra anterior for mais alta que a posterior em DeltaShort pips, abre uma posição vendida. Se a barra posterior for mais alta em DeltaLong pips, abre uma posição comprada.
O volume da posição pode ser fixo ou calculado automaticamente a partir do saldo da conta. Quando o saldo diminui em relação à operação anterior, o lote é multiplicado por BigLotSize.
Cada operação usa seu próprio take-profit e stop-loss em pips. Além disso, um tempo máximo de retenção (MaxOpenTime) fecha a operação após o número de horas especificado.
Parâmetros
CandleType– período das velas processadas (padrão: 1 hora).TradeHour– hora do dia em que as condições de entrada são verificadas.T1,T2– deslocamentos de barras para comparar preços de abertura.DeltaLong,DeltaShort– diferença mínima de preço de abertura em pips.TakeProfitLong,StopLossLong– proteção para operações compradas em pips.TakeProfitShort,StopLossShort– proteção para operações vendidas em pips.Lot– volume de trading base.AutoLot– ativar o cálculo automático de lote.BigLotSize– multiplicador aplicado após perda.MaxOpenTime– tempo máximo em horas para manter uma posição.
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>
/// "20/200 expert v4.2 AntS" strategy.
/// Opens trades based on the difference between two past open prices.
/// Closes positions by stop-loss, take-profit or time.
/// </summary>
public class Twenty200ExpertAutoLotStrategy : Strategy
{
private readonly StrategyParam<int> _takeProfitLong;
private readonly StrategyParam<int> _stopLossLong;
private readonly StrategyParam<int> _takeProfitShort;
private readonly StrategyParam<int> _stopLossShort;
private readonly StrategyParam<int> _t1;
private readonly StrategyParam<int> _t2;
private readonly StrategyParam<int> _deltaLong;
private readonly StrategyParam<int> _deltaShort;
private readonly StrategyParam<DataType> _candleType;
private readonly List<decimal> _opens = new();
private decimal _stopPrice;
private decimal _takePrice;
private DateTimeOffset _entryTime;
private bool _isLong;
public int TakeProfitLong { get => _takeProfitLong.Value; set => _takeProfitLong.Value = value; }
public int StopLossLong { get => _stopLossLong.Value; set => _stopLossLong.Value = value; }
public int TakeProfitShort { get => _takeProfitShort.Value; set => _takeProfitShort.Value = value; }
public int StopLossShort { get => _stopLossShort.Value; set => _stopLossShort.Value = value; }
public int T1 { get => _t1.Value; set => _t1.Value = value; }
public int T2 { get => _t2.Value; set => _t2.Value = value; }
public int DeltaLong { get => _deltaLong.Value; set => _deltaLong.Value = value; }
public int DeltaShort { get => _deltaShort.Value; set => _deltaShort.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public Twenty200ExpertAutoLotStrategy()
{
_takeProfitLong = Param(nameof(TakeProfitLong), 39)
.SetDisplay("TP Long (pips)", "Take profit for long", "Risk");
_stopLossLong = Param(nameof(StopLossLong), 147)
.SetDisplay("SL Long (pips)", "Stop loss for long", "Risk");
_takeProfitShort = Param(nameof(TakeProfitShort), 32)
.SetDisplay("TP Short (pips)", "Take profit for short", "Risk");
_stopLossShort = Param(nameof(StopLossShort), 267)
.SetDisplay("SL Short (pips)", "Stop loss for short", "Risk");
_t1 = Param(nameof(T1), 6)
.SetDisplay("T1", "First bar shift", "Logic");
_t2 = Param(nameof(T2), 2)
.SetDisplay("T2", "Second bar shift", "Logic");
_deltaLong = Param(nameof(DeltaLong), 1)
.SetDisplay("Delta Long", "Min rise in pips", "Logic");
_deltaShort = Param(nameof(DeltaShort), 1)
.SetDisplay("Delta Short", "Min fall in pips", "Logic");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame())
.SetDisplay("Candle Type", "Time frame", "General");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_opens.Clear();
_stopPrice = 0m;
_takePrice = 0m;
_entryTime = default;
_isLong = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_opens.Clear();
_stopPrice = 0m;
_takePrice = 0m;
_entryTime = default;
_isLong = false;
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle)
{
if (candle.State != CandleStates.Finished)
return;
_opens.Add(candle.OpenPrice);
var maxShift = Math.Max(T1, T2);
if (_opens.Count <= maxShift)
return;
var pip = Security?.PriceStep ?? 1m;
var openT1 = _opens[_opens.Count - 1 - T1];
var openT2 = _opens[_opens.Count - 1 - T2];
// Position management: check SL/TP
if (Position != 0)
{
if (_isLong)
{
if (candle.LowPrice <= _stopPrice || candle.HighPrice >= _takePrice)
{
SellMarket();
return;
}
}
else
{
if (candle.HighPrice >= _stopPrice || candle.LowPrice <= _takePrice)
{
BuyMarket();
return;
}
}
return;
}
// Entry logic
var diffShort = openT1 - openT2;
var diffLong = openT2 - openT1;
if (diffShort > DeltaShort * pip && Position >= 0)
{
SellMarket();
_isLong = false;
_entryTime = candle.OpenTime;
_stopPrice = candle.OpenPrice + StopLossShort * pip;
_takePrice = candle.OpenPrice - TakeProfitShort * pip;
}
else if (diffLong > DeltaLong * pip && Position <= 0)
{
BuyMarket();
_isLong = true;
_entryTime = candle.OpenTime;
_stopPrice = candle.OpenPrice - StopLossLong * pip;
_takePrice = candle.OpenPrice + TakeProfitLong * pip;
}
}
}
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.Strategies import Strategy
class twenty_200_expert_auto_lot_strategy(Strategy):
"""Open price difference between two bar offsets with SL/TP management."""
def __init__(self):
super(twenty_200_expert_auto_lot_strategy, self).__init__()
self._tp_long = self.Param("TakeProfitLong", 39).SetDisplay("TP Long", "TP for long", "Risk")
self._sl_long = self.Param("StopLossLong", 147).SetDisplay("SL Long", "SL for long", "Risk")
self._tp_short = self.Param("TakeProfitShort", 32).SetDisplay("TP Short", "TP for short", "Risk")
self._sl_short = self.Param("StopLossShort", 267).SetDisplay("SL Short", "SL for short", "Risk")
self._t1 = self.Param("T1", 6).SetDisplay("T1", "First bar shift", "Logic")
self._t2 = self.Param("T2", 2).SetDisplay("T2", "Second bar shift", "Logic")
self._delta_long = self.Param("DeltaLong", 1).SetDisplay("Delta Long", "Min rise", "Logic")
self._delta_short = self.Param("DeltaShort", 1).SetDisplay("Delta Short", "Min fall", "Logic")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))).SetDisplay("Candle Type", "Timeframe", "General")
@property
def CandleType(self): return self._candle_type.Value
@CandleType.setter
def CandleType(self, value): self._candle_type.Value = value
def OnReseted(self):
super(twenty_200_expert_auto_lot_strategy, self).OnReseted()
self._opens = []
self._stop_price = 0
self._take_price = 0
self._is_long = False
def OnStarted2(self, time):
super(twenty_200_expert_auto_lot_strategy, self).OnStarted2(time)
self._opens = []
self._stop_price = 0
self._take_price = 0
self._is_long = False
sub = self.SubscribeCandles(self.CandleType)
sub.Bind(self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, sub)
self.DrawOwnTrades(area)
def OnProcess(self, candle):
if candle.State != CandleStates.Finished:
return
self._opens.append(float(candle.OpenPrice))
close = float(candle.ClosePrice)
high = float(candle.HighPrice)
low = float(candle.LowPrice)
pip = 1.0
max_shift = max(self._t1.Value, self._t2.Value)
if len(self._opens) <= max_shift:
return
# SL/TP check
if self.Position != 0:
if self._is_long:
if low <= self._stop_price or high >= self._take_price:
self.SellMarket()
self._stop_price = 0
self._take_price = 0
return
else:
if high >= self._stop_price or low <= self._take_price:
self.BuyMarket()
self._stop_price = 0
self._take_price = 0
return
return
open_t1 = self._opens[len(self._opens) - 1 - self._t1.Value]
open_t2 = self._opens[len(self._opens) - 1 - self._t2.Value]
diff_short = open_t1 - open_t2
diff_long = open_t2 - open_t1
if diff_short > self._delta_short.Value * pip and self.Position >= 0:
self.SellMarket()
self._is_long = False
self._stop_price = float(candle.OpenPrice) + self._sl_short.Value * pip
self._take_price = float(candle.OpenPrice) - self._tp_short.Value * pip
elif diff_long > self._delta_long.Value * pip and self.Position <= 0:
self.BuyMarket()
self._is_long = True
self._stop_price = float(candle.OpenPrice) - self._sl_long.Value * pip
self._take_price = float(candle.OpenPrice) + self._tp_long.Value * pip
def CreateClone(self):
return twenty_200_expert_auto_lot_strategy()