#include "my_trade_spi.h"

void MyTradeSpi::on_disconnect(uint64_t session_id) {
    printf("on_disconnect session_id: %lu\n", session_id);
    global_session_id = 0;
    global_login_success.store(false);
    global_login_finished.store(false);
    // 在此重新发送登录请求
}

void MyTradeSpi::on_login(uint64_t session_id, uint64_t request_id, xlt_error_info_t* error_info) {
    if (error_info && error_info->error_code != 0) {
        printf("on_login error_code: %lu, sub_error_code: %lu, error_info: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        // 登录失败
        global_login_success.store(false);
    }
    else {
        printf("on_login success session_id: %lu, request_id: %lu\n", session_id, request_id);
        // 登录成功
        global_session_id = session_id;
        global_login_success.store(true);
    }
    global_login_finished.store(true);
}

void MyTradeSpi::on_order_end(uint64_t session_id, xlt_order_end_t* order_end) {
    printf("on_order_end session_id: %lu, sequence: %lu, xid: %lu,  report_num: %d\n",
           session_id,
           order_end->sequence,
           order_end->xid,
           (int)order_end->report_num);
}

void MyTradeSpi::on_order_response(uint64_t session_id, xlt_order_response_t* order_response) {
    printf("on_order_response session_id: %lu, sequence: %lu, report_id: %s, xid: %lu, order_status: %d, "
           "leaves_quantity: %ld, cancel_quantity: %ld\n",
           session_id,
           order_response->sequence,
           order_response->report_id,
           order_response->xid,
           (int)order_response->order_status,
           order_response->leaves_quantity,
           order_response->cancel_quantity);
}

void MyTradeSpi::on_cancel_response(uint64_t session_id, xlt_cancel_response_t* cancel_response) {
    printf("on_cancel_response session_id: %lu, sequence: %lu, report_id: %s, xid: %lu, origin_xid: %lu, "
           "order_status: %d, cancel_quantity: %ld\n",
           session_id,
           cancel_response->sequence,
           cancel_response->report_id,
           cancel_response->xid,
           cancel_response->origin_xid,
           (int)cancel_response->origin_order_status,
           cancel_response->cancel_quantity
    );
}

void MyTradeSpi::on_trade_report(uint64_t session_id, xlt_trade_report_t* trade_report) {
    printf("on_trade_report session_id: %lu, sequence: %lu, report_id: %s, xid: %lu, order_status: %d, price: %ld, "
           "quantity: %ld, leaves_quantity: %ld\n",
           session_id,
           trade_report->sequence,
           trade_report->report_id,
           trade_report->xid,
           (int)trade_report->order_status,
           trade_report->price,
           trade_report->quantity,
           trade_report->leaves_quantity
    );
}

void MyTradeSpi::on_order_error_response(uint64_t session_id, xlt_order_error_response_t* order_error_response) {
    printf("on_order_error_response session_id: %lu, sequence: %lu, report_id: %s, xid: %lu, origin_xid: %lu, "
           "error_code: %lu, sub_error_code: %lu, error_msg: %s\n",
           session_id,
           order_error_response->sequence,
           order_error_response->report_id,
           order_error_response->xid,
           order_error_response->origin_xid,
           order_error_response->error_info.error_code,
           order_error_response->error_info.sub_error_code,
           order_error_response->error_info.error_msg
    );
}

void MyTradeSpi::on_raw_report(uint64_t session_id, uint8_t client_id, uint64_t xid, char report_id[32],
                               uint64_t sequence,
                               ExchangeIndex exchange_index,
                               uint32_t report_size, char* raw_report) {
    printf("on_raw_report session_id: %lu, exchange_index: %d\n",
           session_id,
           (int)exchange_index
    );
}

void MyTradeSpi::on_query_positions(uint64_t session_id, uint64_t request_id, xlt_position_info_t positions[],
                                    uint32_t data_count, bool is_last, xlt_error_info_t* error_info) {
    printf("on_query_positions session_id: %lu request_id: %lu data_count: %u is_last: %d\n",
           session_id, request_id, data_count, is_last);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }
    for (uint32_t i = 0; i < data_count; ++i) {
        printf("Position %d: security_code: %s, position_security_type: %d, exchange_index: %d, "
               "initial_quantity: %ld, total_quantity: %ld, sellable_quantity: %ld, frozen_quantity: %ld\n",
               i + 1,
               positions[i].security_code,
               (int)positions[i].position_security_type,
               (int)positions[i].exchange_index,
               positions[i].initial_quantity,
               positions[i].total_quantity,
               positions[i].sellable_quantity,
               positions[i].frozen_quantity
        );
    }
}


