/**
 * @file xlt_trade_api.h
 * @author 上海前路有光数字科技
 * @date 2026-01-10
 * @brief 本接口定义XLT的主要接口类，包括交易回调接口类。
 */

#pragma once

#include <cstdint>

#include "xlt_trade_data_type.h"
#include "xlt_trade_struct.h"
#include "xlt_trade_config.h"
#include "xlt_trade_list.h"

namespace x1 {
    /**
     * @brief 交易回调类
     */
    class XLTTradeSpi {
    public:
        virtual ~XLTTradeSpi() = default;
        /**
         * @brief 断线通知
         * 用户断线之后需要重新调用login方法，建立连接并登录
         * @param session_id 会话ID。
         */
        virtual void on_disconnect(uint64_t session_id) {};
        /**
         * @brief 订单超时通知
         * @param session_id 会话id，登录时得到
         * @param xid 超时的订单标识
         * @remark 订单超时通知是指在指定时间内未收到订单的成交回报或状态更新时触发的通知，不代表委托失败，需要用户自行查询确认订单状态。
         */
        virtual void on_order_timeout(uint64_t session_id, uint64_t xid) {};

        // *******************************************
        // 以下开始是请求响应回调
        // 请求响应回调包含：
        // uint64_t request_id 此消息响应函数对应的请求ID
        // const xlt_error_info_t* error_info 发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误。
        // *******************************************
        /**
         * @brief 登录通知
         * @param session_id 本次登录生成的会话ID。如果登录失败则为0。
         * @param request_id 此消息响应函数对应的请求ID
         * @param error_info 登录请求发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误。
         */
        virtual void on_login(uint64_t session_id, uint64_t request_id, const xlt_error_info_t* error_info) {};
        /**
         * @brief 认证通知
         * @param session_id 会话ID。
         * @param request_id 此消息响应函数对应的请求ID
         * @param trade_token 交易令牌，登录成功且需要认证时返回的交易令牌，后续API请求需要携带此令牌进行交易。
         * @param error_info 认证请求发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误。
         */
        virtual void on_auth_trade(uint64_t session_id, uint64_t request_id, uint64_t trade_token, const xlt_error_info_t* error_info) {};
        /**
         * @brief 订阅通知响应
         * @param session_id 会话ID。
         * @param request_id 此消息响应函数对应的请求ID
         * @param start_sequence 订阅请求起始序号，如果是RESTART则为0，如果QUICK则为latest_sequence，如果SPECIFY则为用户请求的start_sequence
         * @param latest_sequence AGW端最新的序列号
         * @param error_info 发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误。
         */
        virtual void on_subscribe_trade_message(uint64_t session_id, uint64_t request_id, uint64_t start_sequence, uint64_t latest_sequence, const xlt_error_info_t* error_info) {};

