Strategi ini berdasarkan sistem crossover purata bergerak, menggunakan salib emas dan salib kematian purata bergerak dalam jangka masa yang berbeza untuk menentukan titik masuk dan keluar.
Strategi ini menggunakan dua set purata bergerak, MA pantas dan MA perlahan. MA pantas mempunyai tempoh yang lebih pendek untuk menangkap trend jangka pendek, sementara MA perlahan mempunyai tempoh yang lebih lama untuk trend jangka panjang. Apabila MA pantas melintasi di atas MA perlahan, salib emas berlaku, menandakan trend menaik. Apabila MA pantas melintasi di bawah MA perlahan, salib kematian berlaku, menandakan trend menurun.
Dalam kod, MA pantas adalah ma1, MA perlahan adalah ma2. Kedua-dua ma1 dan ma2 boleh menjadi jenis yang berbeza seperti SMA, EMA, dengan tempoh yang boleh disesuaikan. ma1 mewakili trend jangka pendek dengan tempoh yang lebih pendek, ma2 mewakili trend jangka panjang dengan tempoh yang lebih lama.
Apabila ma1 emas melintasi ma2, isyarat panjang dihasilkan. Apabila ma1 kematian melintasi ma2, isyarat pendek dihasilkan. Dalam perdagangan sebenar, ciri-ciri seperti trailing stop loss, mengambil keuntungan dan stop loss boleh ditambah untuk mengunci keuntungan dan mengawal risiko.
Strategi ini mempunyai kelebihan berikut:
Logik yang mudah difahami.
Fleksibel dalam memilih pelbagai jenis dan parameter MA untuk keadaan pasaran yang berbeza.
Reka bentuk pelbagai jangka masa untuk menangkap kedua-dua trend jangka pendek dan jangka panjang.
Peraturan kemasukan yang boleh disesuaikan untuk mengawal kekerapan perdagangan dengan ketat.
Stop loss yang boleh dikonfigurasikan dan mengambil keuntungan untuk menguruskan risiko dengan berkesan.
Stop loss trend membolehkan keuntungan untuk berjalan.
Parameter yang boleh dioptimumkan untuk lebih kukuh.
Strategi ini juga mempunyai risiko berikut:
Isu yang tertinggal dari crossover MA berganda mungkin terlepas masa pembalikan yang terbaik.
Tempoh MA yang tidak betul boleh menghasilkan lebih banyak isyarat palsu.
Pembalikan tiba-tiba boleh mencapai stop loss.
Harga boleh kekal di satu sisi MA untuk jangka masa yang panjang di pasaran trend.
Optimizasi berlebihan atas parameter yang dipasang.
Langkah pengurusan risiko:
Tambah penapis untuk mengelakkan isyarat kabur palsu.
Uji dan optimumkan tempoh MA berdasarkan prinsip perdagangan.
Kawalan risiko yang teliti dan penempatan stop loss yang munasabah.
Terima kos kesabaran yang diperlukan.
Ujian ketahanan di bawah keadaan pasaran yang berbeza.
Strategi ini boleh ditingkatkan dari aspek berikut:
Uji lebih banyak jenis MA, seperti purata bergerak yang ditimbang.
Tambah tempoh dinamik berdasarkan turun naik.
Tambah penapis seperti masa dan asas kepada peraturan kemasukan.
Gunakan hentian penyesuaian yang menyesuaikan diri dengan turun naik pasaran.
Membina sistem pengoptimuman parameter untuk backtesting.
Menggabungkan pembelajaran mesin untuk mengoptimumkan parameter dan isyarat penapis.
Kesimpulannya, strategi crossover purata bergerak ini mempunyai logik yang mudah dan jelas untuk mengikuti trend menggunakan crossover MA yang cepat dan perlahan. Dengan pemilihan parameter yang betul, peraturan kemasukan / keluar yang dioptimumkan dan kawalan risiko, ia dapat mencapai keuntungan yang stabil. Walau bagaimanapun, pengguna perlu mentolerir risiko yang tertinggal dan kos masa menunggu. Secara keseluruhan, ia adalah strategi yang mudah dan praktikal yang bernilai pengoptimuman dan kawalan risiko untuk menyesuaikan diri dengan lebih banyak keadaan pasaran.
/*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)