Estratégia de cruzamento da média móvel

Autora:ChaoZhang, Data: 2023-10-24 16:39:40
Tags:

img

Resumo

Esta estratégia baseia-se no princípio de cruzamento da média móvel. Vai longo quando a média móvel de curto prazo cruza acima da média móvel de longo prazo de baixo, e vai curto quando a média móvel de curto prazo cruza abaixo da média móvel de longo prazo de cima.

Estratégia lógica

A estratégia calcula principalmente as médias móveis simples de curto e longo prazo e determina a direcção da tendência com base no seu cruzamento.

Especificamente, calcula primeiro a média móvel de curto prazo xMA e a média móvel de longo prazo, onde o período de curto prazo é Len e o período de longo prazo é 2*Len.

Em seguida, verifica se o MA de curto prazo cruza acima do MA de longo prazo e gera um sinal longo se a cruzação ocorrer.

Ao receber um sinal longo, abre uma posição longa ao preço de mercado se não houver posição. Ao receber um sinal curto, abre uma posição curta ao preço de mercado se não houver posição.

Além disso, os pontos de stop loss e take profit são configurados. Para as negociações longas, o stop loss é definido no preço de entrada - porcentagem de stop loss * preço de entrada, e take profit no preço de entrada + take profit percentage * preço de entrada. Para as negociações curtas, o stop loss é definido no preço de entrada + stop loss percentage * preço de entrada, e take profit no preço de entrada - take profit percentage * preço de entrada.

Finalmente, as médias móveis são traçadas para visualização para ajudar na determinação da tendência.

Vantagens

  • Simples e fácil de entender, adequado para iniciantes.

  • Pode acompanhar eficazmente as tendências do mercado com base em cruzamento de médias móveis.

  • Os riscos são controlados configurando stop loss e take profit.

  • A visualização das médias móveis reflete de forma intuitiva as mudanças de tendência.

Riscos

  • As médias móveis têm efeitos de atraso, o que pode causar a ausência dos melhores pontos de entrada.

  • A configuração inadequada de stop loss pode resultar em paradas demasiado largas ou demasiado apertadas.

  • O balanço dos preços pode gerar sinais falsos.

  • A otimização baseada unicamente nos períodos da média móvel pode conduzir a um sobreajuste.

Estes riscos podem ser reduzidos através da utilização de paradas mais flexíveis, da otimização das combinações de períodos de média móvel, da adição de indicadores de filtro, etc.

Orientações de otimização

  • Adicione outros indicadores como MACD, KDJ para filtragem para evitar sinais falsos.

  • Otimizar as combinações de períodos médios móveis curtos e longos para encontrar parâmetros ideais.

  • Teste diferentes estratégias de stop loss/take profit como trailing stops.

  • Adicionar dimensionamento de posições para otimizar a utilização do capital.

Resumo

A estratégia tem uma lógica clara e simples, pode rastrear as tendências de forma eficaz com base em cruzamento de médias móveis e tem riscos controláveis. É adequado para iniciantes aprenderem. Mas confiar apenas em médias móveis pode gerar sinais falsos. Ainda há muito espaço para otimizá-lo em vários aspectos para torná-lo mais robusto.