void MyTradeSpi::on_query_assets(uint64_t session_id, uint64_t request_id, xlt_asset_info_t assets[],
                                 uint32_t data_count, bool is_last, xlt_error_info_t* error_info) {
    printf("on_query_assets session_id: %lu request_id: %lu data_count: %u is_last: %d\n",
           session_id, request_id, data_count, is_last);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }
    for (uint32_t i = 0; i < data_count; ++i) {
        printf("Asset %d: available_amount: %ld, initial_amount: %ld, withholding_amount: %ld, fund_buy_amount: %ld, "
               "fund_buy_fee: %ld, fund_sell_amount: %ld, fund_sell_fee: %ld\n",
               i + 1,
               assets[i].available_amount,
               assets[i].initial_amount,
               assets[i].withholding_amount,
               assets[i].fund_buy_amount,
               assets[i].fund_buy_fee,
               assets[i].fund_sell_amount,
               assets[i].fund_sell_fee);
    }
}


void MyTradeSpi::on_query_orders(uint64_t session_id, uint64_t request_id, xlt_order_info_t order_infos[],
                                 uint32_t data_count,
                                 bool is_last, xlt_error_info_t* error_info) {
    printf("on_query_orders session_id: %lu request_id: %lu data_count: %u is_last: %d\n",
           session_id, request_id, data_count, is_last);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }

    for (uint32_t i = 0; i < data_count; ++i) {
        const xlt_order_info_t& order = order_infos[i];
        printf("Order %d:, xid: %lu, origin_xid: %lu, order_status: %d, security_code: %s, "
               "exchange_index: %d, order_price: %d, side: %d, business_type: %d, order_price: %ld, "
               "order_quantity: %ld, order_amount: %ld, order_fee: %ld, traded_quantity: %ld, traded_amount: %ld, "
               "traded_fee: %ld, traded_fix_fee: %ld, traded_count: %u, leaves_quantity: %ld, cancel_quantity: %ld, "
               "insert_time: %ld, traded_time: %ld, error_code: %lu, sub_error_code: %lu, error_msg: %s, \n",
               i + 1,
               order.xid,
               order.origin_xid,
               (int)order.order_status,
               order.security_code,
               (int)order.exchange_index,
               (int)order.order_price,
               (int)order.side,
               (int)order.business_type,
               order.order_price,
               order.order_quantity,
               order.order_amount,
               order.order_fee,
               order.trade_quantity,
               order.trade_amount,
               order.trade_fee,
               order.trade_fix_fee,
               order.trade_count,
               order.leaves_quantity,
               order.cancel_quantity,
               order.insert_time,
               order.trade_time,
               order.error_info.error_code,
               order.error_info.sub_error_code,
               order.error_info.error_msg
        );
    }
}

