Sử dụng công nghệ học máy trong giao dịch

Tác giả:Tốt, Tạo: 2019-08-29 09:42:00, Cập nhật: 2023-10-19 21:02:44

img

Bài viết này được lấy cảm hứng từ một số cảnh báo và cạm bẫy phổ biến khi tôi đang nghiên cứu dữ liệu trên nền tảng định lượng của nhà phát minh, cố gắng áp dụng kỹ thuật học máy cho các vấn đề giao dịch.

Nếu bạn chưa đọc bài viết trước của tôi, chúng tôi khuyên bạn nên đọc trước bài viết này hướng dẫn của tôi về môi trường nghiên cứu dữ liệu tự động được xây dựng trên nền tảng định lượng của nhà phát minh và phương pháp hệ thống để xây dựng chiến lược giao dịch.

Địa chỉ ở đây:https://www.fmz.com/digest-topic/4187https://www.fmz.com/digest-topic/4169 这两篇文章.

Xây dựng môi trường nghiên cứu

Khóa học này được thiết kế cho các nghiệp dư, kỹ sư và nhà khoa học dữ liệu ở tất cả các cấp độ kỹ năng, cho dù bạn là một người lớn trong ngành hay là một lập trình viên nhỏ, những kỹ năng duy nhất bạn cần là một kiến thức cơ bản về ngôn ngữ lập trình Python và đủ kiến thức về các hoạt động trên dòng lệnh (để có thể thiết lập một dự án khoa học dữ liệu).

  • Cài đặt Inventor Quantify Host và thiết lập Anaconda

发明者量化平台FMZ.COM除了提供优质的各大主流交易所的数据源,还提供一套丰富的API接口以帮助我们在完成数据的分析后进行自动化交易。这套接口包括查询账户信息,查询各个主流交易所的高,开,低,收价格,成交量,各种常用技术分析指标等实用工具,特别是对于实际交易过程中连接各大主流交易所的公共API接口,提供了强大的技术支持。

Tất cả những tính năng trên được gói gọn trong một hệ thống giống như Docker, và tất cả những gì chúng ta cần làm là mua hoặc thuê dịch vụ điện toán đám mây của riêng mình và triển khai hệ thống Docker.

Trong cái tên chính thức của nền tảng định lượng của nhà phát minh, hệ thống Docker này được gọi là hệ thống quản lý.

Để biết cách triển khai người quản lý và robot, hãy tham khảo bài viết trước của tôi:https://www.fmz.com/bbs-topic/4140

Người đọc muốn mua một nhà quản lý triển khai máy chủ điện toán đám mây của riêng họ có thể tham khảo bài viết này:https://www.fmz.com/bbs-topic/2848

Sau khi triển khai thành công các dịch vụ và hệ thống quản trị đám mây tốt, tiếp theo chúng tôi sẽ cài đặt Python lớn nhất hiện nay: Anaconda.

Để thực hiện tất cả các môi trường ứng dụng liên quan cần thiết cho bài viết này (tài liệu phụ thuộc, quản lý phiên bản, v.v.), cách đơn giản nhất là sử dụng Anaconda. Nó là một hệ sinh thái khoa học dữ liệu Python được đóng gói và quản lý thư viện phụ thuộc.

Vì chúng tôi đang cài đặt Anaconda trên dịch vụ đám mây, chúng tôi khuyên bạn nên cài đặt phiên bản Anaconda trên máy chủ đám mây với dòng lệnh trên hệ thống Linux.

Để biết cách cài đặt Anaconda, hãy xem hướng dẫn chính thức của Anaconda:https://www.anaconda.com/distribution/

Nếu bạn là một lập trình viên Python có kinh nghiệm và cảm thấy không cần phải sử dụng Anaconda, thì hoàn toàn không có vấn đề. Tôi sẽ giả sử bạn không cần sự giúp đỡ khi cài đặt môi trường phụ thuộc cần thiết, bạn có thể bỏ qua phần này.

Xây dựng chiến lược giao dịch

Kết quả cuối cùng của chiến lược giao dịch sẽ trả lời các câu hỏi sau:

  • Định hướng: Xác định tài sản có rẻ, đắt hay có giá trị công bằng.

  • 开仓条件:如果资产价格便宜或者昂贵,你应该做多或者做空.

  • Giao dịch ngang hàng: Nếu giá của tài sản là hợp lý và chúng tôi có vị trí trong tài sản đó (mua hoặc bán trước đó), bạn có nên ngang hàng không?

  • Phạm vi giá: giá giao dịch mở (hoặc phạm vi)

  • Số lượng: Số tiền giao dịch (ví dụ: số tiền kỹ thuật số hoặc số lượng giao dịch tương lai hàng hóa)

Học máy có thể được sử dụng để trả lời từng câu hỏi trên, nhưng cho phần còn lại của bài viết này, chúng tôi sẽ tập trung trả lời câu hỏi đầu tiên, đó là hướng giao dịch.

Phương pháp chiến lược

Có hai loại phương pháp xây dựng chiến lược, một là dựa trên mô hình; một là dựa trên khai thác dữ liệu.

Trong xây dựng chiến lược dựa trên mô hình, chúng ta bắt đầu với mô hình thị trường kém hiệu quả, xây dựng các biểu thức toán học (ví dụ như giá, lợi nhuận) và kiểm tra hiệu quả của chúng trong một chu kỳ thời gian dài hơn. Mô hình này thường là một phiên bản đơn giản của mô hình thực sự phức tạp, cần phải xác minh ý nghĩa và tính ổn định của nó trong chu kỳ dài.

Mặt khác, chúng ta tìm kiếm các mô hình giá cả trước và thử sử dụng các thuật toán trong phương pháp khai thác dữ liệu. Lý do gây ra các mô hình này không quan trọng, bởi vì chỉ có các mô hình xác định sẽ tiếp tục lặp lại trong tương lai. Đây là một phương pháp phân tích mù quáng, chúng ta cần kiểm tra chặt chẽ để xác định các mô hình thực tế từ các mô hình ngẫu nhiên.

