Công cụ của nhà giao dịch lập trình: tính toán phương và chênh lệch của thuật toán cập nhật tăng

Tác giả:Cỏ nhỏ, Tạo: 2023-11-08 16:28:36, Cập nhật: 2023-11-09 20:46:17

img

Địa chỉ

Trong giao dịch lập trình, thường cần phải tính trung bình và chênh lệch, chẳng hạn như các chỉ số như đường trung bình và tỷ lệ biến động. Khi chúng ta cần tính tần số cao và tính toán chu kỳ dài, cần phải lưu trữ dữ liệu lịch sử trong thời gian dài, điều này cũng không cần thiết và tốn nhiều tài nguyên. Bài viết này giới thiệu một thuật toán cập nhật trực tuyến để tính toán trung bình và chênh lệch tăng cân, đặc biệt quan trọng đối với việc xử lý các chiến lược giao dịch chuyển động và điều chỉnh động trong thời gian thực, đặc biệt là các chiến lược tần số cao. Bài viết cũng cung cấp một triển khai mã Python tương ứng để giúp các nhà giao dịch triển khai và áp dụng nhanh chóng thuật toán này trong giao dịch thực tế.

Trung bình và chênh lệch đơn giản

Nếu chúng ta dùng $\mu_n$ để biểu thị giá trị trung bình của $\n$ điểm dữ liệu, giả sử chúng ta đã tính toán số trung bình của ${n-1} $ điểm dữ liệu $\mu_{n-1} $, và bây giờ chúng ta nhận được một điểm dữ liệu mới $x_{n} $. Chúng ta muốn tính toán số trung bình mới $\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}) $

Quá trình cập nhật chênh lệch có thể được chia thành các bước sau:

$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}) $S_n = S_{n-1} + (x_n - \mu_{n-1}) $\sigma_n^2 = \frac{S_n}{n}$

Như hai công thức trên cho thấy, quá trình này cho phép chúng ta chỉ giữ trung bình và chênh lệch của một dữ liệu khi nhận được mỗi điểm dữ liệu mới $x_n$, để có thể cập nhật các trung bình và chênh lệch mới mà không cần lưu trữ dữ liệu lịch sử và tính toán nhanh hơn. Nhưng vấn đề là tính toán theo cách này là trung bình và chênh lệch của toàn bộ mẫu, và trong chiến lược thực tế, chúng ta cần phải xem xét một chu kỳ cố định nhất định.

Chỉ số trọng số chỉ số

Chỉ số trọng số trung bình có thể được định nghĩa bằng các mối quan hệ hồi quy sau:

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

Trong đó, $\mu_t$ là chỉ số trọng số trung bình tại thời điểm $t$, $x_t$ là giá trị quan sát tại thời điểm $t$, $\alpha$ là yếu tố trọng số, $\mu_{t-1} $ là chỉ số trọng số trung bình tại thời điểm trước đó.

Sự khác biệt theo trọng số (Exponentially-weighted variance)

Đối với chênh lệch, chúng ta cần tính toán chỉ số cộng trọng số của chênh lệch hình vuông của mỗi điểm thời gian. Điều này có thể được thực hiện bằng các mối quan hệ hồi quy sau:

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

Trong đó, $\sigma_t^2$ là chênh lệch cộng phương của chỉ số tại thời điểm $t$, và $\sigma_{t-1}^2$ là chênh lệch cộng phương của chỉ số tại thời điểm trước đó.

Các chỉ số quan sát được tính theo các đường cân trung bình và chênh lệch, các hình thức cập nhật gia tăng của chúng phù hợp với trực giác, giữ lại một phần giá trị trong quá khứ, cộng với những thay đổi mới, quá trình suy luận cụ thể có thể được tham khảo trong bài báo này:https://fanf2.user.srcf.net/hermes/doc/antiforgery/stats.pdf

Đường trung bình di chuyển đơn giản (SMA) và đường trung bình di chuyển chỉ số (EMA)

Trung bình đơn giản (còn được gọi là trung bình toán học) và trung bình trọng số chỉ số là hai thước đo thống kê phổ biến, mỗi loại có các đặc điểm và mục đích khác nhau. Trung bình đơn giản gán trọng lượng tương tự cho mỗi giá trị quan sát, nó phản ánh vị trí trung tâm của tập dữ liệu. Trung bình trọng số chỉ số là một phương pháp tính toán hồi quy, nó gán trọng lượng cao hơn cho giá trị quan sát gần nhất.

  • Phân phối trọng lượng: trung bình đơn giản cho mỗi điểm dữ liệu cùng trọng lượng, trong khi trung bình chỉ số tăng trọng lượng cho điểm dữ liệu gần nhất trọng lượng cao hơn.
  • Sự nhạy cảm với thông tin mới: Trung bình đơn giản không nhạy cảm với dữ liệu mới được thêm vào vì nó liên quan đến việc tính lại tất cả các điểm dữ liệu; Trung bình trọng số chỉ số phản ánh sự thay đổi dữ liệu mới nhất nhanh hơn.
  • Sự phức tạp của tính toán: tính toán trung bình đơn giản là tương đối đơn giản, nhưng chi phí tính toán cũng tăng lên khi số điểm dữ liệu tăng lên. Tính toán của chỉ số cộng với trung bình trọng số phức tạp hơn, nhưng do bản chất hồi quy của nó, nó có thể xử lý một luồng dữ liệu liên tục hiệu quả hơn.

