Estrategia de 10 Pips
Esta estrategia de cobertura abre posiciones largas y cortas al mismo tiempo. Cada posición utiliza niveles fijos de take-profit y stop-loss medidos en unidades de precio y puede protegerse con un trailing stop. Cuando un lado se cierra, la estrategia abre inmediatamente una nueva posición en la misma dirección para mantener ambos lados activos.
Parámetros
TakeProfitBuy– distancia de take-profit para posiciones largas.StopLossBuy– distancia de stop-loss para posiciones largas.TrailingStopBuy– distancia de trailing stop para posiciones largas.TakeProfitSell– distancia de take-profit para posiciones cortas.StopLossSell– distancia de stop-loss para posiciones cortas.TrailingStopSell– distancia de trailing stop para posiciones cortas.Volume– tamaño de la orden usado para todas las operaciones.
Notas
- Las posiciones se abren con órdenes de mercado.
- Las órdenes de protección se registran para cada lado por separado.
- Los trailing stops se actualizan cuando el mercado se mueve en una dirección favorable.
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>
/// Simple breakout strategy that enters on momentum moves
/// with fixed take profit and stop loss protection.
/// </summary>
public class TenPipsStrategy : Strategy
{
private readonly StrategyParam<decimal> _takeProfit;
private readonly StrategyParam<decimal> _stopLoss;
private readonly StrategyParam<int> _lookback;
private readonly StrategyParam<DataType> _candleType;
private decimal _entryPrice;
private decimal _previousRoc;
private bool _hasPreviousRoc;
/// <summary>Take profit distance.</summary>
public decimal TakeProfit { get => _takeProfit.Value; set => _takeProfit.Value = value; }
/// <summary>Stop loss distance.</summary>
public decimal StopLoss { get => _stopLoss.Value; set => _stopLoss.Value = value; }
/// <summary>Lookback period for momentum.</summary>
public int Lookback { get => _lookback.Value; set => _lookback.Value = value; }
/// <summary>Candle type.</summary>
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
/// <summary>
/// Initializes a new instance of the strategy.
/// </summary>
public TenPipsStrategy()
{
_takeProfit = Param(nameof(TakeProfit), 500m)
.SetDisplay("Take Profit", "Take profit distance", "Risk")
.SetGreaterThanZero();
_stopLoss = Param(nameof(StopLoss), 300m)
.SetDisplay("Stop Loss", "Stop loss distance", "Risk")
.SetGreaterThanZero();
_lookback = Param(nameof(Lookback), 30)
.SetDisplay("Lookback", "Momentum lookback period", "Indicators")
.SetGreaterThanZero();
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
/// <inheritdoc />
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
/// <inheritdoc />
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_entryPrice = 0m;
_previousRoc = 0m;
_hasPreviousRoc = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_entryPrice = 0;
_previousRoc = 0m;
_hasPreviousRoc = false;
var roc = new RateOfChange { Length = Lookback };
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(roc, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, roc);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal rocValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!IsFormedAndOnlineAndAllowTrading())
return;
var close = candle.ClosePrice;
var buySignal = _hasPreviousRoc && _previousRoc <= 4m && rocValue > 4m;
var sellSignal = _hasPreviousRoc && _previousRoc >= -4m && rocValue < -4m;
if (Position == 0)
{
if (buySignal)
{
BuyMarket();
_entryPrice = close;
}
else if (sellSignal)
{
SellMarket();
_entryPrice = close;
}
}
else if (Position > 0)
{
if (close >= _entryPrice + TakeProfit || close <= _entryPrice - StopLoss)
{
SellMarket(Math.Abs(Position));
}
}
else if (Position < 0)
{
if (close <= _entryPrice - TakeProfit || close >= _entryPrice + StopLoss)
{
BuyMarket(Math.Abs(Position));
}
}
_previousRoc = rocValue;
_hasPreviousRoc = true;
}
}
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 RateOfChange
from StockSharp.Algo.Strategies import Strategy
class ten_pips_strategy(Strategy):
def __init__(self):
super(ten_pips_strategy, self).__init__()
self._take_profit = self.Param("TakeProfit", 500.0)
self._stop_loss = self.Param("StopLoss", 300.0)
self._lookback = self.Param("Lookback", 30)
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1)))
self._entry_price = 0.0
self._previous_roc = 0.0
self._has_previous_roc = False
@property
def TakeProfit(self):
return self._take_profit.Value
@TakeProfit.setter
def TakeProfit(self, value):
self._take_profit.Value = value
@property
def StopLoss(self):
return self._stop_loss.Value
@StopLoss.setter
def StopLoss(self, value):
self._stop_loss.Value = value
@property
def Lookback(self):
return self._lookback.Value
@Lookback.setter
def Lookback(self, value):
self._lookback.Value = value
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
def OnStarted2(self, time):
super(ten_pips_strategy, self).OnStarted2(time)
self._entry_price = 0.0
self._previous_roc = 0.0
self._has_previous_roc = False
roc = RateOfChange()
roc.Length = self.Lookback
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(roc, self.ProcessCandle).Start()
self.StartProtection(
Unit(2000.0, UnitTypes.Absolute),
Unit(1000.0, UnitTypes.Absolute))
def ProcessCandle(self, candle, roc_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
roc_val = float(roc_value)
buy_signal = self._has_previous_roc and self._previous_roc <= 4.0 and roc_val > 4.0
sell_signal = self._has_previous_roc and self._previous_roc >= -4.0 and roc_val < -4.0
tp = float(self.TakeProfit)
sl = float(self.StopLoss)
if self.Position == 0:
if buy_signal:
self.BuyMarket()
self._entry_price = close
elif sell_signal:
self.SellMarket()
self._entry_price = close
elif self.Position > 0:
if close >= self._entry_price + tp or close <= self._entry_price - sl:
self.SellMarket()
elif self.Position < 0:
if close <= self._entry_price - tp or close >= self._entry_price + sl:
self.BuyMarket()
self._previous_roc = roc_val
self._has_previous_roc = True
def OnReseted(self):
super(ten_pips_strategy, self).OnReseted()
self._entry_price = 0.0
self._previous_roc = 0.0
self._has_previous_roc = False
def CreateClone(self):
return ten_pips_strategy()