オープン・ハイ・クロス・オーバー・トレーディング・戦略

作者: リン・ハーンチャオチャン,日付: 2023年10月18日11時22分57秒
タグ:

img

概要

この戦略は,オープン価格と高価格のクロスオーバーに基づいて取引信号を生成する.オープン価格が高価格を超えるとロングになり,オープン価格が高価格を下回るとショートする.移動平均は価格データを滑らかにし,騒々しい取引を減らすために使用できる.移動平均のさまざまな種類とパラメータは構成可能である.トライリングストップロスは利益をロックすることも可能である.

戦略の論理

  1. 入力パラメータ useRes に基づいて代替解像度を使用するかどうかを決定します.有効であれば,解像度を stratRes で設定します.

  2. 入力パラメータに基づいて移動平均値 (useMA) を使用するかどうかを決定します.有効であれば,baseTypeでMA型を選択し,baseLenで期間長さを設定します.

  3. オープン価格 (open) と閉鎖価格 (close) のシリーズデータを取得します. useMA が有効になっている場合,設定されたパラメータで選択されたMA を適用します.

  4. 現在のオープン価格 x をオープンシリーズ openSeries と比較する.x が openSeries より大きい場合,trendState を long に,そうでなければ short に設定する.

  5. オープン価格がオープンMAシリーズの上を横切るときにロング・シグナル・ロング・コンドを生成する. オープン価格がオープンMAシリーズの下を横切るときにショート・シグナル・ショート・コンドを生成する.

  6. ロング・ショート・シグナルに基づいてロング・ショート・ポジションを入力します.ストップ・ロストポイントを設定し,トライリング・ストップ・ロストが有効であればオフセットします.

利点

  1. 2つの異なる価格シリーズ,オープンとハイを使用し,単一のシリーズの制限を避けます.

  2. MA技術では 短期的なノイズをフィルタリングし 主なトレンドに焦点を当てます

  3. 最適な効果のために,MPAの種類とパラメータの柔軟な構成.

  4. リスクをコントロールし 利益を固定するオプションのストップ損失

  5. 異なる製品や市場環境のためのパラメータを調整するための高い最適化空間.

リスク

  1. 単一の信号源は 希少な信号と 失敗する取引につながる可能性があります

  2. MAの遅れは短期的な機会を逃す結果になる可能性があります

  3. 誤ったストップ損失設定は,早速退出または過度の損失につながる可能性があります.

  4. パラメーターの調節が不十分なら 過剰なフィクション取引が 生演奏に影響を与える可能性があります

  5. パラメータ最適化は,さまざまな製品や環境において課題です.

  6. 信号源を豊かにするためにより多くの指標またはMLモデルを追加します. MAタイプとパラメータを細かく調整します. より多くの利益を得るためにいくつかのバッファで注意してストップ損失を設定します. パラメータを徹底的にバックテストして最適化します.

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

  1. 信号源を拡大するために ボリンジャー帯,KDなどなどの追加指標を組み込む

  2. 信号生成に機械学習モデルを適用する.

  3. 最適な設定を見つけるために MA パラメータを最適化します

  4. リスクと利益の捕獲のバランスストップ損失レベル

  5. パラメータ最適化メソッドを追加して,自動で最適な設定を見つけます.

  6. 異なる製品のための特殊なパラメータテンプレートを開発する.

  7. 迅速な戦略の繰り返しのための定量バックテストの枠組みを構築します

概要

この戦略は,オープンハイクロスオーバーに基づいて信号を生成し,ノイズをフィルタリングするためにMAを使用する.設定可能なパラメータを通じて柔軟性を提供する.この戦略には利点があるが,稀な信号や遅延などの問題もある.より多くの指標,機械学習モデルなどを通じてさらなる改善が可能である.さまざまな製品や市場環境の最高のパフォーマンスのために,広範なパラメータチューニングと最適化が必要である.


