マルチタイムフレーム移動平均と取引時間を組み合わせた定量取引戦略


作成日: 2024-01-12 11:50:37 最終変更日: 2024-01-12 11:50:37
コピー: 1 クリック数: 599
1
フォロー
1617
フォロワー

マルチタイムフレーム移動平均と取引時間を組み合わせた定量取引戦略

概要

この戦略は,移動平均の複数の指標を用い,取引のタイミングと,入場と退出のタイミングを組み合わせて,定量取引を実現する.

戦略原則

この戦略は,SMA,EMA,WMAなど9種類の移動平均を使用している.ユーザの選択に応じて,多ポジションに入ると,閉店価格に選択された移動平均を穿い,前K線閉店価格が移動平均より下にある.空き時,閉店価格に選択された移動平均を穿い,前K線閉店価格が移動平均より上にある.すべての取引は,月曜日の開業時にのみ発せられる.平置は,固定ストップ・損失または日曜日の閉店前の平置である.

優位分析

この策略集は,複数の移動平均を1つにまとめており,ユーザーは異なる市場環境に対応するために異なるパラメータを選択することができます. 傾向が確認された場合にのみ入場し,回避します.‘% 失敗した取引’また,この戦略は,月曜日のみにポジションを開き,日曜日までにストップ・ストップ・損失または平仓を設定し,一週間に最大数回のポジション開設を制限し,取引リスクを効果的に制御しています.

リスク分析

この戦略は主に均線指標の判断傾向に依存し,トレンドが逆転すると,一部の取引が封じ込められるリスクがある.さらに,月曜日のみを限定してポジションを開けることができ,月曜日以降により良い取引機会が現れた場合も入場できず,利益の一部を逃す可能性がある.

これらのリスクを制御するために,動的移動平均のパラメータを採用し,市場が震動に陥ったときにパラメータを適切に短縮することを推奨します.同時に,ポジション開設時間を延長し,水曜日または木曜日に新しいポジションを開設することが許可されます.

最適化の方向

この戦略は以下の点で最適化できます.

  1. ストップ・ストップ・損失のAlgerismアルゴリズムを追加し,ストップ・損失のストップ・ポイントを動的に調整する.

  2. 機械学習モデルによるトレンド判断の年数を増やし,波動的な市場への参入を回避する.

  3. ポジション開設とポジションのロジックを最適化し,より多くのポジション開設の機会を可能にします.

要約する

この戦略は,複数の移動平均指標を集約してトレンドの方向を判断し,月曜日にポジションを開き,日曜日の平仓をすることで,一週間の最大取引数を効果的に制御する.同時に,厳格な止損ルールは,単一の取引の最大損失を制限する.総合的に見ると,この戦略は,トレンドの判断とリスク管理の2つの次元から最適化して設計され,より堅牢な量化取引戦略である.

ストラテジーソースコード
/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
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/
// © exlux99

//@version=5
strategy('Time MA strategy ', overlay=true)

longEntry = input.bool(true, group="Type of Entries")
shortEntry = input.bool(false, group="Type of Entries")


//==========DEMA
getDEMA(src, len) =>
    dema = 2 * ta.ema(src, len) - ta.ema(ta.ema(src, len), len)
    dema
//==========HMA
getHULLMA(src, len) =>
    hullma = ta.wma(2 * ta.wma(src, len / 2) - ta.wma(src, len), math.round(math.sqrt(len)))
    hullma
//==========KAMA
getKAMA(src, len, k1, k2) =>
    change = math.abs(ta.change(src, len))
    volatility = math.sum(math.abs(ta.change(src)), len)
    efficiency_ratio = volatility != 0 ? change / volatility : 0
    kama = 0.0
    fast = 2 / (k1 + 1)
    slow = 2 / (k2 + 1)
    smooth_const = math.pow(efficiency_ratio * (fast - slow) + slow, 2)
    kama := nz(kama[1]) + smooth_const * (src - nz(kama[1]))
    kama
//==========TEMA
getTEMA(src, len) =>
    e = ta.ema(src, len)
    tema = 3 * (e - ta.ema(e, len)) + ta.ema(ta.ema(e, len), len)
    tema
//==========ZLEMA
getZLEMA(src, len) =>
    zlemalag_1 = (len - 1) / 2
    zlemadata_1 = src + src - src[zlemalag_1]
    zlema = ta.ema(zlemadata_1, len)
    zlema
//==========FRAMA
getFRAMA(src, len) =>
    Price = src
    N = len
    if N % 2 != 0
        N := N + 1
        N
    N1 = 0.0
    N2 = 0.0
    N3 = 0.0
    HH = 0.0
    LL = 0.0
    Dimen = 0.0
    alpha = 0.0
    Filt = 0.0
    N3 := (ta.highest(N) - ta.lowest(N)) / N
    HH := ta.highest(N / 2 - 1)
    LL := ta.lowest(N / 2 - 1)
    N1 := (HH - LL) / (N / 2)
    HH := high[N / 2]
    LL := low[N / 2]
    for i = N / 2 to N - 1 by 1
        if high[i] > HH
            HH := high[i]
            HH
        if low[i] < LL
            LL := low[i]
            LL
    N2 := (HH - LL) / (N / 2)
    if N1 > 0 and N2 > 0 and N3 > 0
        Dimen := (math.log(N1 + N2) - math.log(N3)) / math.log(2)
        Dimen
    alpha := math.exp(-4.6 * (Dimen - 1))
    if alpha < .01
        alpha := .01
        alpha
    if alpha > 1
        alpha := 1
        alpha
    Filt := alpha * Price + (1 - alpha) * nz(Filt[1], 1)
    if bar_index < N + 1
        Filt := Price
        Filt
    Filt
