"Chiến lược đường trung bình động EMA đôi kỳ diệu" từ YouTube Master
Trong số này, chúng ta sẽ thảo luận về "chiến lược đường trung bình động EMA kép kỳ diệu" từ YouTube, được gọi là "kẻ giết chết thị trường chứng khoán và tiền điện tử". Sau khi xem video, tôi biết rằng chiến lược này là chiến lược ngôn ngữ giao dịch Pine, sử dụng 2 chỉ báo giao dịch. Khi thấy kết quả kiểm tra ngược trong video rất tốt và FMZ cũng hỗ trợ ngôn ngữ Pine của Trading View, tôi không thể không muốn tự mình kiểm tra và phân tích. Sau đó bắt đầu toàn bộ cuộc sống! Chúng ta hãy cùng thực hiện lại chiến lược trong video.
Các chỉ số được sử dụng bởi chiến lược
- Chỉ báo EMA
Để đơn giản hóa thiết kế, chúng ta sẽ không sử dụng Đường trung bình động mũ được liệt kê trong video. Thay vào đó, chúng tôi sử dụng ta.ema tích hợp sẵn trong chế độ xem giao dịch (thực ra chúng giống nhau).
- Chỉ báo VuManChu Swing Free
Đây là một chỉ báo trên Trading View. Chúng ta cần vào Trading View và tải xuống mã nguồn.
Mã miễn phí VuManChu Swing:
pine
// 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")
Chiến lược Logic
Chỉ báo EMA: Chiến lược này sử dụng hai đường trung bình động EMA, một đường nhanh (tham số chu kỳ nhỏ) và một đường chậm (tham số chu kỳ lớn). Chức năng chính của đường trung bình động EMA kép là giúp chúng ta xác định hướng của xu hướng thị trường.
-
Sắp xếp dài
Đường nhanh nằm phía trên đường chậm. -
Sắp xếp ngắn
Đường nhanh nằm bên dưới đường chậm.
Chỉ báo VuManChu Swing Free: Chỉ báo VuManChu Swing Free được sử dụng để phát tín hiệu, sau đó kết hợp với các điều kiện khác để xác định có nên đặt lệnh giao dịch hay không. Từ mã nguồn chỉ báo VuManChu Swing Free, chúng ta có thể thấy rằng biến longCondition biểu thị tín hiệu mua và biến shortCondition biểu thị tín hiệu bán. Hai biến này sẽ được sử dụng khi viết điều kiện thứ tự sau này.
Bây giờ chúng ta hãy nói về các điều kiện kích hoạt tín hiệu giao dịch cụ thể của chiến lược:
-
Quy tắc vào lệnh mua:
Giá đóng cửa của đường K dương phải nằm trên đường nhanh EMA, hai đường trung bình động EMA phải nằm trong một sắp xếp tăng giá (đường nhanh nằm trên đường chậm) và chỉ báo VuManChu Swing Free phải hiển thị tín hiệu mua. (longCondition là đúng). Nếu đáp ứng được cả ba điều kiện, đường K này chính là đường K quan trọng để vào vị thế mua và giá đóng cửa của đường K này chính là vị thế vào. -
Quy tắc vào vị thế bán khống (ngược lại với vị thế mua):
Giá đóng cửa của nến âm phải nằm dưới đường EMA nhanh, hai đường trung bình động EMA phải ở vị thế bán (đường nhanh nằm dưới đường chậm) và chỉ báo VuManChu Swing Free phải hiển thị tín hiệu bán (shortCondition là đúng). Nếu đáp ứng được cả ba điều kiện, giá đóng cửa của đường K này chính là điểm vào lệnh bán khống.
Logic giao dịch không phải rất đơn giản sao? Vì video nguồn không chỉ định chốt lời và dừng lỗ, nên biên tập viên sẽ sử dụng phương pháp chốt lời và dừng lỗ vừa phải hơn, sử dụng điểm dừng lỗ cố định và theo dõi chốt lời.
Thiết kế mã
Chúng tôi đưa mã của chỉ báo VuManChu Swing Free trực tiếp vào mã chiến lược của mình một cách nguyên vẹn.
Sau đó, chúng ta viết một đoạn mã ngôn ngữ Pine để triển khai chức năng giao dịch:
pine
// 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. Như bạn có thể thấy, khi buyCondition là đúng:
- Biến longCondition là đúng (chỉ báo VuManChu Swing Free gửi tín hiệu đi vào lệnh mua).
- emaFast > emaSlow (sắp xếp tăng giá EMA).
- đóng > mở (chỉ ra rằng BAR hiện tại là đường dương), đóng > emaFast (chỉ ra rằng giá đóng cửa nằm trên đường nhanh EMA).
Ba điều kiện để đi dài hạn đều được đáp ứng.
B. Khi sellCondition là đúng, ba điều kiện để bán khống được đáp ứng (không được mô tả ở đây).
Sau đó, khi điều kiện if xác định tín hiệu được kích hoạt, hãy sử dụng hàm strategy.entry để vào thị trường và mở một vị thế, và đặt hàm strategy.exit để dừng lỗ và chốt lời.
Mã hoàn chỉnh
pine
/*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)
Kiểm tra ngược
Phạm vi thời gian kiểm tra ngược được chọn từ tháng 1 năm 2022 đến tháng 10 năm 2022, thời gian của đường K là 15 phút và mô hình giá đóng cửa được sử dụng để kiểm tra ngược. Thị trường lựa chọn hợp đồng vĩnh viễn ETH_USDT của Binance. Cài đặt thông số được nêu trong video nguồn: 50 chu kỳ cho đường nhanh và 200 chu kỳ cho đường chậm, các thông số khác mặc định không thay đổi. Tôi hơi chủ quan về điểm dừng lỗ và điểm chốt lời và chỉ đặt chúng ở mức 30 điểm.
Kết quả kiểm tra ngược thì tạm ổn. Sau nhiều lần kiểm tra ngược, có vẻ như các thông số như chốt lời và dừng lỗ có tác động nhất định đến kết quả kiểm tra ngược. Tôi cảm thấy khía cạnh này cần được tối ưu hóa hơn nữa. Tuy nhiên, tỷ lệ chiến thắng vẫn tốt sau khi tín hiệu chiến lược kích hoạt giao dịch.
Hãy thử hợp đồng vĩnh viễn BTC_USDT:
Kết quả kiểm tra ngược trên BTC cũng rất bùng nổ:
Địa chỉ chiến lược: https://www.fmz.com/strategy/385745
Có vẻ như phương pháp giao dịch này khá đáng tin cậy để nắm bắt xu hướng và thiết kế có thể được tối ưu hóa hơn nữa dựa trên ý tưởng này. Trong bài viết này, chúng ta không chỉ tìm hiểu ý tưởng về chiến lược đường trung bình động kép mà còn tìm hiểu cách xử lý và học tập các chiến lược của các bậc thầy trên YouTube. Được rồi, các mã chiến lược trên chỉ là gợi ý của tôi. Kết quả kiểm tra ngược không đại diện cho kết quả thực tế cụ thể. Các mã chiến lược và thiết kế chỉ mang tính tham khảo. Cảm ơn sự ủng hộ của các bạn, hẹn gặp lại lần sau!
您好,这个是因为图表上显示的BUY标记只是文章中指标的信号显示,后面还结合了均线。
pine
//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))
plotshape(longCondition, title = "Buy Signal", text ="BUY 画图显示时,只是longCondition条件符合了。
下单条件在这一块:
pine
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)
梦大,建议从油管找两三个具有代表性的,改写难度较大,函数、参数、运算方式较多的策略做几个文字版的教程,比如带有类似【line.delete】这样的。(不需要策略盈利,就算是亏损的策略也无所谓,主要是用来学习写策略)。
我现在用这个双均线的策略,已经学会改一些不是非常复杂的组合策略了,改了十几个组合策略,其中有一两个确实是21年22年数据回测结果非常不错的,也已经在跑实盘测试了,但是遇到复杂函数参数运算这种【比如提示:line: 62 Could not find function or function reference 'line.delete',】而在FMZ PINE Script 文档并没有找到line.delete相关解释,用法说明,就懵圈了,所以希望梦大能弄点儿复杂策略改写一下,当然注释也多一些最好。就更方便学习了。[抱拳]
谢谢梦大。
梦大,请教下,PINE可以写复杂点儿的止盈方式吗?比如分层级止盈这样的???谢谢。
如果PINE可以和JS混编就好了,比如用PINE写指标,JS写交易部分就方便多了。。。。。
好的,谢谢梦大,另外请教下,PINE回测时间区间有限制吗?我选择2021年1月1日,到2022年10月11日,提示错误:
RuntimeError: abort(undefined) at Error at jsStackTrace (eval at self.onmessage (https://www.fmz.com/scripts/worker_detours.393054f7.js:1:147), <anonymous>:1:2096171) at stackTrace (eval at self.onmessage (https://www.fmz.com/scripts/worker_detours.393054f7.js:1:147), <anonymous>:1:2096345) at abort (eval at self.onmessage (https://www.fmz.com/scripts/worker_detours.393054f7.js:1:147), <anonymous>:1:2092408) at _abort (eval at self.onmessage (https://www.fmz.com/scripts/worker_detours.393054f7.js:1:147), <anonymous>:1:2137287) at <anonymous>:wasm-function[1297]:0x76bdc at <anonymous>:wasm-function[466]:0x3d789 at <anonymous>:wasm-function[477]:0x42e6b at <anonymous>:wasm-function[471]:0x4149e at <anonymous>:wasm-function[453]:0x3bf18 at <anonymous>:wasm-function[173]:0x13122
- 1
















