3
フォロー
1444
フォロワー

プログラマティックトレーダーのための強力なツール: 平均と分散を計算する増分更新アルゴリズム

作成日:: 2023-11-08 16:28:36, 更新日:: 2024-11-08 09:13:54
comments   0
hits   1735

プログラマティックトレーダーのための強力なツール: 平均と分散を計算する増分更新アルゴリズム

導入

プログラムによる取引では、移動平均やボラティリティなどの指標を計算する場合など、平均と分散を計算する必要があることがよくあります。高頻度かつ長期間の計算が必要な場合、長期の履歴データを保持する必要がありますが、これは不要であり、時間とリソースを消費します。この論文では、加重平均と分散を計算するためのオンライン更新アルゴリズムを紹介します。これは、リアルタイムのデータ ストリームを処理し、取引戦略、特に高頻度戦略を動的に調整するために特に重要です。この記事では、トレーダーがこのアルゴリズムを実際の取引に迅速に展開して適用できるように、対応する Python コード実装も提供します。

単純平均と分散

\(\mu_n\)\(n\)番目のデータポイントの平均を表すために使用すると、\({n-1}\)番目のデータポイントの\(\mu_{n-1}\)の平均をすでに計算していると仮定します。 、ここで新しいデータポイント\(x_{n}\)が受信されます。この新しいデータポイントを含む新しい平均\(\mu_{n}\)を計算します。以下に詳細な導出を示します。

\(\mu_n = \frac{1}{n} \sum_{i=1}^{n} x_i\) \(\mu_n = \frac{1}{n} \left( x_n + \sum_{i=1}^{n-1} x_i \right)\) \(\mu_{n-1} = \frac{1}{n-1} \sum_{i=1}^{n-1} x_i\) \((n-1)\mu_{n-1} = \sum_{i=1}^{n-1} x_i\) \(\mu_n = \frac{1}{n} \left( x_n + (n-1)\mu_{n-1} \right)\) \(\mu_n = \mu_{n-1} + \frac{1}{n} (x_n - \mu_{n-1})\)

差異更新プロセスは、次のステップに分解できます。

\(S_n = \sum_{i=1}^{n} (x_i - \mu_n)^2\) \(S_n = \sum_{i=1}^{n} x_i^2 - n\mu_n^2\) \(S_n - S_{n-1} = x_n^2 - n\mu_n^2 + (n - 1)\mu_{n-1}^2\) \(S_n - S_{n-1} = (x_n - \mu_{n-1})(x_n - \mu_n)\) \(S_n = S_{n-1} + (x_n - \mu_{n-1})(x_n - \mu_n)\) \(\sigma_n^2 = \frac{S_n}{n}\)

上記の2つの式からわかるように、このプロセスにより、履歴データを保存せずに、前のデータの平均と分散のみを保持することで、新しいデータポイント\(x_n\)を受け取るたびに新しい平均と分散を更新できます。計算が速くなります。しかし問題は、このようにして計算されるのはサンプル全体の平均と分散であるのに対し、実際の戦略では、ある固定期間を考慮する必要があることです。上記の平均更新を観察すると、新しい平均更新量は、新しいデータと過去の平均の偏差に比率を掛けたものであることがわかります。この比率が固定されている場合、次に説明する指数加重平均が得られます。

指数加重平均

指数加重平均は、次の再帰関係によって定義できます。

\(\mu_t = \alpha x_t + (1 - \alpha) \mu_{t-1}\)

ここで、\(\mu_t\)は時点\(t\)における指数加重平均、\(x_t\)は時点\(t\)における観測値、\(\alpha\)は重み係数、\(\mu_{t-1}\)は前の時点の指数加重平均です。

指数加重分散

分散については、各時点における偏差の二乗の指数加重平均を計算する必要があります。これは、次の再帰関係を通じて実現できます。

\(S_n = \alpha S_{n-1} + (1 - \alpha)(x_n - \mu_n)(x_n - \mu_{n-1})\)

ここで、\(\sigma_t^2\)は時点\(t\)における指数重み付き分散であり、\(\sigma_{t-1}^2\)は前の時点における指数重み付き分散です。

指数的に加重された平均と分散を観察してください。増分更新形式は直感と一致しています。どちらも過去の値の一部を保持し、新しい変更を追加します。具体的な導出プロセスについては、この論文を参照してください: https://fanf2.user . srcf.net/hermes/doc/antiforgery/stats.pdf

単純移動平均 (SMA) と指数移動平均 (EMA)

単純平均 (算術平均とも呼ばれる) と指数加重平均は、それぞれ異なる特性と用途を持つ 2 つの一般的な統計測定基準です。単純平均は各観測値に等しい重みを与え、データ セットの中心位置を反映します。指数加重平均は、より最近の観測値に重みを付ける再帰計算です。観測が現在の時刻から遠ざかるにつれて、重みは指数関数的に減少します。

  • 重量配分: 単純平均では各データ ポイントに等しい重みが与えられますが、指数加重平均では最新のデータ ポイントに高い重みが与えられます。
  • 新しい情報に対する感受性: 単純平均では、すべてのデータ ポイントが再計算されるため、新しく追加されたデータに対して十分な感度がありません。指数加重平均は、最新データの変化をより迅速に反映できます。
  • 計算の複雑さ: 単純平均の計算は比較的簡単ですが、データポイントの数が増えると計算コストも増加します。指数加重平均は計算がより複雑ですが、再帰的な性質があるため、連続的なデータ ストリームに対してより効率的になる可能性があります。

