Strategi ini menggunakan dua moving average dengan pengaturan parameter yang berbeda untuk operasi crossover untuk menentukan arah tren dan posisi terbuka / dekat. Strategi ini memungkinkan memilih dari 9 jenis moving average yang berbeda, termasuk Simple Moving Average (SMA), Exponential Moving Average (EMA), Weighted Moving Average (WMA), Arnaud Legoux Moving Average (ALMA), Volume Weighted Moving Average (VWMA), dll. Strategi ini juga menetapkan stop loss dan take profit level.
Logika inti dari strategi ini adalah untuk membandingkan nilai dua garis rata-rata bergerak dan menentukan arah tren pasar berdasarkan persilangan mereka. Secara khusus, kita menetapkan garis cepat dan garis lambat menggunakan dua rata-rata bergerak. Ketika garis cepat melintasi di atas garis lambat, kita percaya pasar berada dalam tren naik dan pergi panjang. Ketika garis cepat melintasi di bawah garis lambat, kita percaya pasar berada dalam tren menurun dan pergi pendek.
Setelah memasuki posisi, jika harga menyentuh garis stop loss, kita keluar dari posisi untuk memotong kerugian. Jika harga menyentuh garis take profit, kita keluar dari posisi untuk mengunci keuntungan seperti yang diharapkan. Ini memungkinkan kita untuk mengunci keuntungan dan mencegah kerugian berkembang lebih lanjut.
Dari logika kode, strategi dapat dibagi menjadi empat bagian:
Menghitung rata-rata bergerak Berdasarkan pilihan pengguna dari jenis rata-rata bergerak, menghitung rata-rata bergerak garis cepat dan garis lambat.
Menghasilkan sinyal perdagangan Menghasilkan sinyal panjang dan pendek berdasarkan situasi silang dari jalur cepat dan jalur lambat.
Atur tingkat stop loss dan take profit. Berdasarkan harga masuk dan persentase stop loss / take profit yang ditetapkan, hitung tingkat stop loss dan take profit secara real time.
Masuk dan keluar. Masuk berdasarkan sinyal panjang/pendek, keluar berdasarkan sinyal stop loss/take profit.
Keuntungan terbesar dari strategi ini adalah bahwa ia memungkinkan untuk memilih secara bebas dari berbagai jenis rata-rata bergerak. Berbagai jenis rata-rata bergerak memiliki sensitivitas yang berbeda terhadap harga. Pengguna dapat memilih rata-rata bergerak yang sesuai berdasarkan kebutuhan mereka sendiri. Selain itu, panjang rata-rata bergerak dapat disesuaikan untuk mengoptimalkan dimensi waktu.
Keuntungan lain adalah bahwa mekanisme stop loss dan take profit ditetapkan. Ini dapat secara efektif mencegah kerugian lebih lanjut dan mengunci keuntungan. Secara keseluruhan, strategi ini cukup fleksibel dengan kemampuan penyesuaian yang tinggi, cocok untuk pengguna dengan kebutuhan yang berbeda.
Risiko utama dari strategi ini adalah bahwa rata-rata bergerak memiliki keterlambatan. Ketika harga tiba-tiba berfluktuasi dengan ganas, rata-rata bergerak tidak dapat merespons tepat waktu, yang dapat menyebabkan kehilangan waktu masuk atau keluar terbaik. Ini dapat menyebabkan kerugian besar.
Risiko lain adalah pengaturan level stop loss dan take profit. Jika kisaran terlalu kecil, mungkin rentan terhadap scalpers. Jika terlalu besar, mudah untuk gagal mengunci keuntungan tepat waktu. Oleh karena itu, parameter stop loss / take profit perlu dioptimalkan sesuai dengan kondisi pasar selama perdagangan langsung.
Secara umum, strategi ini terutama bergantung pada moving average untuk menentukan arah tren. sehingga efektivitasnya dapat dikompromikan ketika peristiwa tiba-tiba menyebabkan perubahan harga yang besar. Selain itu, pengaturan parameter juga dapat memiliki dampak besar pada pengembalian strategi.
Strategi ini dapat dioptimalkan dalam aspek berikut:
Optimalkan jenis rata-rata bergerak. Pilih rata-rata bergerak yang lebih cocok berdasarkan lingkungan pasar dan produk perdagangan yang berbeda.
Mengoptimalkan parameter rata-rata bergerak, menyesuaikan panjang rata-rata bergerak agar lebih sesuai dengan karakteristik pasar.
Tambahkan indikator lain untuk penyaringan. MACD, RSI dan indikator lainnya dapat ditambahkan untuk menghindari perdagangan yang sering ketika tidak ada tren yang jelas.
Mengoptimalkan rasio stop loss/take profit Menghitung parameter stop loss/take profit yang optimal berdasarkan data historis.
Tambahkan model pembelajaran mesin. Gunakan LSTM, algoritma hutan acak untuk memprediksi pergerakan harga dan bantuan dalam menghasilkan sinyal perdagangan.
Mengadopsi algoritma stop loss trailing. Memungkinkan garis stop loss untuk bergerak bersama dengan pergerakan harga secara bertahap untuk mengurangi kemungkinan terkena.
Secara keseluruhan, strategi ini relatif sederhana dan langsung. Strategi ini menentukan arah tren melalui crossover dan termasuk dalam strategi trend berikut yang khas. Keuntungannya adalah mudah dimengerti dan sangat fleksibel dengan jenis dan parameter rata-rata bergerak yang dapat disesuaikan. Kelemahannya adalah reaksi yang lebih lambat terhadap peristiwa mendadak dan beberapa tingkat keterlambatan. Secara umum, strategi ini cocok untuk investor yang mencari pengembalian stabil jangka panjang. Peningkatan lebih lanjut pada stabilitas dan pengembalian dapat dicapai melalui optimalisasi.
/*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)