La estrategia se basa en un sistema de cruce de promedios móviles para determinar el momento de comprar y vender a través de promedios móviles de diferentes períodos. La estrategia también combina funciones de seguimiento de tendencias como paradas, paradas y paradas para bloquear ganancias y evitar riesgos.
La estrategia utiliza dos grupos de promedios móviles, los rápidos y los lentos. La línea rápida tiene un período más corto, que representa una tendencia a corto plazo; la línea lenta tiene un período más largo, que representa una tendencia a largo plazo. Cuando la línea rápida rompe la línea lenta desde abajo, produce un cruce dorado, que indica que el mercado cambia de lado y hace más; cuando la línea rápida cae desde arriba y rompe la línea lenta, forma un cruce de muerte, que indica que el mercado cambia de lado y hace menos.
En el código, el indicador de la línea rápida es ma1 y el de la línea lenta es ma2. Tanto ma1 como ma2 pueden elegir diferentes tipos de promedios móviles, como SMA, EMA, etc., y pueden establecer diferentes parámetros de período. 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 golden fork ma2 produce una señal larga, hace más; cuando ma1 dead fork ma2 produce una señal corta, hace falta. En el momento de la negociación real, se puede combinar la función de seguimiento de tendencias, paradas y pérdidas, para bloquear ganancias y evitar riesgos.
La estrategia tiene las siguientes ventajas:
La estrategia es simple, clara, fácil de entender y de implementar.
Una media móvil de diferentes tipos y parámetros de elección flexible para diferentes entornos de mercado.
El diseño multi-ciclo capta las tendencias a corto y largo plazo para evitar errores.
Las condiciones de apertura de posiciones se pueden personalizar, con un control estricto de la frecuencia de las transacciones.
Se pueden configurar las condiciones de parada y deterioro para controlar el riesgo de manera efectiva.
Se puede agregar un seguimiento de tendencias para el seguimiento de ganancias.
Los parámetros se pueden optimizar para que la estrategia sea más estable y confiable.
La estrategia también tiene los siguientes riesgos:
El cruce de las medias móviles dobles se retrasa y puede perder el mejor momento para que el precio se invierta.
La configuración incorrecta de la media móvil puede generar más señales falsas.
El incidente provocó una rápida reversión y detuvo el riesgo de ser derribado.
En una situación de tendencia, la probabilidad de que los precios permanezcan en el lado de la línea media durante mucho tiempo es mayor.
Optimización de parámetros incorrecta, que puede ser excesivamente optimizada para un período de tiempo determinado.
Las medidas de gestión de riesgos correspondientes:
En combinación con otros indicadores, las señales de filtración evitan falsas brechas.
La configuración del ciclo debe seguir el principio de comercio de tendencias y probar los parámetros de optimización.
El control de riesgos debe ser prudente y el ajuste de la posición de parada razonable.
El costo de la paciencia y la espera.
La robustez de los parámetros de prueba en varios entornos de mercado.
La estrategia puede ser optimizada en los siguientes aspectos:
Prueba más tipos de promedios móviles, como promedios móviles ponderados.
Aumentar el ciclo dinámico basado en la volatilidad y ajustar el parámetro de la línea media según los cambios en el mercado.
Las condiciones de entrada estratégicas pueden ser añadidas por tiempo o filtradas de manera básica para reducir la tasa de transacciones erróneas.
Las condiciones de salida pueden establecer un stop loss dinámico, ajustando el stop loss según la volatilidad del mercado.
Se puede crear un sistema de optimización de parámetros para realizar la retroalimentación histórica y la optimización de parámetros de la estrategia.
Aumentar los algoritmos de aprendizaje automático, utilizando la IA para optimizar los parámetros y filtrar las señales.
La estrategia de movimiento de la media cruzada de la línea de la media cruzada de la línea de la media para capturar la tendencia, es una estrategia de seguimiento de la tendencia más clásica. La estrategia puede lograr un beneficio estable mediante la selección de los parámetros adecuados, la optimización de la lógica de salida de entrada y salida, y el control de riesgo estricto.
/*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)