Esta estrategia utiliza un sistema de promedios móviles para determinar la dirección de la tendencia actual y hace posiciones largas o cortas de acuerdo con la tendencia. Cuando el promedio móvil sube, la confianza en largo es mayor, así que vaya largo. Cuando el promedio móvil baja, la confianza en corto es mayor, así que vaya corto. Esta estrategia utiliza principalmente el sistema de promedios móviles para determinar la dirección de la tendencia del mercado, perteneciente a la estrategia de tendencia siguiente.
Calcular la media móvil ponderada vwma como indicador de la media móvil para un determinado período (período predeterminado 400).
Determine si la media móvil vwma está subiendo, si sube, establezca la tendencia alcista de la señal larga; si baja, establezca la tendencia bajista de la señal corta.
Cuando la tendencia alcista es verdadera, ir largo; cuando la tendencia bajista es verdadera, cerrar largo y ir corto.
Calcular la estrategia de retorno bar_pnl y comprar y mantener el retorno bar_bh para cada barra.
De acuerdo con las marcas de tiempo trimestrales y anuales, calcule el rendimiento trimestral de la estrategia quarter_pnl, el rendimiento anual year_pnl y el correspondiente buy & hold return quarter_bh, year_bh.
Mostrar el rendimiento de la estrategia trimestral frente al rendimiento de compra y retención en una tabla.
Las principales ventajas de esta estrategia son las siguientes:
Determina la tendencia del mercado por medio móvil, fácil de entender.
Seguir la tendencia reduce las pérdidas en los mercados no en tendencia.
Pocos parámetros ajustables, principalmente el período de media móvil, fácil de probar y optimizar.
Tabla de retorno intuitiva para mostrar los resultados claramente.
Añadir el rendimiento de compra y retención en la tabla para la comparación, muestra el rendimiento excesivo.
Posición flexible de la mesa, fácil de integrar con otras estrategias.
También hay algunos riesgos:
Bajo rendimiento en el mercado alcista de larga duración en comparación con buy & hold.
El alto riesgo en el mercado limitado por el rango puede agregar condiciones de filtro como romper los máximos anteriores para reducir las transacciones.
El promedio móvil tiene una capacidad de ajuste de curva pobre, puede perder los puntos de inflexión de la tendencia.
No hay un mecanismo de stop loss, el riesgo de una gran reducción, puede establecer un stop loss dinámico o dimensionar la posición.
Para la tabla, puede agregar métricas de riesgo como la proporción de afilado, extracción máxima.
La estrategia se puede optimizar en los siguientes aspectos:
Optimizar los parámetros de las medias móviles, ajustar el período en función de los regímenes del mercado.
Añadir filtros como romper el máximo anterior para reducir las flechas.
Prueba diferentes tipos de promedios móviles, como WMA, DEMA, etc.
Agregue mecanismos de stop loss, como paradas dinámicas o dimensionamiento de posiciones.
Enriquecer el contenido de la tabla, añadir métricas como ratio de nitidez, extracción máxima.
Combina con otros indicadores como MACD, Bandas de Bollinger para determinar tendencias.
Optimizar el tamaño de las posiciones, ajustar las posiciones dinámicamente en función de las condiciones del mercado.
Prueba en diferentes productos, encuentra el mejor ámbito de aplicación.
La estrategia de negociación de promedios móviles es relativamente simple y directa. Sigue la tendencia determinando la tendencia utilizando promedios móviles, con un buen control de descenso, adecuado para los operadores que siguen la tendencia. Todavía hay un gran espacio para la optimización, como el sistema de promedios móviles, el mecanismo de stop loss, el tamaño de posición, etc. para que sea adaptable a entornos de mercado complejos.
/*backtest start: 2022-10-23 00:00:00 end: 2023-10-29 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/ // © Dannnnnnny //@version=4 strategy(title="Quarterly Returns in Strategies vs Buy & Hold", initial_capital= 1000, overlay=true,default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.1) maLength= input(400) wma= vwma(hl2,maLength) uptrend= rising(wma, 5) downtrend= falling(wma,5) plot(wma) if uptrend strategy.entry("Buy", strategy.long) else strategy.close("Buy")// /////////////////// // QUARTERLY TABLE // enableQuarterlyTable = input(title="Enable Quarterly Return table", type=input.bool, defval=false) enableCompareWithMarket = input(title="Compare with Market Benchmark", type=input.bool, defval=false) table_position = input(title="Table Position", type=input.string, defval='bottom_right', options=['bottom_right','bottom_left','top_right', 'top_left']) precision = 2 new_quarter = ceil(month(time)/3) != ceil(month(time[1])/3) new_year = year(time) != year(time[1]) eq = strategy.equity bar_pnl = eq / eq[1] - 1 bar_bh = (close-close[1])/close[1] cur_quarter_pnl = 0.0 cur_year_pnl = 0.0 cur_quarter_bh = 0.0 cur_year_bh = 0.0 // Current Quarterly P&L cur_quarter_pnl := new_quarter ? 0.0 : (1 + cur_quarter_pnl[1]) * (1 + bar_pnl) - 1 cur_quarter_bh := new_quarter ? 0.0 : (1 + cur_quarter_bh[1]) * (1 + bar_bh) - 1 // Current Yearly P&L cur_year_pnl := new_year ? 0.0 : (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1 cur_year_bh := new_year ? 0.0 : (1 + cur_year_bh[1]) * (1 + bar_bh) - 1 // Arrays to store Yearly and Quarterly P&Ls var quarter_pnl = array.new_float(0) var quarter_time = array.new_int(0) var quarter_bh = array.new_float(0) var year_pnl = array.new_float(0) var year_time = array.new_int(0) var year_bh = array.new_float(0) end_time = false end_time:= time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory if (not na(cur_quarter_pnl[1]) and (new_quarter or end_time)) if (end_time[1]) array.pop(quarter_pnl) array.pop(quarter_time) array.push(quarter_pnl , cur_quarter_pnl[1]) array.push(quarter_time, time[1]) array.push(quarter_bh , cur_quarter_bh[1]) if (not na(cur_year_pnl[1]) and (new_year or end_time)) if (end_time[1]) array.pop(year_pnl) array.pop(year_time) array.push(year_pnl , cur_year_pnl[1]) array.push(year_time, time[1]) array.push(year_bh , cur_year_bh[1]) // Quarterly P&L Table var quarterly_table = table(na) getCellColor(pnl, bh) => if pnl > 0 if bh < 0 or pnl > 2 * bh color.new(color.green, transp = 20) else if pnl > bh color.new(color.green, transp = 50) else color.new(color.green, transp = 80) else if bh > 0 or pnl < 2 * bh color.new(color.red, transp = 20) else if pnl < bh color.new(color.red, transp = 50) else color.new(color.red, transp = 80) if (end_time and enableQuarterlyTable) quarterly_table := table.new(table_position, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1) table.cell(quarterly_table, 0, 0, "", bgcolor = #cccccc) table.cell(quarterly_table, 1, 0, "Q1", bgcolor = #cccccc) table.cell(quarterly_table, 2, 0, "Q2", bgcolor = #cccccc) table.cell(quarterly_table, 3, 0, "Q3", bgcolor = #cccccc) table.cell(quarterly_table, 4, 0, "Q4", bgcolor = #cccccc) table.cell(quarterly_table, 5, 0, "Year", bgcolor = #999999) for yi = 0 to array.size(year_pnl) - 1 table.cell(quarterly_table, 0, yi + 1, tostring(year(array.get(year_time, yi))), bgcolor = #cccccc) y_color = getCellColor(array.get(year_pnl, yi), array.get(year_bh, yi)) table.cell(quarterly_table, 5, yi + 1, enableCompareWithMarket ? tostring(round(array.get(year_pnl, yi) * 100, precision)) + " (" + tostring(round(array.get(year_bh, yi) * 100, precision)) + ")" : tostring(round(array.get(year_pnl, yi) * 100, precision)), bgcolor = y_color, text_color=#bfbfbf) for mi = 0 to array.size(quarter_time) - 1 m_row = year(array.get(quarter_time, mi)) - year(array.get(year_time, 0)) + 1 m_col = ceil(month(array.get(quarter_time, mi)) / 3) m_color = getCellColor(array.get(quarter_pnl, mi), array.get(quarter_bh, mi)) table.cell(quarterly_table, m_col, m_row, enableCompareWithMarket ? tostring(round(array.get(quarter_pnl, mi) * 100, precision)) + " (" + tostring(round(array.get(quarter_bh, mi) * 100,precision)) +")" : tostring(round(array.get(quarter_pnl, mi) * 100, precision)), bgcolor = m_color, text_color=#bfbfbf)