オマとアポロ 双列車取引戦略

作者: リン・ハーンチャオチャン, 日付: 2023年11月2日17時09分35秒
タグ:

img

概要

この戦略は,2つの主流の技術指標であるオマ指標とアポロ指標を組み合わせて,ロングとショートポジションのダブルレール取引を実装する.その基本的なアイデアは,中長期トレンドが上昇傾向であると判断された場合,短期的なプルバック機会を見つけ,ロングポジションを確立することです.中長期トレンドが下落傾向であると判断された場合,短期的なリバウンドでショートポジションを確立する機会を探します.

戦略原則

この戦略は,中長期トレンドを決定するために50日間および200日間の移動平均値を使用します. 200日間の線上の50日間の線は上昇傾向を示し,逆もまた下落傾向を示します.

次に,戦略は,短期的な価格逆転の機会を特定するためにOma指標を使用する.Oma指標は,単純な移動平均値で平滑したRSI指標の結果である%Kと%D線を含む.%Kが過買いエリア (80以上) から%D以下に突破すると,価格は過買い状態から引き下げ状態に転移することを示します.%Kが過売りエリア (20以下) から%D以上に突破すると,価格は過売りエリアから反弹していることを示します.これは長い機会を提示します.

この戦略は,誤った信号をさらにフィルタリングするために,アポロインジケーターも組み込む.アポロインジケーターは,K線の%D値の極点を表示する.%Kが新しい低値を形成すると,リバウンド強さは比較的弱いことを意味します.新しい高値を形成すると,リバウンド強さは比較的強いことを意味します.オマインジケーターからの信号と組み合わせると,これはエントリー精度をさらに改善することができます.

具体的には,上昇傾向では,この戦略は,オマ指標が過剰購入領域の下の機会を示したときに,新しい高点情報を同時にチェックし,ブランスの強さを確認します.ダウントレンドでは,オマ指標が過剰販売領域から上昇するショート機会を示したとき,この戦略は,リバウンド強さの弱さを確認するために,新しい低点情報を同時にチェックします.

この戦略は,上記のプロセスを通じて,中長期的傾向判断と短期的逆転指標の強みを充分活用し,安定した二線貿易システムを構築します.

戦略 の 利点

  1. この戦略は,トレンド判断と逆トレンド指標の両方を利用してトレンド取引と反トレンド取引を組み合わせて,安定したハイブリッド取引枠組みを形成します.

  2. 二重インジケータフィルタリングによって 偽信号比率が減少し 信号の信頼性が向上します

  3. 戦略パラメータは比較的シンプルで,理解し最適化しやすいので,定量取引に適しています.

  4. 戦略の業績は堅調で 利得率とリスク・リターン比が良好です

  5. 長線と短線を両線で走らせることで,単一の方向に限定されないまま,継続的に取引機会を得ることができます.

戦略 の リスク

  1. 逆転戦略として,トレンドが変わると連続した損失が発生する可能性があります.

  2. この戦略には,ある程度の引き下げに耐えられるように 交易者が比較的高い感情的コントロールを必要とします.

  3. 移動平均期などのいくつかのパラメータは,ある程度の主観性を伴うため,バックテストと最適化によって決定する必要があります.

  4. オマとアポロの両方の指標は異常波動に敏感で,極端な市場状況では失敗する可能性があります.

  5. この戦略は,範囲限定の変動市場に適しており,強いトレンド市場では劣悪なパフォーマンスを発揮する可能性があります.

リスクは,トレンドフィルタリングを導入するために移動平均期間に適切な調整を行い,ストップ・ロスト/テイク・プロフィートを追加することで軽減できます.市場が強くトレンドになると,その環境での取引を避けるために戦略を一時停止することを検討してください.

オプティマイゼーションの方向性

  1. よりよいパラメータ設定を得るため,異なるパラメータ組み合わせを試験し,例えばEWMAの平滑移動平均を使用する.

  2. 音量またはBV指標を追加して,信号の信頼性を確認するのに役立つ差異を判断します.

  3. VIXのような波動指数を 監視指標として追加して 市場がパニック状態にあるとき ポジションの大きさを減らすのです

  4. ストップ・ロスの戦略を最適化し,ダイナミックなATRストップ・ロスを採用する.

  5. パラメータ設定を動的に最適化するための機械学習アルゴリズムを導入する.

  6. 信号の質を改善するために多要素モデルを追加します

概要

