AlgoPlus 2.0 株式定量取引 SDK 分析例

AlgoPlus 2.0 は、C++ 言語を使用して開発された市場規模のクオンツ トレーディング SDK であり、クオンツ トレーディング開発の効率を向上させ、クオンツ トレーディング技術の交流を促進することを目的としています。

この記事では、AlgoPlus 2.0を使用して株式シミュレーショントレードを実現する方法を例を用いて紹介します。

まず、AlgoPlus 2.0 の主要なメソッドを紹介します。


AlgoPlus のキーメソッド

初期化方法

/// pLoginField中存放了登录所需要的信息;
/// pMarketDataCallback是行情事件回调函数;
/// pOrderCallback是订单事件回调函数;
/// pEventCallback是其他事件回调函数指针;
/// 初始化完成后,pLoopCallback在一个独立线程中被反复执行;
CBaseTrader* init(short nRunID, CAPLoginField* pLoginField, FAPOnMarketDataFunctionType pMarketDataCallback, FAPOnOrderFunctionType pOrderCallback, FAPOnEventFunctionType pEventCallback, FAPOnLoopFunctionType pLoopCallback)

必要なログイン情報とイベント コールバック関数は初期化中に提供する必要があります。これらのコールバック関数はユーザー定義であり、イベントの発生時に AlgoPlus によって呼び出されます。ユーザーはコールバック関数にイベント処理ロジックを実装します。

購読方法

/// 省略交易所,优先匹配A股标的;
/// 如果交易代码不重复,可以省略交易所,且一次订阅不同交易所的标的;
/// 如果交易代码存在重复情况,需指定交易所,且订阅标的必须属于该交易所。
TAPErrorIDType subscribe(CBaseTrader* pAPTrader, char** ppStandardID, int nCount, const char* szExchangeID)

注文方法

/// 买入指定的数量;
CAPOrderField* buy(CBaseTrader* pAPTrader, const char* szStandardID, int nOrderVolume, char chOrderType, double dOrderPrice, short nOrderMark, const char* szExchangeID);
/// 先根据订单类型确定报单价格,再计算金额对应的符合交易所规则的报单数量;
CAPOrderField* buyAmount(CBaseTrader* pAPTrader, const char* szStandardID, double dAmount, char chOrderType, double dOrderPrice, short nOrderMark, const char* szExchangeID);
/// 以可用资金为基数计算买入金额,最终换算成买入数量
CAPOrderField* buyRatio(CBaseTrader* pAPTrader, const char* szStandardID, double dRatio, char chOrderType, double dOrderPrice, short nOrderMark, const char* szExchangeID);

/// 卖出指定的数量,超过可用持仓则卖出全部可用持仓;
CAPOrderField* sell(CBaseTrader* pAPTrader, const char* szStandardID, int nOrderVolume, char chOrderType, double dOrderPrice, short nOrderMark, const char* szExchangeID);
/// 先根据订单类型确定报单价格,再计算金额对应的符合交易所规则的报单数量;
CAPOrderField* sellAmount(CBaseTrader* pAPTrader, const char* szStandardID, double dAmount, char chOrderType, double dOrderPrice, short nOrderMark, const char* szExchangeID);
/// 以可用持仓为基数计算卖出数量;
CAPOrderField* sellRatio(CBaseTrader* pAPTrader, const char* szStandardID, double dRatio, char chOrderType, double dOrderPrice, short nOrderMark, const char* szExchangeID);

/// 调仓指令,将持仓调整至目标数量。
CAPOrderField* balanceToLongValue(CBaseTrader* pAPTrader, const char* szStandardID, double dTargetValue, char chOrderType, double dOrderPrice, short nOrderMark, const char* szExchangeID);
/// 调仓指令,将持仓调整至目标金额。
CAPOrderField* balanceToLongVolume(CBaseTrader* pAPTrader, const char* szStandardID, int nTargetVolume, char chOrderType, double dOrderPrice, short nOrderMark, const char* szExchangeID);

キャンセル方法

/// 根据OrderID撤销某个特定的订单
TAPErrorIDType cancelOrder(CBaseTrader* pAPTrader, int nOrderID);
/// 撤销某只股票所有的未成成交订单
TAPErrorIDType cancelOrderByStandardID(CBaseTrader* pAPTrader, const char* szStandardID, const char* szExchangeID);
/// 撤销某交易所所有未成交订单
TAPErrorIDType cancelOrderByExchangeID(CBaseTrader* pAPTrader, const char* szExchangeID);
/// 撤销账号所有未成交订单
TAPErrorIDType cancelOrderAll(CBaseTrader* pAPTrader);

