DolphinDB と Python Celery を使用して高性能ファクター コンピューティング プラットフォームを構築する

ファクター マイニングは、クオンツ ファイナンスの研究と取引の中心です。従来の開発プロセスでは、Python は通常、リレーショナル データベース (SqlServer、Oracle など) からデータを読み取るために使用され、因子計算は Python で実行されます。証券取引の規模が継続的に拡大し、取引データの量が急増するにつれて、ユーザーはファクター計算プラットフォームのパフォーマンスに対するより高い要件を提唱しています。従来の因子計算工学は、次の問題に直面しています。

  • コンピューティング プラットフォームとしての Python によって引き起こされるデータの増加とパフォーマンスのボトルネックを要因として挙げます。
  • 従来のコンピューティング プラットフォーム フレームワークが問題をシームレスに置き換える方法

このチュートリアルでは、ファクター バッチ計算の実際のビジネス シナリオに焦点を当て、従来のファクター プラットフォームのコア計算ツールとして DolphinDB を紹介します。DolphinDB をコアとするファクター計算プラットフォームには、データ同期モジュール、ファクター バッチ計算モジュール、ファクター スケジューリング モジュールが含まれます。その中で、dataX はデータ同期ツールとして、リレーショナル データベースから DolphinDB への元のデータと増分データの同期保存を担当し、DolphinDB は係数計算およびストレージ モジュールとして使用され、Celery はタスク スケジューリング フレームワーク モジュールとして使用されます。

DolphinDB 因子計算プラットフォームは、リアルタイムの因子計算サービス、ビッグデータのバッチ計算サービス、および事業部門向けの履歴因子クエリ サービスを提供できます。DolphinDB の導入後、高、中、低頻度の係数計算の要件を満たすだけでなく、シームレスな統合を実現するための豊富な API と ETL ツールも備えています。以下では、WorldQuant 101 Alpha ファクター指標ライブラリーのファクター No. 1WQAlpha1を例としてファクター計算プラットフォーム全体の構築プロセスを示します。

1. 全体構成

DolphinDB および Python Celery フレームワークに基づくファクター プラットフォームの構築には、主に、dataX に基づく SQL Server Reader (履歴データ同期モジュール) および DolphinDB (データ ストレージおよび計算モジュール) のデータ ソース インジェクション、DolphinDB ファクター関数の定義および呼び出しが含まれます。 Celery フレームワーク (Factor Platform Scheduling Module) は factor 関数を呼び出してパラメーターを渡し、最終的にデータをDataframeformat。その全体的な構成は次のとおりです。

1.1 SQL サーバーの概要

  • はじめに:
    SQL Server は、Microsoft によって開発および推進されているリレーショナル データベース管理システムです。
    SQL Server は、アーキテクチャ全体の元のデータ ソース部分です。
  • チュートリアルとダウンロードとインストール:
    SQL Server の使用、ダウンロード、およびインストールについては、公式の SQL Server ドキュメントを参照してください。

1.2 dataXの概要

  • はじめに:
    dataX は、MySQL、Oracle、SQL Server、Postgre などのさまざまな異種データ ソース間の効率的なデータ同期を実現するために使用される、異種データ ソース用のオフライン同期ツールです。
    このチュートリアルの dolphindbWriter の dataX プラグインは、ユーザーが SQL Server データを DolphinDB にインポートするのに役立ちます。
  • チュートリアルとダウンロードとインストール:
    dataX の使用とインストールについては、dataX ガイドを参照してください。ダウンロードするには、dataXをクリックしてください。

1.3 DolphinDB の概要

  • はじめに:
    DolphinDB は、高頻度因子と因子ストレージを計算するための高性能時系列データ処理フレームワークです。
    このチュートリアルでは DolphinDB を因子計算のメイン ツールとして使用し、独自の関数ビュー関数を組み合わせて定義済みの因子関数を実現し、Python で DolphinDB の Python API を呼び出します。
  • チュートリアルとダウンロード、インストール:
    DolphinDB インストール ガイドについては、DolphinDB インストールおよびユーザー ガイドを参照してください。ダウンロード リンクをクリックしてダウンロードしてください。Python api の呼び出しについては、Python API for DolphinDBを参照してください。

