トレンド平均に基づく多重反転戦略


作成日: 2023-11-21 14:53:48 最終変更日: 2023-11-21 14:53:48
コピー: 0 クリック数: 601
1
フォロー
1621
フォロワー

トレンド平均に基づく多重反転戦略

概要

この戦略は,複数のトレンド指標を計算して,それらの反転が起きた時に買いと売却の操作を行います. 主要なトレンド指標はTDI,TCF,TTF,TIIです. 戦略は,取引シグナルを生成するためにどの指標を使用するかを設定で選択します.

戦略原則

  • ### TDI指標

TDI指標は,価格の変化のモメンタムに基づいて計算する. 合計とスムージング技術で構築する. TDI方向指標がTDI曲線を横切るときに多めに,横切るときに清算する.

  • ### TCF指標

TCF指数は,多頭と空頭の力を判断するために,価格の正の変化と負の変化を計算する.正の変化の力が負の変化の力より大きいとき,多頭する.そうでなければ,清算する.

  • ### TTF指標

TTF指数は,高点と低点の力を比較してトレンドを判断する.多額のシグナルは,TTF指数で100を突破し,逆に清算する.

  • ### TII指標

TII指数は,平均線と価格区間を組み合わせてトレンドの逆転を判断する.それは,短期と長期のトレンドを同時に考慮する.多信号は,TII指数が80を突破し,清算は,80を突破する.

配置された指標に基づいて適切な取引シグナルを選択する.

戦略的優位性

この戦略は,多くの一般的なトレンド取引指標を統合し,市場環境に柔軟に適応することができます.具体的には,次の利点があります:

  1. トレンドリバーシンの信号を利用して,トレンド転換の機会を間に合うように捉える
  2. 異なる指標を配置して,ターゲットに最適化できます
  3. 豊富な指標の組み合わせで,信号を確認できます

戦略リスク

この戦略には以下のリスクがあります.

  1. トレンド指数による取引信号の誤報により損失が発生する可能性がある
  2. 単一の指標では,トレンドを完全に判断できず,市場騒音の影響を受けやすい.
  3. 指数パラメータと取引パラメータを正しく配置しないことは,市場を歪曲し,誤った取引を引き起こす可能性があります.

リスクを下げるには以下の方法があります.

  1. 指標パラメータを最適化して,最適なパラメータの組み合わせを見つける
  2. 複数の指標信号を組み合わせて取引し,信号の質を向上させる
  3. ポジション管理戦略を調整し,単発損失を制御する

戦略最適化の方向性

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

  1. 異なる市場サイクルにおける最適な指標とパラメータの組み合わせをテストする
  2. 測定値の追加や削除により,最適の測定値の組み合わせが求められます.
  3. 取引信号をフィルタリングし,誤報信号を削除する
  4. ポジション管理戦略の最適化,例えば,可変ポジション,ストップ・ロスの追跡など
  5. 信号の質を判断する機械学習のスコア指標を追加

要約する

この戦略は,複数のトレンド反転指標の優位性を組み合わせて,指数とパラメータを配置して最適化することで,異なる市場環境に適応し,トレンド反転ポイントで操作することができる.鍵は,最適のパラメータと指標の組み合わせを見つけ,リスクを制御することにある.継続的な最適化と検証により,安定したアルファを持つ戦略を構築することができる.