        /**
         * @brief 重推通知响应
         * @param session_id 会话ID。
         * @param request_id 此消息响应函数对应的请求ID
         * @param start_sequence 重推请求起始序号，为用户请求的start_sequence
         * @param end_sequence 重推请求结束序号，为用户请求的end_sequence
         * @param error_info 发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误。
         */
        virtual void on_rebuild_trade_message(uint64_t session_id, uint64_t request_id, uint64_t start_sequence, uint64_t end_sequence, const xlt_error_info_t* error_info) {};
        /**
         * @brief 持仓查询响应
         * @param session_id 会话id，登录时得到
         * @param request_id 此消息响应函数对应的请求ID
         * @param positions 本次响应返回的持仓列表，个数由data_count决定
         * @param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
         * @param error_info 查询账户持仓发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         * @remark 一个查询请求可能对应多个响应，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
         */
        virtual void on_query_positions(uint64_t session_id, uint64_t request_id, const XLTPositionList* positions, bool is_last, const xlt_error_info_t* error_info) {};
        /**
         * @brief 资金查询响应
         * @param session_id 会话id，登录时得到
         * @param request_id 此消息响应函数对应的请求ID
         * @param assets 查询到的资金账户列表情况，个数由data_count决定
         * @param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
         * @param error_info 查询资金账户发生错误时返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         * @remark 需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
         */
        virtual void on_query_assets(uint64_t session_id, uint64_t request_id, const XLTAssetList* assets, bool is_last, const xlt_error_info_t* error_info) {};
        /**
         * @brief 订单查询响应
         * @param session_id 会话id，登录时得到
         * @param request_id 此消息响应函数对应的请求ID
         * @param orders 本次响应返回的订单信息，个数由data_count决定
         * @param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
         * @param error_info 查询订单时发生错误时，返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         * @remark 需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
         */
        virtual void on_query_orders(uint64_t session_id, uint64_t request_id, const XLTOrderList* orders, bool is_last, const xlt_error_info_t* error_info) {};
        /**
         * @brief 分页请求查询报单响应
         * @param session_id 会话id，登录时得到
         * @param request_id 此消息响应函数对应的请求ID
         * @param order_infos 查询到的订单列表
         * @param req_count 分页请求的最大数量
         * @param rsp_count 分页请求的当前回报数量
         * @param query_reference 当前报单信息所对应的查询索引，需要记录下来，在进行下一次分页查询的时候需要用到
         * @param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
         * @param error_info 查询报单时发生错误时，返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         * @remark 当order_sequence为0，表明当次查询没有查到任何记录，当is_last为true时，如果order_sequence等于req_count，那么表示还有报单，可以进行下一次分页查询，如果不等，表示所有报单已经查询完毕。一个查询请求可能对应多个响应，需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线。
         */
        virtual void on_query_orders_by_page(uint64_t session_id, uint64_t request_id, const XLTOrderList* order_infos, uint64_t req_count, uint64_t rsp_count, const xlt_page_query_reference_t* query_reference, bool is_last, const xlt_error_info_t* error_info) {};
        /**
         * @brief 成交回报查询响应
         * @param session_id 会话id，登录时得到
         * @param request_id 此消息响应函数对应的请求ID
         * @param trade_reports 本次响应返回的成交信息，个数由data_count决定
         * @param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
         * @param error_info 查询发生错误时，返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         * @remark 需要快速返回，否则会堵塞后续消息，当堵塞严重时，会触发断线
         */
        virtual void on_query_trades(uint64_t session_id, uint64_t request_id, const XLTTradeReportList* trade_reports, bool is_last, const xlt_error_info_t* error_info) {};

        /**
         * @brief 请求查询初始资产响应
         * @param session_id 会话id，登录时得到
         * @param request_id 此消息响应函数对应的请求ID
         * @param init_assets 查询到的初始化资产信息列表
         * @param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
         * @param error_info 查询发生错误时，返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         */
        virtual void on_query_init_assets(uint64_t session_id, uint64_t request_id, const XLTInitAssetList* init_assets, bool is_last, const xlt_error_info_t* error_info) {};
        /**
         * @brief 请求查询初始持仓响应
         * @param session_id 会话id，登录时得到
         * @param request_id 此消息响应函数对应的请求ID
         * @param init_positions 查询到的初始化持仓信息列表
         * @param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
         * @param error_info 查询发生错误时，返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         */
        virtual void on_query_init_positions(uint64_t session_id, uint64_t request_id, const XLTInitPositionList* init_positions, bool is_last, const xlt_error_info_t* error_info) {};
        /**
         * @brief 请求查询交易账号信息响应
         * @param session_id 会话id，登录时得到
         * @param request_id 此消息响应函数对应的请求ID
         * @param trade_account_infos 查询到的信息列表
         * @param is_last 此消息响应函数是否为request_id这条请求所对应的最后一个响应，当为最后一个的时候为true，如果为false，表示还有其他后续消息响应
         * @param error_info 查询发生错误时，返回的错误信息，当error_info为空，或者error_info.error_id为0时，表明没有错误
         */
        virtual void on_query_trade_account_info(uint64_t session_id, uint64_t request_id, const XLTTradeAccountInfoList* trade_account_infos, bool is_last, const xlt_error_info_t* error_info) {};