Rõ ràng, việc học máy dễ dàng áp dụng cho các phương pháp khai thác dữ liệu. Hãy xem cách sử dụng học máy để tạo ra tín hiệu giao dịch từ việc khai thác dữ liệu.

Ví dụ mã sử dụng công cụ truy cập dựa trên nền tảng định lượng của nhà phát minh và giao dịch tự động API. Sau khi triển khai nhà quản lý và cài đặt Anaconda ở phần trên, bạn chỉ cần cài đặt thư viện phân tích khoa học dữ liệu mà chúng tôi cần và mô hình học máy nổi tiếng scikit-learn.

pip install -U scikit-learn

Sử dụng máy học để tạo ra các tín hiệu chiến lược giao dịch

  • Khai thác dữ liệu

Trước khi chúng ta bắt đầu, một hệ thống vấn đề học máy tiêu chuẩn được thể hiện dưới đây:

img

Hệ thống vấn đề học máy

Các tính năng mà chúng ta muốn tạo ra phải có một số khả năng dự đoán (X), chúng ta muốn dự đoán các biến mục tiêu (Y) và sử dụng dữ liệu lịch sử để đào tạo mô hình ML có thể dự đoán Y càng gần với giá trị thực càng tốt. Cuối cùng, chúng ta sử dụng mô hình này để dự đoán đối với dữ liệu mới mà Y không biết.

Bước 1: Đặt vấn đề của bạn

  • Những gì bạn muốn dự đoán? Những gì là một dự đoán tốt? Bạn đánh giá kết quả của dự đoán như thế nào?

Trong khung trên, y là gì?

img

Bạn muốn dự đoán gì?

Bạn có muốn dự đoán giá tương lai, lợi nhuận tương lai, tín hiệu mua/bán, tối ưu hóa phân bổ danh mục đầu tư và cố gắng thực hiện giao dịch hiệu quả không?

