
Dalam edisi ini, kita akan membahas “strategi rata-rata pergerakan EMA ganda ajaib” dari YouTube, yang disebut sebagai “pembunuh pasar saham dan mata uang kripto.” Setelah menonton video tersebut, saya mengetahui bahwa strategi ini adalah strategi bahasa pinus pandangan perdagangan, yang menggunakan 2 indikator pandangan perdagangan. Melihat hasil pengujian ulang dalam video sangat bagus, dan FMZ juga mendukung bahasa Pine Trading View, mau tak mau saya ingin melakukan pengujian ulang dan menguji analisis sendiri. Kalau begitu, mulailah hidup sepenuhnya! Mari kita tiru strategi dalam video.
Demi kesederhanaan desain, kami tidak akan menggunakan Moving Average Exponential yang tercantum dalam video. Kami menggunakan ta.ema bawaan dalam tampilan perdagangan (sebenarnya keduanya sama).
Ini adalah indikator pada Trading View. Kita perlu masuk ke Trading View dan mengunduh kode sumbernya.

Kode Bebas Swing VuManChu:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Credits to the original Script - Range Filter DonovanWall https://www.tradingview.com/script/lut7sBgG-Range-Filter-DW/
// This version is the old version of the Range Filter with less settings to tinker with
//@version=4
study(title="Range Filter - B&S Signals", shorttitle="RF - B&S Signals", overlay=true)
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Functions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Range Size Function
rng_size(x, qty, n)=>
// AC = Cond_EMA(abs(x - x[1]), 1, n)
wper = (n*2) - 1
avrng = ema(abs(x - x[1]), n)
AC = ema(avrng, wper)*qty
rng_size = AC
//Range Filter Function
rng_filt(x, rng_, n)=>
r = rng_
var rfilt = array.new_float(2, x)
array.set(rfilt, 1, array.get(rfilt, 0))
if x - r > array.get(rfilt, 1)
array.set(rfilt, 0, x - r)
if x + r < array.get(rfilt, 1)
array.set(rfilt, 0, x + r)
rng_filt1 = array.get(rfilt, 0)
hi_band = rng_filt1 + r
lo_band = rng_filt1 - r
rng_filt = rng_filt1
[hi_band, lo_band, rng_filt]
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Inputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Range Source
rng_src = input(defval=close, type=input.source, title="Swing Source")
//Range Period
rng_per = input(defval=20, minval=1, title="Swing Period")
//Range Size Inputs
rng_qty = input(defval=3.5, minval=0.0000001, title="Swing Multiplier")
//Bar Colors
use_barcolor = input(defval=false, type=input.bool, title="Bar Colors On/Off")
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Definitions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Range Filter Values
[h_band, l_band, filt] = rng_filt(rng_src, rng_size(rng_src, rng_qty, rng_per), rng_per)
//Direction Conditions
var fdir = 0.0
fdir := filt > filt[1] ? 1 : filt < filt[1] ? -1 : fdir
upward = fdir==1 ? 1 : 0
downward = fdir==-1 ? 1 : 0
//Trading Condition
longCond = rng_src > filt and rng_src > rng_src[1] and upward > 0 or rng_src > filt and rng_src < rng_src[1] and upward > 0
shortCond = rng_src < filt and rng_src < rng_src[1] and downward > 0 or rng_src < filt and rng_src > rng_src[1] and downward > 0
CondIni = 0
CondIni := longCond ? 1 : shortCond ? -1 : CondIni[1]
longCondition = longCond and CondIni[1] == -1
shortCondition = shortCond and CondIni[1] == 1
//Colors
filt_color = upward ? #05ff9b : downward ? #ff0583 : #cccccc
bar_color = upward and (rng_src > filt) ? (rng_src > rng_src[1] ? #05ff9b : #00b36b) :
downward and (rng_src < filt) ? (rng_src < rng_src[1] ? #ff0583 : #b8005d) : #cccccc
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Outputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Filter Plot
filt_plot = plot(filt, color=filt_color, transp=67, linewidth=3, title="Filter")
//Band Plots
h_band_plot = plot(h_band, color=color.new(#05ff9b, 100), title="High Band")
l_band_plot = plot(l_band, color=color.new(#ff0583, 100), title="Low Band")
//Band Fills
fill(h_band_plot, filt_plot, color=color.new(#00b36b, 92), title="High Band Fill")
fill(l_band_plot, filt_plot, color=color.new(#b8005d, 92), title="Low Band Fill")
//Bar Color
barcolor(use_barcolor ? bar_color : na)
//Plot Buy and Sell Labels
plotshape(longCondition, title = "Buy Signal", text ="BUY", textcolor = color.white, style=shape.labelup, size = size.normal, location=location.belowbar, color = color.new(color.green, 0))
plotshape(shortCondition, title = "Sell Signal", text ="SELL", textcolor = color.white, style=shape.labeldown, size = size.normal, location=location.abovebar, color = color.new(color.red, 0))
//Alerts
alertcondition(longCondition, title="Buy Alert", message = "BUY")
alertcondition(shortCondition, title="Sell Alert", message = "SELL")
Indikator EMA: Strategi ini menggunakan dua rata-rata pergerakan EMA, satu garis cepat (parameter siklus kecil) dan satu garis lambat (parameter siklus besar). Fungsi utama rata-rata pergerakan EMA ganda adalah untuk membantu kita menentukan arah tren pasar.
Pengaturan panjang Garis cepat berada di atas garis lambat.
Pengaturan pendek Garis cepat berada di bawah garis lambat.
Indikator VuManChu Swing Free: Indikator VuManChu Swing Free digunakan untuk mengirimkan sinyal, dan kemudian dikombinasikan dengan kondisi lain untuk menentukan apakah akan mengajukan pesanan perdagangan. Dari kode sumber indikator VuManChu Swing Free, kita dapat melihat bahwa variabel longCondition mewakili sinyal beli, dan variabel shortCondition mewakili sinyal jual. Kedua variabel ini akan digunakan saat menulis kondisi pesanan nanti.
Sekarang mari kita bicarakan tentang kondisi pemicu sinyal perdagangan spesifik dari strategi ini:
Aturan untuk memasuki posisi panjang: Harga penutupan garis K positif harus berada di atas garis cepat EMA, dua rata-rata pergerakan EMA harus berada dalam pengaturan bullish (garis cepat berada di atas garis lambat), dan indikator VuManChu Swing Free harus menunjukkan sinyal beli. (longCondition bernilai benar). Apabila ketiga kondisi tersebut terpenuhi, maka garis K ini merupakan garis K kunci untuk memasuki posisi long, dan harga penutupan garis K ini merupakan posisi masuk.
Aturan untuk memasuki posisi short (berlawanan dengan posisi long): Harga penutupan candlestick negatif harus berada di bawah garis EMA cepat, dua moving average EMA harus berada dalam posisi short (garis cepat berada di bawah garis lambat), dan indikator VuManChu Swing Free harus menunjukkan sinyal jual (shortCondition benar). Apabila ketiga kondisi tersebut terpenuhi, maka harga penutupan garis K ini merupakan titik masuk untuk melakukan penjualan pendek.
Bukankah logika perdagangannya sangat sederhana? Karena video sumber tidak menentukan take-profit dan stop-loss, editor akan menggunakan metode take-profit dan stop-loss yang lebih moderat, menggunakan stop loss titik tetap dan pelacakan mengambil untung.
Kami memasukkan kode indikator VuManChu Swing Free langsung ke dalam kode strategi kami tanpa perubahan apa pun.

Kemudian kita menulis sepotong kode bahasa Pine untuk mengimplementasikan fungsi transaksi:
// extend
fastEmaPeriod = input(50, "fastEmaPeriod") // 快线周期
slowEmaPeriod = input(200, "slowEmaPeriod") // 慢线周期
loss = input(30, "loss") // 止损点数
trailPoints = input(30, "trailPoints") // 移动止盈触发点数
trailOffset = input(30, "trailOffset") // 移动止盈偏移量(点数)
amount = input(1, "amount") // 下单量
emaFast = ta.ema(close, fastEmaPeriod) // 计算快线EMA
emaSlow = ta.ema(close, slowEmaPeriod) // 计算慢线EMA
buyCondition = longCondition and emaFast > emaSlow and close > open and close > emaFast // 做多入场条件
sellCondition = shortCondition and emaFast < emaSlow and close < open and close < emaFast // 做空入场条件
if buyCondition and strategy.position_size == 0
strategy.entry("long", strategy.long, amount)
strategy.exit("exit_long", "long", amount, loss=loss, trail_points=trailPoints, trail_offset=trailOffset)
if sellCondition and strategy.position_size == 0
strategy.entry("short", strategy.short, amount)
strategy.exit("exit_short", "short", amount, loss=loss, trail_points=trailPoints, trail_offset=trailOffset)
A. Seperti yang Anda lihat, ketika buyCondition bernilai true:
- Variabel longCondition bernilai true (indikator VuManChu Swing Free mengirimkan sinyal untuk mengambil posisi long).
- emaFast > emaSlow (pengaturan bullish EMA).
- tutup > buka (menunjukkan bahwa BAR saat ini adalah garis positif), tutup > emaFast (menunjukkan bahwa harga penutupan berada di atas garis cepat EMA).
Ketiga syarat untuk bertindak panjang terpenuhi.
B. Bila sellCondition bernilai true, maka ketiga kondisi untuk short selling terpenuhi (tidak dijelaskan di sini).
Kemudian, ketika kondisi if menentukan bahwa sinyal dipicu, gunakan fungsi strategy.entry untuk memasuki pasar dan membuka posisi, dan atur fungsi strategy.exit untuk menghentikan kerugian dan trailing profit.
/*backtest
start: 2022-01-01 00:00:00
end: 2022-10-08 00:00:00
period: 15m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
args: [["ZPrecision",0,358374]]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Credits to the original Script - Range Filter DonovanWall https://www.tradingview.com/script/lut7sBgG-Range-Filter-DW/
// This version is the old version of the Range Filter with less settings to tinker with
//@version=4
study(title="Range Filter - B&S Signals", shorttitle="RF - B&S Signals", overlay=true)
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Functions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Range Size Function
rng_size(x, qty, n)=>
// AC = Cond_EMA(abs(x - x[1]), 1, n)
wper = (n*2) - 1
avrng = ema(abs(x - x[1]), n)
AC = ema(avrng, wper)*qty
rng_size = AC
//Range Filter Function
rng_filt(x, rng_, n)=>
r = rng_
var rfilt = array.new_float(2, x)
array.set(rfilt, 1, array.get(rfilt, 0))
if x - r > array.get(rfilt, 1)
array.set(rfilt, 0, x - r)
if x + r < array.get(rfilt, 1)
array.set(rfilt, 0, x + r)
rng_filt1 = array.get(rfilt, 0)
hi_band = rng_filt1 + r
lo_band = rng_filt1 - r
rng_filt = rng_filt1
[hi_band, lo_band, rng_filt]
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Inputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Range Source
rng_src = input(defval=close, type=input.source, title="Swing Source")
//Range Period
rng_per = input(defval=20, minval=1, title="Swing Period")
//Range Size Inputs
rng_qty = input(defval=3.5, minval=0.0000001, title="Swing Multiplier")
//Bar Colors
use_barcolor = input(defval=false, type=input.bool, title="Bar Colors On/Off")
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Definitions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Range Filter Values
[h_band, l_band, filt] = rng_filt(rng_src, rng_size(rng_src, rng_qty, rng_per), rng_per)
//Direction Conditions
var fdir = 0.0
fdir := filt > filt[1] ? 1 : filt < filt[1] ? -1 : fdir
upward = fdir==1 ? 1 : 0
downward = fdir==-1 ? 1 : 0
//Trading Condition
longCond = rng_src > filt and rng_src > rng_src[1] and upward > 0 or rng_src > filt and rng_src < rng_src[1] and upward > 0
shortCond = rng_src < filt and rng_src < rng_src[1] and downward > 0 or rng_src < filt and rng_src > rng_src[1] and downward > 0
CondIni = 0
CondIni := longCond ? 1 : shortCond ? -1 : CondIni[1]
longCondition = longCond and CondIni[1] == -1
shortCondition = shortCond and CondIni[1] == 1
//Colors
filt_color = upward ? #05ff9b : downward ? #ff0583 : #cccccc
bar_color = upward and (rng_src > filt) ? (rng_src > rng_src[1] ? #05ff9b : #00b36b) :
downward and (rng_src < filt) ? (rng_src < rng_src[1] ? #ff0583 : #b8005d) : #cccccc
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Outputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Filter Plot
filt_plot = plot(filt, color=filt_color, transp=67, linewidth=3, title="Filter")
//Band Plots
h_band_plot = plot(h_band, color=color.new(#05ff9b, 100), title="High Band")
l_band_plot = plot(l_band, color=color.new(#ff0583, 100), title="Low Band")
//Band Fills
fill(h_band_plot, filt_plot, color=color.new(#00b36b, 92), title="High Band Fill")
fill(l_band_plot, filt_plot, color=color.new(#b8005d, 92), title="Low Band Fill")
//Bar Color
barcolor(use_barcolor ? bar_color : na)
//Plot Buy and Sell Labels
plotshape(longCondition, title = "Buy Signal", text ="BUY", textcolor = color.white, style=shape.labelup, size = size.normal, location=location.belowbar, color = color.new(color.green, 0))
plotshape(shortCondition, title = "Sell Signal", text ="SELL", textcolor = color.white, style=shape.labeldown, size = size.normal, location=location.abovebar, color = color.new(color.red, 0))
//Alerts
alertcondition(longCondition, title="Buy Alert", message = "BUY")
alertcondition(shortCondition, title="Sell Alert", message = "SELL")
// extend
fastEmaPeriod = input(50, "fastEmaPeriod")
slowEmaPeriod = input(200, "slowEmaPeriod")
loss = input(30, "loss")
trailPoints = input(30, "trailPoints")
trailOffset = input(30, "trailOffset")
amount = input(1, "amount")
emaFast = ta.ema(close, fastEmaPeriod)
emaSlow = ta.ema(close, slowEmaPeriod)
buyCondition = longCondition and emaFast > emaSlow and close > open and close > emaFast
sellCondition = shortCondition and emaFast < emaSlow and close < open and close < emaFast
if buyCondition and strategy.position_size == 0
strategy.entry("long", strategy.long, amount)
strategy.exit("exit_long", "long", amount, loss=loss, trail_points=trailPoints, trail_offset=trailOffset)
if sellCondition and strategy.position_size == 0
strategy.entry("short", strategy.short, amount)
strategy.exit("exit_short", "short", amount, loss=loss, trail_points=trailPoints, trail_offset=trailOffset)
Rentang waktu pengujian ulang dipilih dari Januari 2022 hingga Oktober 2022, periode K-line adalah 15 menit, dan model harga penutupan digunakan untuk pengujian ulang. Pasar memilih kontrak berjangka ETH_USDT Binance. Pengaturan parameter sebagaimana dinyatakan dalam video sumber: 50 periode untuk jalur cepat dan 200 periode untuk jalur lambat, dan parameter lainnya tetap tidak berubah secara default. Saya agak subjektif mengenai titik stop loss dan trailing profit dan hanya menetapkannya di 30 poin.


Hasil backtest-nya biasa saja. Setelah beberapa kali backtest, tampaknya parameter seperti take-profit dan stop-loss memiliki pengaruh terhadap hasil backtest. Saya merasa aspek ini perlu pengoptimalan lebih lanjut. Namun, tingkat kemenangan masih bagus setelah sinyal strategi memicu transaksi.
Mari kita coba kontrak perpetual BTC_USDT:

Hasil backtest pada BTC juga eksplosif:


Alamat strategi: https://www.fmz.com/strategy/385745
Tampaknya metode perdagangan ini cukup andal untuk memahami tren, dan desainnya dapat dioptimalkan lebih lanjut berdasarkan ide ini. Dalam artikel ini, kita tidak hanya mempelajari ide strategi rata-rata pergerakan ganda, tetapi juga mempelajari cara memproses dan mempelajari strategi para master di YouTube. Oke, kode strategi di atas hanyalah saran saya. Hasil backtest tidak mewakili hasil aktual yang spesifik. Kode strategi dan desain hanya untuk referensi. Terima kasih atas dukungan Anda, sampai jumpa di lain waktu!