モメンタムブレイクアウト双方向取引戦略


作成日: 2023-10-27 17:04:48 最終変更日: 2023-10-27 17:04:48
コピー: 0 クリック数: 655
1
フォロー
1617
フォロワー

モメンタムブレイクアウト双方向取引戦略

概要

この戦略は,単純移動平均を用いてトレンドの方向を判断し,継続的に上昇するトレンドで多額の取引を行い,継続的に低下するトレンドで空白を行い,双方向の取引を実現します.

戦略原則

この策略は,重量移動平均VWMAを使用して市場の傾向の方向を判断します.VWMAが上昇すると,多額化します.VWMAが低下すると,空白化します.

具体的には,戦略はまず一定の周期のVWMAを計算し,VWMAが5日以上上昇したかどうかを判断し,そうであれば,多めにポジションを開く.VWMAが5日以上下落した場合は,空白を打つ.平仓条件は,VWMAの方向が5日以上逆転した後に平仓する.

策略は,月間および年間収益のパフォーマンスを計算するために,毎月および毎年の収益を記録します. この戦略と市場基準の収益を比較することによって,戦略の相対的な市場のパフォーマンスを直視することができます.

優位分析

この戦略は以下の利点があります.

  1. VWMAを使ってトレンドを判断し,市場騒音を効果的にフィルターして,主要トレンドを捉えます.

  2. トレンドが確認された後にポジションを開くだけで,トレンドの逆転のリスクを回避できます.

  3. 市場が上がったり下がったり,双方向取引で利益を得ることができます.

  4. 戦略の効果を評価するために,月間および年次収益を記録する.

  5. 収益表に市場基準収益を追加し,戦略と市場の相対的なパフォーマンスを直観的に比較することができます.

リスク分析

この戦略にはいくつかのリスクがあります.

  1. VWMAでトレンドを判断すると,トレンドが遅れている可能性があり,トレンドの初期段階のチャンスを逃す可能性があります.

  2. トレンドが確認された後にポジションを開くだけで,Movementの一部を逃す可能性があります.

  3. 双方向取引は,止損点を決定する必要があります.そうでなければ,損失は増加する可能性があります.

  4. 大規模な市場の波動により,ストップが引き出され,トレンドが完全に維持できない.

  5. 逆転の判断は誤りになり,損失を増加させる可能性があります.

最適化の方向

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

  1. VWMA周期パラメータを最適化し,トレンド判断を改善する.

  2. トレンド確認の日数を調整し,出場時間を改善する.

  3. ストップ・ロース戦略を導入し,単発損失を抑制する.

  4. 逆転を判断する他の指標と組み合わせると,確実性が向上する.

  5. ポジション管理の最適化,市場状況に応じてポジションの調整

  6. 取引コストを考慮してMinimumProfitを設定します.

要約する

この戦略の全体的な考え方は明確でシンプルで,VWMAを使用してトレンドの方向を判断し,トレンドが確認された後に双方向取引を行うことで,市場動向を効果的に追跡することができる.しかし,一定のリスクも存在し,パラメータをさらにテストし,最適化し,出場論理を調整し,ポジションの規模を適切に制御する必要がある.この戦略は,双方向取引戦略をベースに,量化取引のための基礎を確立し,さらなる研究と改善に値する.

