
A estratégia de negociação de retorno ao valor médio da EMA é uma estratégia de negociação para abrir e fechar posições com base no grau em que o preço se afasta da linha média. Ela usa a diferença percentual da distância da linha média da EMA do preço atual como sinal de abertura de posição e usa o rastreamento de stop loss para gerenciar posições.
A estratégia usa o EMA como um indicador de linha média e calcula a diferença percentual entre o preço atual e o EMA. Quando o preço está longe o suficiente do EMA (default de 9%), a posição é aberta; quando o preço está perto o suficiente do EMA (default de 1%), a posição é fechada. Após a abertura da posição, ele usa o stop loss operacional para bloquear o lucro e eleva o stop loss gradualmente à medida que o lucro aumenta.
Em particular, a estratégia inclui os seguintes componentes:
Calcule a linha média EMA. Pode ser configurado o ciclo (default 200), a fonte de dados (preço de fechamento), o método de cálculo (EMA, SMA, RMA, WMA).
Calcule a diferença percentual entre o preço atual e o EMA. Observe o tratamento dos valores positivos e negativos.
Abrir posição de acordo com a diferença de proporção. Abrir posição de mais é de 9% (configurável) e abrir posição de menos é de 9% (configurável).
Suporte para a abertura da escada. Pode-se configurar o número de escadas da escada e o grau de cada escada.
Tracking stop loss after opening position. Configuração de um limite para o início do stop loss (profitação padrão de 1%) e tracking amplitude (profitação padrão de 1%)
De acordo com a diferença proporcional de posição plana. Posição plana de várias posições é de 1% (configurável), posição vazia é o mesmo.
Cancelamento de pedidos não cumpridos. Quando o preço se aproxima da EMA, o pedido não cumprido será cancelado.
Percentagem de Stop Loss Configurável.
Suporte para feedback e transações em tempo real.
A estratégia tem as seguintes vantagens:
Utilizando o conceito de regressão de linha média, abrir uma posição quando o preço se desvia da linha média e fechar uma posição quando retorna, de acordo com a teoria de negociação de tendência.
Os parâmetros de abertura, parada e liquidação podem ser configurados com precisão para adaptar-se a diferentes condições de mercado.
A construção de armazéns em escala reduz os custos individuais.
O Stop Loss operacional pode ser usado para bloquear lucros e gerenciar riscos.
Há muito espaço para otimização, e é possível ajustar os parâmetros da linha média ou abrir a diferença de liquidação para se adaptar a diferentes situações.
Suporta a linguagem de programação principal Pine Script, que pode ser usado diretamente no TradingView.
Apresentação gráfica intuitiva para facilitar a observação e análise.
A estratégia também apresenta os seguintes riscos:
Risco de adequação dos dados de ressonância. A otimização de parâmetros pode ser excessivamente adequada aos dados de ressonância, sendo a eficácia do disco real duvidosa.
Risco de falha da linha média. O preço pode se afastar muito da linha média por um longo período de tempo, sem possibilidade de retorno.
O ponto de paragem pode ser ultrapassado.
As transações são frequentes e as taxas de transação são pesadas.
Os ciclos de observação são mais longos e os eventos mais frequentes.
Gestão de Riscos:
A regulação dos parâmetros é feita para garantir a robustez dos parâmetros. A eficácia é verificada em vários mercados.
O ciclo de equilíbrio de configuração razoável não pode ser muito curto ou muito longo.
A largura de suspensão deve ser reduzida de forma adequada para evitar que o sistema seja bloqueado.
A liberalização adequada das condições de abertura de posições e a redução da frequência de negociação.
A partir de agora, o país terá mais indicadores para melhorar a sua capacidade de adaptação a situações de emergência.
A estratégia pode ser melhorada em:
Adicionar condições de filtragem, como volume de negociação, Brinks, RSI e outros indicadores, para reduzir os falsos sinais.
Aumentar a linha média composta, como o sistema de dupla EMA, para aumentar a probabilidade de negociação de tendência.
Optimizar estratégias de parada de perdas, como parada de auto-adaptação, saída de Chandelier, etc., para limitar ainda mais o risco.
Adição de função de otimização automática de parâmetros, para procurar automaticamente combinações de parâmetros mais favoráveis.
Aumentar as previsões de aprendizagem de máquina para auxiliar na determinação da probabilidade de um preço sair da linha média.
Considere a possibilidade de negociar em intervalos de tempo, usando informações de dia ou de pré-dia.
A integração de pools de ações, seleção automática de ações e negociação, ampliação da capacidade de estratégia.
Uma estratégia de retorno de EMA é uma estratégia de acompanhamento de tendências baseada na característica de retorno da linha média de preço. Ela usa razoavelmente as características estatísticas da linha média para julgar a reversão da tendência e controlar o risco com um stop loss. Em comparação com a estratégia de negociação de linha média tradicional, ela se concentra mais no acompanhamento dinâmico de stop loss do que em posições de abertura rígidas.
/*backtest
start: 2022-10-19 00:00:00
end: 2023-10-25 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © jordanfray
//@version=5
strategy(title="EMA Mean Reversion Strategy", overlay=true, max_bars_back=5000, default_qty_type=strategy.percent_of_equity, default_qty_value=100,initial_capital=100000, commission_type=strategy.commission.percent, commission_value=0.05, backtest_fill_limits_assumption=2)
// Indenting Classs
indent_1 = " "
indent_2 = " "
indent_3 = " "
indent_4 = " "
// Tooltips
longEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, a long postion will open."
shortEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, a short postion will open."
closeEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, open postion will close."
ladderInToolTip = "Enable this to use the laddering settings below."
cancelEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, any unfilled entries will be canceled."
// Group Titles
group_one_title = "EMA Settings"
group_two_title = "Entry Settings"
// Colors
blue = color.new(#00A5FF,0)
lightBlue = color.new(#00A5FF,90)
green = color.new(#2DBD85,0)
gray_80 = color.new(#7F7F7F,80)
gray_60 = color.new(#7F7F7F,60)
gray_40 = color.new(#7F7F7F,40)
white = color.new(#ffffff,0)
red = color.new(#E02A4A,0)
transparent = color.new(#000000,100)
// Strategy Settings
EMAtimeframe = input.timeframe(defval="", title="Timeframe", group=group_one_title)
EMAlength = input.int(defval=200, minval=1, title="Length", group=group_one_title)
EMAtype = input.string(defval="EMA", options = ["EMA", "SMA", "RMA", "WMA"], title="Type", group=group_one_title)
EMAsource = input.source(defval=close, title="Source", group=group_one_title)
openLongEntryAbove = input.float(defval=9, title="Long Position Entry Trigger", tooltip=longEntryToolTip, group=group_two_title)
openEntryEntryAbove = input.float(defval=9, title="Short Position Entry Trigger", tooltip=shortEntryToolTip, group=group_two_title)
closeEntryBelow = input.float(defval=1.0, title="Close Position Trigger", tooltip=closeEntryToolTip, group=group_two_title)
cancelEntryBelow = input.float(defval=4, title="Cancel Unfilled Entries Trigger", tooltip=cancelEntryToolTip, group=group_two_title)
enableLaddering = input.bool(defval=true, title="Ladder Into Positions", tooltip=ladderInToolTip, group=group_two_title)
ladderRungs = input.int(defval=4, minval=2, maxval=4, step=1, title=indent_4+"Ladder Rungs", group=group_two_title)
ladderStep = input.float(defval=.5, title=indent_4+"Ladder Step (%)", step=.1, group=group_two_title)/100
stop_loss_val = input.float(defval=4.0, title="Stop Loss (%)", step=0.1, group=group_two_title)/100
start_trailing_after = input.float(defval=1, title="Start Trailing After (%)", step=0.1, group=group_two_title)/100
trail_behind = input.float(defval=1, title="Trail Behind (%)", step=0.1, group=group_two_title)/100
// Calculate trailing stop values
long_start_trailing_val = strategy.position_avg_price + (strategy.position_avg_price * start_trailing_after)
long_trail_behind_val = close - (strategy.position_avg_price * trail_behind)
long_stop_loss = strategy.position_avg_price * (1.0 - stop_loss_val)
short_start_trailing_val = strategy.position_avg_price - (strategy.position_avg_price * start_trailing_after)
short_trail_behind_val = close + (strategy.position_avg_price * trail_behind)
short_stop_loss = strategy.position_avg_price * (1 + stop_loss_val)
// Calulate EMA
EMA = switch EMAtype
"EMA" => ta.ema(EMAsource, EMAlength)
"SMA" => ta.sma(EMAsource, EMAlength)
"RMA" => ta.rma(EMAsource, EMAlength)
"WMA" => ta.wma(EMAsource, EMAlength)
=> na
EMA_ = EMAtimeframe == timeframe.period ? EMA : request.security(syminfo.ticker, EMAtimeframe, EMA[1], lookahead = barmerge.lookahead_on)
plot(EMA_, title="EMA", linewidth=2, color=blue, editable=true)
EMA_cloud_upper_band_val = EMA_ + (EMA_ * openLongEntryAbove/100)
EMA_cloud_lower_band_val = EMA_ - (EMA_ * openLongEntryAbove/100)
EMA_cloud_upper_band = plot(EMA_cloud_upper_band_val, title="EMA Cloud Upper Band", color=blue)
EMA_cloud_lower_band = plot(EMA_cloud_lower_band_val, title="EMA Cloud Upper Band", color=blue)
fill(EMA_cloud_upper_band, EMA_cloud_lower_band, editable=false, color=lightBlue)
distance_from_EMA = ((close - EMA_)/close)*100
if distance_from_EMA < 0
distance_from_EMA := distance_from_EMA * -1
// Calulate Ladder Entries
long_ladder_1_limit_price = close - (close * 1 * ladderStep)
long_ladder_2_limit_price = close - (close * 2 * ladderStep)
long_ladder_3_limit_price = close - (close * 3 * ladderStep)
long_ladder_4_limit_price = close - (close * 4 * ladderStep)
short_ladder_1_limit_price = close + (close * 1 * ladderStep)
short_ladder_2_limit_price = close + (close * 2 * ladderStep)
short_ladder_3_limit_price = close + (close * 3 * ladderStep)
short_ladder_4_limit_price = close + (close * 4 * ladderStep)
var position_qty = strategy.equity/close
if enableLaddering
position_qty := (strategy.equity/close) / ladderRungs
else
position_qty := strategy.equity/close
plot(position_qty, color=white)
//plot(strategy.equity, color=green)
// Entry Conditions
currently_in_a_postion = strategy.position_size != 0
currently_in_a_long_postion = strategy.position_size > 0
currently_in_a_short_postion = strategy.position_size < 0
average_price = strategy.position_avg_price
bars_since_entry = currently_in_a_postion ? bar_index - strategy.opentrades.entry_bar_index(strategy.opentrades - 1) + 1 : 5
long_run_up = ta.highest(high, bar_index == 0 ? 5000: bars_since_entry)
long_run_up_line = plot(long_run_up, style=plot.style_stepline, editable=false, color=currently_in_a_long_postion ? green : transparent)
start_trailing_long_entry = currently_in_a_long_postion and long_run_up > long_start_trailing_val
long_trailing_stop = start_trailing_long_entry ? long_run_up - (long_run_up * trail_behind) : long_stop_loss
long_trailing_stop_line = plot(long_trailing_stop, style=plot.style_stepline, editable=false, color=currently_in_a_long_postion ? long_trailing_stop > strategy.position_avg_price ? green : red : transparent)
short_run_up = ta.lowest(low, bar_index == 0 ? 5000: bars_since_entry)
short_run_up_line = plot(short_run_up, style=plot.style_stepline, editable=false, color=currently_in_a_short_postion ? green : transparent)
start_trailing_short_entry = currently_in_a_short_postion and short_run_up < short_start_trailing_val
short_trailing_stop = start_trailing_short_entry ? short_run_up + (short_run_up * trail_behind) : short_stop_loss
short_trailing_stop_line = plot(short_trailing_stop, style=plot.style_stepline, editable=false, color=currently_in_a_short_postion ? short_trailing_stop < strategy.position_avg_price ? green : red : transparent)
long_conditions_met = distance_from_EMA > openLongEntryAbove and close < EMA_ and not currently_in_a_postion
short_conditions_met = distance_from_EMA > openEntryEntryAbove and close > EMA_ and not currently_in_a_postion
close_long_entries = distance_from_EMA <= closeEntryBelow or close <= long_trailing_stop
close_short_entries = distance_from_EMA <= closeEntryBelow or close >= short_trailing_stop
cancel_entries = distance_from_EMA <= cancelEntryBelow
plotshape(long_conditions_met ? close : na, style=shape.diamond, title="Long Conditions Met" )
plotshape(short_conditions_met ? close : na, style=shape.diamond, title="Short Conditions Met" )
plot(average_price,style=plot.style_stepline, editable=false, color=currently_in_a_postion ? blue : transparent)
// Long Entry
if enableLaddering
if ladderRungs == 2
strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
else if ladderRungs == 3
strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 3", direction=strategy.long, qty=position_qty, limit=long_ladder_3_limit_price, when=long_conditions_met)
else if ladderRungs == 4
strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 3", direction=strategy.long, qty=position_qty, limit=long_ladder_3_limit_price, when=long_conditions_met)
strategy.entry(id="Long Ladder 4", direction=strategy.long, qty=position_qty, limit=long_ladder_4_limit_price, when=long_conditions_met)
strategy.exit(id="Close Long Ladder 1", from_entry="Long Ladder 1", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
strategy.exit(id="Close Long Ladder 2", from_entry="Long Ladder 2", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
strategy.exit(id="Close Long Ladder 3", from_entry="Long Ladder 3", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
strategy.exit(id="Close Long Ladder 4", from_entry="Long Ladder 4", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
strategy.cancel(id="Long Ladder 1", when=cancel_entries)
strategy.cancel(id="Long Ladder 2", when=cancel_entries)
strategy.cancel(id="Long Ladder 3", when=cancel_entries)
strategy.cancel(id="Long Ladder 4", when=cancel_entries)
else
strategy.entry(id="Long", direction=strategy.long, qty=100, when=long_conditions_met)
strategy.exit(id="Close Long", from_entry="Long", stop=long_stop_loss, limit=EMA_, when=close_long_entries)
strategy.cancel(id="Long", when=cancel_entries)
// Short Entry
if enableLaddering
if ladderRungs == 2
strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
else if ladderRungs == 3
strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 3", direction=strategy.short, qty=position_qty, limit=short_ladder_3_limit_price, when=short_conditions_met)
else if ladderRungs == 4
strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 3", direction=strategy.short, qty=position_qty, limit=short_ladder_3_limit_price, when=short_conditions_met)
strategy.entry(id="Short Ladder 4", direction=strategy.short, qty=position_qty, limit=short_ladder_4_limit_price, when=short_conditions_met)
strategy.exit(id="Close Short Ladder 1", from_entry="Short Ladder 1", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
strategy.exit(id="Close Short Ladder 2", from_entry="Short Ladder 2", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
strategy.exit(id="Close Short Ladder 3", from_entry="Short Ladder 3", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
strategy.exit(id="Close Short Ladder 4", from_entry="Short Ladder 4", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
strategy.cancel(id="Short Ladder 1", when=cancel_entries)
strategy.cancel(id="Short Ladder 2", when=cancel_entries)
strategy.cancel(id="Short Ladder 3", when=cancel_entries)
strategy.cancel(id="Short Ladder 4", when=cancel_entries)
else
strategy.entry(id="Short", direction=strategy.short, when=short_conditions_met)
strategy.exit(id="Close Short", from_entry="Short", limit=EMA_, when=close_short_entries)
strategy.cancel(id="Short", when=cancel_entries)