1.4 セロリの概要

  • はじめに:
    Celery は Python をベースに開発されたシンプルで柔軟かつ信頼性の高い分散型非同期メッセージ キューです. 非同期タスク (Async Task) 処理を実装するために使用されます. 実際の使用では, メッセージ ミドルウェア (Broker) を使用してタスクを監視する必要があります.実行ユニット (Worker) を実行し、タスクの実行結果を結果ストレージ (Backend) に格納します。
    セロリには次の利点があります。

  • リクエストを非同期的に開始および処理する機能を実現できます。Python マルチスレッドを実現する方が便利です。

  • rabbitMQ や DolphinDB などのコンポーネントに簡単に統合でき、強力なスケーラビリティを備えています。

このチュートリアルでは、Celery をタスク スケジューリング フレームワークとして使用し、redis をメッセージ ミドルウェアおよび結果ストレージとして使用して、因子計算のタスク呼び出しを実装します。

  • チュートリアルとダウンロードとインストール:
    Celery の使用、ダウンロード、およびインストールについては、Celery の公式中国語ドキュメントを参照してください。

注: Celery フレームワークを使用する場合TypeError: __init__() got an unexpected keyword argument 'username'などの、 5.1.0Celery フレームワークをインストールした後で、デフォルトの kombou ライブラリをアンインストールし、インストールされているライブラリのバージョンを指定することをお勧めします。

2. 環境展開

注: 1. このチュートリアルでは、テスト環境の展開を紹介しているため、展開された DolphinDB サービスは単一ノード バージョンです. 特定の展開チュートリアルについては、 DolphinDB シングルノード展開チュートリアルを
参照してください; 2. で使用されている Celeryバージョンこのチュートリアルは 4.3.0 です。

  • ハードウェア環境:

  • ソフトウェア環境:

3. 開発とユースケース

3.1 データ紹介

このチュートリアルでは、2020.01.01 から 2021.01.01 までの複数の銘柄の日次終値を、合計 544174 データ項目で選択します。以下は、SQL Server と DolphinDB の終値テーブルのデータ構造です。

3.2 ビジネスシナリオと指標の紹介

このチュートリアルでは、WorldQuant 101 アルファ ファクター インジケーター ライブラリのファクター No. 1 を計算のケースWQAlpha1として. インジケーター ライブラリとこのファクターの参照方法の詳細については、 WorldQuant 101 アルファ ファクター インジケーター ライブラリを参照してください.

3.3 dataX は SQL Server データを DolphinDB に同期します

このセクションでは、SQL Server データを DolphinDB に同期する方法について説明します。