Giả sử chúng ta cố gắng dự đoán giá vào thời điểm tiếp theo. Trong trường hợp này, Y ((t) = giá ((t + 1)). Bây giờ chúng ta có thể hoàn thành khung của chúng tôi bằng dữ liệu lịch sử.

Lưu ý rằng Y (t) chỉ được biết trong quá trình tính lại, nhưng khi chúng ta sử dụng mô hình của chúng ta, chúng ta sẽ không biết giá của thời gian t (t + 1);; chúng ta sử dụng mô hình của chúng ta để dự đoán Y (t) và chỉ so sánh nó với giá trị thực tại tại thời gian t + 1; điều này có nghĩa là bạn không thể sử dụng Y như một tính năng trong mô hình dự đoán.

Một khi chúng ta biết mục tiêu Y, chúng ta cũng có thể quyết định cách đánh giá dự đoán của mình. Điều này rất quan trọng để phân biệt các mô hình khác nhau mà chúng ta sẽ thử dữ liệu. Tùy thuộc vào vấn đề mà chúng ta đang giải quyết, chọn một chỉ số đo lường hiệu quả của mô hình của chúng ta. Ví dụ, nếu chúng ta dự đoán giá, chúng ta có thể sử dụng sai lệch gốc ngang như một chỉ số.

img

ML framework được sử dụng để dự đoán giá trong tương lai

Để chứng minh, chúng tôi sẽ tạo ra một mô hình dự đoán để dự đoán giá trị cơ sở dự kiến trong tương lai của một chỉ số đầu tư giả định, trong đó:

basis = Price of Stock — Price of Future

basis(t)=S(t)−F(t)

Y(t) = future expected value of basis = Average(basis(t+1),basis(t+2),basis(t+3),basis(t+4),basis(t+5))

Vì đây là một vấn đề hồi quy, chúng ta sẽ đánh giá mô hình trên RMSE (sự sai lệch gốc ngang); chúng ta cũng sẽ sử dụng Total Pnl như một tiêu chuẩn đánh giá.

Lưu ý: Đối với kiến thức toán học liên quan đến RMSE, hãy tham khảo các nội dung liên quan của từ điển.

  • 我们的目标:创建一个模型,使预测值尽可能接近Y.

Bước 2: Thu thập dữ liệu đáng tin cậy

Thu thập và dọn dẹp dữ liệu để giúp bạn giải quyết vấn đề

Bạn cần xem xét những dữ liệu nào có khả năng dự đoán đối với biến mục tiêu Y? Nếu chúng tôi dự đoán giá, bạn có thể sử dụng dữ liệu giá của chỉ số đầu tư, dữ liệu khối lượng giao dịch của chỉ số đầu tư, dữ liệu tương tự của chỉ số đầu tư liên quan, chỉ số của chỉ số đầu tư, chỉ số thị trường tổng thể, giá của các tài sản liên quan khác.

Bạn cần thiết lập quyền truy cập dữ liệu cho dữ liệu này và đảm bảo dữ liệu của bạn là chính xác và không sai và giải quyết các dữ liệu bị mất (vấn đề rất phổ biến); đồng thời đảm bảo dữ liệu của bạn không thiên vị và đại diện đầy đủ cho tất cả các điều kiện thị trường (ví dụ, cùng một số trường hợp Loss/Loss) để tránh sự sai lệch trong mô hình. Bạn cũng có thể cần phải làm sạch dữ liệu để có được cổ tức, phân chia chỉ số đầu tư, liên tục, v.v.

Nếu bạn đang sử dụng nền tảng định lượng của nhà phát minhFMZ.COMCác nền tảng định lượng của nhà phát minh cũng đã dọn dẹp và lọc trước các dữ liệu này, chẳng hạn như phân chia các chỉ số đầu tư và dữ liệu chuyển động sâu, và trình bày cho các nhà phát triển chiến lược trong một định dạng dễ hiểu cho các công nhân định lượng.

Để dễ dàng trình bày bài viết này, chúng tôi đã sử dụng các dữ liệu sau đây như là các mốc đầu tư ảo của Auquan MQK, và chúng tôi cũng đã sử dụng một công cụ định lượng rất tiện dụng được gọi là Auquan MQS Toolbox, để biết thêm thông tin:https://github.com/Auquan/auquan-toolbox-python

# Load the data
from backtester.dataSource.quant_quest_data_source import QuantQuestDataSource
cachedFolderName = '/Users/chandinijain/Auquan/qq2solver-data/historicalData/'
dataSetId = 'trainingData1'
instrumentIds = ['MQK']
ds = QuantQuestDataSource(cachedFolderName=cachedFolderName,
                                    dataSetId=dataSetId,
                                    instrumentIds=instrumentIds)
def loadData(ds):
    data = None
    for key in ds.getBookDataByFeature().keys():
        if data is None:
            data = pd.DataFrame(np.nan, index = ds.getBookDataByFeature()[key].index, columns=[])
        data[key] = ds.getBookDataByFeature()[key]
    data['Stock Price'] =  ds.getBookDataByFeature()['stockTopBidPrice'] + ds.getBookDataByFeature()['stockTopAskPrice'] / 2.0
    data['Future Price'] = ds.getBookDataByFeature()['futureTopBidPrice'] + ds.getBookDataByFeature()['futureTopAskPrice'] / 2.0
    data['Y(Target)'] = ds.getBookDataByFeature()['basis'].shift(-5)
    del data['benchmark_score']
    del data['FairValue']
    return data
data = loadData(ds)

Với mã trên, Auquan Toolbox đã tải xuống và tải dữ liệu vào từ điển từ khóa dữ liệu. Bây giờ chúng ta cần chuẩn bị dữ liệu theo định dạng mà chúng ta thích. Dùng hàm ds.getBookDataByFeature để trả về từ điển từ khóa dữ liệu, mỗi đặc điểm một từ khóa dữ liệu. Chúng ta tạo ra một từ khóa dữ liệu mới cho các cổ phiếu có tất cả các đặc điểm.

Bước 3: Phân loại dữ liệu

  • Tạo tập hợp huấn luyện từ dữ liệu, kiểm chứng chéo và kiểm tra các tập hợp dữ liệu

Đây là một bước quan trọng!Trước khi chúng ta tiếp tục, chúng ta nên chia dữ liệu thành tập dữ liệu huấn luyện để huấn luyện mô hình của bạn; tập dữ liệu thử nghiệm để đánh giá hiệu suất mô hình.

img

Phân chia dữ liệu thành tập huấn và tập thử nghiệm

Vì dữ liệu đào tạo được sử dụng để đánh giá các tham số của mô hình, mô hình của bạn có thể quá phù hợp với dữ liệu đào tạo này và dữ liệu đào tạo sẽ gây hiểu lầm về hiệu suất mô hình. Nếu bạn không giữ bất kỳ dữ liệu thử nghiệm riêng biệt nào và sử dụng tất cả dữ liệu để đào tạo, bạn sẽ không biết mô hình của bạn thực hiện tốt hay xấu với dữ liệu mới không nhìn thấy. Đây là một trong những lý do chính khiến mô hình ML được đào tạo thất bại với dữ liệu thời gian thực: mọi người đào tạo tất cả dữ liệu có sẵn và phấn khích với các chỉ số dữ liệu đào tạo, nhưng mô hình không thể đưa ra bất kỳ dự đoán có ý nghĩa nào về dữ liệu thời gian thực mà không được đào tạo.

img

Phân chia dữ liệu thành tập huấn, tập xác thực và tập thử nghiệm

Phương pháp này có vấn đề. Nếu chúng ta lặp đi lặp lại dữ liệu đào tạo, đánh giá hiệu suất dữ liệu thử nghiệm và tối ưu hóa mô hình của chúng ta cho đến khi chúng ta hài lòng với hiệu suất, chúng ta ngụ ý dữ liệu thử nghiệm là một phần của dữ liệu đào tạo. Cuối cùng, mô hình của chúng ta có thể hoạt động tốt trên tập dữ liệu đào tạo và thử nghiệm này, nhưng không đảm bảo nó có thể dự đoán tốt dữ liệu mới.

Để giải quyết vấn đề này, chúng ta có thể tạo ra một bộ dữ liệu xác minh riêng. Bây giờ, bạn có thể đào tạo dữ liệu, đánh giá hiệu suất của dữ liệu xác minh, tối ưu hóa cho đến khi bạn hài lòng với hiệu suất, và cuối cùng kiểm tra dữ liệu thử nghiệm.

Hãy nhớ rằng, một khi đã kiểm tra hiệu suất của dữ liệu thử nghiệm, bạn không nên quay lại và cố gắng tối ưu hóa mô hình hơn nữa. Nếu bạn thấy mô hình của mình không mang lại kết quả tốt, hãy loại bỏ mô hình hoàn toàn và bắt đầu lại.

Đối với vấn đề của chúng tôi, chúng tôi có ba tập dữ liệu có sẵn, chúng tôi sẽ sử dụng một tập như tập huấn, tập thứ hai như tập xác thực, tập thứ ba như tập thử nghiệm của chúng tôi.

# Training Data
dataSetId =  'trainingData1'
ds_training = QuantQuestDataSource(cachedFolderName=cachedFolderName,
                                    dataSetId=dataSetId,
                                    instrumentIds=instrumentIds)
training_data = loadData(ds_training)
# Validation Data
dataSetId =  'trainingData2'
ds_validation = QuantQuestDataSource(cachedFolderName=cachedFolderName,
                                    dataSetId=dataSetId,
                                    instrumentIds=instrumentIds)
validation_data = loadData(ds_validation)
# Test Data
dataSetId =  'trainingData3'
ds_test = QuantQuestDataSource(cachedFolderName=cachedFolderName,
                                    dataSetId=dataSetId,
                                    instrumentIds=instrumentIds)
out_of_sample_test_data = loadData(ds_test)

Đối với mỗi một trong số đó, chúng ta thêm vào các biến mục tiêu Y, được định nghĩa là trung bình của năm giá trị cơ bản tiếp theo.

def prepareData(data, period):
    data['Y(Target)'] = data['basis'].rolling(period).mean().shift(-period)
    if 'FairValue' in data.columns:
        del data['FairValue']
    data.dropna(inplace=True)
period = 5
prepareData(training_data, period)
prepareData(validation_data, period)
prepareData(out_of_sample_test_data, period)

Bước 4: Thiết kế đặc điểm

Phân tích hành vi dữ liệu và tạo ra các tính năng có khả năng dự đoán

Bây giờ bắt đầu xây dựng kỹ thuật thực sự. Quy tắc vàng của lựa chọn đặc điểm là khả năng dự đoán chủ yếu đến từ các đặc điểm, chứ không phải từ mô hình. Bạn sẽ thấy rằng lựa chọn đặc điểm ảnh hưởng đến hiệu suất nhiều hơn so với lựa chọn mô hình.

  • Không chọn một tập hợp các đặc điểm một cách ngẫu nhiên nếu chưa khám phá mối quan hệ với các biến mục tiêu.

  • Có ít hoặc không liên quan đến các biến mục tiêu có thể dẫn đến quá phù hợp

  • Các đặc điểm bạn chọn có thể có liên quan cao với nhau, trong trường hợp đó, một số ít các đặc điểm cũng có thể giải thích mục tiêu

  • Tôi thường tạo ra một số tính năng trực quan để xem các biến mục tiêu có liên quan đến các tính năng đó và mối quan hệ giữa chúng để quyết định sử dụng những gì

  • Bạn cũng có thể thử sắp xếp các đặc điểm ứng cử viên theo hệ số thông tin lớn nhất (MIC), thực hiện phân tích thành phần chính (PCA) và các phương pháp khác.

Các đặc điểm chuyển đổi / chuẩn hóa:

Các mô hình ML thường hoạt động tốt trong việc chuẩn hóa. Tuy nhiên, việc chuẩn hóa là khó khăn khi xử lý dữ liệu chuỗi thời gian vì phạm vi dữ liệu trong tương lai là không rõ. Dữ liệu của bạn có thể vượt ra ngoài phạm vi chuẩn hóa, dẫn đến lỗi mô hình.

  • Tăng quy mô: đặc điểm phân chia theo khoảng cách tiêu chuẩn hoặc bốn chữ số

  • Địa điểm: Trừ trung bình lịch sử từ giá trị hiện tại

  • Kết hợp: hai giai đoạn ngược của ((x - mean) / stdev ở trên

  • Tính thống nhất thông thường: Tiêu chuẩn hóa dữ liệu trong khoảng từ -1 đến +1 trong thời gian x-min) / max-min và xác định lại trung tâm

Lưu ý rằng vì chúng ta sử dụng các giá trị trung bình liên tục lịch sử, sai lệch chuẩn, giá trị tối đa hoặc tối thiểu vượt quá thời gian hồi quy, nên giá trị chuẩn hóa của đặc tính sẽ được thể hiện ở các thời điểm khác nhau. Ví dụ, nếu giá trị hiện tại của đặc tính là 5, giá trị trung bình 30 chu kỳ liên tục là 4.5, sau đó sẽ được chuyển thành 0.5; sau đó, nếu giá trị trung bình 30 chu kỳ liên tục trở thành 3, giá trị 3.5 sẽ trở thành 0.5;; đây có thể là nguyên nhân gây ra lỗi mô hình. Do đó, quy chuẩn hóa là khó khăn, bạn phải tìm ra những gì thực sự cải thiện hiệu suất của mô hình (nếu có).

Đối với lần lặp đầu tiên trong vấn đề của chúng tôi, chúng tôi đã tạo ra một số lượng lớn các tính năng bằng các tham số hỗn hợp. Sau đó, chúng tôi sẽ thử xem có thể giảm số lượng các tính năng hay không.

def difference(dataDf, period):
    return dataDf.sub(dataDf.shift(period), fill_value=0)
def ewm(dataDf, halflife):
    return dataDf.ewm(halflife=halflife, ignore_na=False,
                      min_periods=0, adjust=True).mean()
def rsi(data, period):
    data_upside = data.sub(data.shift(1), fill_value=0)
    data_downside = data_upside.copy()
    data_downside[data_upside > 0] = 0
    data_upside[data_upside < 0] = 0
    avg_upside = data_upside.rolling(period).mean()
    avg_downside = - data_downside.rolling(period).mean()
    rsi = 100 - (100 * avg_downside / (avg_downside + avg_upside))
    rsi[avg_downside == 0] = 100
    rsi[(avg_downside == 0) & (avg_upside == 0)] = 0
return rsi
def create_features(data):
    basis_X = pd.DataFrame(index = data.index, columns =  [])
    
    basis_X['mom3'] = difference(data['basis'],4)
    basis_X['mom5'] = difference(data['basis'],6)
    basis_X['mom10'] = difference(data['basis'],11)
    
    basis_X['rsi15'] = rsi(data['basis'],15)
    basis_X['rsi10'] = rsi(data['basis'],10)
    
    basis_X['emabasis3'] = ewm(data['basis'],3)
    basis_X['emabasis5'] = ewm(data['basis'],5)
    basis_X['emabasis7'] = ewm(data['basis'],7)
    basis_X['emabasis10'] = ewm(data['basis'],10)
    basis_X['basis'] = data['basis']
    basis_X['vwapbasis'] = data['stockVWAP']-data['futureVWAP']
    
    basis_X['swidth'] = data['stockTopAskPrice'] -
                        data['stockTopBidPrice']
    basis_X['fwidth'] = data['futureTopAskPrice'] -
                        data['futureTopBidPrice']
    
    basis_X['btopask'] = data['stockTopAskPrice'] -
                         data['futureTopAskPrice']
    basis_X['btopbid'] = data['stockTopBidPrice'] -
                         data['futureTopBidPrice']

    basis_X['totalaskvol'] = data['stockTotalAskVol'] -
                             data['futureTotalAskVol']
    basis_X['totalbidvol'] = data['stockTotalBidVol'] -
                             data['futureTotalBidVol']
    
    basis_X['emabasisdi7'] = basis_X['emabasis7'] -
                             basis_X['emabasis5'] + 
                             basis_X['emabasis3']
    
    basis_X = basis_X.fillna(0)
    
    basis_y = data['Y(Target)']
    basis_y.dropna(inplace=True)
    
    print("Any null data in y: %s, X: %s"
            %(basis_y.isnull().values.any(), 
             basis_X.isnull().values.any()))
    print("Length y: %s, X: %s"
            %(len(basis_y.index), len(basis_X.index)))
    
    return basis_X, basis_y
basis_X_train, basis_y_train = create_features(training_data)
basis_X_test, basis_y_test = create_features(validation_data)

Bước 5: Chọn mô hình

Chọn mô hình thống kê/ML phù hợp theo câu hỏi được chọn

Lựa chọn mô hình phụ thuộc vào cách xây dựng vấn đề. Bạn đang giải vấn đề giám sát (tất cả các điểm X trong ma trận tính năng được lập bản đồ cho biến mục tiêu Y) hoặc không có vấn đề học tập giám sát (không có bản đồ nào, mô hình cố gắng học mô hình không biết)? Bạn đang giải vấn đề hồi quy (làm dự đoán giá thực tế trong thời gian tương lai) hoặc vấn đề phân loại (chỉ dự đoán hướng giá trong thời gian tương lai) (tăng / giảm)

img

Học tập theo dõi hoặc không theo dõi

img

Quay trở lại or phân loại

Một số thuật toán học được giám sát phổ biến có thể giúp bạn bắt đầu:

  • Chuyển hướng tuyến tính (đối với các tham số, quay trở lại)

  • Logistic regression (định số, phân loại)

  • K gần gũi (KNN) thuật toán (Dựa trên trường hợp, hồi quy)

  • SVM, SVR (đối với các tham số, phân loại và hồi quy)

  • Cây quyết định

  • Rừng quyết định

Tôi khuyên bạn nên bắt đầu với một mô hình đơn giản, chẳng hạn như linear hoặc logic regression, và xây dựng mô hình phức tạp hơn từ đó nếu cần thiết. Tôi cũng khuyên bạn nên đọc toán học đằng sau mô hình, thay vì sử dụng nó như một hộp đen.

Bước 6: Đào tạo, xác minh và tối ưu hóa (lặp lại bước 4-6)

img

Sử dụng huấn luyện và xác minh bộ dữ liệu để đào tạo và tối ưu hóa mô hình của bạn

Bây giờ, bạn đã sẵn sàng để xây dựng mô hình cuối cùng. Trong giai đoạn này, bạn thực sự chỉ lặp lại mô hình và các tham số mô hình. Hãy đào tạo mô hình của bạn trên dữ liệu đào tạo, đo hiệu suất của nó trên dữ liệu xác minh, và sau đó quay lại, tối ưu hóa, đào tạo lại và đánh giá.

Chỉ khi nào bạn có được một mô hình mà bạn thích, bạn sẽ tiếp tục thực hiện bước tiếp theo.

Để làm bài thuyết trình của chúng tôi, chúng ta hãy bắt đầu với một sự hồi quy tuyến tính đơn giản.

from sklearn import linear_model
from sklearn.metrics import mean_squared_error, r2_score
def linear_regression(basis_X_train, basis_y_train,
                      basis_X_test,basis_y_test):
    
    regr = linear_model.LinearRegression()
    # Train the model using the training sets
    regr.fit(basis_X_train, basis_y_train)
    # Make predictions using the testing set
    basis_y_pred = regr.predict(basis_X_test)
    # The coefficients
    print('Coefficients: \n', regr.coef_)
    
    # The mean squared error
    print("Mean squared error: %.2f"
          % mean_squared_error(basis_y_test, basis_y_pred))
    
    # Explained variance score: 1 is perfect prediction
    print('Variance score: %.2f' % r2_score(basis_y_test,
                                            basis_y_pred))
    # Plot outputs
    plt.scatter(basis_y_pred, basis_y_test,  color='black')
    plt.plot(basis_y_test, basis_y_test, color='blue', linewidth=3)
    plt.xlabel('Y(actual)')
    plt.ylabel('Y(Predicted)')
    plt.show()
    
    return regr, basis_y_pred
_, basis_y_pred = linear_regression(basis_X_train, basis_y_train, 
                                    basis_X_test,basis_y_test)

img

Không có sự hồi quy tuyến tính thống nhất

('Coefficients: \n', array([ -1.0929e+08, 4.1621e+07, 1.4755e+07, 5.6988e+06, -5.656e+01, -6.18e-04, -8.2541e-05,4.3606e-02, -3.0647e-02, 1.8826e+07, 8.3561e-02, 3.723e-03, -6.2637e-03, 1.8826e+07, 1.8826e+07, 6.4277e-02, 5.7254e-02, 3.3435e-03, 1.6376e-02, -7.3588e-03, -8.1531e-04, -3.9095e-02, 3.1418e-02, 3.3321e-03, -1.3262e-06, -1.3433e+07, 3.5821e+07, 2.6764e+07, -8.0394e+06, -2.2388e+06, -1.7096e+07]))
Mean squared error: 0.02
Variance score: 0.96

Hãy nhìn vào hệ số mô hình. Chúng ta không thể thực sự so sánh chúng hoặc nói điều gì quan trọng, vì chúng thuộc về các quy mô khác nhau.

def normalize(basis_X, basis_y, period):
    basis_X_norm = (basis_X - basis_X.rolling(period).mean())/
                    basis_X.rolling(period).std()
    basis_X_norm.dropna(inplace=True)
    basis_y_norm = (basis_y - 
                    basis_X['basis'].rolling(period).mean())/
                    basis_X['basis'].rolling(period).std()
    basis_y_norm = basis_y_norm[basis_X_norm.index]
    
    return basis_X_norm, basis_y_norm
norm_period = 375
basis_X_norm_test, basis_y_norm_test = normalize(basis_X_test,basis_y_test, norm_period)
basis_X_norm_train, basis_y_norm_train = normalize(basis_X_train, basis_y_train, norm_period)
regr_norm, basis_y_pred = linear_regression(basis_X_norm_train, basis_y_norm_train, basis_X_norm_test, basis_y_norm_test)
basis_y_pred = basis_y_pred * basis_X_test['basis'].rolling(period).std()[basis_y_norm_test.index] + basis_X_test['basis'].rolling(period).mean()[basis_y_norm_test.index]

img

Sự trở lại tuyến tính của sự thống nhất

Mean squared error: 0.05
Variance score: 0.90

Mô hình này không cải thiện mô hình trước, nhưng cũng không tệ hơn. Bây giờ chúng ta có thể thực sự so sánh các hệ số và xem những hệ số thực sự quan trọng là gì.

Chúng ta hãy xem xét các hệ số.

for i in range(len(basis_X_train.columns)):
    print('%.4f, %s'%(regr_norm.coef_[i], basis_X_train.columns[i]))

Kết quả là:

19.8727, emabasis4
-9.2015, emabasis5
8.8981, emabasis7
-5.5692, emabasis10
-0.0036, rsi15
-0.0146, rsi10
0.0196, mom10
-0.0035, mom5
-7.9138, basis
0.0062, swidth
0.0117, fwidth
2.0883, btopask
2.0311, btopbid
0.0974, bavgask
0.0611, bavgbid
0.0007, topaskvolratio
0.0113, topbidvolratio
-0.0220, totalaskvolratio
0.0231, totalbidvolratio

Chúng ta có thể thấy rõ rằng một số đặc điểm có hệ số cao hơn so với các đặc điểm khác và có thể có khả năng dự đoán mạnh hơn.

Chúng ta hãy xem mối quan hệ giữa các đặc điểm khác nhau.

import seaborn

c = basis_X_train.corr()
plt.figure(figsize=(10,10))
seaborn.heatmap(c, cmap='RdYlGn_r', mask = (np.abs(c) <= 0.8))
plt.show()

img

Sự liên quan giữa các đặc điểm

Các vùng màu đỏ đậm biểu thị các biến có liên quan cao. Hãy tạo/thay đổi một số tính năng một lần nữa và cố gắng cải thiện mô hình của chúng tôi.

例如,我可以轻松地丢弃像emabasisdi7这样的特征,这些特征只是其他特征的线性组合.

def create_features_again(data):
    basis_X = pd.DataFrame(index = data.index, columns =  [])
    basis_X['mom10'] = difference(data['basis'],11)
    basis_X['emabasis2'] = ewm(data['basis'],2)
    basis_X['emabasis5'] = ewm(data['basis'],5)
    basis_X['emabasis10'] = ewm(data['basis'],10)
    basis_X['basis'] = data['basis']
    basis_X['totalaskvolratio'] = (data['stockTotalAskVol']
                                 - data['futureTotalAskVol'])/
                                   100000
    basis_X['totalbidvolratio'] = (data['stockTotalBidVol']
                                 - data['futureTotalBidVol'])/
                                   100000
    basis_X = basis_X.fillna(0)
    
    basis_y = data['Y(Target)']
    basis_y.dropna(inplace=True)
    return basis_X, basis_y
basis_X_test, basis_y_test = create_features_again(validation_data)
basis_X_train, basis_y_train = create_features_again(training_data)
_, basis_y_pred = linear_regression(basis_X_train, basis_y_train, basis_X_test,basis_y_test)
basis_y_regr = basis_y_pred.copy()

img

('Coefficients: ', array([ 0.03246139,
0.49780982, -0.22367172,  0.20275786,  0.50758852,
-0.21510795, 0.17153884]))
Mean squared error: 0.02
Variance score: 0.96

Nhìn xem, hiệu suất của mô hình của chúng tôi không thay đổi, chúng tôi chỉ cần một số tính năng để giải thích các biến mục tiêu của chúng tôi. Tôi khuyên bạn nên thử nhiều tính năng trên, thử các kết hợp mới, v.v., và xem có gì có thể cải thiện mô hình của chúng tôi.

我们还可以尝试更复杂的模型,看看模型的变化是否可以提高性能.

  • K-neighbor (KNN)
from sklearn import neighbors
n_neighbors = 5
model = neighbors.KNeighborsRegressor(n_neighbors, weights='distance')
model.fit(basis_X_train, basis_y_train)
basis_y_pred = model.predict(basis_X_test)
basis_y_knn = basis_y_pred.copy()

img

  • SVR
from sklearn.svm import SVR
model = SVR(kernel='rbf', C=1e3, gamma=0.1)
model.fit(basis_X_train, basis_y_train)
basis_y_pred = model.predict(basis_X_test)
basis_y_svr = basis_y_pred.copy()

img

  • Cây quyết định
model=ensemble.ExtraTreesRegressor()
model.fit(basis_X_train, basis_y_train)
basis_y_pred = model.predict(basis_X_test)
basis_y_trees = basis_y_pred.copy()

img

Bước 7: Kiểm tra lại dữ liệu thử nghiệm

Kiểm tra hiệu suất của dữ liệu mẫu thực tế

img

Hiệu suất kiểm tra lại trên bộ dữ liệu thử nghiệm chưa được chạm vào

Đây là thời điểm then chốt. Chúng tôi bắt đầu chạy mô hình tối ưu hóa cuối cùng của chúng tôi từ bước cuối cùng của dữ liệu thử nghiệm, chúng tôi đặt nó sang một bên ngay từ đầu, dữ liệu chưa được tiếp xúc.

Điều này cung cấp cho bạn một kỳ vọng thực tế về cách mô hình của bạn sẽ thực hiện trên dữ liệu mới và chưa được nhìn thấy khi bạn bắt đầu giao dịch trong thời gian thực. Do đó, cần đảm bảo rằng bạn có một bộ dữ liệu sạch mà không được sử dụng để đào tạo hoặc xác minh mô hình.

Nếu bạn không thích kết quả kiểm tra lại dữ liệu thử nghiệm, hãy loại bỏ mô hình và bắt đầu lại. Đừng bao giờ quay lại để tối ưu hóa lại mô hình của bạn, điều này sẽ dẫn đến quá phù hợp!

Ở đây, chúng ta sẽ sử dụng hộp công cụ của Auquan.

import backtester
from backtester.features.feature import Feature
from backtester.trading_system import TradingSystem
from backtester.sample_scripts.fair_value_params import FairValueTradingParams
class Problem1Solver():
def getTrainingDataSet(self):
        return "trainingData1"
def getSymbolsToTrade(self):
        return ['MQK']
def getCustomFeatures(self):
        return {'my_custom_feature': MyCustomFeature}
def getFeatureConfigDicts(self):
                            
        expma5dic = {'featureKey': 'emabasis5',
                 'featureId': 'exponential_moving_average',
                 'params': {'period': 5,
                              'featureName': 'basis'}}
        expma10dic = {'featureKey': 'emabasis10',
                 'featureId': 'exponential_moving_average',
                 'params': {'period': 10,
                              'featureName': 'basis'}}                     
        expma2dic = {'featureKey': 'emabasis3',
                 'featureId': 'exponential_moving_average',
                 'params': {'period': 3,
                              'featureName': 'basis'}}
        mom10dic = {'featureKey': 'mom10',
                 'featureId': 'difference',
                 'params': {'period': 11,
                              'featureName': 'basis'}}
        
        return [expma5dic,expma2dic,expma10dic,mom10dic]    
    
    def getFairValue(self, updateNum, time, instrumentManager):
        # holder for all the instrument features
        lbInstF = instrumentManager.getlookbackInstrumentFeatures()
        mom10 = lbInstF.getFeatureDf('mom10').iloc[-1]
        emabasis2 = lbInstF.getFeatureDf('emabasis2').iloc[-1]
        emabasis5 = lbInstF.getFeatureDf('emabasis5').iloc[-1]
        emabasis10 = lbInstF.getFeatureDf('emabasis10').iloc[-1] 
        basis = lbInstF.getFeatureDf('basis').iloc[-1]
        totalaskvol = lbInstF.getFeatureDf('stockTotalAskVol').iloc[-1] - lbInstF.getFeatureDf('futureTotalAskVol').iloc[-1]
        totalbidvol = lbInstF.getFeatureDf('stockTotalBidVol').iloc[-1] - lbInstF.getFeatureDf('futureTotalBidVol').iloc[-1]
        
        coeff = [ 0.03249183, 0.49675487, -0.22289464, 0.2025182, 0.5080227, -0.21557005, 0.17128488]
        newdf['MQK'] = coeff[0] * mom10['MQK'] + coeff[1] * emabasis2['MQK'] +\
                      coeff[2] * emabasis5['MQK'] + coeff[3] * emabasis10['MQK'] +\
                      coeff[4] * basis['MQK'] + coeff[5] * totalaskvol['MQK']+\
                      coeff[6] * totalbidvol['MQK']
                    
        newdf.fillna(emabasis5,inplace=True)
        return newdf
problem1Solver = Problem1Solver()
tsParams = FairValueTradingParams(problem1Solver)
tradingSystem = TradingSystem(tsParams)
tradingSystem.startTrading(onlyAnalyze=False, 
                           shouldPlot=True,
                           makeInstrumentCsvs=False)

img

Kết quả xét nghiệm, Pnl tính bằng đô la (Pnl không tính chi phí giao dịch và chi phí khác)

Bước 8: Những cách khác để cải thiện mô hình

Xác thực cuộn, tập học, Bagging và Boosting

Ngoài việc thu thập nhiều dữ liệu hơn, tạo ra các tính năng tốt hơn hoặc thử nhiều mô hình hơn, đây là một vài điều bạn có thể cố gắng cải thiện.

1. Kiểm tra cuộn

img

Kiểm tra cuộn

Điều kiện thị trường hiếm khi giữ nguyên. Giả sử bạn có một năm dữ liệu, và bạn được đào tạo với dữ liệu từ tháng 1 đến tháng 8, và sử dụng dữ liệu từ tháng 9 đến tháng 12 để kiểm tra mô hình của bạn, bạn có thể cuối cùng được đào tạo đối với một tập hợp các điều kiện thị trường rất cụ thể. Có lẽ trong nửa đầu năm không có biến động thị trường, một số tin tức cực đoan dẫn đến thị trường tăng mạnh vào tháng 9, mô hình của bạn sẽ không thể học được mô hình này và sẽ mang lại cho bạn kết quả dự đoán rác.

Có thể sẽ tốt hơn nếu bạn thử thực hiện kiểm tra lăn lăn phía trước: đào tạo từ tháng 1 đến tháng 2, kiểm tra từ tháng 3, kiểm tra từ tháng 4 đến tháng 5, kiểm tra lại từ tháng 6 và vân vân.

2. Học tập tập thể

img

Học tập tập thể

Một số mô hình có thể hoạt động tốt khi dự đoán một số tình huống, trong khi dự đoán một số tình huống khác hoặc trong một số trường hợp mô hình có thể quá phù hợp. Một cách để giảm lỗi và quá phù hợp là sử dụng các tập hợp các mô hình khác nhau. Dự báo của bạn sẽ là trung bình của dự đoán của nhiều mô hình, và các lỗi của các mô hình khác nhau có thể được bù đắp hoặc giảm. Một số phương pháp tập hợp phổ biến là Bagging và Boosting.

img

Bổn

img

Tăng cường

Tôi sẽ bỏ qua các phương pháp này để giới thiệu ngắn gọn, nhưng bạn có thể tìm hiểu thêm thông tin liên quan trực tuyến.

Hãy thử một phương pháp tổng hợp cho vấn đề của chúng ta.

basis_y_pred_ensemble = (basis_y_trees + basis_y_svr +
                         basis_y_knn + basis_y_regr)/4

img

Mean squared error: 0.02
Variance score: 0.95

Chúng tôi đã tích lũy được rất nhiều kiến thức và thông tin cho đến nay.

  • Giải quyết vấn đề của bạn

  • Thu thập dữ liệu đáng tin cậy và làm sạch dữ liệu

  • Phân chia dữ liệu thành tập huấn, xác minh và thử nghiệm

  • Tạo các đặc điểm và phân tích hành vi của chúng

  • Chọn mô hình đào tạo phù hợp theo hành vi

  • Sử dụng dữ liệu đào tạo để đào tạo mô hình của bạn và dự đoán

  • Kiểm tra và tối ưu hóa lại hiệu suất trên bộ xác minh

  • Xác minh hiệu suất cuối cùng của bộ thử nghiệm

Có phải đó là đầu tiên không? Nhưng chưa hết, bạn chỉ có một mô hình dự đoán đáng tin cậy bây giờ.

  • Phát triển các tín hiệu dựa trên mô hình dự đoán để xác định hướng giao dịch

  • Phát triển các chiến lược cụ thể để xác định các giao dịch mở

  • Hệ thống thực hiện để xác định vị trí và giá

Những điều trên sẽ được sử dụng cho nền tảng định lượng của nhà phát minh.FMZ.COMTrong nền tảng định lượng của nhà phát minh, có rất nhiều chiến lược lựa chọn hoàn hảo, kết hợp với phương pháp học máy trong bài viết này, sẽ giúp cho chiến lược cụ thể của bạn như lưỡi hổ.https://www.fmz.com/square

Thông tin quan trọng về chi phí giao dịch:你的模型会告诉你所选资产何时是做多或做空。然而,它没有考虑费用/交易成本/可用交易量/止损等。交易成本通常会使有利可图的交易成为亏损。例如,预期价格上涨0.05美元的资产是买入,但如果你必须支付0.10美元进行此交易,你将最终获得净亏损$0.05。在你考虑经纪人佣金,交换费和点差后,我们上面看起来很棒的盈利图实际上是这样的:

img

Kết quả kiểm tra lại sau khi phí giao dịch và điểm chênh lệch, Pnl là đô la

Phí giao dịch và chênh lệch giá chiếm hơn 90% PNL của chúng tôi! Chúng tôi sẽ thảo luận chi tiết về điều này trong bài viết tiếp theo.

Cuối cùng, chúng ta hãy xem một số cái bẫy phổ biến.

Những điều nên làm và không nên làm

  • Hãy cố gắng hết sức để tránh quá phù hợp!

  • Không được đào tạo lại sau mỗi điểm dữ liệu: Đây là một sai lầm phổ biến mà mọi người mắc phải trong phát triển học máy. Nếu mô hình của bạn cần đào tạo lại sau mỗi điểm dữ liệu, nó có thể không phải là một mô hình rất tốt. Đó là, nó cần đào tạo lại thường xuyên, chỉ cần đào tạo với tần suất hợp lý (ví dụ, nếu dự đoán trong ngày, hãy đào tạo lại vào cuối tuần).

  • Tránh sai lệch, đặc biệt là sai lệch về phía trước: đây là một lý do khác khiến mô hình không hoạt động, hãy đảm bảo rằng bạn không sử dụng bất kỳ thông tin nào về tương lai. Trong hầu hết các trường hợp, điều này có nghĩa là không sử dụng biến mục tiêu Y như một tính năng trong mô hình. Bạn có thể sử dụng nó trong quá trình kiểm tra ngược, nhưng sẽ không được sử dụng khi thực sự chạy mô hình, điều này sẽ khiến mô hình của bạn không thể sử dụng được.

  • Cẩn thận với sự lệch dữ liệu khai thác: Vì chúng tôi đang cố gắng thực hiện một loạt các mô hình hóa dữ liệu của chúng tôi để xác định sự phù hợp, nếu không có lý do đặc biệt, hãy đảm bảo bạn chạy các thử nghiệm nghiêm ngặt để tách các mô hình ngẫu nhiên khỏi các mô hình thực tế có thể xảy ra. Ví dụ, sự hồi quy tuyến tính giải thích rất tốt các mô hình xu hướng lên, mà chỉ có thể là một phần nhỏ của sự di chuyển ngẫu nhiên lớn hơn!

Tránh quá phù hợp

Điều này rất quan trọng, và tôi cảm thấy cần phải nhắc lại.

  • Việc quá phù hợp là một trong những cạm bẫy nguy hiểm nhất trong chiến lược giao dịch.

  • Một thuật toán phức tạp có thể hoạt động rất tốt trong việc kiểm tra lại, nhưng lại thất bại thảm khốc với dữ liệu mới không nhìn thấy, thuật toán này không thực sự tiết lộ bất kỳ xu hướng nào trong dữ liệu và không có khả năng dự đoán thực sự. Nó rất phù hợp với dữ liệu mà nó nhìn thấy.

  • Làm cho hệ thống của bạn đơn giản nhất có thể. Nếu bạn thấy mình cần rất nhiều tính năng phức tạp để giải thích dữ liệu, bạn có thể quá phù hợp.

  • Phân loại dữ liệu có sẵn của bạn thành dữ liệu đào tạo và thử nghiệm và luôn kiểm chứng hiệu suất của dữ liệu mẫu thực trước khi sử dụng mô hình để giao dịch trong thời gian thực.


Có liên quan

Thêm nữa

Một lá biếtCảm ơn các bạn.

congcong009Bài viết, ý tưởng và tóm tắt tuyệt vời cho những người mới bắt đầu

lalalademaxiyaBọn chúng ta sẽ bị giết.