ストラテジーソースコード
/*backtest
start: 2023-01-01 00:00:00
end: 2023-10-26 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="Monthly Returns in Strategies with Market Benchmark", shorttitle="Monthly P&L With Market", initial_capital= 1000, overlay=true,default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.1)
maLength= input(400)

wma= vwma(hl2,maLength)
uptrend= rising(wma, 5)
downtrend= falling(wma,5)

plot(wma)

if uptrend
    strategy.entry("Buy", strategy.long)
else
    strategy.close("Buy")//

///////////////////
// MONTHLY TABLE //

new_month = month(time) != month(time[1])
new_year  = year(time)  != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1
bar_bh = (close-close[1])/close[1]

cur_month_pnl = 0.0
cur_year_pnl  = 0.0
cur_month_bh = 0.0
cur_year_bh  = 0.0

// Current Monthly P&L
cur_month_pnl := new_month ? 0.0 : 
                 (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 
cur_month_bh := new_month ? 0.0 : 
                 (1 + cur_month_bh[1]) * (1 + bar_bh) - 1

// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1
cur_year_bh := new_year ? 0.0 : 
                 (1 + cur_year_bh[1]) * (1 + bar_bh) - 1

// Arrays to store Yearly and Monthly P&Ls
var month_pnl  = array.new_float(0)
var month_time = array.new_int(0)
var month_bh  = array.new_float(0)

var year_pnl  = array.new_float(0)
var year_time = array.new_int(0)
var year_bh  = array.new_float(0)

last_computed = false

if (not na(cur_month_pnl[1]) and (new_month or time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory))
    if (last_computed[1])
        array.pop(month_pnl)
        array.pop(month_time)
        
    array.push(month_pnl , cur_month_pnl[1])
    array.push(month_time, time[1])
    array.push(month_bh , cur_month_bh[1])

if (not na(cur_year_pnl[1]) and (new_year or time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory))
    if (last_computed[1])
        array.pop(year_pnl)
        array.pop(year_time)
        
    array.push(year_pnl , cur_year_pnl[1])
    array.push(year_time, time[1])
    array.push(year_bh , cur_year_bh[1])

last_computed := (time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory) ? true : nz(last_computed[1])

// Monthly P&L Table    
var monthly_table = table(na)

getCellColor(pnl, bh)  => 
    if pnl > 0
        if bh < 0 or pnl > 2 * bh
            color.new(color.green, transp = 20)
        else if pnl > bh
            color.new(color.green, transp = 50)
        else
            color.new(color.green, transp = 80)
    else
        if bh > 0
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if last_computed
    monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1)

    table.cell(monthly_table, 0,  0, "",     bgcolor = #cccccc)
    table.cell(monthly_table, 1,  0, "Jan",  bgcolor = #cccccc)
    table.cell(monthly_table, 2,  0, "Feb",  bgcolor = #cccccc)
    table.cell(monthly_table, 3,  0, "Mar",  bgcolor = #cccccc)
    table.cell(monthly_table, 4,  0, "Apr",  bgcolor = #cccccc)
    table.cell(monthly_table, 5,  0, "May",  bgcolor = #cccccc)
    table.cell(monthly_table, 6,  0, "Jun",  bgcolor = #cccccc)
    table.cell(monthly_table, 7,  0, "Jul",  bgcolor = #cccccc)
    table.cell(monthly_table, 8,  0, "Aug",  bgcolor = #cccccc)
    table.cell(monthly_table, 9,  0, "Sep",  bgcolor = #cccccc)
    table.cell(monthly_table, 10, 0, "Oct",  bgcolor = #cccccc)
    table.cell(monthly_table, 11, 0, "Nov",  bgcolor = #cccccc)
    table.cell(monthly_table, 12, 0, "Dec",  bgcolor = #cccccc)
    table.cell(monthly_table, 13, 0, "Year", bgcolor = #999999)


    for yi = 0 to array.size(year_pnl) - 1
        table.cell(monthly_table, 0,  yi + 1, tostring(year(array.get(year_time, yi))), bgcolor = #cccccc)
        
        y_color = getCellColor(array.get(year_pnl, yi), array.get(year_bh, yi))
        table.cell(monthly_table, 13, yi + 1, tostring(round(array.get(year_pnl, yi) * 100)) + " (" + tostring(round(array.get(year_bh, yi) * 100)) + ")", bgcolor = y_color)
        
    for mi = 0 to array.size(month_time) - 1
        m_row   = year(array.get(month_time, mi))  - year(array.get(year_time, 0)) + 1
        m_col   = month(array.get(month_time, mi)) 
        m_color = getCellColor(array.get(month_pnl, mi), array.get(month_bh, mi))
        
        table.cell(monthly_table, m_col, m_row, tostring(round(array.get(month_pnl, mi) * 100)) + " (" + tostring(round(array.get(month_bh, mi) * 100)) +")", bgcolor = m_color)