void MyTradeSpi::on_query_orders_by_page(uint64_t session_id, uint64_t request_id, xlt_order_info_t order_infos[],
                                         uint64_t data_count, uint64_t req_count, uint64_t rsp_count,
                                         uint64_t query_reference, bool is_last, xlt_error_info_t* error_info) {
    printf("on_query_orders_by_page session_id: %lu request_id: %lu data_count: %lu req_count: %lu, rsp_count: %lu, "
           "query_reference: %lu is_last: %d\n",
           session_id, request_id, data_count, req_count, rsp_count, query_reference, is_last);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }

    for (uint32_t i = 0; i < data_count; ++i) {
        const xlt_order_info_t& order = order_infos[i];
        printf("Order %d:, xid: %lu, origin_xid: %lu, order_status: %d, security_code: %s, "
               "exchange_index: %d, order_price: %d, side: %d, business_type: %d, order_price: %ld, "
               "order_quantity: %ld, order_amount: %ld, order_fee: %ld, traded_quantity: %ld, traded_amount: %ld, "
               "traded_fee: %ld, traded_fix_fee: %ld, traded_count: %u, leaves_quantity: %ld, cancel_quantity: %ld, "
               "insert_time: %ld, traded_time: %ld, error_code: %lu, sub_error_code: %lu, error_msg: %s, \n",
               i + 1,
               order.xid,
               order.origin_xid,
               (int)order.order_status,
               order.security_code,
               (int)order.exchange_index,
               (int)order.order_price,
               (int)order.side,
               (int)order.business_type,
               order.order_price,
               order.order_quantity,
               order.order_amount,
               order.order_fee,
               order.trade_quantity,
               order.trade_amount,
               order.trade_fee,
               order.trade_fix_fee,
               order.trade_count,
               order.leaves_quantity,
               order.cancel_quantity,
               order.insert_time,
               order.trade_time,
               order.error_info.error_code,
               order.error_info.sub_error_code,
               order.error_info.error_msg
        );
    }

    if (is_last) {
        // 当页请求返回结束
        if (rsp_count < req_count) {
            // 当页返回数量小于请求数量，说明已经查询到最后的数据
            printf("All orders got! \n");
        }
        else {
            // 可能还有数据，继续查询
            xlt_query_by_page_param_t order_query_by_page_param = {};
            order_query_by_page_param.req_count = 10;
            order_query_by_page_param.reference = query_reference;
            if (my_xapi->query_orders_by_page(global_session_id, next_request_id(), &order_query_by_page_param) > 0) {
                printf("Query orders info request send failed!!\n");
            }
        }
    }
    else {
        // 当页请求未结束，还有后续数据
        printf("More orders to come, waiting for next page...\n");
    }
}

void MyTradeSpi::on_query_trades(uint64_t session_id, uint64_t request_id, xlt_trade_report_t trade_reports[],
                                 uint32_t data_count, bool is_last, xlt_error_info_t* error_info) {
    printf("on_query_trades session_id: %lu request_id: %lu data_count: %u is_last: %d\n",
           session_id, request_id, data_count, is_last);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }
    for (uint32_t i = 0; i < data_count; ++i) {
        printf("Trade %d: sequence: %lu, report_id: %s, xid: %lu, order_status: %d, price: %ld, "
               "quantity: %ld, leaves_quantity: %ld\n",
               i + 1,
               trade_reports[i].sequence,
               trade_reports[i].report_id,
               trade_reports[i].xid,
               (int)trade_reports[i].order_status,
               trade_reports[i].price,
               trade_reports[i].quantity,
               trade_reports[i].leaves_quantity
        );
    }
}

void MyTradeSpi::on_query_static_quote_info(uint64_t session_id, uint64_t request_id,
                                            xlt_static_quote_full_info_t static_quote_full_infos[], uint32_t data_count,
                                            bool is_last,
                                            xlt_error_info_t* error_info) {
    printf("on_query_static_quote_info session_id: %lu request_id: %lu data_count: %u is_last: %d\n",
           session_id, request_id, data_count, is_last);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }
    for (uint32_t i = 0; i < data_count; ++i) {
        auto info = static_quote_full_infos[i];
        printf("Static info: %d, "
               "exchange_index: %d, "
               "security_code: %s, "
               "security_name: %s, "
               "security_type: %d, "
               "is_registration: %d, "
               "is_vie: %d, "
               "is_noprofit: %d, "
               "is_weighted_voting_rights: %d, "
               "is_have_price_limit: %d, "
               "upper_limit_price: %ld, "
               "lower_limit_price: %ld, "
               "pre_close_price: %ld, "
               "price_tick: %ld, "
               "bid_qty_upper_limit: %d, "
               "bid_qty_lower_limit: %d, "
               "bid_qty_unit: %d, "
               "ask_qty_upper_limit: %d, "
               "ask_qty_lower_limit: %d, "
               "ask_qty_unit: %d, "
               "market_bid_qty_upper_limit: %d, "
               "market_bid_qty_lower_limit: %d, "
               "market_bid_qty_unit: %d, "
               "market_ask_qty_upper_limit: %d, "
               "market_ask_qty_lower_limit: %d, "
               "market_ask_qty_unit: %d, "
               "security_status: %.*s\n",
               i,
               (int)info.exchange_index,
               info.security_code,
               info.security_name,
               (int)info.security_type,
               info.is_registration,
               info.is_vie,
               info.is_noprofit,
               info.is_weighted_voting_rights,
               info.is_have_price_limit,
               info.upper_limit_price,
               info.lower_limit_price,
               info.pre_close_price,
               info.price_tick,
               info.bid_qty_upper_limit,
               info.bid_qty_lower_limit,
               info.bid_qty_unit,
               info.ask_qty_upper_limit,
               info.ask_qty_lower_limit,
               info.ask_qty_unit,
               info.market_bid_qty_upper_limit,
               info.market_bid_qty_lower_limit,
               info.market_bid_qty_unit,
               info.market_ask_qty_upper_limit,
               info.market_ask_qty_lower_limit,
               info.market_ask_qty_unit,
               8, info.security_status
        );
    }
}

