スーパートレンド指標とエクイティカーブ取引に基づく定量戦略


作成日: 2024-01-15 11:41:53 最終変更日: 2024-01-15 11:41:53
コピー: 1 クリック数: 601
1
フォロー
1617
フォロワー

スーパートレンド指標とエクイティカーブ取引に基づく定量戦略

概要

この戦略の核心的な考え方は,超トレンド指標と純値曲線を組み合わせて取引することであり,超トレンド指標が買ったり売ったりするシグナルを発信すると,我々は直接取引を実行するのではなく,現在の純値曲線が移動平均より低いかどうかを判断する. 純値曲線が移動平均より高い場合にのみ,我々はポジションを開く. 純値曲線が移動平均より低いときは,我々は現在の戦略の取引を停止する.

戦略原則

この戦略は主に2つの部分から構成されています.

  1. 超トレンド指標
  2. 純資産曲線取引

超トレンド指数の計算式は以下のとおりである.

上線 = 源価格 - ATRの倍数 * ATR 下線 = 源価格 + ATR 倍数 * ATR

その中でATRは平均真波幅を表している.超トレンド指標はATRを利用して上下線を設定し,価格が上下線を突破すると売り信号,価格が下下線を突破すると買い信号である.

純価曲線取引の考え方は,戦略の純価曲線を移動平均にして,純価曲線が移動平均より低いとき,現在の戦略の取引を一時停止し,純価曲線が移動平均より上昇するまで待って,再び取引を開始することです.

この戦略は,両者を組み合わせて,超トレンド指標が取引信号を生じさせた後,我々は直接取引するのではなく,現在の純値曲線が移動平均より高いかどうかを判断する.両者が同時に条件を満たす場合にのみ,我々はポジションを開きます.これは,超トレンド指標そのもののリスクを効果的に回避し,過大な損失を防ぐことができます.

優位分析

この戦略の主な利点は

  1. 超トレンド指標のリスクを効果的に防ぐことができる.超トレンド指標自体は損失を効果的に回避することはできません.純資産曲線取引は,この欠陥を補うことができます.

  2. 取引が不利なときは,戦略の取引を一時停止して,過大な損失を避けることができる.市場が転換するまで再開できるまで待つことができる.

  3. ポジションを自動で管理し,人工の介入を必要としません. 純値曲線が移動平均より低ければ自動的に停止し,高ければ自動的に起動します.

リスク分析

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

  1. パラメータ設定の誤りにより,純資産曲線取引の効果を有効に発揮できない可能性があります.適切な移動平均周期を選択する必要があります.

  2. 市場動向が変化したときに,ポジションを適時に調整できないかもしれない。これは一定の損失をもたらすだろう。

  3. 純資産曲線が上昇するのを待つことで,入場の良い機会を逃す可能性があります.

対策として

  1. パーメータを最適化し,最適な移動平均周期を選択する.

  2. 他の指標とトレンドを組み合わせて,タイミングでポジションを調整する.

  3. 取引を一時停止する時間を短縮し,入場を逃す確率を減らす.

最適化の方向

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

  1. 異なるパラメータの組み合わせをテストして,最適なATR周期とATR倍数を見つけます.

  2. 指数移動平均,ハル移動平均など,他の種類の移動平均を試してみてください.

  3. 市場動向を判断する他の指標を追加し,動向が変化した時にポジションを適時調整する.

  4. 移動平均周期を最適化し,最適なバランスポイントを見つけます. 周期が長すぎるとチャンスを逃し,短すぎると頻繁に停止します.

  5. 取引停止の条件を最適化します.例えば,損失が一定程度に達した後にのみ停止するストップ・ロースラインを設定します.

要約する

この戦略は超トレンド指数と純値曲線取引を巧妙に組み合わせている.超トレンド指数によるトレンド判断の利点が保たれても,純値曲線取引によってリスクが効果的に管理されている.テスト結果は,ほとんどの場合,純値曲線取引を適用することは,収益性のレベルを低下させることを示している.したがって,この戦略は防衛型のトレーダーに適している.パラメータ最適化とルール最適化により,この戦略は非常に実用的な量化取引戦略になることができる.

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

//@version=5
strategy('Supertrend & Equity curve with EMA', overlay=false, format=format.price, precision=2, initial_capital=100000)

eqlen = input.int(25, "EQ EMA len", group = "New Equity Curve Settings")
shEQandMA = input.bool(true, "Show Original Equity Curve and MA")
shEQfilt = input.bool(true, "Show Filtered Equity Curve by MA")

Periods = input(title='ATR Period', defval=10, group = "SuperTrend Settings")
src = input(hl2, title='Source', group = "SuperTrend Settings")
Multiplier = input.float(title='ATR Multiplier', step=0.1, defval=3.0, group = "SuperTrend Settings")
changeATR = input(title='Change ATR Calculation Method ?', defval=true, group = "SuperTrend Settings")

//SuperTrend Code
atr2 = ta.sma(ta.tr, Periods)
atr = changeATR ? ta.atr(Periods) : atr2
up = src - Multiplier * atr
up1 = nz(up[1], up)
up := close[1] > up1 ? math.max(up, up1) : up
dn = src + Multiplier * atr
dn1 = nz(dn[1], dn)
dn := close[1] < dn1 ? math.min(dn, dn1) : dn
trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend

