ストックとEMAに基づく定量的な取引戦略

作者: リン・ハーンチャオチャン, 日付: 2023-09-15 11:31:16
タグ:

この記事では,ストック指標とEMA移動平均を組み合わせた定量的な取引戦略を詳細に説明します.これはストック値に基づいて取引信号を生成し,EMAを使用して主流でない信号をフィルタリングします.

I. 戦略の論理

主なツールと論理は次のとおりです

  1. K と D の値でストック指標を計算する.ここで K は急速な価格変化を反映し,D はスムーズな信号である.

  2. ストックに過剰購入/過剰販売ゾーンを設定します.シグナルは,KとDの相対値に基づいています.

  3. 価格の主流傾向を測定するために,期間中のEMAを計算します.

  4. ストックシグナルが EMAの指針に合致する時だけ取引をします

  5. ストップ・ロスのシグナルでロング・ショート・ポジションを設定し 利益を得ます

ストックは過剰購入/過剰売却の機会を捉え EMAは不適切な信号をフィルターで 強力な戦略を形成します

戦略の利点

最も大きな利点は指標の互いを補完することである.ストックはO/SレベルとEMAは主流傾向を判断し,誤りを減らすために組み合わせます.

また,調整可能なK/D値は,異なる製品で最適化することができます.

最後に,ストップ・ロスト/テイク・プロフィートは,慎重なマネーマネジメントのリスク/報酬を明確に定義しています.

III.潜在的な弱点

しかし,いくつかの潜在的な問題は次のとおりです.

まず ストックとEMAの両方が遅れがちで 最適エントリが逃れる可能性があります

2つ目に 緊密なストップは 早期に多くの無効化を引き起こします

最後に,過剰なフィットメントを避けるために,広範なパラメータ最適化が必要です.

IV.要約

この記事では,ストックと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))

もっと