Estrategia Expert AutoLot 20/200
Esta estrategia abre como máximo una posición por día en una hora definida por el usuario. Compara el precio de apertura de dos barras pasadas (T1 y T2). Si la barra anterior es más alta que la posterior en DeltaShort pips, abre una posición corta. Si la barra posterior es más alta en DeltaLong pips, abre una posición larga.
El volumen de la posición puede ser fijo o calcularse automáticamente a partir del balance de la cuenta. Cuando el balance disminuye respecto a la operación anterior, el lote se multiplica por BigLotSize.
Cada operación usa su propio take-profit y stop-loss en pips. Además, un tiempo máximo de retención (MaxOpenTime) cierra la operación después del número de horas especificado.
Parámetros
CandleType– marco temporal de las velas procesadas (por defecto 1 hora).TradeHour– hora del día en que se verifican las condiciones de entrada.T1,T2– desplazamientos de barras para comparar precios de apertura.DeltaLong,DeltaShort– diferencia mínima de precio de apertura en pips.TakeProfitLong,StopLossLong– protección para operaciones largas en pips.TakeProfitShort,StopLossShort– protección para operaciones cortas en pips.Lot– volumen de trading base.AutoLot– activar el cálculo automático de lote.BigLotSize– multiplicador aplicado tras una pérdida.MaxOpenTime– tiempo máximo en horas para mantener una posición.
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()