EMAとSMAのおおよその変換方法

単純平均と指数加重平均は概念的に異なりますが、適切な \(\alpha\) の値を選択することで、指数加重平均を特定の観測値数の単純平均に近づけることができます。この近似関係は、指数加重平均の重み係数 \(\alpha\) の関数である有効サンプルサイズによって説明できます。

単純移動平均 (SMA) は、特定の時間枠内のすべての価格の算術平均です。時間ウィンドウ\(N\)の場合、SMAの重心(平均がある場所)は次のように考えられます。

\(\text{SMA 重心} = \frac{1 + N}{2}\)

指数移動平均 (EMA) は、より新しいデータ ポイントの重みが大きくなる加重平均です。 EMA の重みは時間の経過とともに指数関数的に減少します。 EMA の重心は、次の数列を合計することによって得られます。

\(\text{EMA 重心} = \alpha \times \left[1 + 2(1 - \alpha) + 3(1 - \alpha)^2 + \cdots \right] = \frac{1}{\alpha}\)

SMA と EMA の重心が同じであると仮定すると、次のようになります。

\(\frac{1 + N}{2} = \frac{1}{\alpha}\)

この方程式を解くと、\(\alpha\)\(N\)の関係が得られます。

\(\alpha = \frac{2}{N + 1}\)

これは、特定の \(N\) 日 SMA に対して、対応する \(\alpha\) 値を使用して「同等の」 EMA を計算でき、2 つの EMA が同じ質量中心を持ち、結果が非​​常に類似することを意味します。

更新頻度の異なるEMAの変換

重み係数 \(\alpha_1\) で毎秒更新される EMA があるとします。これは、毎秒、新しいデータ ポイントが \(\alpha_1\) の重みで EMA に追加され、古いデータ ポイントの影響が \(1 - \alpha_1\) で乗算されることを意味します。

更新頻度を変更して、たとえば\(f\)秒ごとに更新する場合、\(f\)秒以内のデータポイントの全体的な影響が1秒ごとに更新する場合と同じになるように、新しい重み係数\(\alpha_2\)を見つけます。 。

\(f\) 秒間に更新が行われない場合、古いデータ ポイントの影響は \(f\) 回連続的に減少し、そのたびに \(1 - \alpha_1\) が乗算されます。したがって、\(f\)秒後の総減衰係数は\((1 - \alpha_1)^f\)です。

\(f\)秒ごとに更新されるEMAが1回の更新サイクルで1秒に1回更新されるEMAと同じ減衰効果を持つようにするために、\(f\)秒後の総減衰係数を1回の更新での減衰係数と等しくなるように設定します。サイクル:

\((1 - \alpha_1)^f = 1 - \alpha_2\)

この方程式を解くと、新しい重み係数\(\alpha_2\)が得られます。

\(\alpha_2 = 1 - (1 - \alpha_1)^f\)

この式は、更新頻度が変化しても EMA 平滑化効果を一定に保つ新しい重み係数 \(\alpha_2\) の近似値を与えます。例えば、価格平均\(\alpha_1\)を0.001として計算し、10秒ごとに最新の価格を更新します。これを1秒に変更すると、同等の\(\alpha_2\)は約0.01になります。

Pythonコードの実装

class ExponentialWeightedStats:
    def __init__(self, alpha):
        self.alpha = alpha
        self.mu = 0
        self.S = 0
        self.initialized = False

    def update(self, x):
        if not self.initialized:
            self.mu = x
            self.S = 0
            self.initialized = True
        else:
            temp = x - self.mu
            new_mu = self.mu + self.alpha * temp
            self.S = self.alpha * self.S + (1 - self.alpha) * temp * (x - self.mu)
            self.mu = new_mu

    @property
    def mean(self):
        return self.mu

    @property
    def variance(self):
        return self.S

# 使用示例
alpha = 0.05  # 权重因子
stats = ExponentialWeightedStats(alpha)
data_stream = [] # 数据流
for data_point in data_stream:
    stats.update(data_point)

要約する

高頻度のプログラム取引では、リアルタイムデータの迅速な処理が重要です。計算効率を改善し、リソース消費を削減するために、本論文では、データ ストリームの加重平均と分散を継続的に計算するオンライン更新アルゴリズムを紹介します。リアルタイムでの増分更新の計算は、2 つの資産価格の相関関係や線形フィッティングなど、さまざまな統計データや指標を計算するためにも使用でき、大きな可能性を秘めています。増分更新では、データを信号システムとして扱います。これは、固定期間の計算と比較すると考え方が進化したものです。戦略に履歴データの計算を保存する部分もある場合は、この考え方に従って変更し、システム ステータスの推定値のみを記録し、新しいデータが到着したらシステム ステータスを更新するなどすることもできます。