ストラテジーソースコード
/*backtest
start: 2023-11-13 00:00:00
end: 2023-11-15 03:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
//
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © kruskakli
//
// Here is a collection of Trend Indicators as defined by M.H Pee and presented
// in various articles of the "STOCKS & COMMODITIES Magazine"
//
// The actual implementation of the indicators here are made by: everget
//
// I have gather them here so that they easily can be tested.
//
// My own test was made using 15 companies from the OMXS30 list
// during the time period of 2016-2018, and I only went LONG.
//
// The result was as follows:
//
//        Average    Std.Dev
//        profit
//  TDI    3.04%      5.97
//  TTF    1.22%.     5.73
//  TII    1.07%      6.2
//  TCF    0.32%      2.68
//
strategy("M.H Pee indicators", overlay=true)


use = input(defval="TDI", title="Use Indicator", type=input.string,
             options=["TDI","TCF","TTF","TII"])

src = close


//
// TDI
//
length = input(title="Length", type=input.integer, defval=20)
mom = change(close, length)
tdi = abs(sum(mom, length)) - sum(abs(mom), length * 2) + sum(abs(mom), length)
// Direction Indicator
tdiDirection = sum(mom, length)
tdiLong = crossover(tdiDirection, tdi)
tdiXLong = crossunder(tdiDirection, tdi)

//
// TCF
//
tcflength = input(title="Length", type=input.integer, defval=35)

plusChange(src) =>
    change_1 = change(src)
    change(src) > 0 ? change_1 : 0.0
minusChange(src) =>
    change_1 = change(src)
    change(src) > 0 ? 0.0 : -change_1

plusCF = 0.0
plusChange__1 = plusChange(src)
plusCF := plusChange(src) == 0 ? 0.0 : plusChange__1 + nz(plusCF[1])

minusCF = 0.0
minusChange__1 = minusChange(src)
minusCF := minusChange(src) == 0 ? 0.0 : minusChange__1 + nz(minusCF[1])

plusTCF = sum(plusChange(src) - minusCF, tcflength)
minusTCF = sum(minusChange(src) - plusCF, tcflength)

tcfLong = plusTCF > 0 
tcfXLong = plusTCF < 0

//
// TTF
//
ttflength = input(title="Lookback Length", type=input.integer, defval=15)

hh = highest(length)
ll = lowest(length)

buyPower = hh - nz(ll[length])
sellPower = nz(hh[length]) - ll

ttf = 200 * (buyPower - sellPower) / (buyPower + sellPower)

ttfLong = crossover(ttf, 100)
ttfXLong = crossunder(ttf, -100)

//
// TII
//
majorLength = input(title="Major Length", type=input.integer, defval=60)
minorLength = input(title="Minor Length", type=input.integer, defval=30)
upperLevel = input(title="Upper Level", type=input.integer, defval=80)
lowerLevel = input(title="Lower Level", type=input.integer, defval=20)

sma = sma(src, majorLength)

positiveSum = 0.0
negativeSum = 0.0

for i = 0 to minorLength - 1 by 1
    price = nz(src[i])
    avg = nz(sma[i])
    positiveSum := positiveSum + (price > avg ? price - avg : 0)
    negativeSum := negativeSum + (price > avg ? 0 : avg - price)
    negativeSum

tii = 100 * positiveSum / (positiveSum + negativeSum)

tiiLong = crossover(tii, 80)
tiiXLong = crossunder(tii,80)

//
// LOGIC 
//
enterLong = (use == "TDI" and tdiLong) or (use == "TCF" and tcfLong) or (use == "TTF" and ttfLong) or (use == "TII" and tiiLong)
exitLong = (use == "TDI" and tdiXLong) or (use == "TCF" and tcfXLong) or (use == "TTF" and ttfXLong) or (use == "TII" and tiiXLong)


// Time range for Back Testing
btStartYear  = input(title="Back Testing Start Year",  type=input.integer, defval=2016)
btStartMonth = input(title="Back Testing Start Month", type=input.integer, defval=1)
btStartDay   = input(title="Back Testing Start Day",   type=input.integer, defval=1)
startTime = timestamp(btStartYear, btStartMonth, btStartDay, 0, 0)

btStopYear  = input(title="Back Testing Stop Year",  type=input.integer, defval=2028)
btStopMonth = input(title="Back Testing Stop Month", type=input.integer, defval=12)
btStopDay   = input(title="Back Testing Stop Day",   type=input.integer, defval=31)
stopTime  = timestamp(btStopYear, btStopMonth, btStopDay, 0, 0)

window() => time >= startTime and time <= stopTime ? true : false


riskPerc     = input(title="Max Position  %", type=input.float, defval=20, step=0.5)
maxLossPerc  = input(title="Max Loss Risk %", type=input.float, defval=5, step=0.25)

// Average True Range (ATR) measures market volatility.
// We use it for calculating position sizes.
atrLen   = input(title="ATR Length", type=input.integer, defval=14)
stopOffset = input(title="Stop Offset", type=input.float, defval=1.5, step=0.25)
limitOffset = input(title="Limit Offset", type=input.float, defval=1.0, step=0.25)
atrValue = atr(atrLen)


// Calculate position size
maxPos = floor((strategy.equity * (riskPerc/100)) / src)
// The position sizing algorithm is based on two parts:
// a certain percentage of the strategy's equity and
// the ATR in currency value.
riskEquity  = (riskPerc / 100) * strategy.equity
// Translate the ATR into the instrument's currency value.
atrCurrency = (atrValue * syminfo.pointvalue)
posSize0    = min(floor(riskEquity / atrCurrency), maxPos)
posSize     = posSize0 < 1 ? 1 : posSize0

if (window())
    strategy.entry("Long", long=true, qty=posSize0, when=enterLong)
    strategy.close_all(when=exitLong)