EMA và SMA tương tự nhau

Mặc dù trung bình đơn giản và trung bình trọng số chỉ số khác nhau về khái niệm, chúng ta có thể làm cho trung bình trọng số chỉ số gần gũi với một trung bình đơn giản chứa các giá trị quan sát của một số lượng cụ thể bằng cách chọn giá trị $\alpha$ thích hợp. Mối quan hệ gần gũi này có thể được mô tả bằng kích thước mẫu hiệu quả, đó là hàm của yếu tố trọng số $\alpha$ trong trung bình trọng số chỉ số.

Đơn giản trung bình di chuyển (SMA) là giá trị trung bình toán học của tất cả các giá trong một cửa sổ thời gian nhất định. Đối với một cửa sổ thời gian $N$, trung tâm của SMA (đó là vị trí của số trung bình) có thể được xem là:

$\text{SMA} = \frac{1 + N}{2}$

EMA là một số trung bình được cân nhắc, trong đó các điểm dữ liệu gần nhất có trọng lượng lớn hơn. EMA giảm trọng lượng theo thời gian.

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

Khi chúng ta giả định rằng SMA và EMA có cùng trọng tâm, chúng ta có:

$\frac{1 + N}{2} = \frac{1}{\alpha}$

Nếu chúng ta giải được phương trình này, chúng ta có được mối quan hệ giữa $\alpha$ và $N$:

$\alpha = \frac{2}{N + 1}$

Điều này có nghĩa là đối với một SMA $N$ ngày, giá trị $\alpha$ tương ứng có thể được sử dụng để tính EMA của một EMA tương đương với EMA, làm cho cả hai có cùng trọng lượng và kết quả rất gần nhau.

EMA thay đổi tần suất cập nhật khác nhau

Giả sử chúng ta có một EMA được cập nhật mỗi giây với yếu tố trọng lượng là $\alpha_1$. Điều này có nghĩa là mỗi giây, một điểm dữ liệu mới được thêm vào EMA với trọng lượng $\alpha_1$, trong khi ảnh hưởng của điểm dữ liệu cũ sẽ được nhân bằng $1 - \alpha_1$.

Nếu chúng ta thay đổi tần suất cập nhật, ví dụ như mỗi $f$ giây, chúng ta muốn tìm ra một yếu tố trọng lượng mới $\alpha_2$ để tổng ảnh hưởng của các điểm dữ liệu trong $f$ giây giống như khi cập nhật mỗi giây.

Trong khoảng thời gian $f$ giây, nếu không được cập nhật, ảnh hưởng của điểm dữ liệu cũ sẽ giảm liên tục $f$ lần, mỗi lần nhân $1 - \alpha_1$. Do đó, tổng yếu tố suy giảm sau $f$ giây là $(1 - \alpha_1) ^ f$.

Để làm cho EMA được cập nhật một lần trong vòng 1 lần cập nhật có tác dụng suy giảm tương tự như EMA được cập nhật mỗi giây, chúng ta đặt tổng yếu tố suy giảm sau $f$ giây bằng với yếu tố suy giảm trong vòng 1 lần cập nhật:

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

Nếu chúng ta giải được phương trình này, chúng ta sẽ có một yếu tố trọng lượng mới là $\alpha_2$:

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

Công thức này cung cấp giá trị gần của nhân trọng mới $\alpha_2$ để giữ hiệu ứng EMA không thay đổi khi thay đổi tần suất cập nhật. Ví dụ: chúng ta tính giá trung bình $\alpha_1$ là 0.001, và giá mới nhất được cập nhật mỗi 10s, nếu thay đổi thành 1s được cập nhật một lần, tương đương $\alpha_2$ là khoảng 0.01

Thực hiện mã 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)

Tóm lại

Trong giao dịch lập trình tần số cao, việc xử lý dữ liệu trong thời gian thực là rất quan trọng. Để tăng hiệu quả tính toán và giảm tiêu thụ tài nguyên, bài viết này giới thiệu một thuật toán cập nhật trực tuyến để tính toán liên tục các đường dẫn dữ liệu. Tính toán cập nhật tăng trưởng trong thời gian thực cũng có thể được sử dụng để tính toán các số liệu thống kê và các chỉ số khác nhau, chẳng hạn như mối quan hệ giá hai loại tài sản, sự phù hợp tuyến tính, v.v.


Thêm nữa