注:
1. このチュートリアルでは、データを含む SQL Server データベースがデフォルトで事前に構築されており、その構築プロセスは次のプロセス紹介では説明しません; 2. DolphinDB サービスの単一ノード バージョンの対応する
ポートのこのチュートリアルで展開されます8848

  • DolphinDB データベース テーブルの構築:
    DolphinDB にデータをインポートする前に、デプロイされた DolphinDB サービスでデータベース テーブルを事前に構築する必要があります。次の DolphinDB スクリプトを実行して、データベースdfs://tick_closetick_close

    dbName = “dfs://tick_close” tbName = “tick_close” if(existsDatabase(dbName)){ dropDatabase(dbName) } db = データベース(dbName, RANGE, date(datetimeAdd(2000.01M,0…50*12,'M '))) name = SecurityIDTradeDate Value type =SYMBOL DATEDOUBLE schemaTable = table(1:0, name, type) db.createPartitionedTable(table=schemaTable, tableName=tbName, partitionColumns=`TradeDate)

  • インポート構成ファイルを作成する:
    dataX を起動してデータ インポート コマンドを実行する場合、最初に構成ファイルを json 形式で書き込む必要があります。これは、データ同期中にデータ ソース関連の構成を指定するために使用されます。
    一般に、各データ テーブルの同期には、対応する構成ファイルの作成が必要になることがよくあります。このチュートリアルでは、次の tick_close.json ファイルが tick_close データ テーブル用に書き込まれます。

    { "job": { "content": [ { "writer": { "parameter": { "dbPath": "dfs://tick_close", "tableName": "tick_close", "batchSize": 100, "userId ”: “admin”, “pwd”: “123456”, “host”: “127.0.0.1”, “table”: [ { “type”: “DT_SYMBOL”, “name”: “SecurityID” }, { “type ”: “DT_DATE”, “name”: “TradeDate” }, { “type”: “DT_DOUBLE”, “name”: “Value” } ], “port”: 8848 }, “name”: “dolphindbwriter” }, “reader”: { “name”: “sqlserverreader”, “parameter”: { “username”: “SA”, “password”: “Sa123456”, “column”: [ “*” ], “connection”: [ { “table”: [ “tick_close” ], “jdbcUrl”: [ “jdbc:sqlserver://127.0.0.1:1234;DatabaseName=tick_close” ]

                            }
                        ]
                    }
                }
            }
        ],
        "setting": {
          
          
            "speed": {
          
          
                "channel": 1
            }
        }
    }
    

    }

注: このチュートリアルに含まれるデータ同期は、履歴データの完全な同期のみです. 実際のプロセスでは、増分同期などの必要がある場合は、2 つの構成 と をwriter構成DataX ツールに基づくDolphinDBデータsaveFunctionNameインポート を参照してくださいsaveFunctionDef

  • データ インポート コマンドを実行します。dataXディレクトリ
    に入り、次のコマンドを実行してデータを DolphinDB データ テーブルにインポートします。bintick_close

    $ python datax.py …/conf/tick_close.json

パラメータの説明:

  • datax.py: dataX を開始するために使用されるスクリプト、必須
  • ../conf/tick_close.json: 構成ファイルを保存するパス (必須)

期待される出力:

3.4 Celery フレームワークが DolphinDB の定義済み関数の計算をトリガーする

このセクションでは、DolphinDB スクリプトを使用して間隔リターンを計算するための係数関数を実装し、Celery フレームワークを使用してフレームワークを呼び出してトリガーする方法について説明します。

  • メッセージ ミドルウェアと結果ストレージ モジュールの redis サービスの構築:

Celery フレームワークには、メッセージを送信してタスク スケジューリングを実装するためのメッセージ ミドルウェアと、結果を保存するための結果保存ツールが必要です。このチュートリアルでは、メッセージ ミドルウェアおよび結果ストレージ ツールとして redis を使用することをお勧めします。そのデプロイ ポートは です6379実際の使用では、ユーザーは実際の状況に応じて使用するツールと展開方法を選択できます。このチュートリアルでの redis のデプロイ プロセスは省略されています。

  • DolphinDB ファクター関数の実装プロセス:

マシンにログインするか、DolphinDB GUI または VScode プラグインを使用して DolphinDB サービスに接続し、DolphinDB スクリプトの定義済み関数を使用します。このチュートリアルでは、WorldQuant 101 アルファ ファクター インジケーター ライブラリの No. 1 ファクターをカプセル化しWQAlpha1、例として取り上げます。コードの実装は次のとおりです。

/**
 * 因子:WorldQuant 101 Alpha 因子指标库中的1号因子 WQAlpha1
参数:
       security_id:STRING VECTOR,股票代码序列
       begin_date:DATE,区间开始日期
       end_date:DATE,区间结束日期
 */
