平滑化Zスコアクロスオーバーに基づくモメンタム最適化価格統計取引戦略

Z-SCORE SMA stdev PNL Momentum Filter
作成日: 2025-06-03 10:44:56 最終変更日: 2025-06-03 10:44:56
コピー: 0 クリック数: 330
2
フォロー
319
フォロワー

平滑化Zスコアクロスオーバーに基づくモメンタム最適化価格統計取引戦略 平滑化Zスコアクロスオーバーに基づくモメンタム最適化価格統計取引戦略

概要

この策略は,Zスコア ((Z-Score) という統計学的な概念に基づいている. 価格の局所平均に対する統計的偏差を識別するために使用される. この策略は,閉店価格のZスコアを計算し,その後,短期および長期の移動平均をZスコアを平らげるために適用する. 短期平らなZスコアの上に長期平らなZスコアを通るときに多頭入場信号を生成し,短期平らなZスコアの下に長期平らなZスコアを通るときに平衡信号を生成する.

戦略原則

この戦略の核心は,Zスコアの計算と適用である.Zスコアは,標準差単位で,データポイントがサンプル平均から偏っている程度を測定するための統計量である.この戦略では,Zスコアの計算の公式は次のとおりである. Z = (終了価格 - SMA (終了価格,N)) / STDEV (終了価格,N) Nはユーザ定義の基本周期である.

戦略の実行プロセスは以下の通りです.

  1. クローズアップ価格の原始Zスコアを計算する
  2. 原始Z評価に適用される短期平滑 (SMA)
  3. 原始Zスコアに適用された長期平滑 ((SMA)
  4. 短期平滑Zのスコアに長期平滑Zのスコアをつけると,追加の条件を満たす場合,多額のポジションを開きます.
  5. 短期平滑Zの評価の下での長期平滑Zの評価は,追加の条件を満たす場合,平衡されます.

追加条件は以下の通りです.

  • 信号間隔:同じタイプの2つの信号 (入力または出力) の間には最小のK線間隔が必須
  • 動量フィルタリング:連続して3つまたはそれ以上の上昇K線が発生した場合,入場禁止;連続して3つまたはそれ以上の下降K線が発生した場合,出場禁止

戦略的優位性

  1. 基本統計Zスコアは,価格が平均から偏っている程度を効果的に識別する成熟した統計的ツールであり,価格が平均に戻る機会を捉えるのに適しています.
  2. スムーズな処理: 原始Zスコアに短期および長期の平滑性を適用することで,ノイズを軽減し,信号品質を向上させる.
  3. 信号間隔制御: 最小の信号間隔を設定することで,過剰取引と重複信号を効果的に減らす.
  4. パワーフィルター強いトレンドでは逆転取引を禁止し,強いトレンドでは不必要な損失を避ける.
  5. 簡潔さについて戦略は,閉盤価格データのみを使用し,複雑な指標の組み合わせに依存せず,容易に理解し,実行します.
  6. リアルタイムの監視: 取引者が保有状態を監視するために,未稼働の利益のリアルタイム表示を含む表.
  7. パラメータの柔軟性: ユーザは,異なる市場と時間枠に応じてZ評価の基礎周期と滑らかなパラメータを調整して,適応性を向上させることができます.

戦略リスク

  1. 統計上のリスク:Z評価は,価格分布がほぼ正規分布であると仮定し,正規分布でない市場環境で不良なパフォーマンスを示す可能性がある.
  2. パラメータ感度:Zスコア ベースサイクルと滑り方パラメータの選択は,戦略の性能に顕著な影響を及ぼし,パラメータの間違った選択は,オーバーフィットまたは信号遅延を引き起こす可能性があります.
  3. 単一因子制限:策略はZスコアのみに基づいて信号をクロス生成し,他の確認指標がないため,偽信号を引き起こす可能性があります.
  4. 市場環境への依存: 強いトレンドの市場では,平均値の回帰に基づく戦略は,誤ったシグナルを継続的に生み出す可能性があります.
  5. 信号が遅れている: 移動平均の滑り方を使用しているため,信号が遅れて,最適なエントリーまたは出場点を逃す可能性があります.

解決策は

  • 異なる市場環境を反省し,最適なパラメータの組み合わせを見つける
  • トレンドフィルターと組み合わせて,強いトレンド市場での取引を減らすか禁止する
  • 取引量分析やその他の技術指標などの追加確認指標
  • 適応パラメータを使用し,市場の変動に応じてZスコアパラメータを自動的に調整することを検討する

最適化の方向

  1. トレンド認識 統合: トレンド識別コンポーネントを追加し,明確なトレンド方向の市場で戦略行動を調整する.これは,長期移動平均またはADX指標によって実現し,強いトレンドで誤った平均回帰信号を生じることを避ける.
  2. 波動性調整: Zスコアパラメータの自主調整を実現し,市場変動に応じてベースサイクルと滑りパラメータを自動的に最適化する.これは,異なる市場環境における戦略の強性を向上させるだろう.
  3. 複数の時間枠分析:より高いタイムフレームのZスコア信号を統合する 確認として,複数のタイムフレームの信号が一致するときにのみ取引し,偽信号を減らす.
  4. 損失を抑える仕組み:Z評価の変動範囲に基づくダイナミックなストップを実現し,リスク管理能力を向上させる.例えば,入場Z評価の特定の偏差倍数としてストップを設定することができる.
  5. 利益の一部: 分期収益化戦略を導入し,Zスコアが特定の値に達したときに部分的に平仓し,資金管理を最適化.
  6. 交付確認: 取引量分析を取引確認として追加し,Zスコアシグナルが取引量で支持された場合にのみ取引を実行し,信号品質を向上させる.
  7. 指数组合: ZスコアをRSIやブリン帯のような他の統計的または技術的な指標と組み合わせて,多要素の意思決定モデルを作成し,戦略の信頼性を高めます.

要約する

スムーズZスコア交差に基づく動的最適化価格統計取引戦略は,統計学原理に基づく簡潔な取引システムで,価格の局所平均値に対する偏差と回帰を捕捉することに焦点を当てている.スムーズ処理,信号間隔制御,動的量フィルタリングにより,この戦略は,ノイズ取引を効果的に減らし,信号品質を向上させる.この戦略は,特に揺れ動いた市場と均等値回帰行動が顕著な金融商品に適している.

しかし,戦略には,統計的仮定,パラメータの感度,単一因子決定などの依存などのいくつかの制限があります. トレンド識別,波動性調整,複数時間枠分析,ストップダストメカニズム,交付量確認,および複数の因子組み合わせなどの最適化措置を追加することによって,戦略の頑丈性とパフォーマンスを大幅に向上させることができます.

全体として,これは理論的な基礎が堅固で,簡潔で,理解しやすい,拡張可能な戦略的枠組みを実現し,取引システムの基本的な構成要素として,または,取引における統計学の応用を理解するトレーダーを支援する教育ツールとして適しています.

ストラテジーソースコード
/*backtest
start: 2024-06-03 00:00:00
end: 2025-06-02 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/

//@version=6
strategy("Price Statistical Strategy-Z Score V 1.01", overlay=true)

// === Enable / Disable Z-Score Strategy Block ===
enableZScore = input.bool(true, title="Enable Smoothed Z-Score Strategy", tooltip="When enabled, this block calculates a smoothed Z-Score of the closing price and generates entry/exit signals based on crossover behavior between short-term and long-term smoothed Z-Scores.\n\nRecommended for quick and classic detection of price deviation from mean.\nSensitive to outliers. Best suited for relatively normal-distributed market conditions.")

// === Z-Score Parameters ===
zBaseLength = input.int(3, minval=1, title="Z-Score Base Period")
shortSmooth = input.int(3, title="Short-Term Smoothing")
longSmooth = input.int(5, title="Long-Term Smoothing")

// === Z-Score Calculation Function ===
f_zscore(src, length) =>
    mean = ta.sma(src, length)
    std_dev = ta.stdev(src, length)
    z = (src - mean) / std_dev
    z

// === Z-Score Logic ===
zRaw = f_zscore(close, zBaseLength)
zShort = ta.sma(zRaw, shortSmooth)
zLong = ta.sma(zRaw, longSmooth)


// === Minimum gap between identical signals ===
gapBars = input.int(5, minval=1, title="Bars gap between identical signals", tooltip="Minimum number of bars required between two identical signals (entry or exit). Helps reduce signal noise.")


// === Candle-based momentum filters ===
bullish_3bars = close > close[1] and close[1] > close[2] and close[2] > close[3] and close[3] > close[4]
bearish_3bars = close < close[1] and close[1] < close[2] and close[2] < close[3] and close[3] < close[4]

// === Entry and Exit Logic with minimum signal gap and candle momentum filter ===
var int lastEntryBar = na
var int lastExitBar  = na

if enableZScore
    longCondition = (zShort > zLong)
    exitCondition = (zShort < zLong)

    if longCondition and (na(lastEntryBar) or bar_index - lastEntryBar > gapBars) and not bullish_3bars
        strategy.entry("Z Score", strategy.long)
        lastEntryBar := bar_index

    if exitCondition and (na(lastExitBar) or bar_index - lastExitBar > gapBars) and not bearish_3bars
        strategy.close("Z Score", comment="Z Score")
        lastExitBar := bar_index

// === Real-time PnL Table for Last Open Position ===
var table positionTable = table.new(position.bottom_right, 2, 2, border_width=1)

// Header Labels
table.cell(positionTable, 0, 0, "Entry Price", text_color=color.white, bgcolor=color.gray)
table.cell(positionTable, 1, 0, "Unrealized PnL (%)", text_color=color.white, bgcolor=color.gray)

// Values (only when position is open)
isLong        = strategy.position_size > 0
entryPrice    = strategy.position_avg_price
unrealizedPnL = isLong ? (close - entryPrice) / entryPrice * 100 : na

// Define dynamic text color for PnL
pnlColor = unrealizedPnL > 0 ? color.green : unrealizedPnL < 0 ? color.red : color.gray

// Update Table Content
if isLong
    table.cell(positionTable, 0, 1, str.tostring(entryPrice, "#.####"), text_color=color.gray, bgcolor=color.new(color.gray, 90))
    table.cell(positionTable, 1, 1, str.tostring(unrealizedPnL, "#.##") + " %", text_color=pnlColor, bgcolor=color.new(pnlColor, 90))
else
    table.cell(positionTable, 0, 1, "—", text_color=color.gray, bgcolor=color.new(color.gray, 90))
    table.cell(positionTable, 1, 1, "—", text_color=color.gray, bgcolor=color.new(color.gray, 90))