        // *******************************************
        // 以下开始是消息推送回调
        // 当用户调用subscribe_trade_message或rebuild_trade_message接口后，交易系统会根据用户请求的消息类型TradeMessageType和起始序号，推送相应的消息给用户。用户需要在对应的回调函数中处理这些消息。
        // 消息推送回调包含：
        // const xlt_msg_desc_t* msg_desc
        // msg_desc.sequence 消息序号，递增，断点续传标识。为0时，不能作为续传标识。快速订单回报为0。
        // msg_desc.is_rebuild 是否为重推请求消息，若是通过rebuild_trade_message接口发起则为true，若是通过subscribe_trade_message接口发起则为false
        //
        // *******************************************
        /**
         * @brief 新订单申报成功响应
         * 此函数用于处理来自交易系统的申报成功响应。
         * subscribe_trade_message或rebuild_trade_message指定消息类型包含TradeMessageType::REPORT时，交易系统会在订单申报成功后推送该响应。
         * @param session_id 会话ID。
         * @param msg_desc 消息描述信息
         * @param order_response 申报成功响应数据指针。
         */
        virtual void on_order_response(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_order_response_t* order_response) {};
        /**
         * @brief 撤单成功响应
         * 此函数用于处理来自交易系统的撤单成功响应。
         * subscribe_trade_message或rebuild_trade_message指定消息类型包含TradeMessageType::REPORT时，交易系统会在撤单成功后推送该响应。
         * @param session_id 会话ID。
         * @param msg_desc 消息描述信息
         * @param cancel_response 撤单成功响应数据指针。
         */
        virtual void on_cancel_response(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_cancel_response_t* cancel_response) {};
        /**
         * @brief 成交回报通知
         * 此函数用于处理来自交易系统的成交回报通知。
         * subscribe_trade_message或rebuild_trade_message指定消息类型包含TradeMessageType::REPORT时，交易系统会在订单发生成交时推送该通知。
         * @param session_id 会话ID。
         * @param msg_desc 消息描述信息
         * @param trade_report 成交回报通知数据指针。
         */
        virtual void on_trade_report(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_trade_report_t* trade_report) {};
        /**
         * @brief 委托失败通知
         * 此函数用于处理来自交易系统的委托失败通知。
         * 包括内部拒单、交易所拒单、废单及撤单失败等情况。
         * subscribe_trade_message或rebuild_trade_message指定消息类型包含TradeMessageType::REPORT时，交易系统会在订单委托失败时推送该通知。
         * @param session_id 会话ID。
         * @param msg_desc 消息描述信息
         * @param order_error_response 委托失败通知数据指针。
         */
        virtual void on_order_error_response(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_order_error_response_t* order_error_response) {};
        /**
         * @brief 订单结束通知
         * 本函数用于接收订单结束通知；当订单状态变为完全成交、撤单成功、废单等终结状态时，交易系统会发送该通知。
         * subscribe_trade_message或rebuild_trade_message指定消息类型包含TradeMessageType::REPORT时，交易系统会在订单结束时推送该通知。
         * @param session_id 会话ID。
         * @param msg_desc 消息描述信息
         * @param order_end 包含订单结束信息的数据指针。
         */
        virtual void on_order_end(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_order_end_t* order_end) {};
        /**
         * @brief 交易所原始订单执行报告（需用户自行解码）
         * 此函数用于接收原始的订单执行报告。报告内容包括但不限于订单状态、执行细节等。
         * 由于报告是原始形式，因此需要用户自行解码以获取具体信息。
         * subscribe_trade_message或rebuild_trade_message指定消息类型包含TradeMessageType::RAW_REPORT时，交易系统会在订单状态变更时推送该通知。
         * @param session_id 会话ID。
         * @param msg_desc 消息描述信息
         * @param client_id 委托源标识，用户登录时自定义
         * @param xid 报单标识，通常是订单的唯一标识符。
         * @param report_id 回报标识，32字节，非字符串。
         * @param exchange_index 交易所索引，表示报告来自哪个交易所。
         * @param platform_type 平台类型
         * @param gateway_index 网关索引
         * @param report_size 回报长度
         * @param raw_report 报告数据的指针，具体内容依赖于报告类型，需用户自行解码。
         */
        virtual void on_raw_report(uint64_t session_id, const xlt_msg_desc_t* msg_desc, uint8_t client_id, uint64_t xid, char report_id[32], ExchangeIndex exchange_index, uint16_t
                                   platform_type, uint16_t gateway_index, uint32_t report_size, char* raw_report) {};
        /**
         * @brief 主柜资金划拨请求推送
         * subscribe_trade_message或rebuild_trade_message指定任意消息类型时，交易系统会在收到主柜资金划拨请求时推送该通知。
         * @param session_id 会话id，登录时得到
         * @param msg_desc 消息描述信息
         * @param fund_transfer_request 资金划拨请求
         */
        virtual void on_counter_fund_transfer_request(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_counter_fund_transfer_request_t* fund_transfer_request) {};
        /**
         * @brief 主柜资金划拨结果回调
         * subscribe_trade_message或rebuild_trade_message指定任意消息类型时，交易系统会在收到主柜资金划拨结果时推送该通知。
         * @param session_id 会话ID
         * @param msg_desc 消息描述信息
         * @param fund_transfer_result 资金划转结果
         */
        virtual void on_counter_fund_transfer_result(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_counter_fund_transfer_result_t* fund_transfer_result) {};
        /**
         * @brief 双中心资金划拨请求推送
         * subscribe_trade_message或rebuild_trade_message指定任意消息类型时，交易系统会在收到双中心资金划拨请求时推送该通知。
         * @param session_id 会话id，登录时得到
         * @param msg_desc 消息描述信息
         * @param cluster_fund_transfer_request 双中心资金划拨请求
         */
        virtual void on_cluster_fund_transfer_request(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_cluster_fund_transfer_request_t* cluster_fund_transfer_request) {};
        /**
         * @brief 双中心资金划转结果回调
         * subscribe_trade_message或rebuild_trade_message指定任意消息类型时，交易系统会在收到双中心资金划拨结果时推送该通知。
         * @param session_id 会话ID
         * @param msg_desc 消息描述信息
         * @param cluster_fund_transfer_result 双中心资金划转结果
         */
        virtual void on_cluster_fund_transfer_result(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_cluster_fund_transfer_result_t* cluster_fund_transfer_result) {};
        /**
         * @brief 订单簿消息：新订单通知回调
         * @param session_id 会话ID
         * @param msg_desc 消息描述信息
         * @param order_insert 订单委托明细
         */
        virtual void on_order_book_insert(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_order_book_insert_t* order_insert) {};
        /**
         * @brief 订单簿消息：订单变动通知回调
         * @param session_id 会话ID
         * @param msg_desc 消息描述信息
         * @param order_update 订单响应明细
         */
        virtual void on_order_book_update(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_order_book_update_t* order_update) {};
        /**
         * @brief 订单簿消息：订单错误通知回调
         * @param session_id 会话ID
         * @param msg_desc 消息描述信息
         * @param order_error 订单错误明细
         */
        virtual void on_order_book_error(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_order_book_error_t* order_error) {};
        /**
         * @brief 订单簿消息：资金变动通知回调
         * @param session_id 会话ID
         * @param msg_desc 消息描述信息
         * @param asset_info 资金变动明细
         */
        virtual void on_asset(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_asset_info_t* asset_info) {};
        /**
         * @brief 订单簿消息：持仓变动通知回调
         * @param session_id 会话ID
         * @param msg_desc 消息描述信息
         * @param position_info 持仓变动明细
         */
        virtual void on_position(uint64_t session_id, const xlt_msg_desc_t* msg_desc, const xlt_position_info_t* position_info) {};
    };

