YouTube Master의 "Magical Double EMA Moving Average Strategy"
이번 호에서는 YouTube의 "마법의 이중 EMA 이동 평균 전략"에 대해 논의하겠습니다. 이는 "주식 및 암호화폐 시장 킬러"라고 불립니다. 영상을 본 후, 이 전략은 2개의 트레이딩 뷰 지표를 사용하는 트레이딩 뷰 파인 언어 전략이라는 것을 알게 되었습니다. 영상에서 백테스팅 결과가 매우 좋았고, FMZ도 Trading View의 Pine 언어를 지원해서, 직접 백테스팅을 하고 분석을 테스트하고 싶지 않을 수 없었습니다. 그러면 인생 전체를 시작하세요! 영상 속 전략을 재현해 보겠습니다.
전략에서 사용하는 지표
- EMA 지표
디자인의 단순성을 위해 영상에 나와 있는 이동 평균 지수는 사용하지 않을 것입니다. 대신 Trading View에 내장된 ta.ema를 사용합니다(실제로 둘은 동일합니다).
- VuManChu 스윙 프리 인디케이터
이것은 Trading View의 지표입니다. Trading View로 가서 소스 코드를 다운로드해야 합니다.
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")
전략 논리
EMA 지표: 이 전략은 두 개의 EMA 이동 평균선을 사용합니다. 하나는 빠른 선(작은 주기 매개변수)이고 다른 하나는 느린 선(큰 주기 매개변수)입니다. 이중 EMA 이동평균선의 주요 기능은 시장 추세의 방향을 결정하는 데 도움이 되는 것입니다.
-
긴 배열
빠른 선은 느린 선 위에 있습니다. -
짧은 배열
빠른 선은 느린 선 아래에 있습니다.
VuManChu Swing Free 지표: VuManChu Swing Free 지표는 신호를 보내는 데 사용되며, 이후 다른 조건과 결합하여 거래 주문을 할지 여부를 결정합니다. VuManChu Swing Free 지표 소스 코드에서 longCondition 변수는 매수 신호를 나타내고 shortCondition 변수는 매도 신호를 나타낸다는 것을 알 수 있습니다. 이 두 변수는 나중에 주문 조건을 작성할 때 사용됩니다.
이제 전략의 구체적인 거래 신호 발동 조건에 대해 알아보겠습니다.
-
롱 포지션 진입 규칙:
양의 K-라인의 종가는 EMA 패스트라인 위에 있어야 하며, 두 개의 EMA 이동평균은 강세 배열에 있어야 합니다(패스트라인이 슬로우라인 위에 있음), VuManChu Swing Free 지표는 매수 신호를 보여야 합니다. (longCondition이 참입니다). 세 가지 조건이 충족된다면, 이 K-라인은 롱 포지션에 진입하기 위한 주요 K-라인이고, 이 K-라인의 종가가 진입 포지션이 됩니다. -
숏 포지션(롱 포지션과 반대) 진입 규칙:
음의 캔들스틱의 종가는 빠른 EMA 라인 아래에 있어야 하며, 두 개의 EMA 이동 평균은 숏 포지션에 있어야 합니다(빠른 라인은 느린 라인 아래에 있음), 그리고 VuManChu Swing Free 지표는 매도 신호를 보여야 합니다(shortCondition (사실입니다). 세 가지 조건이 충족된다면, 이 K-라인의 종가는 공매도의 진입점입니다.
거래 로직이 매우 간단하지 않나요? 소스 비디오에는 이익실현과 손절매가 명시되어 있지 않기 때문에 편집자는 고정 포인트 손절매와 추적을 사용하여 보다 온건한 이익실현 및 손절매 방법을 사용할 것입니다. 이익 실현.
코드 디자인
우리는 VuManChu Swing Free 지표의 코드를 그대로 전략 코드에 직접 넣었습니다.
그런 다음 트랜잭션 기능을 구현하기 위해 Pine 언어 코드를 작성합니다.
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. 보시다시피 buyCondition이 참일 때:
- longCondition 변수가 참입니다(VuManChu Swing Free 지표가 롱 포지션으로 전환하라는 신호를 보냅니다).
- emaFast > emaSlow (EMA 강세 조정).
- close > open (현재 BAR이 양의 선임을 나타냄), close > emaFast (마진 가격이 EMA fast line 위에 있음을 나타냄).
장기 투자를 위한 세 가지 조건이 충족되었습니다.
B. sellCondition이 참인 경우 공매도에 대한 세 가지 조건이 충족됩니다(여기서는 설명하지 않음).
그런 다음 if 조건에서 신호가 트리거되었다고 판단되면 strategy.entry 함수를 사용하여 시장에 진입하고 포지션을 개시하고, strategy.exit 함수를 설정하여 손실 중단 및 추적 이익을 설정합니다.
완전한 코드
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)
백테스팅
백테스팅 시간 범위는 2022년 1월부터 2022년 10월까지로 선택되었으며, K-라인 기간은 15분이고, 백테스팅에는 종가 모델을 사용했습니다. 시장에서는 바이낸스의 ETH_USDT 선물 계약을 선택합니다. 매개변수 설정은 소스 영상에 나와 있는 대로입니다. 빠른 회선의 경우 50주기, 느린 회선의 경우 200주기이며, 다른 매개변수는 기본적으로 변경되지 않습니다. 저는 손절매와 추적 이익 지점을 설정하는 데 약간 주관적이며, 그냥 30포인트로 설정합니다.
백테스트 결과는 그저 그렇습니다. 여러 백테스트를 거친 후, 이익 실현 및 손절매와 같은 매개변수가 백테스트 결과에 어느 정도 영향을 미치는 것으로 보입니다. 저는 이 측면이 더욱 최적화되어야 한다고 생각합니다. 하지만 전략적 신호가 거래를 촉발한 후에도 승률은 여전히 좋습니다.
BTC_USDT 영구 계약을 시도해 보겠습니다.
BTC 백테스트 결과 역시 폭발적입니다.
전략 주소: https://www.fmz.com/strategy/385745
이 거래 방식은 추세를 파악하는 데 비교적 신뢰할 만한 것으로 보이며, 이 아이디어를 바탕으로 설계를 더욱 최적화할 수 있습니다. 이 글에서는 이중 이동 평균 전략의 개념을 배울 뿐만 아니라 유튜브 거장들의 전략을 처리하고 학습하는 방법도 알아보았습니다. 알겠습니다. 위의 전략 코드는 제 제안일 뿐입니다. 백테스트 결과는 구체적인 실제 결과를 나타내지 않습니다. 전략 코드와 설계는 참고용일 뿐입니다. 여러분의 응원에 감사드립니다. 다음에 또 뵙겠습니다!
您好,这个是因为图表上显示的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
