/*backtest
start: 2022-10-17 00:00:00
end: 2023-10-17 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2

//strategy(title = "Open Close Cross Strategy", shorttitle = "OCC Strategy", overlay = true, pyramiding = 0, default_qty_type = strategy.percent_of_equity, default_qty_value = 10)

// Revision:        1
// Author:          @JayRogers
//
// Description:
//  - Strategy based around Open-Close Crossovers.
// Setup:
//  - I have generally found that setting the strategy resolution to 3-4x that of the chart you are viewing
//    tends to yield the best results, regardless of which MA option you may choose (if any)
//  - Don't aim for perfection. Just aim to get a reasonably snug fit with the O-C band, with good runs of
//    green and red.
//  - Option to either use basic open and close series data, or pick your poison with a wide array of MA types.
//  - Optional trailing stop for damage mitigation if desired (can be toggled on/off)
//  - Positions get taken automagically following a crossover - which is why it's better to set the resolution
//    of the script greater than that of your chart, so that the trades get taken sooner rather than later.
//  - If you make use of the trailing stops, be sure to take your time tweaking the values. Cutting it too fine
//    will cost you profits but keep you safer, while letting them loose could lead to more drawdown than you
//    can handle.

// === INPUTS ===
useRes      = input(defval = true, title = "Use Alternate Resolution? ( recommended )")
stratRes    = input(defval = "120", title = "Set Resolution ( should not be lower than chart )")
useMA       = input(defval = true, title = "Use MA? ( otherwise use simple Open/Close data )")
basisType   = input(defval = "DEMA", title = "MA Type: SMA, EMA, DEMA, TEMA, WMA, VWMA, SMMA, HullMA, LSMA, ALMA ( case sensitive )")
basisLen    = input(defval = 14, title = "MA Period", minval = 1)
offsetSigma = input(defval = 6, title = "Offset for LSMA / Sigma for ALMA", minval = 0)
offsetALMA  = input(defval = 0.85, title = "Offset for ALMA", minval = 0, step = 0.01)
useStop     = input(defval = true, title = "Use Trailing Stop?")
slPoints    = input(defval = 200, title = "Stop Loss Trail Points", minval = 1)
slOffset    = input(defval = 400, title = "Stop Loss Trail Offset", minval = 1)
// === /INPUTS ===

// === BASE FUNCTIONS ===
// Returns MA input selection variant, default to SMA if blank or typo.
variant(type, src, len, offSig, offALMA) =>
    v1 = sma(src, len)                                                  // Simple
    v2 = ema(src, len)                                                  // Exponential
    v3 = 2 * v2 - ema(v2, len)                                          // Double Exponential
    v4 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len)               // Triple Exponential
    v5 = wma(src, len)                                                  // Weighted
    v6 = vwma(src, len)                                                 // Volume Weighted
    v7 = na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len    // Smoothed
    v8 = wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len)))   // Hull
    v9 = linreg(src, len, offSig)                                       // Least Squares
    v10 = alma(src, len, offALMA, offSig)                               // Arnaud Legoux
    type=="EMA"?v2 : type=="DEMA"?v3 : type=="TEMA"?v4 : type=="WMA"?v5 : type=="VWMA"?v6 : type=="SMMA"?v7 : type=="HullMA"?v8 : type=="LSMA"?v9 : type=="ALMA"?v10 : v1
// security wrapper for repeat calls
reso(exp, use, res) => use ? request.security(syminfo.tickerid, res, exp) : exp
// === /BASE FUNCTIONS ===

// === SERIES SETUP ===
// open/close
//closeSeries = useMA ? reso(variant(basisType, close, basisLen, offsetSigma, offsetALMA), useRes, stratRes) : reso(close, useRes, stratRes)
openSeries  = useMA ? reso(variant(basisType, open, basisLen, offsetSigma, offsetALMA), useRes, stratRes) : reso(open, useRes, stratRes)
x = openSeries[1]
trendState  = x > openSeries ? true : x < openSeries ? false : trendState[1]
// === /SERIES ===

// === PLOTTING ===
barcolor(color = x > openSeries ? #006600 : #990000, title = "Bar Colours")
// channel outline
closePlot   = plot(x, title = "Close Line", color = #009900, linewidth = 2, style = line, transp = 90)
openPlot    = plot(openSeries, title = "Open Line", color = #CC0000, linewidth = 2, style = line, transp = 90)
// channel fill
closePlotU  = plot(trendState ? x : na, transp = 100, editable = false)
openPlotU   = plot(trendState ? openSeries : na, transp = 100, editable = false)
closePlotD  = plot(trendState ? na : x, transp = 100, editable = false)
openPlotD   = plot(trendState ? na : openSeries, transp = 100, editable = false)
fill(openPlotU, closePlotU, title = "Up Trend Fill", color = #009900, transp = 40)
fill(openPlotD, closePlotD, title = "Down Trend Fill", color = #CC0000, transp = 40)
// === /PLOTTING ===

// === STRATEGY ===
// conditions
longCond    = crossover(openSeries, x)
shortCond   = crossunder(openSeries, x)
// entries and base exit
strategy.entry("long", true, when = longCond)
strategy.entry("short", false, when = shortCond)
// if we're using the trailing stop
//if (useStop)
//    strategy.exit("XL", from_entry = "long", trail_points = slPoints, trail_offset = slOffset)
//    strategy.exit("XS", from_entry = "short", trail_points = slPoints, trail_offset = slOffset)
// not sure needed, but just incase..
//strategy.exit("XL", from_entry = "long", when = shortCond)
//strategy.exit("XS", from_entry = "short", when = longCond)
// === /STRATEGY ===

もっと