A Estratégia básica de modelo de MA é uma versão StockSharp fiel do MetaTrader 4 consultor especialista da entrada do repositório MQL/27964. O robô original negociou um único símbolo em uma média móvel de período de tempo superior e abriu uma posição sempre que a vela anterior cruzou a média. Esta versão C# mantém a estrutura minimalista enquanto expõe cada controle como um parâmetro para que o comportamento possa ser ajustado ou otimizado diretamente dentro de StockSharp.
O modelo espera por uma vela totalmente concluída e compara seus preços de abertura e fechamento com uma média móvel alterada. Se a barra abrir acima da média e fechar abaixo dela, a estratégia abre uma posição curta. Quando acontece o inverso, abre-se uma negociação longa. O sistema permite apenas uma posição de mercado por vez, refletindo a verificação MQL "nenhum ticket ativo". As distâncias protetoras de stop-loss e take-profit são definidas em pips. No início, a estratégia converte essas distâncias de pip em compensações de preços absolutos usando a etapa do instrumento e a precisão decimal, replicando a lógica de conversão ponto a pip que dependia dos dígitos de cotação em MetaTrader.
Lógica de negociação
Fonte de dados: uma única série de velas determinada pelo parâmetro CandleType (padrão H4).
Indicador: média móvel configurável (SMA, EMA, SMMA ou LWMA). O parâmetro MovingAverageShift desloca o indicador para frente exatamente como a função MetaTrader iMA.
Regras de entrada:
Longo: a vela anterior abriu abaixo e fechou acima da média móvel deslocada enquanto nenhuma posição está aberta.
Curto: a vela anterior abriu acima e fechou abaixo da média móvel deslocada enquanto nenhuma posição está aberta.
Regras de saída: tratadas automaticamente pelo módulo StockSharp StartProtection usando distâncias de take-profit e stop-loss baseadas em pip. Quando ambos os alvos são zero, a estratégia ainda ativa o serviço de proteção, de modo que saídas manuais ou de rastreamento permanecem possíveis.
Filtro de posição: a estratégia ignora novos sinais enquanto uma posição está ativa, mantendo o comportamento idêntico à rotina PosSelect() original.
Parâmetros
Parâmetro
Descrição
Padrão
CandleType
Agregação de velas usada para sinais.
H4 (velas de 4 horas)
MovingAveragePeriod
Duração do período da média móvel.
49
MovingAverageShift
Deslocamento para frente aplicado ao buffer de média móvel.
0
MovingAverageMethod
Modo de cálculo de média móvel (Simple, Exponential, Smoothed, LinearWeighted).
Simple
TakeProfitPips
Distância de lucro em pips convertida em compensações de preço absoluto em tempo de execução.
38,5
StopLossPips
Distância de stop-loss em pips convertida em compensações de preço absoluto em tempo de execução.
48,5
Tratamento de riscos
O subsistema de proteção recebe as distâncias absolutas calculadas e as atribui a cada ordem de mercado. Como o tamanho do pip é derivado do passo do símbolo e da precisão decimal (aspas de 5 e 3 dígitos multiplicam o passo por dez), os níveis de stop respeitam o espaçamento mínimo imposto pelos corretores na versão MetaTrader.
Notas de conversão
A colocação de ordem em duas etapas no estilo ECN original é simplificada para StockSharp ordens de mercado com proteção automática, que já trata da anexação de SL/TP após a execução.
As rotinas CheckVolumeValue e CheckMoneyForTrade são omitidas. O dimensionamento da posição deve ser configurado através das configurações de risco padrão StockSharp.
As instruções de registro são substituídas por ganchos de desenho de gráfico para que a média móvel e as negociações executadas possam ser visualizadas diretamente na área do gráfico de estratégia.
Essa conversão mantém o modelo de decisão idêntico ao adotar APIs idiomáticas de alto nível StockSharp (SubscribeCandles, Bind e StartProtection). Use-o como uma estrutura leve para construir sistemas de média móvel mais avançados.
namespace StockSharp.Samples.Strategies;
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.Messages;
/// <summary>
/// Basic MA Template strategy: trades when price crosses a moving average.
/// Opens long when previous candle crosses above MA, short when crosses below.
/// </summary>
public class BasicMaTemplateStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _maPeriod;
private decimal? _prevOpen;
private decimal? _prevClose;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int MaPeriod { get => _maPeriod.Value; set => _maPeriod.Value = value; }
public BasicMaTemplateStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(5).TimeFrame())
.SetDisplay("Candle Type", "Candle timeframe", "General");
_maPeriod = Param(nameof(MaPeriod), 49)
.SetGreaterThanZero()
.SetDisplay("MA Period", "Moving average period", "Indicators");
}
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevOpen = null;
_prevClose = null;
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevOpen = null;
_prevClose = null;
var sma = new SimpleMovingAverage { Length = MaPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(sma, ProcessCandle).Start();
}
private void ProcessCandle(ICandleMessage candle, decimal sma)
{
if (candle.State != CandleStates.Finished) return;
if (_prevOpen.HasValue && _prevClose.HasValue)
{
if (_prevOpen.Value > sma && _prevClose.Value < sma && Position >= 0)
SellMarket();
else if (_prevOpen.Value < sma && _prevClose.Value > sma && Position <= 0)
BuyMarket();
}
_prevOpen = candle.OpenPrice;
_prevClose = candle.ClosePrice;
}
}
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 basic_ma_template_strategy(Strategy):
def __init__(self):
super(basic_ma_template_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(5))) \
.SetDisplay("Candle Type", "Candle timeframe", "General")
self._ma_period = self.Param("MaPeriod", 49) \
.SetDisplay("MA Period", "Moving average period", "Indicators")
self._prev_open = None
self._prev_close = None
@property
def candle_type(self):
return self._candle_type.Value
@candle_type.setter
def candle_type(self, value):
self._candle_type.Value = value
@property
def ma_period(self):
return self._ma_period.Value
@ma_period.setter
def ma_period(self, value):
self._ma_period.Value = value
def OnReseted(self):
super(basic_ma_template_strategy, self).OnReseted()
self._prev_open = None
self._prev_close = None
def OnStarted2(self, time):
super(basic_ma_template_strategy, self).OnStarted2(time)
self._prev_open = None
self._prev_close = None
sma = SimpleMovingAverage()
sma.Length = self.ma_period
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(sma, self.OnProcess).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, sma)
self.DrawOwnTrades(area)
def OnProcess(self, candle, sma_value):
if candle.State != CandleStates.Finished:
return
if self._prev_open is not None and self._prev_close is not None:
if self._prev_open > sma_value and self._prev_close < sma_value and self.Position >= 0:
self.SellMarket()
elif self._prev_open < sma_value and self._prev_close > sma_value and self.Position <= 0:
self.BuyMarket()
self._prev_open = float(candle.OpenPrice)
self._prev_close = float(candle.ClosePrice)
def CreateClone(self):
return basic_ma_template_strategy()