    /**
     * @brief 接口类
     */
    class XLTTradeApi {
    public:
        /**
         * @brief 创建实例（只能创建一次）
         * @return 返回交易接口实例
         */
        static XLTTradeApi* create();
        /**
         * @brief 获取API版本号
         * @return API版本号
         */
        static const char* get_api_version();
        /**
         * @brief 获取错误信息
         * @return 错误信息
         */
        static xlt_error_info_t get_last_error();
        /**
         * @brief 根据订单ID获取订单序列号
         * @param xid 订单ID
         * @return 返回订单序列号
         * @remark 若用户启用自定义订单序号功能（XLTTradeConfig::set_order_seq_self_define），则此接口将返回用户自定义的订单序号xlt_order_insert_info_t.order_sequence，否则返回系统生成的订单序号。
         */
        static uint64_t get_order_sequence(uint64_t xid);
        /**
         * @brief 初始化交易，登录之前必须调用此函数，只能初始化一次
         * @param trade_config 配置参数
         * @param trade_spi 派生自交易响应类的实例，请在登录之前设定
         * @return 初始化是否成功
         */
        bool initialize(XLTTradeConfig* trade_config, XLTTradeSpi* trade_spi);
        /**
         * @brief 停止交易API
         * 断开所有交易session连接，清空所有session上的回调指针，停止回调。
         * @remark 调用stop后，所有未完成的回调将不再触发，用户可安全地释放对象。
         */
        void stop();
        /**
         * @brief 用户登录请求
         * @param request_id 用于用户定位请求响应的ID，由用户自定义
         * @param client_id 客户端标识ID
         * @param account_name 交易账号
         * @param password 登录密码
         * @param pub_key 用户公钥(长度64字节)，用户开户时申请得到，暂未启用
         * @param info 终端信息，若当前API为最终端则填nullptr，否则填写终端信息
         * @return 查询请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool login(uint64_t request_id, uint16_t client_id, const char* account_name, const char* password, const char* pub_key, const xlt_user_terminal_info_t* info=nullptr);
        /**
         * @brief 登出请求
         * @param session_id 会话id，登录时得到
         * @return true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool logout(uint64_t session_id);
        /**
         * @brief 交易授权认证
         * @param session_id 会话ID，登录时得到
         * @param request_id 用于用户定位请求的ID，由用户自定义
         * @param account_name 交易账号
         * @param password 登录密码
         * @param pub_key 用户公钥(长度64字节)，用户开户时申请得到，暂未启用
         * @param info 终端信息，若当前API为最终端则填nullptr，否则填写终端信息
         * @return true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool auth_trade(uint64_t session_id, uint64_t request_id, const char* account_name, const char* password, const char* pub_key, const xlt_user_terminal_info_t* info=nullptr);
        /**
         * @brief 解除交易授权认证
         * @param session_id 会话ID，登录时得到
         * @param request_id 用于用户定位请求的ID，由用户自定义
         * @param trade_token 交易令牌，交易授权认证时得到
         * @return true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool deauth_trade(uint64_t session_id, uint64_t request_id, uint64_t trade_token);

        /**
         * @brief 获取当前交易日。只有登录成功后,才能得到正确的交易日。
         * @return 返回日期，格式为YYYYMMDD
         */
        uint32_t get_trading_day();
        /**
         * @brief 获取初始资产信息
         * @param session_id 会话ID，登录时得到
         * @param trade_token 交易令牌，交易授权认证时得到，如果登录账户即为交易账户，填0即可
         * @return 初始资产信息指针，如果未登录或不存在则返回nullptr
         */
        const xlt_init_asset_info_t* get_init_assets(uint64_t session_id, uint64_t trade_token = 0);
        /**
         * @brief 获取初始持仓信息
         * @param session_id 会话ID，登录时得到
         * @param trade_token 交易令牌，交易授权认证时得到，如果登录账户即为交易账户，填0即可
         * @return 初始持仓信息列表指针，如果未登录或不存在则返回nullptr
         */
        const XLTInitPositionList* get_init_positions(uint64_t session_id, uint64_t trade_token = 0);
        /**
         * @brief 获取账户索引，只有登录成功后，才能得到正确的资金账户索引
         * @param session_id 会话id，登录时得到
         * @param trade_token 交易令牌，交易授权认证时得到，如果登录账户即为交易账户，填0即可
         * @return 账户索引，0表示失败，非0表示成功
         */
        uint64_t get_account_index(uint64_t session_id, uint64_t trade_token = 0);
        /**
         * @brief 根据订单ID获取订单发送者信息，包括session_id和trade_token
         * @param xid 订单ID
         * @param session_id 订单发送者的session_id
         * @param trade_token 订单发送者的trade_token
         */
        void get_xid_sender(uint64_t xid, uint64_t &session_id, uint64_t &trade_token);
        /**
         * @brief 根据业务编号获取发送者信息，包括session_id和trade_token
         * @param biz_no 业务编号
         * @param session_id 发送者的session_id
         * @param trade_token 发送者的trade_token
         */
        void get_biz_sender(char *biz_no, uint64_t &session_id, uint64_t &trade_token);

