Estratégia Simples XAUUSD com 20 de Lucro e 100 de Perda
Esta estratégia abre uma posição comprada quando não há posição aberta e ambos os temporizadores de resfriamento estão inativos. Fecha a posição quando o lucro não realizado atinge $20 ou a perda chega a $100. Após uma saída lucrativa, a estratégia aguarda 15 minutos antes de reentrar, e após uma saída com perda aguarda 12 horas.
Parâmetros
ProfitTarget– meta de lucro em USD.LossLimit– perda máxima em USD.TradeCooldown– tempo de espera após uma perda.EntryCooldown– tempo de espera após um lucro.CandleType– período de tempo das velas.
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 XAUUSD strategy with fixed profit and loss targets.
/// Buys and holds until hitting percent-based TP or SL, then waits cooldown.
/// </summary>
public class XauusdSimple20Profit100LossStrategy : Strategy
{
private readonly StrategyParam<decimal> _tpPct;
private readonly StrategyParam<decimal> _slPct;
private readonly StrategyParam<int> _cooldownBars;
private readonly StrategyParam<DataType> _candleType;
private int _barsSinceExit;
private decimal _entryPrice;
public decimal TpPct { get => _tpPct.Value; set => _tpPct.Value = value; }
public decimal SlPct { get => _slPct.Value; set => _slPct.Value = value; }
public int CooldownBars { get => _cooldownBars.Value; set => _cooldownBars.Value = value; }
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public XauusdSimple20Profit100LossStrategy()
{
_tpPct = Param(nameof(TpPct), 0.3m)
.SetGreaterThanZero()
.SetDisplay("TP %", "Take profit percent", "Risk");
_slPct = Param(nameof(SlPct), 1.5m)
.SetGreaterThanZero()
.SetDisplay("SL %", "Stop loss percent", "Risk");
_cooldownBars = Param(nameof(CooldownBars), 100)
.SetGreaterThanZero()
.SetDisplay("Cooldown", "Bars between trades", "Risk");
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(1).TimeFrame())
.SetDisplay("Candle Type", "Type of candles", "General");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities()
{
return [(Security, CandleType)];
}
protected override void OnReseted()
{
base.OnReseted();
_barsSinceExit = 100;
_entryPrice = 0;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
var sma = new SimpleMovingAverage { Length = 10 };
_barsSinceExit = 100;
_entryPrice = 0;
var subscription = SubscribeCandles(CandleType);
subscription.Bind(sma, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal _dummy)
{
if (candle.State != CandleStates.Finished)
return;
_barsSinceExit++;
if (Position == 0 && _barsSinceExit >= CooldownBars)
{
BuyMarket();
_entryPrice = candle.ClosePrice;
return;
}
if (Position > 0 && _entryPrice > 0)
{
var tp = _entryPrice * (1 + TpPct / 100m);
var sl = _entryPrice * (1 - SlPct / 100m);
if (candle.ClosePrice >= tp || candle.ClosePrice <= sl)
{
SellMarket();
_barsSinceExit = 0;
_entryPrice = 0;
}
}
}
}
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.Indicators import SimpleMovingAverage
from StockSharp.Algo.Strategies import Strategy
class xauusd_simple20_profit100_loss_strategy(Strategy):
def __init__(self):
super(xauusd_simple20_profit100_loss_strategy, self).__init__()
self._tp_pct = self.Param("TpPct", 0.3) \
.SetDisplay("TP %", "Take profit percent", "Risk")
self._sl_pct = self.Param("SlPct", 1.5) \
.SetDisplay("SL %", "Stop loss percent", "Risk")
self._cooldown_bars = self.Param("CooldownBars", 100) \
.SetDisplay("Cooldown", "Bars between trades", "Risk")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(1))) \
.SetDisplay("Candle Type", "Type of candles", "General")
self._bars_since_exit = 0
self._entry_price = 0.0
@property
def tp_pct(self):
return self._tp_pct.Value
@property
def sl_pct(self):
return self._sl_pct.Value
@property
def cooldown_bars(self):
return self._cooldown_bars.Value
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(xauusd_simple20_profit100_loss_strategy, self).OnReseted()
self._bars_since_exit = 0
self._entry_price = 0.0
def OnStarted2(self, time):
super(xauusd_simple20_profit100_loss_strategy, self).OnStarted2(time)
sma = SimpleMovingAverage()
sma.Length = 10
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, self.on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def on_process(self, candle, _dummy):
if candle.State != CandleStates.Finished:
return
self._bars_since_exit += 1
if self.Position == 0 and self._bars_since_exit >= self.cooldown_bars:
self.BuyMarket()
self._entry_price = candle.ClosePrice
return
if self.Position > 0 and self._entry_price > 0:
tp = self._entry_price * (1 + self.tp_pct / 100)
sl = self._entry_price * (1 - self.sl_pct / 100)
if candle.ClosePrice >= tp or candle.ClosePrice <= sl:
self.SellMarket()
self._bars_since_exit = 0
self._entry_price = 0
def CreateClone(self):
return xauusd_simple20_profit100_loss_strategy()