//==========VIDYA
getVIDYA(src, len) =>
    mom = ta.change(src)
    upSum = math.sum(math.max(mom, 0), len)
    downSum = math.sum(-math.min(mom, 0), len)
    out = (upSum - downSum) / (upSum + downSum)
    cmo = math.abs(out)
    alpha = 2 / (len + 1)
    vidya = 0.0
    vidya := src * alpha * cmo + nz(vidya[1]) * (1 - alpha * cmo)
    vidya
//==========JMA
getJMA(src, len, power, phase) =>
    phase_ratio = phase < -100 ? 0.5 : phase > 100 ? 2.5 : phase / 100 + 1.5
    beta = 0.45 * (len - 1) / (0.45 * (len - 1) + 2)
    alpha = math.pow(beta, power)
    MA1 = 0.0
    Det0 = 0.0
    MA2 = 0.0
    Det1 = 0.0
    JMA = 0.0
    MA1 := (1 - alpha) * src + alpha * nz(MA1[1])
    Det0 := (src - MA1) * (1 - beta) + beta * nz(Det0[1])
    MA2 := MA1 + phase_ratio * Det0
    Det1 := (MA2 - nz(JMA[1])) * math.pow(1 - alpha, 2) + math.pow(alpha, 2) * nz(Det1[1])
    JMA := nz(JMA[1]) + Det1
    JMA
//==========T3
getT3(src, len, vFactor) =>
    ema1 = ta.ema(src, len)
    ema2 = ta.ema(ema1, len)
    ema3 = ta.ema(ema2, len)
    ema4 = ta.ema(ema3, len)
    ema5 = ta.ema(ema4, len)
    ema6 = ta.ema(ema5, len)
    c1 = -1 * math.pow(vFactor, 3)
    c2 = 3 * math.pow(vFactor, 2) + 3 * math.pow(vFactor, 3)
    c3 = -6 * math.pow(vFactor, 2) - 3 * vFactor - 3 * math.pow(vFactor, 3)
    c4 = 1 + 3 * vFactor + math.pow(vFactor, 3) + 3 * math.pow(vFactor, 2)
    T3 = c1 * ema6 + c2 * ema5 + c3 * ema4 + c4 * ema3
    T3
//==========TRIMA
getTRIMA(src, len) =>
    N = len + 1
    Nm = math.round(N / 2)
    TRIMA = ta.sma(ta.sma(src, Nm), Nm)
    TRIMA


src = input.source(close, title='Source', group='Parameters')
len = input.int(17, minval=1, title='Moving Averages', group='Parameters')
out_ma_source = input.string(title='MA Type', defval='ALMA', options=['SMA', 'EMA', 'WMA', 'ALMA', 'SMMA', 'LSMA', 'VWMA', 'DEMA', 'HULL', 'KAMA', 'FRAMA', 'VIDYA', 'JMA', 'TEMA', 'ZLEMA', 'T3', 'TRIM'], group='Parameters')
out_ma = out_ma_source == 'SMA' ? ta.sma(src, len) : out_ma_source == 'EMA' ? ta.ema(src, len) : out_ma_source == 'WMA' ? ta.wma(src, len) : out_ma_source == 'ALMA' ? ta.alma(src, len, 0.85, 6) : out_ma_source == 'SMMA' ? ta.rma(src, len) : out_ma_source == 'LSMA' ? ta.linreg(src, len, 0) : out_ma_source == 'VWMA' ? ta.vwma(src, len) : out_ma_source == 'DEMA' ? getDEMA(src, len) : out_ma_source == 'HULL' ? ta.hma(src, len) : out_ma_source == 'KAMA' ? getKAMA(src, len, 2, 30) : out_ma_source == 'FRAMA' ? getFRAMA(src, len) : out_ma_source == 'VIDYA' ? getVIDYA(src, len) : out_ma_source == 'JMA' ? getJMA(src, len, 2, 50) : out_ma_source == 'TEMA' ? getTEMA(src, len) : out_ma_source == 'ZLEMA' ? getZLEMA(src, len) : out_ma_source == 'T3' ? getT3(src, len, 0.7) : out_ma_source == 'TRIM' ? getTRIMA(src, len) : na


plot(out_ma)

long = close> out_ma and close[1] < out_ma and dayofweek==dayofweek.monday
short = close< out_ma and close[1] > out_ma and dayofweek==dayofweek.monday


stopPer = input.float(10.0, title='LONG Stop Loss % ', group='Fixed Risk Management') / 100
takePer = input.float(30.0, title='LONG Take Profit %', group='Fixed Risk Management') / 100

stopPerShort = input.float(5.0, title='SHORT Stop Loss % ', group='Fixed Risk Management') / 100
takePerShort = input.float(10.0, title='SHORT Take Profit %', group='Fixed Risk Management') / 100


longStop = strategy.position_avg_price * (1 - stopPer)
longTake = strategy.position_avg_price * (1 + takePer)

shortStop = strategy.position_avg_price * (1 + stopPerShort)
shortTake = strategy.position_avg_price * (1 - takePerShort)

// strategy.risk.max_intraday_filled_orders(2) // After 10 orders are filled, no more strategy orders will be placed (except for a market order to exit current open market position, if there is any).

if(longEntry)
    strategy.entry("long",strategy.long,when=long )
    strategy.exit('LONG EXIT', "long", limit=longTake, stop=longStop)
    strategy.close("long",when=dayofweek==dayofweek.sunday)

if(shortEntry)
    strategy.entry("short",strategy.short,when=short )
    strategy.exit('SHORT EXIT', "short", limit=shortTake, stop=shortStop)
    strategy.close("short",when=dayofweek==dayofweek.sunday)