Стратегия с несколькими периодами пересечения скользящих средних


Дата создания: 2023-10-09 16:41:04 Последнее изменение: 2023-10-09 16:41:04
Копировать: 2 Количество просмотров: 655
1
Подписаться
1621
Подписчики

Обзор

Стратегия основана на пересечении системы перемещающихся средних, с помощью перемещающихся средних различных циклов золотой крест и смерть крест, чтобы определить время покупки и продажи. Стратегия одновременно сочетает в себе функции отслеживания тенденции, такие как остановки, остановки, остановки, чтобы зафиксировать прибыль и избежать риска.

Стратегический принцип

Эта стратегия использует две группы движущихся средних: быструю и медленную. Быстрая линия имеет короткий цикл, который представляет собой краткосрочную тенденцию; медленная линия имеет длинный цикл, который представляет собой долгосрочную тенденцию.

В коде указатель быстрого курса - ma1, медленного курса - ma2. ma1 и ma2 могут выбирать различные типы скользящих средних, такие как SMA, EMA и т. д., и могут устанавливать различные параметры цикла. ma1 представляет собой краткосрочную тенденцию с более короткими циклами; ma2 представляет собой долгосрочную тенденцию с более длительными циклами.

Когда ma1 золотой форк ma2 , создает длинный сигнал, сделать больше; когда ma1 мертвый форк ma2 , создает короткий сигнал, сделать короткий. При фактической торговле, может быть объединен с функцией отслеживания тренда, остановки, остановки, чтобы закрепить прибыль и избежать риска.

Анализ преимуществ

Эта стратегия имеет следующие преимущества:

  1. Стратегическая концепция проста и понятна, легко понятна и реализуема.

  2. Гибкий выбор подвижных средних различных типов и параметров, применимых к различным рыночным условиям.

  3. Дизайн с несколькими циклами, чтобы одновременно улавливать как краткосрочные, так и долгосрочные тенденции и избегать ошибок.

  4. Условия открытия позиции могут быть настроены, а частота торгов строго контролируется.

  5. Можно установить условия для остановки и остановки, чтобы эффективно контролировать риск.

  6. Можно добавить трек-стоп, чтобы отслеживать прибыль.

  7. Оптимизируемые параметры, которые делают стратегию более стабильной и надежной.

Анализ рисков

Также существуют следующие риски:

  1. Двойная пересекающаяся средняя сама по себе отстает и может упустить наилучшее время для обратного поворота цены.

  2. Неправильно настроенный цикл скользящих средних может привести к большему количеству ложных сигналов.

  3. Внезапные события приводят к быстрому развороту, предотвращают риск пробивания.

  4. При трендовых условиях вероятность того, что цены останутся на стороне средней линии в течение длительного времени, выше.

  5. Недостаточная оптимизация параметров, возможно, переоптимизация в определенный период времени.

Соответствующие меры управления рисками:

  1. В сочетании с другими показателями фильтруют сигналы, чтобы избежать ложных прорывов.

  2. Циклическая настройка должна следовать принципу трендового трейдинга, тестировать параметры оптимизации.

  3. Контроль риска должен быть осторожным, а установка стоп-позиции - разумной.

  4. Необходимо терпеливо ждать.

  5. Тестирование прочности параметров в различных рыночных условиях.

Направление оптимизации

Эта стратегия может быть оптимизирована в следующих аспектах:

  1. Проверяйте больше типов скользящих средних, таких как весовые скользящие средние и т. д.

  2. Добавление динамических циклов, основанных на волатильности, корректировка среднелинейных параметров в соответствии с изменениями рынка.

  3. Входные условия стратегии могут включать в себя дополнительные временные или фундаментальные фильтры, снижающие уровень ошибочных сделок.

  4. В условиях выхода можно установить динамический стоп-стоп, который будет корректироваться в зависимости от степени волатильности рынка.

  5. Можно создать систему оптимизации параметров, чтобы реализовать историческую обратную связь и оптимизацию параметров стратегии.

  6. Добавление алгоритмов машинного обучения с использованием ИИ для оптимизации параметров и фильтрации сигналов.

Подвести итог

Общая концепция движущейся средней скрещивания многоциклической стратегии ясна и понятна, она захватывает тенденции с помощью быстрого и медленного среднелинейного скрещивания, это более классическая стратегия отслеживания тенденций. Стратегия может обеспечить стабильную прибыль путем выбора подходящих параметров, оптимизации логики входа и выхода из и строгого контроля риска.

Исходный код стратегии
/*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)