void MyTradeSpi::on_query_sse_l1_index(uint64_t session_id, uint64_t request_id, sse_l1_index_t* sse_l1_index,
                                       xlt_error_info_t* error_info) {
    printf("on_query_sse_l1_index session_id: %lu request_id: %lu\n",
           session_id, request_id);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }
    if (!sse_l1_index) return;
    printf("security_type: %u\n", sse_l1_index->security_type);
    printf("sending_time: %llu\n", (unsigned long long)sse_l1_index->sending_time);
    printf("trad_ses_mode: %u\n", sse_l1_index->trad_ses_mode);
    printf("trade_date: %u\n", sse_l1_index->trade_date);
    printf("last_update_time: %u\n", sse_l1_index->last_update_time);
    printf("md_stream_id: %.*s\n", 5, sse_l1_index->md_stream_id);
    printf("security_code: %.*s\n", CONST_STR_SECURITY_CODE_LEN, sse_l1_index->security_code);
    printf("prev_close_px: %llu\n", (unsigned long long)sse_l1_index->prev_close_px);
    printf("total_volume_traded: %llu\n", (unsigned long long)sse_l1_index->total_volume_traded);
    printf("num_trades: %llu\n", (unsigned long long)sse_l1_index->num_trades);
    printf("total_value_traded: %llu\n", (unsigned long long)sse_l1_index->total_value_traded);
    printf("trading_phase_code: %.*s\n", 8, sse_l1_index->trading_phase_code);
    printf("last_px: %llu\n", (unsigned long long)sse_l1_index->last_px);
    printf("open_px: %llu\n", (unsigned long long)sse_l1_index->open_px);
    printf("close_px: %llu\n", (unsigned long long)sse_l1_index->close_px);
    printf("high_px: %llu\n", (unsigned long long)sse_l1_index->high_px);
    printf("low_px: %llu\n", (unsigned long long)sse_l1_index->low_px);
    printf("\n");
}