use wq101alpha
defg get_alpha1(security_id, begin_date, end_date){
	if (typestr(security_id) == 'STRING VECTOR' && typestr(begin_date) == `DATE && typestr(end_date) == `DATE){
	tick_list = select * from loadTable("dfs://tick_close", "tick_close") where TradeDate >= begin_date and TradeDate <= end_date and SecurityID in security_id
	alpha1_list=WQAlpha1(panel(tick_list.TradeDate, tick_list.SecurityID, tick_list.Value))
	return table(alpha1_list.rowNames() as TradeDate, alpha1_list)
	}
	else {
		print("What you have entered is a wrong type")
		return `NULLValue
	}
}

パラメータの説明:

  • リクエスト パラメータ:

  • 戻りパラメータ:

Python API を使用して Python コードで DolphinDB 定義済み関数を呼び出す操作は、サーバー サービスで定義済み関数を呼び出す操作とは異なるため、sessionPython API が DolphinDB スクリプトで定義された関数を正常に呼び出せるようにするために、このチュートリアルで紹介したfunctionView(つまり関数ビュー) 関数を使用するには、最初に関数ビューに関数を追加し、研究者に関数ビューの実行権限を与える必要があります (管理者ユーザーは権限を付与する必要はありません)。コードの実装は次のとおりです。

//将该函数加入到函数视图中
addFunctionView(get_alpha1)
//将该函数的调用权限赋予给xxx用户
grant("xxx", VIEW_EXEC, "get_alpha1")
  • Celery は因子関数プロジェクトの構築プロセスを呼び出します。

このセクションでは、Celery フレームワークに基づいてプロジェクトをビルドする方法を紹介します. このチュートリアルで使用される Celery のインストール方法は、pipコマンドマシンにログインして、次のコマンドを実行します. ユーザーは他のインストール方法も使用できます。

$ pip install celery==4.3.0 && pip install redis==3.2.0

注:TypeError: __init__() got an unexpected keyword argument 'username'の、Celery フレームワークのインストールと同時にインストールされたコンポーネント kombu ライブラリのバージョンに問題があることを意味します. 元のバージョンのpip3 install kombu==5.1.0ライブラリをアンインストールしてから、ライブラリのインストール5.1.0バージョン。

必要なライブラリをインストールした後、特定のディレクトリで次のコマンドを実行して、プロジェクトのディレクトリ構造と必要なファイルを構築します。

$ mkdir celery_project && touch celery_project/tasks.py celery_project/app.py

tree ./celery_project次のコマンドを実行して、プロジェクトのディレクトリ構造を表示します。

./celery_project ├── app.py └── tasks.py  0 directories, 2 files

そのうち、2つのファイルの内容は次のように書かれています。

tasks.py: このファイルは、DolphinDB でsessionパッケージ、Celery フレームワークによって非同期にスケジュールできるタスクとしてパッケージ化された関数を宣言します。

まず、必要な Python ライブラリをインポートします。

from celery import Celery
import dolphindb as ddb
import numpy as np
import pandas as pd
from datetime import datetime

次に、DolphinDB の Python API を呼び出して、以前の DolphinDB サービスを確立しますsession

s = ddb.session()
s.connect("127.0.0.1", 8848, "admin", "123456")

同時に、Celery オブジェクトをインスタンス化し、関連する構成を設定します。

app = Celery(
    'celeryApp',
    broker='redis://localhost:6379/1',
    backend='redis://localhost:6379/2'
)
app.conf.update(
    task_serializer='pickle',
    accept_content=['pickle'], 
    result_serializer='pickle',
    timezone='Asia/Shanghai',
    enable_utc=True,
)

注: 計算プロセスにdatetimeDataFrameフォーマット データの送信と返信が含まれるため、Celery の既定のシリアル化メソッドはこのタイプのデータのシリアル化をサポートjsonできません。そのためtask_serializeraccept_content、 、およびresult_serializer3 つのパラメーターを設定して、シリアル化メソッドを として指定する必要がありますpickle

最後に、DolphinDB を呼び出す事前定義された関数を呼び出し用の関数にカプセル化し、実行されたタスクが Celery によって呼び出すことができる非同期タスクであることを示す@app.task()デコレーター。

@app.task()
def get_alpha1(security_id, begin_date, end_time):
    return s.run("get_alpha1", security_id, begin_date, end_time)

注: ここでは、Python のデータ型のパラメーターを使用して渡します. Python と DolphinDB のデータ型の対応関係と DolphinDB のデータ型のパラメーターの受け渡しについては、Python API for DolphinDBのセクション 1.3 を参照してください.

  • app.py: このファイルは、DolphinDB でsessionパッケージ、Celery フレームワークによって非同期にスケジュールできるタスクとしてパッケージ化された関数を宣言します。

以下はコードの実装です。ここでは、ループ ステートメントを使用し、Celery でdelay()関数 2 つのタスク呼び出し要求を Celery フレームワークに送信し、各ループでタスクを出力しますid

import numpy as np
from tasks import get_alpha1
security_id_list=[["600020", "600021"],["600022", "600023"]]
if __name__ == '__main__':
  for i in security_id_list:
    result = get_alpha1.delay(i, np.datetime64('2020-01-01'), np.datetime64('2020-01-31'))
    print(result)
  • Celery は factor 関数タスクの実装プロセスを呼び出します。

コマンドラインで次のステートメントを実行して、Celery フレームワークのワーカー側を実行します。

$ celery -A tasks worker --loglevel=info

期待される出力:

 -------------- celery@cnserver9 v4.3.0 (rhubarb)
---- **** -----
--- * ***  * -- Linux-3.10.0-1160.53.1.el7.x86_64-x86_64-with-centos-7.9.2009-Core 2022-11-11 00:10:34
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app:         celeryApp:0x7f597a1d4e48
- ** ---------- .> transport:   redis://localhost:6379/1
- ** ---------- .> results:     redis://localhost:6379/2
- *** --- * --- .> concurrency: 64 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery


[tasks]
  . tasks.max_drawdown

[2022-11-11 00:10:37,413: INFO/MainProcess] Connected to redis://localhost:6379/1
[2022-11-11 00:10:37,437: INFO/MainProcess] mingle: searching for neighbors
[2022-11-11 00:10:38,465: INFO/MainProcess] mingle: all alone
[2022-11-11 00:10:38,488: INFO/MainProcess] celery@cnserver9 ready.

このコマンドは の実行worker後も、マシンとの新しいセッションを確立し、Celery プロジェクト ディレクトリに入った後、次のコマンドを実行して非同期タスク呼び出し要求を Celery フレームワークに送信する必要があります。

$ python3 app.py

期待される出力:

400a3024-65a1-4ba6-b8a9-66f6558be242
cd830360-e866-4850-aba0-3a07e8738f78

このとき、前に実行状態だったworker端末、非同期タスクの実行ステータスと返された結果情報を確認できます。

 -------------- celery@cnserver9 v4.3.0 (rhubarb)
---- **** -----
--- * ***  * -- Linux-3.10.0-1160.53.1.el7.x86_64-x86_64-with-centos-7.9.2009-Core 2022-11-11 00:10:34
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app:         celeryApp:0x7f597a1d4e48
- ** ---------- .> transport:   redis://localhost:6379/1
- ** ---------- .> results:     redis://localhost:6379/2
- *** --- * --- .> concurrency: 64 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery


[tasks]
  . tasks.max_drawdown

[2022-11-11 00:10:37,413: INFO/MainProcess] Connected to redis://localhost:6379/1
[2022-11-11 00:10:37,437: INFO/MainProcess] mingle: searching for neighbors
[2022-11-11 00:10:38,465: INFO/MainProcess] mingle: all alone
[2022-11-11 00:10:38,488: INFO/MainProcess] celery@cnserver9 ready.
[2022-11-11 00:12:44,365: INFO/MainProcess] Received task: tasks.max_drawdown[400a3024-65a1-4ba6-b8a9-66f6558be242]
[2022-11-11 00:12:44,369: INFO/MainProcess] Received task: tasks.max_drawdown[cd830360-e866-4850-aba0-3a07e8738f78]
[2022-11-11 00:12:44,846: INFO/ForkPoolWorker-63] Task tasks.get_alpha1[400a3024-65a1-4ba6-b8a9-66f6558be242] succeeded in 0.04292269051074982s:    TradeDate  600020  600021
0  2020-01-01     NaN     NaN
1  2020-01-02     NaN     NaN
2  2020-01-03     NaN     NaN
3  2020-01-06     NaN     NaN
4  2020-01-07     0.5     0.0
5  2020-01-08     0.5     0.0
6  2020-01-09     0.0     0.5
7  2020-01-10     0.0     0.5
8  2020-01-13     0.0     0.5
9  2020-01-14     0.0     0.5
10 2020-01-15     0.5     0.0
11 2020-01-16     0.5     0.0
12 2020-01-17     0.5     0.0
13 2020-01-20     0.5     0.0
14 2020-01-21     0.0     0.5
15 2020-01-22     0.5     0.0
16 2020-01-23     0.5     0.0
17 2020-01-24     0.5     0.0
18 2020-01-27     0.5     0.0
19 2020-01-28     0.0     0.5
20 2020-01-29     0.0     0.5
21 2020-01-30     0.0     0.5
22 2020-01-31     0.0     0.5

[2022-11-11 00:12:45,054: INFO/ForkPoolWorker-1] Task tasks.get_alpha1[cd830360-e866-4850-aba0-3a07e8738f78] succeeded in 0.06510275602340698s:     TradeDate  600022  600023
0  2020-01-01     NaN     NaN
1  2020-01-02     NaN     NaN
2  2020-01-03     NaN     NaN
3  2020-01-06     NaN     NaN
4  2020-01-07     0.0     0.0
5  2020-01-08     0.0     0.0
6  2020-01-09     0.0     0.0
7  2020-01-10     0.0     0.0
8  2020-01-13     0.0     0.0
9  2020-01-14     0.0     0.0
10 2020-01-15     0.0     0.5
11 2020-01-16     0.0     0.0
12 2020-01-17     0.0     0.5
13 2020-01-20     0.5     0.0
14 2020-01-21     0.5     0.0
15 2020-01-22     0.5     0.0
16 2020-01-23     0.5     0.0
17 2020-01-24     0.0     0.5
18 2020-01-27     0.0     0.0
19 2020-01-28     0.5     0.0
20 2020-01-29     0.5     0.0
21 2020-01-30     0.5     0.0
22 2020-01-31     0.5     0.0

タスクの実行が終了すると、redis に保存されているタスクの実行結果の対応する情報を表示することもできます。

注: Celery フレームワーク端末が開始されていないときに、Celery フレームワーク端末に非同期タスク呼び出し要求を送信することもできますが、この時点では、開始されていないworker端末はid

4. まとめ

このチュートリアルでは、DolphinDB を従来のファクター コンピューティング プラットフォームに導入して、従来のファクター プラットフォームのパフォーマンスのボトルネックを解決する方法に焦点を当てています。実際のテストの後、Celery フレームワークのタスク非同期呼び出しの利点と、DolphinDB のコンピューティングおよびストレージ統合の強力なパフォーマンスの利点を組み合わせて、実際の生産プロセスのソリューション ケースを提供しました。

同時に、スペースが限られているため、SQL Server、dataX、DolphinDB、Celery フレームワークに関連するその他の操作をさらに表示することはできず、ユーザーは使用中に実際の状況に応じて調整する必要があります。また、このチュートリアルで考えられる間違いや欠陥を批判し、修正することも歓迎します。

付録

おすすめ

転載: blog.csdn.net/qq_34626094/article/details/130517199