Esta estrategia se basa en el sistema de cruce de promedios móviles, utilizando cruces dorados y cruces de muerte de promedios móviles en diferentes marcos de tiempo para determinar los puntos de entrada y salida.
La estrategia utiliza dos conjuntos de promedios móviles, MA rápido y MA lento. El MA rápido tiene un período más corto para capturar la tendencia a corto plazo, mientras que el MA lento tiene un período más largo para la tendencia a largo plazo. Cuando el MA rápido cruza por encima del MA lento, se produce una cruz de oro, lo que indica una tendencia alcista. Cuando el MA rápido cruza por debajo del MA lento, se produce una cruz de muerte, lo que indica una tendencia bajista.
En el código, el MA rápido es ma1, el MA lento es ma2. Tanto ma1 como ma2 pueden ser diferentes tipos como SMA, EMA, con períodos personalizables. ma1 representa una tendencia a corto plazo con un período más corto, ma2 representa una tendencia a largo plazo con un período más largo.
Cuando ma1 oro cruza ma2, se genera una señal larga. Cuando ma1 muerte cruza ma2, se genera una señal corta. En el comercio real, se pueden agregar características como stop loss, take profit y stop loss para bloquear las ganancias y controlar los riesgos.
La estrategia tiene las siguientes ventajas:
Una lógica sencilla y fácil de entender.
Flexible en la elección de diferentes tipos y parámetros de AMP para diferentes condiciones de mercado.
Diseño de marcos de tiempo múltiples para capturar las tendencias a corto y largo plazo.
Reglas de entrada personalizables para controlar estrictamente la frecuencia de las operaciones.
Stop loss y take profit configurables para gestionar eficazmente los riesgos.
El seguimiento de la tendencia de stop loss permite que las ganancias se ejecuten.
Parámetros optimizados para una mayor robustez.
La estrategia también presenta los siguientes riesgos:
El retraso en la emisión de cruces de doble MA puede perder el mejor momento de inversión.
Los períodos de MA incorrectos pueden generar más señales falsas.
Las inversiones repentinas pueden afectar el stop loss.
El precio puede permanecer en un lado de MA durante períodos prolongados en mercados de tendencia.
Sobre-optimización sobre los parámetros ajustados.
Medidas de gestión de riesgos:
Añadir filtros para evitar señales falsas de fuga.
Prueba y optimización de los períodos de MA basados en principios comerciales.
Control cuidadoso del riesgo y colocación razonable de stop loss.
Acepta el costo necesario de la paciencia.
Prueba de robustez en diferentes condiciones de mercado.
La estrategia puede mejorarse en los siguientes aspectos:
Prueba más tipos de MA, como la media móvil ponderada.
Se añadirán períodos dinámicos basados en la volatilidad.
Añadir filtros como el tiempo y los fundamentos a las reglas de entrada.
Utilice paradas adaptativas que se ajusten a la volatilidad del mercado.
Construir un sistema de optimización de parámetros para las pruebas de retroceso.
Incorporar aprendizaje automático para optimizar parámetros y señales de filtro.
En conclusión, esta estrategia de cruce de media móvil multiframe tiene una lógica simple y clara para seguir las tendencias utilizando cruces de MA rápidos y lentos. Con la selección adecuada de parámetros, reglas de entrada / salida optimizadas y control de riesgos, puede lograr ganancias constantes. Sin embargo, los usuarios deben tolerar riesgos rezagados y costos de tiempo de espera. En general, es una estrategia simple y práctica que vale la pena optimizar y controlar el riesgo para adaptarse a más condiciones de mercado.
/*backtest start: 2023-09-08 00:00:00 end: 2023-10-08 00:00:00 period: 4h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=3 // The majority of this script I took from the Autoview website. There are some typos in the original that I've fixed, some things I've added, things I will add, and I'm tired pulling my strategy code out and uploading this to pastebin for people. // DISCLAIMER: I am not a financial advisor, this is not financial advice, do not use this code without first doing your own research, etc, etc, it's not my fault when you lose your house. strategy("Moving Averages Cross - MTF - Strategy", "MA Cross", overlay=true, pyramiding=0, initial_capital=100000, currency=currency.USD, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type=strategy.commission.percent, commission_value=0.1) bgcolor ( color=black, transp=40, title='Blackground', editable=true) /////////////////////////////////////////////// //* Backtesting Period Selector | Component *// /////////////////////////////////////////////// //* https://www.tradingview.com/script/eCC1cvxQ-Backtesting-Period-Selector-Component *// //* https://www.tradingview.com/u/pbergden/ *// //* Modifications made *// testStartYear = input(2018, "Backtest Start Year") testStartMonth = input(1, "Backtest Start Month") testStartDay = input(1, "Backtest Start Day") testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,00,00) testStopYear = input(9999, "Backtest Stop Year") testStopMonth = input(12, "Backtest Stop Month") testStopDay = input(31, "Backtest Stop Day") testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0) testPeriod() => true ///////////////////////////////////// //* Put your strategy logic below *// ///////////////////////////////////// sp1 = input("----", title="--------Moving Average 1----------", options=["----"]) maUseRes1 = input(defval = false, title = "Use Different Resolution?") //maReso1 = input(defval = "60", title = "Set Resolution", type = resolution) maReso1 = input(defval='60', title = "Set Resolution Minutes") maType1 = input("EMA", title="MA", options=["SMA", "EMA", "DEMA", "TEMA", "WMA", "VWMA", "SMMA", "Hull", "LSMA", "ALMA"]) maSource1 = input(defval = close, title = "Source") maLength1 = input(defval = 15, title = "Period", minval = 1) lsmaOffset1 = input(defval = 1, title = "Least Squares (LSMA) Only - Offset Value", minval = 0) almaOffset1 = input(defval = 0.85, title = "Arnaud Legoux (ALMA) Only - Offset Value", minval = 0, step = 0.01) almaSigma1 = input(defval = 6, title = "Arnaud Legoux (ALMA) Only - Sigma Value", minval = 0) sp2 = input("----", title="--------Moving Average 2----------", options=["----"]) maUseRes2 = input(defval = false, title = "Use Different Resolution?") //maReso2 = input(defval = "60", title = "Set Resolution", type = resolution) maReso2 = input(defval='60', title = "Set Resolution Minutes") maType2 = input("EMA", title="MA", options=["SMA", "EMA", "DEMA", "TEMA", "WMA", "VWMA", "SMMA", "Hull", "LSMA", "ALMA"]) maSource2 = input(defval = close, title = "Source") maLength2 = input(defval = 30, title = "Period", minval = 1) lsmaOffset2 = input(defval = 1, title = "Least Squares (LSMA) Only - Offset Value", minval = 0) almaOffset2 = input(defval = 0.85, title = "Arnaud Legoux (ALMA) Only - Offset Value", minval = 0, step = 0.01) almaSigma2 = input(defval = 6, title = "Arnaud Legoux (ALMA) Only - Sigma Value", minval = 0) //Function from @JayRogers thank you man awesome work variant(type, src, len, lsmaOffset, almaOffset, almaSigma) => v1 = sma(src, len) // Simple v2 = ema(src, len) // Exponential v3 = 2 * v2 - ema(v2, len) // Double Exponential v4 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len) // Triple Exponential v5 = wma(src, len) // Weighted v6 = vwma(src, len) // Volume Weighted v7 = na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len // Smoothed v8 = wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len))) // Hull v9 = linreg(src, len, lsmaOffset) // Least Squares v10 = alma(src, len, almaOffset, almaSigma) // Arnaud Legoux type=="EMA"?v2 : type=="DEMA"?v3 : type=="TEMA"?v4 : type=="WMA"?v5 : type=="VWMA"?v6 : type=="SMMA"?v7 : type=="Hull"?v8 : type=="LSMA"?v9 : type=="ALMA"?v10 : v1 //Different resolution function reso(exp, res, use) => use ? security(tickerid, res, exp) : exp ma1 = reso(variant(maType1, maSource1, maLength1, lsmaOffset1, almaOffset1, almaSigma1), maReso1, maUseRes1) ma2 = reso(variant(maType2, maSource2, maLength2, lsmaOffset2, almaOffset2, almaSigma2), maReso2, maUseRes2) plotma1 = plot(ma1, color=green, tranps=50, linewidth = 2 ) plotma2 = plot(ma2, color=red, tranps=50, linewidth = 2 ) // Long/Short Logic longLogic = crossover(ma1,ma2) ? 1 : 0 shortLogic = crossunder(ma1,ma2) ? 1 : 0 ////////////////////////// //* Strategy Component *// ////////////////////////// isLong = input(false, "Longs Only") isShort = input(false, "Shorts Only") isFlip = input(false, "Flip the Opens") long = longLogic short = shortLogic if isFlip long := shortLogic short := longLogic else long := longLogic short := shortLogic if isLong long := long short := na if isShort long := na short := short //////////////////////////////// //======[ Signal Count ]======// //////////////////////////////// sectionLongs = 0 sectionLongs := nz(sectionLongs[1]) sectionShorts = 0 sectionShorts := nz(sectionShorts[1]) if long sectionLongs := sectionLongs + 1 sectionShorts := 0 if short sectionLongs := 0 sectionShorts := sectionShorts + 1 ////////////////////////////// //======[ Pyramiding ]======// ////////////////////////////// pyrl = input(1, "Pyramiding less than") // If your count is less than this number pyre = input(0, "Pyramiding equal to") // If your count is equal to this number pyrg = input(1000000, "Pyramiding greater than") // If your count is greater than this number longCondition = long and sectionLongs <= pyrl or long and sectionLongs >= pyrg or long and sectionLongs == pyre ? 1 : 0 shortCondition = short and sectionShorts <= pyrl or short and sectionShorts >= pyrg or short and sectionShorts == pyre ? 1 : 0 //////////////////////////////// //======[ Entry Prices ]======// //////////////////////////////// last_open_longCondition = na last_open_shortCondition = na last_open_longCondition := longCondition ? close : nz(last_open_longCondition[1]) last_open_shortCondition := shortCondition ? close : nz(last_open_shortCondition[1]) //////////////////////////////////// //======[ Open Order Count ]======// //////////////////////////////////// sectionLongConditions = 0 sectionLongConditions := nz(sectionLongConditions[1]) sectionShortConditions = 0 sectionShortConditions := nz(sectionShortConditions[1]) if longCondition sectionLongConditions := sectionLongConditions + 1 sectionShortConditions := 0 if shortCondition sectionLongConditions := 0 sectionShortConditions := sectionShortConditions + 1 /////////////////////////////////////////////// //======[ Position Check (long/short) ]======// /////////////////////////////////////////////// last_longCondition = na last_shortCondition = na last_longCondition := longCondition ? time : nz(last_longCondition[1]) last_shortCondition := shortCondition ? time : nz(last_shortCondition[1]) in_longCondition = last_longCondition > last_shortCondition in_shortCondition = last_shortCondition > last_longCondition ///////////////////////////////////// //======[ Position Averages ]======// ///////////////////////////////////// totalLongs = 0.0 totalLongs := nz(totalLongs[1]) totalShorts = 0.0 totalShorts := nz(totalShorts[1]) averageLongs = 0.0 averageLongs := nz(averageLongs[1]) averageShorts = 0.0 averageShorts := nz(averageShorts[1]) if longCondition totalLongs := totalLongs + last_open_longCondition totalShorts := 0.0 if shortCondition totalLongs := 0.0 totalShorts := totalShorts + last_open_shortCondition averageLongs := totalLongs / sectionLongConditions averageShorts := totalShorts / sectionShortConditions ///////////////////////////////// //======[ Trailing Stop ]======// ///////////////////////////////// isTS = input(false, "Trailing Stop") tsi = input(1000, "Activate Trailing Stop Price (%). Divided by 100 (1 = 0.01%)") / 100 ts = input(575, "Trailing Stop (%). Divided by 100 (1 = 0.01%)") / 100 last_high = na last_low = na last_high_short = na last_low_short = na last_high := not in_longCondition ? na : in_longCondition and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1]) last_high_short := not in_shortCondition ? na : in_shortCondition and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1]) last_low := not in_shortCondition ? na : in_shortCondition and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1]) last_low_short := not in_longCondition ? na : in_longCondition and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1]) long_ts = isTS and not na(last_high) and low <= last_high - last_high / 100 * ts and longCondition == 0 and last_high >= averageLongs + averageLongs / 100 * tsi short_ts = isTS and not na(last_low) and high >= last_low + last_low / 100 * ts and shortCondition == 0 and last_low <= averageShorts - averageShorts/ 100 * tsi /////////////////////////////// //======[ Take Profit ]======// /////////////////////////////// isTP = input(false, "Take Profit") tp = input(300, "Take Profit (%). Divided by 100 (1 = 0.01%)") / 100 long_tp = isTP and close > averageLongs + averageLongs / 100 * tp and not longCondition short_tp = isTP and close < averageShorts - averageShorts / 100 * tp and not shortCondition ///////////////////////////// //======[ Stop Loss ]======// ///////////////////////////// isSL = input(false, "Stop Loss") sl = input(575, "Stop Loss (%). Divided by 100 (1 = 0.01%)") / 100 long_sl = isSL and close < averageLongs - averageLongs / 100 * sl and longCondition == 0 short_sl = isSL and close > averageShorts + averageShorts / 100 * sl and shortCondition == 0 ///////////////////////////////// //======[ Close Signals ]======// ///////////////////////////////// longClose = long_tp or long_sl or long_ts ? 1 : 0 shortClose = short_tp or short_sl or short_ts ? 1: 0 /////////////////////////////// //======[ Plot Colors ]======// /////////////////////////////// longCloseCol = na shortCloseCol = na longCloseCol := long_tp ? purple : long_sl ? maroon : long_ts ? blue : longCloseCol[1] shortCloseCol := short_tp ? purple : short_sl ? maroon : short_ts ? blue : shortCloseCol[1] tpColor = isTP and in_longCondition ? purple : isTP and in_shortCondition ? purple : white slColor = isSL and in_longCondition ? red : isSL and in_shortCondition ? red : white ////////////////////////////////// //======[ Strategy Plots ]======// ////////////////////////////////// // Comment out these lines to use alerts plot(isTS and in_longCondition ? averageLongs + averageLongs / 100 * tsi : na, "Long Trailing Activate", blue, style=3, linewidth=2) plot(isTS and in_longCondition and last_high >= averageLongs + averageLongs / 100 * tsi ? last_high - last_high / 100 * ts : na, "Long Trailing", fuchsia, style=2, linewidth=3) plot(isTS and in_shortCondition ? averageShorts - averageShorts/ 100 * tsi : na, "Short Trailing Activate", blue, style=3, linewidth=2) plot(isTS and in_shortCondition and last_low <= averageShorts - averageShorts/ 100 * tsi ? last_low + last_low / 100 * ts : na, "Short Trailing", fuchsia, style=2, linewidth=3) plot(isTP and in_longCondition and last_high < averageLongs + averageLongs / 100 * tp ? averageLongs + averageLongs / 100 * tp : na, "Long TP", tpColor, style=3, linewidth=2) plot(isTP and in_shortCondition and last_low > averageShorts - averageShorts / 100 * tp ? averageShorts - averageShorts / 100 * tp : na, "Short TP", tpColor, style=3, linewidth=2) plot(isSL and in_longCondition and last_low_short > averageLongs - averageLongs / 100 * sl ? averageLongs - averageLongs / 100 * sl : na, "Long SL", slColor, style=3, linewidth=2) plot(isSL and in_shortCondition and last_high_short < averageShorts + averageShorts / 100 * sl ? averageShorts + averageShorts / 100 * sl : na, "Short SL", slColor, style=3, linewidth=2) /////////////////////////////// //======[ Alert Plots ]======// /////////////////////////////// // Uncomment to use Alerts, or the new Signal Plots, but not both // Old Signal Plots //plot(longCondition, "Long", green) //plot(shortCondition, "Short", red) //plot(longClose, "Long Close", longCloseCol) //plot(shortClose, "Short Close", shortCloseCol) // Uncomment for your alerts //alertcondition(condition=longCondition, title="Long", message="") //alertcondition(condition=shortCondition, title="Short", message="") //alertcondition(condition=longClose, title="Long Close", message="") //alertcondition(condition=shortClose, title="Short Close", message="") /////////////////////////////////// //======[ Reset Variables ]======// /////////////////////////////////// if longClose or not in_longCondition averageLongs := 0 totalLongs := 0.0 sectionLongs := 0 sectionLongConditions := 0 if shortClose or not in_shortCondition averageShorts := 0 totalShorts := 0.0 sectionShorts := 0 sectionShortConditions := 0 //////////////////////////////////////////// //======[ Strategy Entry and Exits ]======// //////////////////////////////////////////// // Comment out to use alerts if testPeriod() strategy.entry("Long", 1, when=longCondition) strategy.entry("Short", 0, when=shortCondition) strategy.close("Long", when=longClose) strategy.close("Short", when=shortClose)