取引環境も必要ですが、ここではN Vision( http://www.n-sight.com.cn )が提供する株式模擬取引環境を利用します

N Vision 株式シミュレーション取引環境

N Vision には 3 セットの株式模擬取引環境があり、そのうちの 1 つは実際の市場と同じ取引時間を持ちます。

交易前置 tcp://210.14.72.11:4400
行情交易 tcp://210.14.72.11:4402

他の 2 つのセットは 7*24 時間環境です。

A:
7*24股票模拟环境交易前置 tcp://210.14.72.15:4400
7*24股票模拟环境行情前置 tcp://210.14.72.15:4402

B:
7*24股票模拟环境交易前置 tcp://210.14.72.16:9500
7*24股票模拟环境行情前置 tcp://210.14.72.16:9402

例と分析

import AlgoPlus as ap

def stock_on_event(event_id, field, islast, error_id, error_msg):
    field = ap.decode_ctp_event_field(event_id, field)
    print(f"-------")
    print(f"on_event -> EventID:{event_id},LastFlag:{islast},ErrorID:{error_id},ErrorMsg:{error_msg}")
    print(f"on_event -> Content: {field}")
    print(f"-------")

@ap.ap_marketdata_callback_wraps
def stock_on_marketdata_event(data):
    print(f"-------")
    print(f"on_marketdata -> {data}")
    print(f"-------")

@ap.ap_order_callback_wraps
def stock_on_order_event(event_id, order, position, cash):
    print(f"-------")
    print(f"on_order -> EventID:{event_id},UsableCash:{cash}")
    print(f"on_order -> {order}")
    print(f"on_order -> {position}")
    print(f"-------")

def stock_on_loop():
    global counter
    global standard_list
    global trader
    global last_order

    counter += 1
    if counter == 1:
        ap.cancelOrderAll(trader)
        print(f"-------")
        print(f"loop:{counter} -> cancelOrderAll")
        print(f"-------")
    elif counter == 100:
        print(f"-------")
        for item in standard_list:
            order = ap.buy(trader, item, 100, ap.ENUM_OrderType_FrontierLimitAndWait, 0)
            if order is not None:
                print(f"loop:{counter} -> buy UpperLimitPrice -> ErrorID:{order.ErrorID},StandardID:{item},Volume:{100},Price:{order.OriginalPrice}")
        print(f"-------")
    elif counter == 150:
        print(f"-------")
        for item in standard_list:
            order = ap.buy(trader, item, 100, ap.ENUM_OrderType_HomeBestLimitAndWait, 0)
            if order is not None:
                print(f"loop:{counter} -> buy HomeBestPrice -> ErrorID:{order.ErrorID},StandardID:{item},Volume:{100},Price:{order.OriginalPrice}")
                if order.ErrorID == 0:
                    last_order = order
        print(f"-------")
    elif counter == 200:
        if last_order is not None:
            ap.cancelOrder(trader, last_order.OrderID)
            print(f"-------")
            print(f"loop:{counter} -> cancelOrder last_order -> StandardID:{last_order.StandardID}")
            print(f"-------")
    elif counter == 250:
        ap.cancelOrderAll(trader)
        print(f"-------")
        print(f"loop:{counter} -> cancelOrderAll")
        print(f"-------")

if __name__ == '__main__':

    login = ap.CAPLoginField()
    login.License = ""
    login.UserType = ap.ENUM_UserType_NSIGHTStock
    login.UserID = ""
    login.InvestorID = ""
    login.Password = ""
    login.TraderFront = "tcp://210.14.72.15:4400"
    login.MdFront = "tcp://210.14.72.15:4402"
    login.ConnectTimeout = 0
    login.TaskExecuteGap = ap.MICROSECONDS_IN_SECOND * 2
    login.BasePath = "./"

    last_order = None
    counter = 0
    standard_list = ["600000", "000001", "300001"]
    trader = ap.init(0, login, stock_on_marketdata_event, stock_on_order_event, stock_on_event, stock_on_loop)
    if trader is not None:
        ap.subscribe(trader, standard_list)
        ap.loop()
    else:
        init_error_id = ap.getInitError()
        print(f"init_error -> InitErrorID:{init_error_id}")
  • stock_on_eventこれは、私たちが定義した他のイベント コールバック関数です。ap.decode_ctp_event_field 関数は、event_id に基づいて C++ 構造を Python オブジェクトに変換します。

ここに画像の説明を挿入します
図に示すように、初期化フェーズでは ENUM_EventID_DayRolling (10008) イベントと ENUM_EventID_Ready (10009) イベントがそれぞれトリガーされます。

  • stock_on_marketdata_eventこれは、定義した市場通知イベントのコールバック関数です。@ap.ap_marketdata_callback_wraps は、C++ マーケット データ構造を Python オブジェクトに変換できるデコレーターです。

ここに画像の説明を挿入します

  • 初期化が完了すると、stock_on_loop別のスレッドで繰り返し実行されます。

ここに画像の説明を挿入します

図に示すように、100回目の約定では、600000、000001、300001の100株を日次指値で購入しました。使用される注文命令はbuy、注文タイプはENUM_OrderType_FrontierLimitAndWaitです。

ここに画像の説明を挿入します

150回目の約定では、600000、000001、300001の100株を最高指値で購入しました。使用される注文コマンドはbuy、注文タイプはENUM_OrderType_HomeBestLimitAndWaitです。

その中で、stock_on_order_event注文ステータスと取引金額の変更をリアルタイムでプッシュする役割を果たします。@ap.ap_order_callback_wraps は、C++ の順序構造と位置構造を Python オブジェクトに変換するデコレーターです。


クライアント

Nビジョン公式サイトのダウンロードページ(http://n-sight.com.cn/u/w/download/download.html )のカスタマイズサービスエリアからSwordfish Star端末をダウンロードしてください。

ログインする前に、N Horizo​​n シミュレーションの取引アドレスを選択します。

ここに画像の説明を挿入します
ここに画像の説明を挿入します

ログイン後、アカウントの取引ステータスを監視できます。

ここに画像の説明を挿入します

写真にあるように、これはサンプル注文状況で、最初の 3 つの日次指値注文はすべて約定され、最後の 3 つのベスト指値注文は 2 回約定されました。初めて cancelOrder を使用して注文をキャンセルする場合、注文キャンセル オブジェクトは 300001 です。この注文は完了しているため、まだ約定されていません。2 回目の注文キャンセルに使用される命令は cancelOrderAll です。注文キャンセルの対象はすべての未約定注文であるため、今回は 600000 がキャンセルされます。


プロジェクトアドレス

おすすめ

転載: blog.csdn.net/AlgoPlus/article/details/116244763