void MyTradeSpi::on_query_sse_l1_snapshot(uint64_t session_id, uint64_t request_id, sse_l1_snapshot_t* sse_l1_snapshot,
                                          xlt_error_info_t* error_info) {
    printf("on_query_sse_l1_snapshot session_id: %lu request_id: %lu\n",
           session_id, request_id);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }
    if (!sse_l1_snapshot) return;
    printf("security_type: %u\n", sse_l1_snapshot->security_type);
    printf("sending_time: %llu\n", (unsigned long long)sse_l1_snapshot->sending_time);
    printf("trad_ses_mode: %u\n", sse_l1_snapshot->trad_ses_mode);
    printf("trade_date: %u\n", sse_l1_snapshot->trade_date);
    printf("last_update_time: %u\n", sse_l1_snapshot->last_update_time);
    printf("md_stream_id: %.*s\n", 5, sse_l1_snapshot->md_stream_id);
    printf("security_code: %.*s\n", CONST_STR_SECURITY_CODE_LEN, sse_l1_snapshot->security_code);
    printf("prev_close_px: %llu\n", (unsigned long long)sse_l1_snapshot->prev_close_px);
    printf("total_volume_traded: %llu\n", (unsigned long long)sse_l1_snapshot->total_volume_traded);
    printf("num_trades: %llu\n", (unsigned long long)sse_l1_snapshot->num_trades);
    printf("total_value_traded: %llu\n", (unsigned long long)sse_l1_snapshot->total_value_traded);
    printf("trading_phase_code: %.*s\n", 8, sse_l1_snapshot->trading_phase_code);
    printf("last_px: %llu\n", (unsigned long long)sse_l1_snapshot->last_px);
    printf("open_px: %llu\n", (unsigned long long)sse_l1_snapshot->open_px);
    printf("close_px: %llu\n", (unsigned long long)sse_l1_snapshot->close_px);
    printf("settle_px: %llu\n", (unsigned long long)sse_l1_snapshot->settle_px);
    printf("high_px: %llu\n", (unsigned long long)sse_l1_snapshot->high_px);
    printf("low_px: %llu\n", (unsigned long long)sse_l1_snapshot->low_px);
    printf("iopv: %llu\n", (unsigned long long)sse_l1_snapshot->iopv);
    printf("pre_iopv: %llu\n", (unsigned long long)sse_l1_snapshot->pre_iopv);
    printf("option_ref_px: %llu\n", (unsigned long long)sse_l1_snapshot->option_ref_px);
    printf("option_notional_amount: %llu\n", (unsigned long long)sse_l1_snapshot->option_notional_amount);
    printf("pre_settle_px: %llu\n", (unsigned long long)sse_l1_snapshot->pre_settle_px);
    printf("option_open_qty: %llu\n", (unsigned long long)sse_l1_snapshot->option_open_qty);

    for (int i = 0; i < 5; ++i) {
        printf("bid_px[%d]: %llu\n", i, (unsigned long long)sse_l1_snapshot->bid_px[i]);
        printf("bid_volume[%d]: %llu\n", i, (unsigned long long)sse_l1_snapshot->bid_volume[i]);
    }

    for (int i = 0; i < 5; ++i) {
        printf("offer_px[%d]: %llu\n", i, (unsigned long long)sse_l1_snapshot->offer_px[i]);
        printf("offer_volume[%d]: %llu\n", i, (unsigned long long)sse_l1_snapshot->offer_volume[i]);
    }
    printf("\n");
}

void MyTradeSpi::on_query_szse_l1_index(uint64_t session_id, uint64_t request_id, szse_l1_index_t* szse_l1_index,
                                        xlt_error_info_t* error_info) {
    printf("on_query_szse_l1_index session_id: %lu request_id: %lu\n",
           session_id, request_id);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }
    if (!szse_l1_index) return;
    printf("channel_no: %u\n", szse_l1_index->channel_no);
    printf("orig_time: %lld\n", (long long)szse_l1_index->orig_time);
    printf("md_stream_id: %.*s\n", 3, szse_l1_index->md_stream_id);
    printf("security_code: %.*s\n", CONST_STR_SECURITY_CODE_LEN, szse_l1_index->security_code);
    printf("security_id_source: %.*s\n", 4, szse_l1_index->security_id_source);
    printf("trading_phase_code: %.*s\n", 8, szse_l1_index->trading_phase_code);
    printf("prev_close_px: %lld\n", (long long)szse_l1_index->prev_close_px);
    printf("num_trades: %lld\n", (long long)szse_l1_index->num_trades);
    printf("total_volume_trade: %lld\n", (long long)szse_l1_index->total_volume_trade);
    printf("total_value_trade: %lld\n", (long long)szse_l1_index->total_value_trade);
    printf("last_index: %lld\n", (long long)szse_l1_index->last_index);
    printf("prev_close_index: %lld\n", (long long)szse_l1_index->prev_close_index);
    printf("open_index: %lld\n", (long long)szse_l1_index->open_index);
    printf("high_index: %lld\n", (long long)szse_l1_index->high_index);
    printf("low_index: %lld\n", (long long)szse_l1_index->low_index);
    printf("close_index: %lld\n", (long long)szse_l1_index->close_index);
    printf("\n");
}

