オープン・クローズ・クロスポイント戦略

作者: リン・ハーンチャオチャン, 日付: 2023-12-13 15:51:13
タグ:

img

概要

オープン・クローズ・クロスポイント戦略は,移動平均のクロスオーバーに基づいた定量的な取引戦略である. 移動平均のクロスオーバーを計算することによって価格動向を決定し,クロスオーバーポイントで買い売り信号を生成する. この戦略は,ハル・ムービング・アベアを高速ライン,スーパー・スムース・フィルターをスローラインとして使用する. この組み合わせは,移動平均のスムーズ性とトレンド決定能力の両方を組み込み,比較的信頼性の高い取引信号を生み出すために価格動向を効果的に識別することができます.

戦略原則

オープン・クローズ・クロスポイント戦略を計算する式は以下のとおりである. スピードライン (Hull MA): WMA ((2 * WMA ((価格,n/2) - WMA ((価格,n),SQRT ((n)) スローライン (超スムーズフィルター): 価格トリプルフィルター

WMAは重度の移動平均値であり,SQRTは平方根であり,フィルターは1つの第1順次遅延項と2つの第2順位遅延項を含みます.

戦略は,速度と遅さの関係を計算して判断します. 高速線の上向きクロスオーバーは購入信号です
ダウンクロスオーバーの高速ラインは販売信号です

利点分析

オープン・クローズ・クロス・ポイント戦略は,ダブル・ムービング・平均判断とポイント・トレーディングの利点を組み合わせている.タイムリーなエントリーと出口のためのトレンドターニングポイントを正確に把握することができる.シングル・ムービング・平均戦略と比較して,以下の利点がある:

  1. 二重移動平均の組み合わせは誤った信号を排除します.速い線はトレンドの方向/強さを決定し,遅い線は振動をフィルタリングし,信号はより信頼性になります.
  2. スーパースムースフィルターは 価格動向を効果的に抽出する 優れたデータフィッティング能力を備えています
  3. Hull MAは価格変動に敏感で,時速に逆転を検知できる.

リスク分析

オープン・クローズ・クロス・ポイント戦略には リスクもあります

  1. 変動市場ではより多くのウィップソー信号が発生する.誤った信号を減らすためにMA間の間隔を拡大することができます.
  2. MA の間隔があまりにも広い場合,いくつかの機会が失われる可能性があります.信号の量と質をバランスする必要があります.
  3. この戦略は,より明確な傾向を持つ製品に適しており,非常に揮発性のある製品には推奨されません.

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

オープン・クローズ・クロス・ポイント戦略は,次の次元で最適化できる.

  1. 異なる期間の商品と変動範囲に合わせて MA パラメータを調整する.
  2. トレンド品質を決定するために補足的な指標やフィルターを追加し,ウィップソウを減らす.
  3. トレンド強度指標を組み込むことでポジションサイズを最適化する.

結論

オープン・クローズ・クロスポイント戦略は,より高度かつ信頼性の高い定量的な取引スキームを形成するために,二重移動平均判断とポイント取引モデルの使用を拡大しながら,移動平均戦略の利点を受け継いでいます. タイムリング取引において,ライブテストとアプリケーション探求に値するユニークな利点があります. この記事は,この戦略の原則,強み,弱点を徹底的に解析し,参考のために最適化アイデアを提供します. モデルとパラメータの継続的な改善により,この戦略は,強力な市場タイムリングツールになるでしょう.


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

//@version=5
//

strategy(title='Open Close Cross Strategy ', shorttitle='sacinvesting', overlay=true, pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=10, calc_on_every_tick=false)

// === INPUTS ===
useRes = input(defval=true, title='Use Alternate Resolution?')
intRes = input(defval=3, title='Multiplier for Alernate Resolution')
stratRes = timeframe.ismonthly ? str.tostring(timeframe.multiplier * intRes, '###M') : timeframe.isweekly ? str.tostring(timeframe.multiplier * intRes, '###W') : timeframe.isdaily ? str.tostring(timeframe.multiplier * intRes, '###D') : timeframe.isintraday ? str.tostring(timeframe.multiplier * intRes, '####') : '60'
basisType = input.string(defval='SMMA', title='MA Type: ', options=['SMA', 'EMA', 'DEMA', 'TEMA', 'WMA', 'VWMA', 'SMMA', 'HullMA', 'LSMA', 'ALMA', 'SSMA', 'TMA'])
basisLen = input.int(defval=8, title='MA Period', minval=1)
offsetSigma = input.int(defval=6, title='Offset for LSMA / Sigma for ALMA', minval=0)
offsetALMA = input.float(defval=0.85, title='Offset for ALMA', minval=0, step=0.01)
scolor = input(false, title='Show coloured Bars to indicate Trend?')
delayOffset = input.int(defval=0, title='Delay Open/Close MA (Forces Non-Repainting)', minval=0, step=1)
tradeType = input.string('BOTH', title='What trades should be taken : ', options=['LONG', 'SHORT', 'BOTH', 'NONE'])
// === /INPUTS ===

// Constants colours that include fully non-transparent option.
green100 = #008000FF
lime100 = #00FF00FF
red100 = #FF0000FF
blue100 = #0000FFFF
aqua100 = #00FFFFFF
darkred100 = #8B0000FF
gray100 = #808080FF

// === BASE FUNCTIONS ===
// Returns MA input selection variant, default to SMA if blank or typo.
variant(type, src, len, offSig, offALMA) =>
    v1 = ta.sma(src, len)  // Simple
    v2 = ta.ema(src, len)  // Exponential
    v3 = 2 * v2 - ta.ema(v2, len)  // Double Exponential
    v4 = 3 * (v2 - ta.ema(v2, len)) + ta.ema(ta.ema(v2, len), len)  // Triple Exponential
    v5 = ta.wma(src, len)  // Weighted
    v6 = ta.vwma(src, len)  // Volume Weighted
    v7 = 0.0
    sma_1 = ta.sma(src, len)  // Smoothed
    v7 := na(v7[1]) ? sma_1 : (v7[1] * (len - 1) + src) / len
    v8 = ta.wma(2 * ta.wma(src, len / 2) - ta.wma(src, len), math.round(math.sqrt(len)))  // Hull
    v9 = ta.linreg(src, len, offSig)  // Least Squares
    v10 = ta.alma(src, len, offALMA, offSig)  // Arnaud Legoux
    v11 = ta.sma(v1, len)  // Triangular (extreme smooth)
    // SuperSmoother filter
    // ©️ 2013 John F. Ehlers
    a1 = math.exp(-1.414 * 3.14159 / len)
    b1 = 2 * a1 * math.cos(1.414 * 3.14159 / len)
    c2 = b1
    c3 = -a1 * a1
    c1 = 1 - c2 - c3
    v12 = 0.0
    v12 := c1 * (src + nz(src[1])) / 2 + c2 * nz(v12[1]) + c3 * nz(v12[2])
    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 : type == 'TMA' ? v11 : type == 'SSMA' ? v12 : v1

// security wrapper for repeat calls
reso(exp, use, res) =>
    security_1 = request.security(syminfo.tickerid, res, exp, gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)
    use ? security_1 : exp

// === /BASE FUNCTIONS ===

// === SERIES SETUP ===
closeSeries = variant(basisType, close[delayOffset], basisLen, offsetSigma, offsetALMA)
openSeries = variant(basisType, open[delayOffset], basisLen, offsetSigma, offsetALMA)
// === /SERIES ===

// === PLOTTING ===

// Get Alternate resolution Series if selected.
closeSeriesAlt = reso(closeSeries, useRes, stratRes)
openSeriesAlt = reso(openSeries, useRes, stratRes)
//
trendColour = closeSeriesAlt > openSeriesAlt ? color.green : color.red
bcolour = closeSeries > openSeriesAlt ? lime100 : red100
barcolor(scolor ? bcolour : na, title='Bar Colours')
closeP = plot(closeSeriesAlt, title='Close Series', color=trendColour, linewidth=2, style=plot.style_line, transp=20)
openP = plot(openSeriesAlt, title='Open Series', color=trendColour, linewidth=2, style=plot.style_line, transp=20)
fill(closeP, openP, color=trendColour, transp=80)

// === /PLOTTING ===
//
//
// === ALERT conditions
xlong = ta.crossover(closeSeriesAlt, openSeriesAlt)
xshort = ta.crossunder(closeSeriesAlt, openSeriesAlt)
longCond = xlong  // alternative: longCond[1]? false : (xlong or xlong[1]) and close>closeSeriesAlt and close>=open
shortCond = xshort  // alternative: shortCond[1]? false : (xshort or xshort[1]) and close<closeSeriesAlt and close<=open
// === /ALERT conditions.

// === STRATEGY ===
// stop loss
slPoints = input.int(defval=0, title='Initial Stop Loss Points (zero to disable)', minval=0)
tpPoints = input.int(defval=0, title='Initial Target Profit Points (zero for disable)', minval=0)
// Include bar limiting algorithm
ebar = input.int(defval=10000, title='Number of Bars for Back Testing', minval=0)
dummy = input(false, title='- SET to ZERO for Daily or Longer Timeframes')
//
// Calculate how many mars since last bar
tdays = (timenow - time) / 60000.0  // number of minutes since last bar
tdays := timeframe.ismonthly ? tdays / 1440.0 / 5.0 / 4.3 / timeframe.multiplier : timeframe.isweekly ? tdays / 1440.0 / 5.0 / timeframe.multiplier : timeframe.isdaily ? tdays / 1440.0 / timeframe.multiplier : tdays / timeframe.multiplier  // number of bars since last bar
//
//set up exit parameters
TP = tpPoints > 0 ? tpPoints : na
SL = slPoints > 0 ? slPoints : na

// Make sure we are within the bar range, Set up entries and exit conditions
if (ebar == 0 or tdays <= ebar) and tradeType != 'NONE'
    strategy.entry('long', strategy.long, when=longCond == true and tradeType != 'SHORT')
    strategy.entry('short', strategy.short, when=shortCond == true and tradeType != 'LONG')
    strategy.close('long', when=shortCond == true and tradeType == 'LONG')
    strategy.close('short', when=longCond == true and tradeType == 'SHORT')
    strategy.exit('XL', from_entry='long', profit=TP, loss=SL)
    strategy.exit('XS', from_entry='short', profit=TP, loss=SL)

// === /STRATEGY ===
// eof



もっと