一般的に,これは安定かつ効率的な定量的な取引戦略である.トレンド判断と逆転指標を組み合わせ,オマとアポロ指標を使用して二重検証を採用し,短期的な価格逆転機会を効果的に発見することができる.純粋にトレンドまたは逆転システムを使用すると比較して,この戦略形態は優れた引き下げ制御によりより堅牢であり,推奨される定量的な取引戦略である.もちろん,ユーザーはリスクに意識し,パラメータ最適化,ストップ損失/利益採取,市場体制識別などを使用してリスクを制御し,最高のパフォーマンスを達成する必要があります.


/*backtest
start: 2023-10-25 00:00:00
end: 2023-10-28 00:00:00
period: 5m
basePeriod: 1m
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/
// © PtGambler

//@version=5
strategy("2 EMA + Stoch RSI + ATR [Pt]", shorttitle = "2EMA+Stoch+ATR", overlay=true, initial_capital = 10000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, calc_on_order_fills = false, max_bars_back = 500)

// ********************************** Trade Period / Strategy Setting **************************************
startY = input(title='Start Year', defval=2011, group = "Backtesting window")
startM = input.int(title='Start Month', defval=1, minval=1, maxval=12, group = "Backtesting window")
startD = input.int(title='Start Day', defval=1, minval=1, maxval=31, group = "Backtesting window")
finishY = input(title='Finish Year', defval=2050, group = "Backtesting window")
finishM = input.int(title='Finish Month', defval=12, minval=1, maxval=12, group = "Backtesting window")
finishD = input.int(title='Finish Day', defval=31, minval=1, maxval=31, group = "Backtesting window")
timestart = timestamp(startY, startM, startD, 00, 00)
timefinish = timestamp(finishY, finishM, finishD, 23, 59)

// ******************************************************************************************

group_ema = "EMA"
group_stoch = "Stochastic RSI"
group_atr = "ATR Stoploss Finder"

// ----------------------------------------- 2 EMA -------------------------------------

ema1_len = input.int(50, "EMA Length 1", group = group_ema)
ema2_len = input.int(200, "EMA Length 2", group = group_ema)

ema1 = ta.ema(close, ema1_len)
ema2 = ta.ema(close, ema2_len)

plot(ema1, "ema1", color.white, linewidth = 2)
plot(ema2, "ema2", color.orange, linewidth = 2)

ema_bull = ema1 > ema2
ema_bear = ema1 < ema2


// -------------------------------------- Stochastic RSI -----------------------------

smoothK = input.int(3, "K", minval=1, group = group_stoch)
smoothD = input.int(3, "D", minval=1, group = group_stoch)
lengthRSI = input.int(14, "RSI Length", minval=1, group = group_stoch)
lengthStoch = input.int(14, "Stochastic Length", minval=1, group = group_stoch)
src = close
rsi1 = ta.rsi(src, lengthRSI)
k = ta.sma(ta.stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = ta.sma(k, smoothD)

var trigger_stoch_OB = k > 80
var trigger_stoch_OS = k < 20

stoch_crossdown = ta.crossunder(k, d)
stoch_crossup = ta.crossover(k, d)

P_hi = ta.pivothigh(k,1,1)
P_lo = ta.pivotlow(k,1,1)

previous_high = ta.valuewhen(P_hi, k, 1)
previous_low = ta.valuewhen(P_lo, k, 1)
recent_high = ta.valuewhen(P_hi, k, 0)
recent_low = ta.valuewhen(P_lo, k, 0)

// --------------------------------------- ATR stop loss finder ------------------------

length = input.int(title='Length', defval=14, minval=1, group = group_atr)
smoothing = input.string(title='Smoothing', defval='EMA', options=['RMA', 'SMA', 'EMA', 'WMA'], group = group_atr)
m = input.float(0.7, 'Multiplier', step = 0.1, group = group_atr)
src1 = input(high, "Source for upper band", group = group_atr)
src2 = input(low, "Source for lower band", group = group_atr)

showatr = input.bool(true, 'Show ATR Bands', group = group_atr)
collong = input.color(color.purple, 'Long ATR SL', inline='1', group = group_atr)
colshort = input.color(color.purple, 'Short ATR SL', inline='2', group = group_atr)

ma_function(source, length) =>
    if smoothing == 'RMA'
        ta.rma(source, length)
    else
        if smoothing == 'SMA'
            ta.sma(source, length)
        else
            if smoothing == 'EMA'
                ta.ema(source, length)
            else
                ta.wma(source, length)

a = ma_function(ta.tr(true), length) * m
up = ma_function(ta.tr(true), length) * m + src1
down = src2 - ma_function(ta.tr(true), length) * m

p1 = plot(showatr ? up : na, title='ATR Short Stop Loss', color=colshort)
p2 = plot(showatr ? down : na, title='ATR Long Stop Loss', color=collong)

// ******************************* Profit Target / Stop Loss *********************************************

RR = input.float(2.0, "Reward to Risk ratio (X times SL)", step = 0.1, group = "Profit Target")

var L_PT = 0.0
var S_PT = 0.0
var L_SL = 0.0
var S_SL = 0.0

BSLE = ta.barssince(strategy.opentrades.entry_bar_index(0) == bar_index)

if strategy.position_size > 0 and BSLE == 1
    L_PT := close + (close-down)*RR
    L_SL := L_SL[1]
    S_PT := close - (up - close)*RR
    S_SL := up
else if strategy.position_size < 0 and BSLE == 1
    S_PT := close - (up - close)*RR
    S_SL := S_SL[1]
    L_PT := close + (close-down)*RR
    L_SL := down
else if strategy.position_size != 0
    L_PT := L_PT[1] 
    S_PT := S_PT[1]
else
    L_PT := close + (close-down)*RR
    L_SL := down
    S_PT := close - (up - close)*RR
    S_SL := up

entry_line = plot(strategy.position_size != 0 ? strategy.opentrades.entry_price(0) : na, "Entry Price", color.white, linewidth = 1, style = plot.style_linebr)

L_PT_line = plot(strategy.position_size > 0 and BSLE > 0 ? L_PT : na, "L PT", color.green, linewidth = 2, style = plot.style_linebr)
S_PT_line = plot(strategy.position_size < 0 and BSLE > 0 ? S_PT : na, "S PT", color.green, linewidth = 2, style = plot.style_linebr)

L_SL_line = plot(strategy.position_size > 0 and BSLE > 0 ? L_SL : na, "L SL", color.red, linewidth = 2, style = plot.style_linebr)
S_SL_line = plot(strategy.position_size < 0 and BSLE > 0 ? S_SL : na, "S SL", color.red, linewidth = 2, style = plot.style_linebr)

fill(L_PT_line, entry_line, color = color.new(color.green,90))
fill(S_PT_line, entry_line, color = color.new(color.green,90))
fill(L_SL_line, entry_line, color = color.new(color.red,90))
fill(S_SL_line, entry_line, color = color.new(color.red,90))


// ---------------------------------- strategy setup ------------------------------------------------------

var L_entry_trigger1 = false
var S_entry_trigger1 = false

L_entry_trigger1 := ema_bull and close < ema1 and k < 20 and strategy.position_size == 0
S_entry_trigger1 := ema_bear and close > ema1 and k > 80 and strategy.position_size == 0

L_entry1 = L_entry_trigger1[1] and stoch_crossup and recent_low > previous_low
S_entry1 = S_entry_trigger1[1] and stoch_crossdown and recent_high < previous_high

//debugging
plot(L_entry_trigger1[1]?1:0, "L Entry Trigger")
plot(stoch_crossup?1:0, "Stoch Cross Up")
plot(recent_low > previous_low?1:0, "Higher low")

plot(S_entry_trigger1[1]?1:0, "S Entry Trigger")
plot(stoch_crossdown?1:0, "Stoch Cross down")
plot(recent_high < previous_high?1:0, "Lower high")

if L_entry1
    strategy.entry("Long", strategy.long)

if S_entry1
    strategy.entry("Short", strategy.short)

strategy.exit("Exit Long", "Long", limit = L_PT, stop = L_SL, comment_profit = "Exit Long, PT hit", comment_loss = "Exit Long, SL hit")
strategy.exit("Exit Short", "Short", limit = S_PT, stop = S_SL, comment_profit = "Exit Short, PT hit", comment_loss = "Exit Short, SL hit")

//resetting triggers
L_entry_trigger1 := L_entry_trigger1[1] ? L_entry1 or ema_bear or S_entry1 ? false : true : L_entry_trigger1
S_entry_trigger1 := S_entry_trigger1[1] ? S_entry1 or ema_bull or L_entry1 ? false : true : S_entry_trigger1

//Trigger zones
bgcolor(L_entry_trigger1 ? color.new(color.green ,90) : na)
bgcolor(S_entry_trigger1 ? color.new(color.red,90) : na)

もっと