Strategi ini adalah berdasarkan sistem persilangan purata bergerak, dengan purata bergerak yang berbeza dalam kitaran golden cross dan death cross untuk menilai masa membeli dan menjual. Strategi ini juga menggabungkan fungsi trend tracking seperti stop loss, stop loss, dan stop loss untuk mengunci keuntungan dan mengelakkan risiko.
Strategi ini menggunakan dua set rata-rata bergerak, iaitu garis cepat dan garis perlahan. Garis cepat adalah lebih pendek, mewakili trend jangka pendek; garis perlahan adalah lebih lama, mewakili trend jangka panjang. Apabila garis cepat menembusi garis perlahan dari arah bawah, ia akan menghasilkan golden cross, yang menunjukkan pergerakan dari bear ke bull, melakukan lebih banyak; dan apabila garis cepat jatuh dari arah atas ke bawah dan melanggar garis perlahan, ia akan membentuk cross kematian, yang menunjukkan pergerakan dari bull ke bear, melakukan kosong.
Dalam kod, indikator garis cepat adalah ma1 dan garis perlahan adalah ma2. Kedua-dua ma1 dan ma2 boleh memilih pelbagai jenis purata bergerak, seperti SMA, EMA, dan sebagainya, dan boleh menetapkan parameter kitaran yang berbeza. Ma1 mewakili trend jangka pendek, dengan kitaran yang lebih pendek; ma2 mewakili trend jangka panjang, dengan kitaran yang lebih lama.
Apabila ma1 garpu emas ma2, menghasilkan isyarat panjang, melakukan lebih banyak; apabila ma1 garpu mati ma2, menghasilkan isyarat pendek, kosong. Apabila perdagangan sebenar, ia boleh digabungkan dengan fungsi penjejakan trend, berhenti, dan berhenti untuk mengunci keuntungan dan mengelakkan risiko.
Strategi ini mempunyai kelebihan berikut:
Strategi ini mudah difahami dan dilaksanakan.
Rata-rata bergerak yang fleksibel untuk pelbagai jenis dan parameter yang sesuai untuk keadaan pasaran yang berbeza.
Reka bentuk pelbagai kitaran, menangkap trend jangka pendek dan jangka panjang, dan mengelakkan kesilapan.
Syarat pembukaan kedudukan boleh disesuaikan, kekerapan perdagangan dikawal ketat.
Anda boleh menetapkan keadaan hentian dan hentian untuk mengawal risiko.
Anda boleh menambah trend tracking untuk menjejaki keuntungan.
Parameter yang boleh dioptimumkan untuk menjadikan strategi lebih stabil dan boleh dipercayai.
Strategi ini juga mempunyai risiko:
Dalam kes ini, pergerakan purata bergerak berganda yang bersilang terlewat dan mungkin terlepas peluang terbaik untuk membalikkan harga.
Pergerakan purata yang tidak betul boleh menghasilkan lebih banyak isyarat palsu.
Ia boleh menyebabkan kemalangan yang tidak dijangka dan boleh menyebabkan kemalangan yang tidak dijangka.
Dalam keadaan trend, harga berkemungkinan besar berada di sebelah garis rata-rata untuk jangka masa yang lama.
Parameter tidak dioptimumkan dengan betul, mungkin terlalu dioptimumkan untuk tempoh masa tertentu.
Kaedah pengurusan risiko:
Gabungan dengan petunjuk lain, isyarat penapisan untuk mengelakkan penembusan palsu.
Tetapan kitaran harus mengikuti prinsip perdagangan trend, menguji parameter pengoptimuman.
Pengendalian risiko perlu berhati-hati, dan kedudukan hentian perlu diletakkan dengan wajar.
Ia memerlukan kesabaran untuk menunggu.
Kaedah ini digunakan untuk menguji kekuatan parameter dalam pelbagai persekitaran pasaran.
Strategi ini boleh dioptimumkan dengan:
Uji lebih banyak jenis purata bergerak, seperti purata bergerak bertimbangan.
Menambah kitaran dinamik berdasarkan kadar turun naik, menyesuaikan parameter garis purata mengikut perubahan pasaran.
Syarat kemasukan strategi boleh ditambah dengan pilihan masa atau penapisan asas untuk mengurangkan kadar kesilapan perdagangan.
Keadaan keluar boleh menetapkan hentian hentian dinamik, menyesuaikan ketinggian hentian mengikut tahap turun naik pasaran.
Anda boleh membina sistem pengoptimuman parameter untuk mengesan semula sejarah dan penyesuaian parameter strategi.
Menambah algoritma pembelajaran mesin, menggunakan AI untuk mengoptimumkan parameter dan penapisan isyarat.
Strategi bergerak rata-rata melintasi pelbagai kitaran strategi keseluruhan idea yang jelas dan mudah difahami, dengan cepat perlahan rata-rata melintasi untuk menangkap trend, adalah satu strategi trend yang lebih klasik. Strategi boleh mencapai keuntungan yang stabil dengan memilih parameter yang sesuai, mengoptimumkan masuk dan keluar logik, kawalan risiko yang ketat.
/*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)