        /**
         * @brief 订阅交易数据
         * 每个session_id，仅第一次调用有效。
         * @param session_id 会话ID，登录时得到
         * @param request_id 用于用户定位请求的ID，由用户自定义
         * @param trade_message_type 订阅的交易数据类型，可以同时订阅多种类型，用按位或方式组合
         * @param resume_type 消息推送方式
         * @param start_sequence 数据推送的起始序列号，默认值为0，当resume_type为TradeResumeType::SPECIFY时有效
         * @return true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool subscribe_trade_message(uint64_t session_id, uint64_t request_id, trade_message_type_t trade_message_type, TradeResumeType resume_type, uint64_t start_sequence);
        /**
         * @brief 重推消息
         * @param session_id 会话ID，登录时得到
         * @param request_id 用于用户定位请求的ID，由用户自定义
         * @param trade_message_type 交易数据类型，可以同时订阅多种类型，用按位或方式组合
         * @param start_sequence 数据推送的起始序列号，从start_sequence+1开始推
         * @param end_sequence 数据推送的结束序列号，end_sequence必须大于start_sequence
         * @param account_index 交易账号索引，0表示查所有或者当前登录交易账号索引，非0表示指定交易账号索引。可通过get_account_index或者query_trade_account_info获取交易账号索引
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool rebuild_trade_message(uint64_t session_id, uint64_t request_id, trade_message_type_t trade_message_type, uint64_t start_sequence, uint64_t end_sequence, uint64_t account_index=0);
        /**
         * @brief 本地发送初始化函数，预分配本地发送资源，非必须调用。
         * 若不调用，会在首次发送订单时自动进行初始化，故建议在用户线程调用发送接口前调用此函数以避免首次发送订单时的延迟。
         */
        void init_local_send();
        /**
         * @brief 委托
         * 报单录入请求，所有业务统一报单接口，根据业务类型字段区分不同业务。
         * Xlight接收订单后，会在报单响应函数on_order_response, on_cancel_response, on_order_error_response中返回,
         * 之后所有的成交明细会在on_trade_report中返回，当订单到达终止状态会触发订单状态结束响应。
         * @param session_id   资金账户对应的session_id，登录时得到
         * @param order 委托信息
         * @param trade_token 交易令牌，如果是普通交易账号填0；如果为授权认证的账号，填写认证成功时on_auth_trade回调函数返回的trade_token。
         * @return 返回系统生成的订单ID，如果为‘0’表示订单发送失败，非"0"表示订单发送成功，用户需要记录下返回的order_xid，它保证一个交易日内唯一，不同的交易日不保证唯一性。
         */
        uint64_t insert_order(uint64_t session_id, xlt_order_insert_info_t* order, uint64_t trade_token = 0);
        /**
         * @brief 撤单
         * 撤单请求。
         * 如果撤单成功，会在报单响应函数on_cancel_response里返回原单部撤或者全撤的消息，
         * 如果不成功，会在on_order_error_response响应函数中返回错误原因。
         * @param session_id 会话id，登录时得到
         * @param cancel_order 撤单信息
         * @param trade_token 如果是普通交易账号填0；如果为授权认证的账号，填写认证成功时on_auth_trade回调函数返回的trade_token。
         * @return  撤单xid(在xLight系统中的ID),如果为‘0’表示撤单发送失败，非"0"表示撤单发送成功，用户需要记录下返回的order_cancel_xid，它保证一个交易日内唯一，不同的交易日不保证唯一性。
         */
        uint64_t cancel_order(uint64_t session_id, xlt_cancel_order_info_t* cancel_order, uint64_t trade_token = 0);
        /**
         * @brief 重发订单请求
         * @param session_id 会话id，登录时得到
         * @param xid 需要重发的订单ID
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         * @remark 当委托超时时，用户可以调用此函数来重发订单请求，xid为订单ID。
         */
        bool resend_order_request(uint64_t session_id, uint64_t xid);
        /**
         * @brief 提交主柜资金划转请求
         * @param session_id 会话id，登录时得到
         * @param request_id 由用户自定义
         * @param side  划转方向，IN-划入（从主柜划入到xlight），OUT-划出（从xlight划出到主柜）
         * @param amount 划转金额，放大10000倍
         * @param biz_no 输出参数，返回系统生成的业务流水号，缓冲区至少20字节。传nullptr则不返回。划拨结果通过on_counter_fund_transfer_result返回。
         * @param trade_token 如果是普通交易账号填0；如果为授权认证的账号，填写认证成功时on_auth_trade回调函数返回的trade_token。
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误代码
         */
        bool submit_counter_fund_transfer_request(uint64_t session_id, uint64_t request_id, FundTransSide side, amount_t amount, char* biz_no=nullptr, uint64_t trade_token=0);
        /**
         * @brief 提交双中心资金划转请求，方向固定为划入
         * @param session_id 会话id，登录时得到
         * @param request_id 由用户自定义
         * @param amount 划入金额，放大10000倍
         * @param biz_no 输出参数，返回系统生成的业务流水号，缓冲区至少20字节。传nullptr则不返回。划拨结果通过on_cluster_fund_transfer_result返回。
         * @param trade_token 如果是普通交易账号填0；如果为授权认证的账号，填写认证成功时on_auth_trade回调函数返回的trade_token。
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误代码
         */
        bool submit_cluster_fund_transfer_request(uint64_t session_id, uint64_t request_id, amount_t amount, char* biz_no=nullptr, uint64_t trade_token=0);
        /**
         * @brief 请求查询资产
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @param account_index 交易账号索引，0表示查所有或者当前登录交易账号索引，非0表示指定交易账号索引。可通过get_account_index或者query_trade_account_info获取交易账号索引
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool query_assets(uint64_t session_id, uint64_t request_id, uint64_t account_index = 0);
        /**
         * @brief 请求查询投资者持仓
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @param security_code 需要查询持仓的合约代码，可以为空表示查询全市场，如果不为空，请不带空格，并以'\0'结尾
         * @param exchange_index 需要查询持仓的合约所在市场，默认为INIT。如果想正确查询指定持仓，请指定exchange_index
         * @param account_index 交易账号索引，0表示查所有或者当前登录交易账号索引，非0表示指定交易账号索引。可通过get_account_index或者query_trade_account_info获取交易账号索引
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         * @remark 该方法如果用户提供了合约代码，则会查询此合约的持仓信息，如果合约代码为空，则默认查询所有持仓信息。
         */
        bool query_positions(uint64_t session_id, uint64_t request_id, const char* security_code, ExchangeIndex exchange_index = ExchangeIndex::INIT, uint64_t account_index = 0);
        /**
         * @brief 请求查询订单
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @param order_query_param 需要查询的订单相关筛选条件，其中xid如果不为0，则只查询指定订单，否则根据后续条件进行查询：
         * 其中证券代码可以为空，则默认所有存在的证券代码，如果不为空，请不带空格,
         * 其中起始时间格式为YYYYMMDDHHMMSSsss，为0则默认当前交易日0点，结束时间格式为YYYYMMDDHHMMSSsss，为0则默认当前时间
         * @param account_index 交易账号索引，0表示查所有或者当前登录交易账号索引，非0表示指定交易账号索引。可通过get_account_index或者query_trade_account_info获取交易账号索引
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool query_orders(uint64_t session_id, uint64_t request_id, const xlt_order_query_param_t* order_query_param, uint64_t account_index = 0);
        /**
         * @brief 分页请求查询报单
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @param request_count 分页请求的订单数量，建议小于1000
         * @param query_reference 需要分页查询订单的条件，如果第一次查询，那么page_query_param.reference填0
         * @param account_index 交易账号索引，0表示查所有或者当前登录交易账号索引，非0表示指定交易账号索引。可通过get_account_index或者query_trade_account_info获取交易账号索引
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         * @remark 该方法支持分页查询，注意用户需要记录下最后一笔查询结果的reference以便用户下次查询使用
         */
        bool query_orders_by_page(uint64_t session_id, uint64_t request_id, uint32_t request_count, const xlt_page_query_reference_t* query_reference, uint64_t account_index = 0);
        /**
         * @brief 请求查询成交回报
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @param xid 需要查询的订单ID
         * @param account_index 交易账号索引，0表示查所有或者当前登录交易账号索引，非0表示指定交易账号索引。可通过get_account_index或者query_trade_account_info获取交易账号索引
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool query_trades(uint64_t session_id, uint64_t request_id, uint64_t xid, uint64_t account_index = 0);

        //////  以下接口为PB、机构登录等特殊场景预留接口，普通交易场景不使用，普通交易场景获取日初资金和持仓请使用 get_init_assets和 get_init_positions//////

        /**
         * @brief 请求查询初始资产
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @param account_index 交易账号索引，0表示查所有或者当前登录交易账号索引，非0表示指定交易账号索引。可通过get_account_index或者query_trade_account_info获取交易账号索引
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool query_init_assets(uint64_t session_id, uint64_t request_id, uint64_t account_index = 0);
        /**
         * @brief 请求查询初始持仓
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @param security_code 需要查询持仓的合约代码，可以为空表示查询全市场，如果不为空，请不带空格，并以'\0'结尾
         * @param exchange_index 需要查询持仓的合约所在市场，默认为INIT。
         * @param account_index 交易账号索引，0表示查所有或者当前登录交易账号索引，非0表示指定交易账号索引。可通过get_account_index或者query_trade_account_info获取交易账号索引
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool query_init_positions(uint64_t session_id, uint64_t request_id, const char* security_code, ExchangeIndex exchange_index, uint64_t account_index = 0);

        /**
         * @brief 请求查询交易账户信息
         * @param session_id 会话id，登录时得到
         * @param request_id 用于用户定位查询响应的ID，由用户自定义
         * @param account_index 交易账号索引，0表示查所有或者当前登录交易账号索引，非0表示指定交易账号索引。可通过get_account_index或者query_trade_account_info获取交易账号索引
         * @return 请求发送是否成功，true表示成功，false表示出错，此时用户可以调用get_last_error()来获取错误信息。
         */
        bool query_trade_account_info(uint64_t session_id, uint64_t request_id, uint64_t account_index = 0);

        bool dump_api_performance_info();
    protected:
        XLTTradeApi()=default;
    };
}