void MyTradeSpi::on_query_szse_l1_snapshot(uint64_t session_id, uint64_t request_id,
                                           szse_l1_snapshot_t* szse_l1_snapshot, xlt_error_info_t* error_info) {
    printf("on_query_szse_l1_snapshot session_id: %lu request_id: %lu\n",
           session_id, request_id);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }
    if (!szse_l1_snapshot) return;

    printf("channel_no: %u\n", szse_l1_snapshot->channel_no);
    printf("orig_time: %lld\n", (long long)szse_l1_snapshot->orig_time);
    printf("md_stream_id: %.*s\n", 3, szse_l1_snapshot->md_stream_id);
    printf("security_code: %.*s\n", CONST_STR_SECURITY_CODE_LEN, szse_l1_snapshot->security_code);
    printf("security_id_source: %.*s\n", 4, szse_l1_snapshot->security_id_source);
    printf("trading_phase_code: %.*s\n", 8, szse_l1_snapshot->trading_phase_code);
    printf("prev_close_px: %lld\n", (long long)szse_l1_snapshot->prev_close_px);
    printf("num_trades: %lld\n", (long long)szse_l1_snapshot->num_trades);
    printf("total_volume_trade: %lld\n", (long long)szse_l1_snapshot->total_volume_trade);
    printf("total_value_trade: %lld\n", (long long)szse_l1_snapshot->total_value_trade);
    printf("last_px: %lld\n", (long long)szse_l1_snapshot->last_px);
    printf("open_px: %lld\n", (long long)szse_l1_snapshot->open_px);
    printf("high_px: %lld\n", (long long)szse_l1_snapshot->high_px);
    printf("low_px: %lld\n", (long long)szse_l1_snapshot->low_px);
    printf("px_gain: %lld\n", (long long)szse_l1_snapshot->px_gain);
    printf("px_gain_2: %lld\n", (long long)szse_l1_snapshot->px_gain_2);
    printf("weighted_avg_bid_px: %lld\n", (long long)szse_l1_snapshot->weighted_avg_bid_px);
    printf("total_bid_qty: %lld\n", (long long)szse_l1_snapshot->total_bid_qty);
    printf("weighted_avg_offer_px: %lld\n", (long long)szse_l1_snapshot->weighted_avg_offer_px);
    printf("total_offer_qty: %lld\n", (long long)szse_l1_snapshot->total_offer_qty);
    printf("pe_ratio_1: %lld\n", (long long)szse_l1_snapshot->pe_ratio_1);
    printf("pe_ratio_2: %lld\n", (long long)szse_l1_snapshot->pe_ratio_2);
    printf("nav: %lld\n", (long long)szse_l1_snapshot->nav);
    printf("iopv: %lld\n", (long long)szse_l1_snapshot->iopv);
    printf("warrant_premium: %lld\n", (long long)szse_l1_snapshot->warrant_premium);
    printf("limit_up_px: %lld\n", (long long)szse_l1_snapshot->limit_up_px);
    printf("limit_down_px: %lld\n", (long long)szse_l1_snapshot->limit_down_px);
    printf("option_open_qty: %lld\n", (long long)szse_l1_snapshot->option_open_qty);
    printf("option_break_px: %lld\n", (long long)szse_l1_snapshot->option_break_px);

    for (int i = 0; i < 5; ++i) {
        printf("bid_px[%d]: %lld\n", i, (long long)szse_l1_snapshot->bid_px[i]);
        printf("bid_volume[%d]: %lld\n", i, (long long)szse_l1_snapshot->bid_volume[i]);
    }

    for (int i = 0; i < 5; ++i) {
        printf("offer_px[%d]: %lld\n", i, (long long)szse_l1_snapshot->offer_px[i]);
        printf("offer_volume[%d]: %lld\n", i, (long long)szse_l1_snapshot->offer_volume[i]);
    }
    printf("\n");
}

