モメントブレイク逆転取引戦略

作者: リン・ハーンチャオチャン開催日:2023年10月27日17時04分48秒
タグ:

img

概要

この戦略は,トレンドの方向性を決定するために単純な移動平均を使用し,上昇傾向ではロングで,下落傾向ではショートで逆転取引を実施します.

戦略の論理

この戦略は,市場傾向の方向性を決定するために,重度の移動平均 (VWMA) を使用します.VWMAが上昇するときに長くなって,VWMAが落ちるときに短くなります.

具体的には,最初に特定の期間のVWMAを計算し,その後VWMAが5日以上上昇したかどうかを判断します.そうであれば,ロングポジションを開きます.VWMAが5日以上下落した場合,ショートポジションを開きます.閉じる条件は,VWMAの方向が5日以上逆転したときです.

戦略は毎月と年収を計算するために,毎月と年の利益/損失を記録します.この戦略の収益を市場ベンチマークと比較することで,相対的なパフォーマンスを視覚的に見ることができます.

利点分析

この戦略の利点は以下の通りです.

  1. トレンドを判断するために VWMA を使用することで,市場のノイズを効果的にフィルタリングし,主要なトレンドを把握することができます.

  2. トレンドが確認された後のみ ポジションを開設すると,トレンド逆転に関連するリスクが回避できます.

  3. 逆転取引は 上向きと下向きの両方から利益を得ることができます.

  4. 月間・年次収益を記録することで 戦略の業績を評価することが容易になります

  5. 市場基準の収益を追加することで 戦略と市場の直接的な比較が可能になります

リスク分析

この戦略のリスクは

  1. トレンドを判断するために VWMA を使用すると,トレンドの開始時に遅れて機会を逃す可能性があります.

  2. 確認後のみ ポジションを開く場合 動きが見逃される可能性があります

  3. リバース・トレーディングはストップ・ロスを設定する必要があります そうでなければ損失は拡大する可能性があります

  4. 市場変動が大きい場合,ストップロスは引き起こす可能性があり,トレンド全体を維持できない場合もあります.

  5. トレンド逆転判断は誤りで損失を増やす可能性があります.

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

戦略を最適化できる部分:

  1. トレンド決定を改善するために,VWMA 期間パラメータを最適化する.

  2. トレンドを確認するために日数を調整し,入出タイミングを改善します.

  3. ストップ・ロスの戦略を追加して単一の取引損失を制御します.

  4. 確実性を高めるため,逆転を決定するための他の指標を組み込む.

  5. 市場の状況に基づいてポジションのサイズを最適化します

  6. 取引コストを考慮し 最低利益目標を設定します

概要

この戦略の全体的な論理は単純で明確で,確認後にトレンド方向と逆転トレードを決定するために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)

もっと