Strategi ini menggunakan dua purata bergerak dengan tetapan parameter yang berbeza untuk operasi silang untuk menentukan arah trend dan kedudukan terbuka / dekat. Strategi ini membolehkan memilih dari 9 jenis purata bergerak yang berbeza, termasuk Purata Bergerak Sederhana (SMA), Purata Bergerak Eksponensial (EMA), Purata Bergerak Bertimbang (WMA), Purata Bergerak Arnaud Legoux (ALMA), Purata Bergerak Bertimbang Volume (VWMA), dll. Strategi ini juga menetapkan tahap stop loss dan mengambil keuntungan.
Logik teras strategi ini adalah untuk membandingkan nilai dua garis purata bergerak dan menentukan arah trend pasaran berdasarkan persilangan mereka. Khususnya, kita menetapkan garis pantas dan garis perlahan menggunakan dua purata bergerak. Apabila garis pantas melintasi di atas garis perlahan, kita percaya pasaran berada dalam trend menaik dan pergi panjang. Apabila garis pantas melintasi di bawah garis perlahan, kita percaya pasaran berada dalam trend menurun dan pergi pendek.
Selepas memasuki kedudukan, jika harga menyentuh garisan stop loss, kita keluar dari kedudukan untuk memotong kerugian. Jika harga menyentuh garisan mengambil keuntungan, kita keluar dari kedudukan untuk mengunci keuntungan seperti yang dijangkakan. Ini membolehkan kita mengunci keuntungan dan mencegah kerugian berkembang lebih lanjut.
Dari logik kod, strategi boleh dibahagikan kepada empat bahagian:
Mengira purata bergerak. Berdasarkan pilihan pengguna jenis purata bergerak, mengira purata bergerak garis pantas dan garis perlahan.
Menghasilkan isyarat perdagangan. Menghasilkan isyarat panjang dan pendek berdasarkan situasi persilangan garis cepat dan garis perlahan.
Tetapkan paras stop loss dan mengambil keuntungan. Berdasarkan harga masuk dan peratusan stop loss / mengambil keuntungan yang ditetapkan, mengira paras stop loss dan mengambil keuntungan dalam masa nyata.
Masuk dan keluar. Masuk berdasarkan isyarat panjang/pendek, keluar berdasarkan isyarat stop loss/take profit.
Kelebihan terbesar strategi ini ialah ia membolehkan memilih secara bebas dari pelbagai jenis purata bergerak. Pelbagai jenis purata bergerak mempunyai kepekaan yang berbeza terhadap harga. Pengguna boleh memilih purata bergerak yang sesuai berdasarkan keperluan mereka sendiri. Di samping itu, panjang purata bergerak boleh disesuaikan untuk mengoptimumkan dimensi masa.
Satu lagi kelebihan adalah bahawa mekanisme stop loss dan mengambil keuntungan ditetapkan. Ini dapat secara berkesan mencegah kerugian lebih lanjut dan mengunci keuntungan. Secara keseluruhan, strategi ini agak fleksibel dengan penyesuaian yang tinggi, sesuai untuk pengguna dengan keperluan yang berbeza.
Risiko utama strategi ini adalah bahawa purata bergerak mempunyai kelewatan. Apabila harga tiba-tiba turun naik secara ganas, purata bergerak tidak dapat bertindak balas tepat pada masanya, yang boleh menyebabkan kehilangan masa masuk atau keluar yang terbaik. Ini boleh menyebabkan kerugian besar.
Risiko lain ialah menetapkan tahap stop loss dan mengambil keuntungan. Jika julatnya terlalu kecil, ia mungkin terdedah kepada scalpers. Jika terlalu besar, mudah untuk gagal mengunci keuntungan tepat pada masanya. Oleh itu, parameter stop loss / take profit perlu dioptimumkan mengikut keadaan pasaran semasa perdagangan langsung.
Secara umum, strategi ini terutamanya bergantung kepada purata bergerak untuk menentukan arah trend. jadi keberkesanannya boleh dikompromikan apabila peristiwa tiba-tiba menyebabkan perubahan harga yang besar.
Strategi ini boleh dioptimumkan dalam aspek berikut:
Mengoptimumkan jenis purata bergerak. Pilih purata bergerak yang lebih sesuai berdasarkan persekitaran pasaran dan produk perdagangan yang berbeza.
Mengoptimumkan parameter purata bergerak. Sesuaikan panjang purata bergerak untuk menjadikannya lebih sesuai dengan ciri pasaran.
Tambah penunjuk lain untuk penapisan. MACD, RSI dan penunjuk lain boleh ditambah untuk mengelakkan perdagangan yang kerap apabila tidak ada trend yang jelas.
Mengoptimumkan nisbah stop loss / mengambil keuntungan. Mengira parameter stop loss / mengambil keuntungan yang optimum berdasarkan data sejarah.
Tambah model pembelajaran mesin. Gunakan LSTM, algoritma hutan rawak untuk meramalkan pergerakan harga dan bantuan dalam menjana isyarat perdagangan.
Mengambil algoritma stop loss yang mengikuti. Membolehkan garis stop loss bergerak bersama pergerakan harga secara beransur-ansur untuk mengurangkan kebarangkalian dipukul.
Secara keseluruhan, strategi ini agak mudah dan mudah. Ia menentukan arah trend melalui persilangan dan tergolong dalam strategi trend berikut yang biasa. Kelebihannya adalah mudah difahami dan sangat fleksibel dengan jenis dan parameter purata bergerak yang boleh disesuaikan. Kelemahannya adalah tindak balas yang lebih perlahan terhadap peristiwa tiba-tiba dan beberapa tahap kelewatan. Secara umum, strategi ini sesuai untuk pelabur yang mencari pulangan yang stabil dalam jangka panjang. Penambahbaikan lebih lanjut mengenai kestabilan dan pulangan dapat dicapai melalui pengoptimuman.
/*backtest start: 2022-12-26 00:00:00 end: 2024-01-01 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=3 strategy("Kozlod - Yet Another Moving Average Cross Strategy", shorttitle="kozlod_yamacs", overlay = true) // // author: Kozlod // date: 2018-03-06 // //////////// // INPUTS // //////////// ma_type = input(title = "MA Type", defval = "SMA", options = ['SMA', 'EMA', 'WMA', 'ALMA', 'VWMA', 'HMA', 'LSMA', 'SMMA', 'DEMA']) short_ma_len = input(title = "Short MA Length", defval = 5, minval = 1) short_ma_src = input(title = "Short MA Source", defval = close) long_ma_len = input(title = "Long MA Length", defval = 15, minval = 2) long_ma_src = input(title = "Long MA Source", defval = close) alma_offset = input(title = "ALMA Offset", type = float, defval = 0.85, step = 0.01, minval = 0, maxval = 1) alma_sigma = input(title = "ALMA Sigma", type = float, defval = 6, step = 0.01) lsma_offset = input(title = "LSMA Offset", defval = 0, step = 1) sl_lev_perc = input(title = "SL Level % (0 - Off)", type = float, defval = 0, minval = 0, step = 0.01) pt_lev_perc = input(title = "PT Level % (0 - Off)", type = float, defval = 0, minval = 0, step = 0.01) // Set initial values to 0 short_ma = 0.0 long_ma = 0.0 // Simple Moving Average (SMA) if ma_type == 'SMA' short_ma := sma(short_ma_src, short_ma_len) long_ma := sma(long_ma_src, long_ma_len) // Exponential Moving Average (EMA) if ma_type == 'EMA' short_ma := ema(short_ma_src, short_ma_len) long_ma := ema(long_ma_src, long_ma_len) // Weighted Moving Average (WMA) if ma_type == 'WMA' short_ma := wma(short_ma_src, short_ma_len) long_ma := wma(long_ma_src, long_ma_len) // Arnaud Legoux Moving Average (ALMA) if ma_type == 'ALMA' short_ma := alma(short_ma_src, short_ma_len, alma_offset, alma_sigma) long_ma := alma(long_ma_src, long_ma_len, alma_offset, alma_sigma) // Hull Moving Average (HMA) if ma_type == 'HMA' short_ma := wma(2*wma(short_ma_src, short_ma_len/2)-wma(short_ma_src, short_ma_len), round(sqrt(short_ma_len))) long_ma := wma(2*wma(long_ma_src, long_ma_len /2)-wma(long_ma_src, long_ma_len), round(sqrt(long_ma_len))) // Volume-weighted Moving Average (VWMA) if ma_type == 'VWMA' short_ma := vwma(short_ma_src, short_ma_len) long_ma := vwma(long_ma_src, long_ma_len) // Least Square Moving Average (LSMA) if ma_type == 'LSMA' short_ma := linreg(short_ma_src, short_ma_len, lsma_offset) long_ma := linreg(long_ma_src, long_ma_len, lsma_offset) // Smoothed Moving Average (SMMA) if ma_type == 'SMMA' short_ma := na(short_ma[1]) ? sma(short_ma_src, short_ma_len) : (short_ma[1] * (short_ma_len - 1) + short_ma_src) / short_ma_len long_ma := na(long_ma[1]) ? sma(long_ma_src, long_ma_len) : (long_ma[1] * (long_ma_len - 1) + long_ma_src) / long_ma_len // Double Exponential Moving Average (DEMA) if ma_type == 'DEMA' e1_short = ema(short_ma_src, short_ma_len) e1_long = ema(long_ma_src, long_ma_len) short_ma := 2 * e1_short - ema(e1_short, short_ma_len) long_ma := 2 * e1_long - ema(e1_long, long_ma_len) ///////////// // SIGNALS // ///////////// long_signal = crossover( short_ma, long_ma) short_signal = crossunder(short_ma, long_ma) // Calculate PT/SL levels // Initial values last_signal = 0 prev_tr_price = 0.0 pt_level = 0.0 sl_level = 0.0 // Calculate previous trade price prev_tr_price := long_signal[1] or short_signal[1] ? open : nz(last_signal[1]) != 0 ? prev_tr_price[1] : na // Calculate SL/PT levels pt_level := nz(last_signal[1]) == 1 ? prev_tr_price * (1 + pt_lev_perc / 100) : nz(last_signal[1]) == -1 ? prev_tr_price * (1 - pt_lev_perc / 100) : na sl_level := nz(last_signal[1]) == 1 ? prev_tr_price * (1 - sl_lev_perc / 100) : nz(last_signal[1]) == -1 ? prev_tr_price * (1 + sl_lev_perc / 100) : na // Calculate if price hit sl/pt long_hit_pt = pt_lev_perc > 0 and nz(last_signal[1]) == 1 and close >= pt_level long_hit_sl = sl_lev_perc > 0 and nz(last_signal[1]) == 1 and close <= sl_level short_hit_pt = pt_lev_perc > 0 and nz(last_signal[1]) == -1 and close <= pt_level short_hit_sl = sl_lev_perc > 0 and nz(last_signal[1]) == -1 and close >= sl_level // What is last active trade? last_signal := long_signal ? 1 : short_signal ? -1 : long_hit_pt or long_hit_sl or short_hit_pt or short_hit_sl ? 0 : nz(last_signal[1]) ////////////// // PLOTTING // ////////////// // Plot MAs plot(short_ma, color = red, linewidth = 2) plot(long_ma, color = green, linewidth = 2) // Plot Levels plotshape(prev_tr_price, style = shape.cross, color = gray, location = location.absolute, size = size.small) plotshape(sl_lev_perc > 0 ? sl_level : na, style = shape.cross, color = red, location = location.absolute, size = size.small) plotshape(pt_lev_perc > 0 ? pt_level : na, style = shape.cross, color = green, location = location.absolute, size = size.small) ////////////// // STRATEGY // ////////////// strategy.entry("long", true, when = long_signal) strategy.entry("short", false, when = short_signal) strategy.close("long", when = long_hit_pt or long_hit_sl) strategy.close("short", when = short_hit_pt or short_hit_sl)