Little EA é um expert de cruzamento de médias móveles originalmente escrito para o MetaTrader. A estratégia observa o candle selecionado pelo parâmetro OHLC bar index e reage quando esse candle cruza uma média móvel deslocada de baixo para cima ou de cima para baixo. O port StockSharp mantém a ideia original de múltiplas entradas ao permitir várias tranches por direção, respeitando uma exposição máxima configurável.
Lógica de trading
Assinar a série de candles configurada e alimentar o tipo de média móvel selecionado com a fonte de preço escolhida (fechamento, abertura, máxima, mínima, mediana, típico ou ponderado).
Armazenar candles completados para que a estratégia possa referenciar o candle no OhlcBarIndex (o valor padrão 1 significa o último candle completamente fechado).
Aplicar o MaShift opcional lendo o valor da média móvel de várias barras atrás, replicando o deslocamento visual do MetaTrader.
Quando o candle de referência fecha acima da MA deslocada, tratar como cruzamento altista. Quando fecha abaixo, tratar como cruzamento baixista.
Para um cruzamento altista:
Se a exposição vendida líquida já iguala o máximo configurado, fechar toda a posição vendida.
Caso contrário, se a exposição comprada ainda está abaixo do máximo, adicionar uma tranche de TradeVolume ao lado comprado.
Para um cruzamento baixista:
Se a exposição comprada já iguala o máximo, fechar toda a posição comprada.
Caso contrário, se a exposição vendida está abaixo do limite, adicionar uma tranche de TradeVolume ao lado vendido.
O limite de volume emula o limite Int_Max_Pos do expert original enquanto trabalha com as posições líquidas do StockSharp.
Parâmetros
Nome
Tipo
Padrão
Descrição
CandleType
DataType
Período de 1 minuto
Período principal usado para sinais e cálculos de indicadores.
OhlcBarIndex
int
1
Índice do candle histórico usado para detecção de cruzamento (0 = candle atual em formação, 1 = último candle terminado).
MaxPositionsPerSide
int
15
Número máximo de tranches de TradeVolume que podem ser acumuladas por direção.
MaPeriod
int
64
Comprimento da média móvel.
MaShift
int
0
Número de barras para deslocar a MA para trás ao verificar cruzamentos.
MaType
MovingAverageType
Smoothed
Modo de cálculo da média móvel (Simple, Exponential, Smoothed, Weighted).
AppliedPrice
AppliedPriceType
Close
Fonte de preço usada como entrada do indicador.
TradeVolume
decimal
1
Volume de ordem enviado com cada nova tranche.
Diferenças em relação ao expert original do MetaTrader
A gestão de dinheiro está simplificada: apenas entradas de volume fixo são suportadas. O dimensionamento de risco percentual do EA original não está implementado.
O StockSharp trabalha com posições líquidas, então posições em direção oposta são fechadas antes de nova exposição ser acumulada. O limite de MaxPositionsPerSide é aplicado à exposição líquida em lotes.
Os valores do indicador e o histórico de candles são processados através da API de assinatura de candles de alto nível em vez de cópias manuais de buffer.
Dicas de uso
Ajustar TradeVolume para corresponder ao passo de lote do instrumento antes de lançar a estratégia; o construtor também atribui o mesmo valor a Strategy.Volume para que os métodos auxiliares usem o tamanho desejado por padrão.
Usar MaShift em combinação com OhlcBarIndex para recriar o alinhamento visual do gráfico MetaTrader se necessário.
Adicionar a estratégia a um gráfico para ver candles, a sobreposição da média móvel e as operações executadas, o que ajuda a verificar o comportamento de cruzamento.
Indicadores
Uma média móvel configurável (Simple, Exponential, Smoothed ou Weighted).
using System;
using System.Collections.Generic;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Strategies;
using StockSharp.BusinessEntities;
using StockSharp.Messages;
namespace StockSharp.Samples.Strategies;
public class LittleEaStrategy : Strategy
{
private readonly StrategyParam<DataType> _candleType;
private readonly StrategyParam<int> _momentumPeriod;
private decimal? _prevMom;
public DataType CandleType { get => _candleType.Value; set => _candleType.Value = value; }
public int MomentumPeriod { get => _momentumPeriod.Value; set => _momentumPeriod.Value = value; }
public LittleEaStrategy()
{
_candleType = Param(nameof(CandleType), TimeSpan.FromHours(4).TimeFrame()).SetDisplay("Candle Type", "Timeframe", "General");
_momentumPeriod = Param(nameof(MomentumPeriod), 10).SetGreaterThanZero().SetDisplay("Momentum Period", "Momentum lookback", "Indicators");
}
public override IEnumerable<(Security sec, DataType dt)> GetWorkingSecurities() => [(Security, CandleType)];
/// <inheritdoc />
protected override void OnReseted()
{
base.OnReseted();
_prevMom = null;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
_prevMom = null;
var mom = new Momentum { Length = MomentumPeriod };
var subscription = SubscribeCandles(CandleType);
subscription.Bind(mom, ProcessCandle).Start();
var area = CreateChartArea();
if (area != null) { DrawCandles(area, subscription); DrawOwnTrades(area); }
}
private void ProcessCandle(ICandleMessage candle, decimal momVal)
{
if (candle.State != CandleStates.Finished) return;
if (!IsFormedAndOnlineAndAllowTrading()) { _prevMom = momVal; return; }
if (_prevMom == null) { _prevMom = momVal; return; }
if (_prevMom.Value < 100m && momVal >= 100m && Position <= 0) { if (Position < 0) BuyMarket(); BuyMarket(); }
else if (_prevMom.Value > 100m && momVal <= 100m && Position >= 0) { if (Position > 0) SellMarket(); SellMarket(); }
_prevMom = momVal;
}
}
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 Momentum
from StockSharp.Algo.Strategies import Strategy
class little_ea_strategy(Strategy):
def __init__(self):
super(little_ea_strategy, self).__init__()
self._candle_type = self.Param("CandleType", DataType.TimeFrame(TimeSpan.FromHours(4))) \
.SetDisplay("Candle Type", "Timeframe", "General")
self._momentum_period = self.Param("MomentumPeriod", 10) \
.SetDisplay("Momentum Period", "Momentum lookback", "Indicators")
self._prev_mom = None
@property
def CandleType(self):
return self._candle_type.Value
@property
def MomentumPeriod(self):
return self._momentum_period.Value
def OnReseted(self):
super(little_ea_strategy, self).OnReseted()
self._prev_mom = None
def OnStarted2(self, time):
super(little_ea_strategy, self).OnStarted2(time)
self._prev_mom = None
mom = Momentum()
mom.Length = self.MomentumPeriod
subscription = self.SubscribeCandles(self.CandleType)
subscription.Bind(mom, self._on_process).Start()
area = self.CreateChartArea()
if area is not None:
self.DrawCandles(area, subscription)
self.DrawOwnTrades(area)
def _on_process(self, candle, mom_value):
if candle.State != CandleStates.Finished:
return
mv = float(mom_value)
if not self.IsFormedAndOnlineAndAllowTrading():
self._prev_mom = mv
return
if self._prev_mom is None:
self._prev_mom = mv
return
if self._prev_mom < 100.0 and mv >= 100.0 and self.Position <= 0:
if self.Position < 0:
self.BuyMarket()
self.BuyMarket()
elif self._prev_mom > 100.0 and mv <= 100.0 and self.Position >= 0:
if self.Position > 0:
self.SellMarket()
self.SellMarket()
self._prev_mom = mv
def CreateClone(self):
return little_ea_strategy()