Esta estrategia se basa en el principio de cruce de promedios móviles. Va largo cuando el promedio móvil a corto plazo cruza por encima del promedio móvil a largo plazo desde abajo, y va corto cuando el promedio móvil a corto plazo cruza por debajo del promedio móvil a largo plazo desde arriba.
La estrategia calcula principalmente las medias móviles simples a corto y a largo plazo y determina la dirección de la tendencia en función de su cruce.
En concreto, primero calcula la media móvil a corto plazo xMA y la media móvil a largo plazo, donde el período a corto plazo es Len y el período a largo plazo es 2*Len.
Luego comprueba si el MA a corto plazo cruza por encima del MA a largo plazo, y genera una señal larga si ocurre el cruce.
Al recibir una señal larga, abre una posición larga al precio de mercado si no hay posición.
Además, los puntos de stop loss y take profit se configuran. Para las operaciones largas, el stop loss se establece en el precio de entrada - porcentaje de stop loss * precio de entrada, y obtener ganancias al precio de entrada + porcentaje de take profit * precio de entrada. Para las operaciones cortas, el stop loss se establece en el precio de entrada + porcentaje de stop loss * precio de entrada, y obtener ganancias al precio de entrada - porcentaje de take profit * precio de entrada.
Por último, los promedios móviles se trazan para su visualización para ayudar con la determinación de la tendencia.
Simple y fácil de entender, adecuado para principiantes.
Puede realizar un seguimiento eficaz de las tendencias del mercado basándose en los cruces de la media móvil.
Los riesgos se controlan configurando el stop loss y el take profit.
La visualización de las medias móviles refleja intuitivamente los cambios de tendencia.
Las medias móviles tienen efectos de retraso, lo que puede causar que se pierdan los mejores puntos de entrada.
La configuración incorrecta de la pérdida de parada puede dar lugar a que las paradas sean demasiado anchas o demasiado ajustadas.
El cambio de precios puede generar señales falsas.
La optimización basada únicamente en los períodos de media móvil puede conducir a un sobreajuste.
Estos riesgos pueden reducirse mediante el uso de paradas más sueltas, la optimización de las combinaciones de períodos de media móvil, la adición de indicadores de filtro, etc.
Añadir otros indicadores como MACD, KDJ para filtrar para evitar señales falsas.
Optimizar las combinaciones de períodos medios móviles cortos y largos para encontrar parámetros óptimos.
Prueba diferentes estrategias de stop loss / take profit como las paradas de seguimiento.
Añadir el tamaño de la posición para optimizar la utilización del capital.
La estrategia tiene una lógica clara y simple, puede rastrear tendencias de manera efectiva basada en cruces de promedios móviles y tiene riesgos controlables. Es adecuado para que los principiantes aprendan de ella. Pero confiar únicamente en los promedios móviles puede generar señales falsas. Todavía hay mucho espacio para optimizarlo en varios aspectos para hacerlo más 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')