A estratégia Maybeawo222 replica o consultor especialista MetaTrader "maybeawo222" usando o StockSharp de alto nível de API. Ele negocia um único instrumento com um cruzamento de média móvel simples (SMA) na vela anterior e limita a atividade a uma janela de tempo configurável. A conversão mantém o gerenciamento de equilíbrio encenado que tenta travar os lucros assim que o preço avança em distâncias predefinidas.
Lógica de negociação
A estratégia assina a série principal de velas selecionada por meio de CandleType e calcula uma média móvel simples com o período especificado por MovingPeriod.
No fechamento de cada vela, o valor de SMA é deslocado em MovingShift barras antes de ser usado na decisão. Isso reproduz a chamada iMA original com um parâmetro shift.
Os sinais de negociação são avaliados apenas quando o horário de fechamento da vela finalizada está dentro da faixa [StartHour, EndHour). Fora dessa janela não são criadas novas ordens, embora as posições abertas continuem a ser geridas.
Um sinal de compra aparece quando a vela anterior (aquela que acabou de fechar) abre abaixo do SMA deslocado e fecha acima dele. Um sinal de venda requer o cruzamento oposto. A estratégia reverte as posições existentes, se necessário, para que apenas uma direção permaneça aberta.
Em cada vela finalizada, o mecanismo verifica os extremos máximo/mínimo para detectar acertos de stop-loss ou take-profit. Sempre que qualquer um dos níveis é atingido, a saída do mercado correspondente é acionada imediatamente.
A posição também ativa até dois ajustes de equilíbrio em estágios. Quando o lucro flutuante excede BreakevenPips1, o stop se aproxima da entrada de acordo com DesiredBreakevenDistancePips1. Uma segunda etapa repete o processo com BreakevenPips2 e DesiredBreakevenDistancePips2.
Gestão de risco
As distâncias iniciais de stop-loss e take-profit são configuradas em pips. A conversão usa o instrumento PriceStep e aplica o fator convencional MetaTrader de 10 para cotações de três e cinco dígitos.
Os níveis de equilíbrio são aplicados apenas uma vez por lado da posição. Cada nova entrada redefine os sinalizadores, permitindo que o stop seja seguido duas vezes durante a vida da negociação.
As saídas de posição usam ordens de mercado para que o mecanismo possa fechar negociações mesmo que os níveis de stop ou alvo não estejam disponíveis no lado da corretora.
Parâmetros
Nome
Padrão
Faixa/Notas
Descrição
MovingPeriod
14
Inteiro positivo
Comprimento SMA usado para a verificação cruzada.
MovingShift
0
0 – 10 (sugerido)
Número de velas concluídas para deslocar o valor SMA para trás.
StopLossPips
100
0 desativa
Distância do preço de entrada ao stop loss de proteção, medida em pips.
TakeProfitPips
800
0 desativa
Distância da entrada ao nível de take-profit, medida em pips.
BreakevenPips1
180
0 desativa
Limite de lucro (em pips) que aciona o primeiro ajuste de equilíbrio.
DesiredBreakevenDistancePips1
60
Qualquer não negativo
Nova distância de parada a partir da entrada após o estágio 1 de equilíbrio ser acionado.
BreakevenPips2
500
0 desativa
Limite de lucro (em pips) que aciona o segundo ajuste de equilíbrio.
DesiredBreakevenDistancePips2
350
Qualquer não negativo
Nova distância de parada a partir da entrada após o estágio de equilíbrio 2 disparar.
StartHour
3
0 – 23
Hora de início da sessão de negociação inclusiva, com base no horário da bolsa.
EndHour
22
0 – 23
Horário de término exclusivo do pregão.
OrderVolume
0.5
Maior que 0
Volume enviado com cada ordem de mercado antes da compensação de posições.
CandleType
H1
Qualquer tipo de dados de vela
Série de velas usada para gerar sinais e calcular o SMA.
Notas para uso
Certifique-se de que a segurança conectada forneça um PriceStep válido; caso contrário, a conversão do pip volta para 1. Ajuste os parâmetros relacionados ao pip de acordo se o seu instrumento cotar em ticks grandes.
A estratégia espera uma configuração de símbolo único. Adicione-o a um esquema com o instrumento desejado antes de iniciar a estratégia.
Para negociação em tempo real, considere permitir permissões de derrapagem ou ordens de stop de proteção através de extensões específicas da corretora se as saídas do mercado não forem suficientes.
using System;
using Ecng.Common;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
/// <summary>
/// Moving average crossover strategy with price crossing the SMA line.
/// Buys when candle opens below MA and closes above it, sells vice versa.
/// </summary>
public class Maybeawo222Strategy : Strategy
{
private readonly StrategyParam<int> _movingPeriod;
private readonly StrategyParam<DataType> _candleType;
private ExponentialMovingAverage _ema;
private decimal? _prevClose;
private decimal? _prevMa;
public int MovingPeriod
{
get => _movingPeriod.Value;
set => _movingPeriod.Value = value;
}
public DataType CandleType
{
get => _candleType.Value;
set => _candleType.Value = value;
}
public Maybeawo222Strategy()
{
_movingPeriod = Param(nameof(MovingPeriod), 20)
.SetDisplay("MA Period", "Simple moving average period", "Indicators");
_candleType = Param(nameof(CandleType), TimeSpan.FromMinutes(30).TimeFrame())
.SetDisplay("Candle Type", "Primary candle series", "General");
}
/// <inheritdoc />
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_ema = new ExponentialMovingAverage { Length = MovingPeriod };
_prevClose = null;
_prevMa = null;
var subscription = SubscribeCandles(CandleType);
subscription
.Bind(_ema, ProcessCandle)
.Start();
var area = CreateChartArea();
if (area != null)
{
DrawCandles(area, subscription);
DrawIndicator(area, _ema);
DrawOwnTrades(area);
}
}
private void ProcessCandle(ICandleMessage candle, decimal maValue)
{
if (candle.State != CandleStates.Finished)
return;
if (!_ema.IsFormed)
{
_prevClose = candle.ClosePrice;
_prevMa = maValue;
return;
}
var close = candle.ClosePrice;
if (_prevClose is null || _prevMa is null)
{
_prevClose = close;
_prevMa = maValue;
return;
}
// Buy signal: candle crosses MA from below to above
var buySignal = _prevClose <= _prevMa && close > maValue;
// Sell signal: candle crosses MA from above to below
var sellSignal = _prevClose >= _prevMa && close < maValue;
if (buySignal && Position <= 0)
{
BuyMarket(Position < 0 ? Math.Abs(Position) + 1 : 1);
}
else if (sellSignal && Position >= 0)
{
SellMarket(Position > 0 ? Math.Abs(Position) + 1 : 1);
}
_prevClose = close;
_prevMa = maValue;
}
/// <inheritdoc />
protected override void OnReseted()
{
_ema = null;
_prevClose = null;
_prevMa = null;
base.OnReseted();
}
}
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 maybeawo222_strategy(Strategy):
"""
EMA crossover: buy when price crosses MA from below, sell from above.
"""
def __init__(self):
super(maybeawo222_strategy, self).__init__()
self._moving_period = self.Param("MovingPeriod", 20).SetDisplay("MA Period", "EMA period", "Indicators")
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromMinutes(30))).SetDisplay("Candle Type", "Candles", "General")
self._prev_close = None
self._prev_ma = None
@property
def candle_type(self):
return self._candle_type.Value
def OnReseted(self):
super(maybeawo222_strategy, self).OnReseted()
self._prev_close = None
self._prev_ma = None
def OnStarted2(self, time):
super(maybeawo222_strategy, self).OnStarted2(time)
ema = ExponentialMovingAverage()
ema.Length = self._moving_period.Value
subscription = self.SubscribeCandles(self.candle_type)
subscription.Bind(ema, self._process_candle).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawIndicator(area, ema)
self.DrawOwnTrades(area)
def _process_candle(self, candle, ma_val):
if candle.State != CandleStates.Finished:
return
close = float(candle.ClosePrice)
ma = float(ma_val)
if self._prev_close is None or self._prev_ma is None:
self._prev_close = close
self._prev_ma = ma
return
buy_signal = self._prev_close <= self._prev_ma and close > ma
sell_signal = self._prev_close >= self._prev_ma and close < ma
if buy_signal and self.Position <= 0:
self.BuyMarket()
elif sell_signal and self.Position >= 0:
self.SellMarket()
self._prev_close = close
self._prev_ma = ma
def CreateClone(self):
return maybeawo222_strategy()