// Strategy main code
buySignal = trend == 1 and trend[1] == -1
sellSignal = trend == -1 and trend[1] == 1
if buySignal
    strategy.entry('Long', strategy.long)
if sellSignal
    strategy.entry('Short', strategy.short)



//Equity Curve calcs
eq = strategy.netprofit
ch = ta.change(eq)
neq = ch != 0 ? eq : na
mova = ta.ema(neq,eqlen)

// New Equity Curve
var float neweq = 0
var int ttrades = 0
var int wintrades = 0
var int losetrades = 0

switch
    strategy.netprofit == strategy.netprofit[1]  => na
    strategy.netprofit < mova and strategy.netprofit[1] > mova  => neweq := neweq + ch
    strategy.netprofit < mova and strategy.netprofit[1] < mova => na
    strategy.netprofit > mova and strategy.netprofit[1] > mova => neweq := neweq + ch

newch = ta.change(neweq)
switch
    newch == 0 => na
    newch > 0 => 
        wintrades := wintrades +1
        ttrades := ttrades +1
    newch < 0 =>
        losetrades := losetrades +1
        ttrades := ttrades +1

//plot(eq, linewidth = 2)
//plot(mova, color=color.red)
//plot(neweq, color= color.green, linewidth = 3)


//Table 
var testTable = table.new(position = position.top_right, columns = 5, rows = 10, bgcolor = color.green, border_width = 1)
table.cell(table_id = testTable, column = 0, row = 0, text = "Strategy: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 1, row = 0, text = "Original: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 2, row = 0, text = "Equity Curve EMA: ", bgcolor=color.white)     

table.cell(table_id = testTable, column = 0, row = 1, text = "Total Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 2, text = "Win Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 3, text = "Lose Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 4, text = "Win Rate: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 5, text = "Net Profit: ", bgcolor=color.white)     

//Equity Curve EMA stat
table.cell(table_id = testTable, column = 2, row = 1, text = str.tostring(ttrades), bgcolor=color.white)     
table.cell(table_id = testTable, column = 2, row = 2, text = str.tostring(wintrades), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 3, text = str.tostring(losetrades), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 4, text = str.tostring(math.round(100*wintrades/ttrades,2)), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 5, text = str.tostring(math.round(neweq)), bgcolor=color.white)

//Original Strategy stat
// table.cell(table_id = testTable, column = 1, row = 1, text = str.tostring(strategy.closedtrades), bgcolor=color.white)     
// table.cell(table_id = testTable, column = 1, row = 2, text = str.tostring(strategy.wintrades), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 3, text = str.tostring(strategy.losstrades), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 4, text = str.tostring(math.round(100*strategy.wintrades/strategy.closedtrades,2)), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 5, text = str.tostring(math.round(strategy.netprofit)), bgcolor=color.white)




//New Equity curve
var newcurve = array.new_float(0)
var int ida = 0
var bool printEQ = false
if newch !=0 
    array.push(newcurve, neweq)
if bar_index > last_bar_index - array.size(newcurve) - 1 - 20  and array.size(newcurve) > 20 
    printEQ := true
else
    printEQ := false

plot(printEQ and ida < strategy.closedtrades and shEQfilt ? array.get(newcurve, ida) : na, color=color.green, linewidth = 2)

if printEQ
    ida := ida + 1
if ida >= array.size(newcurve) and printEQ
    ida := array.size(newcurve) -1



//Original Equity curve
var newcurve2 = array.new_float(0)
var int ida2 = 0
var bool printEQ2 = false
if ch !=0 
    array.push(newcurve2, eq)
if bar_index > last_bar_index - array.size(newcurve2) - 1 - 20  and array.size(newcurve2) > 20 
    printEQ2 := true
else
    printEQ2 := false

plot(printEQ2 and ida2 < strategy.closedtrades and shEQandMA  ? array.get(newcurve2, ida2) : na, color=color.blue, linewidth = 2)

if printEQ2
    ida2 := ida2 + 1
if ida2 >= array.size(newcurve2) and printEQ2
    ida2 := array.size(newcurve2) -1



//Moving Average Array
var marray = array.new_float(0)
if ch
    array.push(marray, mova)

plot(printEQ2 and  array.size(marray) > 40 and shEQandMA ? array.get(marray, ida2-1) : na, color=color.red, linewidth = 1)

hline(0,"0 line", color=color.black, linestyle = hline.style_dotted)


if (last_bar_index-1) and array.size(newcurve2) > 20 and array.size(newcurve) > 20
    l = label.new(bar_index+2, array.get(newcurve2, array.size(newcurve2)-1), "Original Equity Curve", color=color.rgb(33, 149, 243, 85), textcolor = color.black, style = label.style_label_left)
    label.delete(l[1])
    f = label.new(bar_index+2, array.get(newcurve, array.size(newcurve)-1), "Filtered Equity Curve", color=color.rgb(69, 238, 97, 85), textcolor = color.black, style = label.style_label_left)
    label.delete(f[1])