TugbaGold é um consultor especialista em média baseado em grade que se origina de MetaTrader 5. A estratégia convertida recria seu dimensionamento de posição martingale e lógica de gerenciamento de cesta usando o StockSharp de alto nível de API. O sistema coloca novas ordens sempre que a vela anterior fecha com impulso direcional e constrói progressivamente uma grade de posições espaçadas por uma distância configurável. As saídas de média são executadas bloqueando os lucros nas posições extremas ou fechando parcialmente a cesta, dependendo do modo selecionado.
Como funciona
A estratégia avalia velas concluídas a partir do parâmetro CandleType. Os sinais usam a vela anterior, correspondendo à lógica MT5 original.
Uma vela de alta permite a colocação de uma nova ordem de compra. Uma vela de baixa permite uma nova ordem de venda.
Os pedidos serão adicionados somente se a distância do melhor preço existente naquela direção exceder PointOrderStepPips.
O primeiro pedido usa StartVolume. As entradas subsequentes duplicam o volume da posição mais favorável, respeitando MaxVolume e os limites da corretora.
Uma vez que existam pelo menos duas posições, a estratégia calcula preços-alvo que incluem o buffer MinimalProfitPips. O cálculo difere de acordo com o modo de saída:
Média – média ponderada das posições extremas mais o buffer de lucro.
Parcial – combinação dos piores e melhores tickets onde o pior ticket usa StartVolume e o melhor usa seu tamanho real.
Quando as metas são atingidas, a estratégia fecha as ordens correspondentes:
Modo médio – fecha totalmente ambas as entradas extremas.
Modo parcial – fecha completamente a pior entrada e reduz a melhor entrada em StartVolume.
Posições autônomas únicas usam TakeProfitPips para sair quando o preço atinge a distância configurada.
Parâmetros
Parâmetro
Descrição
TakeProfitPips
Distância de take-profit aplicada quando apenas uma posição está aberta. Defina como 0 para desativar.
StartVolume
Volume inicial para a primeira ordem em uma sequência de grade.
MaxVolume
Volume máximo de pedidos. 0 mantém a sequência de duplicação ilimitada.
CloseMode
Modo de saída: Average (fechar ambos os extremos) ou Partial (fechar parcial + total).
PointOrderStepPips
Distância mínima em pips antes que uma nova ordem média possa ser adicionada.
MinimalProfitPips
Buffer de lucro adicional adicionado às metas médias.
CandleType
Série de velas usada para avaliação de sinal.
Gestão de posição
As etapas de preço são derivadas de Security.PriceStep. Se não estiver disponível, um padrão de 0.0001 será usado.
Os volumes são automaticamente normalizados para as restrições mínimas, máximas e de etapas do corretor.
A estratégia rastreia as posições preenchidas internamente e emite ordens de mercado (BuyMarket / SellMarket) ao fechar partes da cesta.
A proteção é ativada automaticamente por meio de StartProtection() assim que a estratégia é iniciada.
Notas e limitações
A implementação pressupõe atendimento imediato para ordens de mercado, semelhante ao ambiente MT5.
Os sinais de média dependem das melhores cotações de compra/venda atuais; garantir que os dados do Nível 1 estejam disponíveis para uma execução precisa.
Como as saídas são impulsionadas pela lógica estratégica, os níveis de stop loss do especialista original não são recriados.
Utilize uma gestão de risco cautelosa: o dimensionamento do martingale pode levar a uma grande exposição se as tendências persistirem.
Detalhes da conversão
As fórmulas de média e os ajustes da cesta refletem o código-fonte original.
A seleção de posição (melhores/piores tickets) é reproduzida rastreando os preços de abertura mais altos e mais baixos em cada direção.
Toda a lógica é executada dentro da assinatura da vela usando o API de alto nível de StockSharp sem recorrer ao acesso a dados de baixo nível.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// TugbaGold strategy: candle direction + EMA trend filter with martingale-style averaging.
/// Buys on bullish candle above EMA, sells on bearish candle below EMA.
/// </summary>
public class TugbaGoldStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _emaPeriod;
private bool _wasBullishSignal;
private bool _hasPrevSignal;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int EmaPeriod { get => _emaPeriod.Value; set => _emaPeriod.Value = value; }
public TugbaGoldStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(60).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_emaPeriod = Param(nameof(EmaPeriod), 50)
.SetGreaterThanZero()
.SetDisplay("EMA Period", "EMA trend filter period", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_wasBullishSignal = false;
_hasPrevSignal = false;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_wasBullishSignal = false;
_hasPrevSignal = false;
var ema = new ExponentialMovingAverage { Length = EmaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(ema, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal emaValue)
{
if (candle.State != CandleStates.Finished) return;
var bullish = candle.ClosePrice > candle.OpenPrice;
var bearish = candle.ClosePrice < candle.OpenPrice;
var bullishSignal = bullish && candle.ClosePrice > emaValue;
var bearishSignal = bearish && candle.ClosePrice < emaValue;
var crossedUp = bullishSignal && (!_hasPrevSignal || !_wasBullishSignal);
var crossedDown = bearishSignal && (!_hasPrevSignal || _wasBullishSignal);
if (crossedUp && Position <= 0)
BuyMarket();
else if (crossedDown && Position >= 0)
SellMarket();
if (bullishSignal || bearishSignal)
{
_wasBullishSignal = bullishSignal;
_hasPrevSignal = 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
from StockSharp.Algo.Indicators import ExponentialMovingAverage
from StockSharp.Algo.Strategies import Strategy
class tugba_gold_strategy(Strategy):
def __init__(self):
super(tugba_gold_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(60)))
self._ema_period = self.Param("EmaPeriod", 50)
self._was_bullish_signal = False
self._has_prev_signal = False
@property
def CandleType(self):
return self._candle_type.Value
@CandleType.setter
def CandleType(self, value):
self._candle_type.Value = value
@property
def EmaPeriod(self):
return self._ema_period.Value
@EmaPeriod.setter
def EmaPeriod(self, value):
self._ema_period.Value = value
def OnReseted(self):
super(tugba_gold_strategy, self).OnReseted()
self._was_bullish_signal = False
self._has_prev_signal = False
def OnStarted2(self, time):
super(tugba_gold_strategy, self).OnStarted2(time)
self._was_bullish_signal = False
self._has_prev_signal = False
ema = ExponentialMovingAverage()
ema.Length = self.EmaPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(ema, self._process_candle).Start()
def _process_candle(self, candle, ema_value):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
open_price = float(candle.OpenPrice)
ema_val = float(ema_value)
bullish = close > open_price
bearish = close < open_price
bullish_signal = bullish and close > ema_val
bearish_signal = bearish and close < ema_val
crossed_up = bullish_signal and (not self._has_prev_signal or not self._was_bullish_signal)
crossed_down = bearish_signal and (not self._has_prev_signal or self._was_bullish_signal)
if crossed_up and self.Position <= 0:
self.BuyMarket()
elif crossed_down and self.Position >= 0:
self.SellMarket()
if bullish_signal or bearish_signal:
self._was_bullish_signal = bullish_signal
self._has_prev_signal = True
def CreateClone(self):
return tugba_gold_strategy()