이 글은 스토흐 지표와 EMA 평선을 결합하여 양적 거래를 하는 전략에 대해 자세히 설명할 것이다. 이 전략은 스토흐 지표의 값에 따라 거래 신호를 생성하고, EMA 을 이용한 다른 주요 방향의 신호를 사용한다.
1 전략
이 전략은 주로 다음과 같은 도구와 논리를 통해 거래됩니다.
K값과 D값으로 구성된 스토흐 지표의 계산, K값은 급격한 가격 변화를 반영하고, D값은 부드러운 처리를 한다.
스토흐 지표의 오버 바이 오버 세일 영역을 설정하여 K, D 값의 상대적인 크기에 따라 거래 신호를 생성합니다.
가격의 주류를 판단하기 위해 주기적 EMA의 평균선을 계산합니다.
스토흐 지표 신호가 EMA 평균선 방향과 일치할 때만 거래한다.
신호에 따라 다단계 또는 빈단계 포지션을 설정하고, 스톱 스톱 손실을 설정한다.
이렇게 하면, 스토흐 지표는 오버 바이 오버 셀 영역 기회를 포착하고, EMA는 불합리한 신호를 제거하며, 둘은 안정화 전략을 형성한다.
2 전략적 장점
이 전략의 가장 큰 장점은 지표의 상호보완성, 스토흐의 과매매 판단, EMA의 주류의 방향을 판단하는 등 잘못된 거래의 감소와 결합되어 있다.
둘째, K, D 값은 조정할 수 있으며, 다양한 품종의 파라미터 최적화에 적응할 수 있다.
마지막으로, 정지/손실 설정은 거래 당 수익 위험을 명확히 하고, 자금 관리에 도움이 됩니다.
그러나 이 전략에는 다음과 같은 잠재적인 문제들이 있습니다.
우선, 스토흐와 EMA 지표는 모두 지연될 수 있으며, 이로 인해 최고의 거래 시기가 손실될 수 있습니다.
두 번째, 너무 작은 정지 손실은 너무 많은 무효 정지를 초래할 수 있습니다.
마지막으로, 다중 변수 최적화는 과다 적합성을 방지하기 위해 많은 작업이 필요합니다.
네 가지 내용
이 글은 스토흐와 EMA를 결합한 한 가지 양적 거래 전략에 대해 자세히 소개한다. 이 전략은 오버 바이 오버 셀 영역 반전 기회를 식별하고, EMA를 통해 무효 신호를 필터링한다. 이 전략은 변수 최적화를 통해 안정적인 수익을 얻을 수 있지만, 상기 문제의 발생을 방지하는 데 주의를 기울여야 한다.
/*backtest
start: 2023-08-15 00:00:00
end: 2023-08-26 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=5
strategy(title="EMA Stoch Strategy For ProfitView", overlay=true, calc_on_every_tick=true, process_orders_on_close=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1, initial_capital=1000)
// take profit e stop loss
TakeProfitPercent = input.float(defval = 0.0, title="Take Profit (%) [0 = Disabled]",minval = 0, step=.25,group='TP / SL')
StopLossPercent = input.float(defval = 0.0, title="Stop Loss (%) [0 = Disabled]",minval = 0, step=.25,group='TP / SL')
// Stoch
smoothK = input.int(1, title="K Smoothing", minval=1,group='Stochastic')
periodD = input.int(3, title="D Smoothing", minval=1,group='Stochastic')
lenghtRSI= input.int(14, "RSI Length", minval=1)
lenghtStoch = input.int(14, "Stochastic Length", minval=1)
src = input(close, title="RSI Source")
rsi1 = ta.rsi(src, lenghtRSI)
k = ta.sma(ta.stoch(rsi1, rsi1, rsi1, lenghtStoch), smoothK)
d = ta.sma(k, periodD)
plot(k, title="K", color=#2962FF)
plot(d, title="D", color=#FF6D00)
// bgcolor(color=color.from_gradient(k, 0, 100, color.new(#2962FF, 100), color.new(#2962FF, 95)), title="K BG")
// bgcolor(color=color.from_gradient(d, 0, 100, color.new(#FF6D00, 100), color.new(#FF6D00, 95)), title="D BG")
// ema
src1= input(close,title='Source EMA ',group='EMA')
len1= input(200,title='Length EMA ',group='EMA')
ema1= ta.ema(src1,len1)
plot(ema1,title='EMA',color= color.blue ,linewidth=2)
// signals
LongVal= input(20,title='Stoch below/cross this value for Long signals',group='Signal Options')
scegliLong= input.string('Stoch Below Value', options= ['Stoch Below Value' , 'K&D Cross Below Value' , 'Stoch CrossUp the Value'] , title='Long Signal Type')
long1= scegliLong == 'Stoch Below Value' ? k < LongVal and d < LongVal and close > ema1 : na
long2= scegliLong == 'K&D Cross Below Value' ? ta.cross(k,d) and k < LongVal and d < LongVal and close > ema1 : na
long3= scegliLong == 'Stoch CrossUp the Value' ? ta.crossover(k,LongVal) and close > ema1 : na
shortVal= input(80,title='Stoch above/cross this value for Short signals',group='Signal Options')
scegliShort= input.string('Stoch Above Value', options= ['Stoch Above Value' , 'K&D Cross Above Value' , 'Stoch CrossDown the Value'] , title='Short Signal Type' )
short1= scegliShort == 'Stoch Above Value' ? k > shortVal and d > shortVal and close < ema1 : na
short2= scegliShort == 'K&D Cross Above Value' ? ta.cross(k,d) and k > shortVal and d > shortVal and close < ema1 : na
short3= scegliShort == 'Stoch CrossDown the Value' ? ta.crossunder(k,shortVal) and close < ema1 : na
// Strategy Backtest Limiting Algorithm/
i_startTime = input(defval = timestamp("01 Jan 2014 00:00 +0000"), title = "Backtesting Start Time", inline="timestart", group='Backtesting')
i_endTime = input(defval = timestamp("01 Jan 2100 23:59 +0000"), title = "Backtesting End Time", inline="timeend", group='Backtesting')
timeCond = true
pv_ex = input.string("deribit-testnet", title="Exchange", group='PV Settings')
pv_sym = input.string("btc-perpetual", title="Symbol", group='PV Settings')
pv_acc = input.string("", title="Account", group='PV Settings')
pv_alert_long = input.string("", title="PV Alert Name Longs", group='PV Settings')
pv_alert_short = input.string("", title="PV Alert Name Shorts", group='PV Settings')
pv_alert_cancel = input.string("", title="PV Alert Name TP/SL", group='PV Settings')
profit_abs = (close * (TakeProfitPercent / 100))
stop_abs = (close * (StopLossPercent / 100))
ProfitTarget = TakeProfitPercent > 0 ? profit_abs / syminfo.mintick : na
LossTarget = StopLossPercent > 0 ? stop_abs / syminfo.mintick : na
// Make sure we are within the bar range, Set up entries and exit conditions
var entryprice = 0.0
var profitprice = 0.0
var stopprice = 0.0
exsym = pv_ex == "" ? "" : "ex=" + pv_ex + ","
exsym := pv_sym == "" ? exsym : exsym + "sym=" + pv_sym
if ((long1 or long2 or long3) and timeCond and strategy.position_size <= 0)
strategy.entry("Long", strategy.long, when=barstate.isconfirmed)
entryprice := close
profitprice := entryprice+profit_abs
stopprice := entryprice-stop_abs
tpsl_str = TakeProfitPercent > 0 ? ",mytp=" + str.tostring(profitprice) : ""
tpsl_str := StopLossPercent > 0 ? tpsl_str + ",mysl=" + str.tostring(stopprice) : tpsl_str
alert(pv_alert_long + "(" + exsym + ",acc=" + pv_acc + tpsl_str + ")", alert.freq_once_per_bar_close)
if ((short1 or short2 or short3) and timeCond and strategy.position_size >= 0)
strategy.entry("Short", strategy.short, when=barstate.isconfirmed)
entryprice := close
profitprice := entryprice-profit_abs
stopprice := entryprice+stop_abs
tpsl_str = TakeProfitPercent > 0 ? ",mytp=" + str.tostring(profitprice) : ""
tpsl_str := StopLossPercent > 0 ? tpsl_str + ",mysl=" + str.tostring(stopprice) : tpsl_str
alert(pv_alert_short + "(" + exsym + ",acc=" + pv_acc + tpsl_str + ")", alert.freq_once_per_bar_close)
tpsl_hit_long = (strategy.position_size[1] > 0 and ((TakeProfitPercent > 0 and high > profitprice[1]) or (StopLossPercent > 0 and low < stopprice[1])))
tpsl_hit_short = (strategy.position_size[1] < 0 and ((TakeProfitPercent > 0 and low < profitprice[1]) or (StopLossPercent > 0 and high > stopprice[1])))
if (tpsl_hit_long or tpsl_hit_short)
alert(pv_alert_cancel + "(" + exsym + ",acc=" + pv_acc + ")", alert.freq_once_per_bar)
strategy.exit("Exit Long (TP/SL)", from_entry = "Long" , profit = ProfitTarget, loss = LossTarget)
strategy.exit("Exit Short (TP/SL)", from_entry = "Short", profit = ProfitTarget, loss = LossTarget)
plot(entryprice, title="Entry Price", color=strategy.opentrades > 0 ? color.gray : color.new(color.gray, 100))
plot(profitprice, title="Profit Price", color=strategy.opentrades > 0 and TakeProfitPercent > 0 ? color.green : color.new(color.green, 100))
plot(stopprice, title="Stop Price", color=strategy.opentrades > 0 and StopLossPercent > 0? color.red : color.new(color.red, 100))