void MyTradeSpi::on_query_szse_l1_snapshot_bond(uint64_t session_id, uint64_t request_id,
                                                szse_l1_snapshot_bond_t* szse_l1_snapshot_bond,
                                                xlt_error_info_t* error_info) {
    printf("on_query_szse_l1_snapshot_bond session_id: %lu request_id: %lu\n",
           session_id, request_id);
    if (error_info && error_info->error_code != 0) {
        printf("Error: error_code: %lu, sub_error_code: %lu, error_msg: %s\n", error_info->error_code,
               error_info->sub_error_code, error_info->error_msg);
        return;
    }
    if (!szse_l1_snapshot_bond) return;

    printf("channel_no: %u\n", szse_l1_snapshot_bond->channel_no);
    printf("orig_time: %lld\n", (long long)szse_l1_snapshot_bond->orig_time);
    printf("md_stream_id: %.*s\n", 3, szse_l1_snapshot_bond->md_stream_id);
    printf("security_code: %.*s\n", CONST_STR_SECURITY_CODE_LEN, szse_l1_snapshot_bond->security_code);
    printf("security_id_source: %.*s\n", 4, szse_l1_snapshot_bond->security_id_source);
    printf("trading_phase_code: %.*s\n", 8, szse_l1_snapshot_bond->trading_phase_code);
    printf("prev_close_px: %lld\n", (long long)szse_l1_snapshot_bond->prev_close_px);
    printf("num_trades: %lld\n", (long long)szse_l1_snapshot_bond->num_trades);
    printf("total_volume_trade: %lld\n", (long long)szse_l1_snapshot_bond->total_volume_trade);
    printf("total_value_trade: %lld\n", (long long)szse_l1_snapshot_bond->total_value_trade);
    printf("last_px: %lld\n", (long long)szse_l1_snapshot_bond->last_px);
    printf("open_px: %lld\n", (long long)szse_l1_snapshot_bond->open_px);
    printf("close_px: %lld\n", (long long)szse_l1_snapshot_bond->close_px);
    printf("high_px: %lld\n", (long long)szse_l1_snapshot_bond->high_px);
    printf("low_px: %lld\n", (long long)szse_l1_snapshot_bond->low_px);
    printf("weighted_avg_px: %lld\n", (long long)szse_l1_snapshot_bond->weighted_avg_px);
    printf("px_gain: %lld\n", (long long)szse_l1_snapshot_bond->px_gain);
    printf("px_gain_2: %lld\n", (long long)szse_l1_snapshot_bond->px_gain_2);
    printf("weighted_avg_bid_px: %lld\n", (long long)szse_l1_snapshot_bond->weighted_avg_bid_px);
    printf("total_bid_qty: %lld\n", (long long)szse_l1_snapshot_bond->total_bid_qty);
    printf("weighted_avg_offer_px: %lld\n", (long long)szse_l1_snapshot_bond->weighted_avg_offer_px);
    printf("total_offer_qty: %lld\n", (long long)szse_l1_snapshot_bond->total_offer_qty);
    printf("weighted_avg_ir_gain: %lld\n", (long long)szse_l1_snapshot_bond->weighted_avg_ir_gain);
    printf("weighted_avg_prev_ir: %lld\n", (long long)szse_l1_snapshot_bond->weighted_avg_prev_ir);
    printf("match_last_px: %lld\n", (long long)szse_l1_snapshot_bond->match_last_px);
    printf("auction_volume_trade: %lld\n", (long long)szse_l1_snapshot_bond->auction_volume_trade);
    printf("auction_value_trade: %lld\n", (long long)szse_l1_snapshot_bond->auction_value_trade);

    for (int i = 0; i < 6; ++i) {
        printf("sub_trading_phase_code[%d]: %.*s\n", i, 8, szse_l1_snapshot_bond->sub_trading_phase_code[i]);
    }

    for (int i = 0; i < 5; ++i) {
        printf("bid_px[%d]: %lld\n", i, (long long)szse_l1_snapshot_bond->bid_px[i]);
        printf("bid_volume[%d]: %lld\n", i, (long long)szse_l1_snapshot_bond->bid_volume[i]);
    }

    for (int i = 0; i < 5; ++i) {
        printf("offer_px[%d]: %lld\n", i, (long long)szse_l1_snapshot_bond->offer_px[i]);
        printf("offer_volume[%d]: %lld\n", i, (long long)szse_l1_snapshot_bond->offer_volume[i]);
    }
    printf("\n");
}

void MyTradeSpi::on_order_timeout(uint64_t session_id, uint64_t xid) {
    printf("on_order_timeout session_id: %lu, xid: %lu\n", session_id, xid);
}

void MyTradeSpi::on_request_timeout(uint64_t session_id, uint64_t request_id) {
    printf("on_request_timeout session_id: %lu, request_id: %lu\n", session_id, request_id);
}