/*backtest
start: 2023-09-23 00:00:00
end: 2023-10-23 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
//@strategy_alert_message {{strategy.order.alert_message}} 
////////////////////////////////////////////////////////////
//  Copyright by HPotter v2.0 19/09/2023
// MA Crossover Bot for OKX Exchange
////////////////////////////////////////////////////////////
var ALERTGRP_CRED = "entry"
signalToken = input("", "Signal Token", inline = "11", group = ALERTGRP_CRED)
OrderType = input.string("market", "Order Type", options = ["market", "limit"], inline = "21", group = ALERTGRP_CRED)
OrderPriceOffset = input.float(0, "Order Price Offset", minval = 0, maxval = 100, step = 0.01, inline = "21", group = ALERTGRP_CRED)
InvestmentType = input.string("percentage_balance", "Investment Type", options = ["margin", "contract", "percentage_balance", "percentage_investment"], inline = "31", group = ALERTGRP_CRED)
Amount = input.float(100, "Amount", minval = 0.01, inline = "31", group = ALERTGRP_CRED)

getAlertMsg(action, instrument, signalToken, orderType, orderPriceOffset, investmentType, amount) =>
    str = '{'
    str := str + '"action": "' + action + '", '
    str := str + '"instrument": "' + instrument + '", '
    str := str + '"signalToken": "' + signalToken + '", '
    //str := str + '"timestamp": "' + str.format_time(timenow, "yyyy-MM-dd'T'HH:mm:ssZ", "UTC+0") + '", '
    str := str + '"timestamp": "' + '{{timenow}}' + '", '
    str := str + '"orderType": "' + orderType + '", '
    str := str + '"orderPriceOffset": "' + str.tostring(orderPriceOffset) + '", '
    str := str + '"investmentType": "' + investmentType + '", '
    str := str + '"amount": "' + str.tostring(amount) + '"'
    str := str + '}'
    str

getOrderAlertMsgExit(action, instrument, signalToken) =>
    str = '{'
    str := str + '"action": "' + action + '", '
    str := str + '"instrument": "' + instrument + '", '
    str := str + '"signalToken": "' + signalToken + '", '
    str := str + '"timestamp": "' + '{{timenow}}' + '", '
    str := str + '}'
    str

strategy(title='OKX: MA Crossover', overlay=true)
Len = input(13)
Profit = input.float(7, title='Take Profit %', minval=0.01) / 100
Stop =  input.float(7, title='Stop Loss %', minval=0.01) / 100
xMA = ta.sma(close, Len)
//Robot State
isLong = strategy.position_size > 0 
isShort = strategy.position_size < 0 
isFlat = strategy.position_size == 0 
//Current Signal
doLong = low < xMA[1] ? true : false
doShort =   high > xMA[1] ? true:  false
//Backtest Start Date
tm =  timestamp(2022, 01, 01, 09, 30)
//Entry and exit orders
if  doLong[2] == false and isLong == false and doLong and time > tm
    strategy.cancel_all()
    buyAlertMsgExit = getOrderAlertMsgExit(action = 'EXIT_LONG', instrument = syminfo.ticker, signalToken = signalToken)
    buyAlertMsg = getAlertMsg(action = 'ENTER_LONG', instrument = syminfo.ticker, signalToken = signalToken, orderType =  OrderType, orderPriceOffset =  OrderPriceOffset, investmentType =  InvestmentType, amount = Amount)
    strategy.entry('Long', strategy.long, limit = close, comment='Long', alert_message =buyAlertMsg)
    strategy.exit("ExitLong", 'Long', stop=close - close * Stop  , limit = close + close * Profit , qty_percent = 100, alert_message = buyAlertMsgExit)  
if doShort[2] == false and isShort == false and doShort and time > tm
    strategy.cancel_all()
    sellAlertMsgExit = getOrderAlertMsgExit(action = 'EXIT_SHORT', instrument = syminfo.ticker, signalToken = signalToken)
    sellAlertMsg = getAlertMsg(action = 'ENTER_SHORT', instrument = syminfo.ticker, signalToken = signalToken, orderType =  OrderType, orderPriceOffset =  OrderPriceOffset, investmentType =  InvestmentType, amount = Amount)
    strategy.entry('Short', strategy.short, limit=close, comment='Short', alert_message = sellAlertMsg)
    strategy.exit("ExitShort", 'Short', stop=close + close * Stop  , limit = close - close * Profit  , qty_percent = 100, alert_message = sellAlertMsgExit)  
//Visual
barcolor(isShort  ? color.red : isLong ? color.green : color.blue)
plot(xMA, color=color.new(color.red, 0), title='MA')

Mais.