#![allow(unused_variables)]
use std::{env::var, path::Path, sync::Arc};
use ctp_dyn::{copy_str_to_i8_array, gb18030_cstr_i8_to_str, print_rsp_info, v1alpha1::*};
pub struct BaseTraderSpi {
pub tdapi: Arc<TraderApi>,
pub request_id: i32,
}
impl TraderSpi for BaseTraderSpi {
fn on_front_connected(&mut self) {
println!("tdspi.on_front_connected !!!");
let mut req: CThostFtdcReqAuthenticateField = CThostFtdcReqAuthenticateField::default();
let user_id = var("SIMNOW_USER0").unwrap();
copy_str_to_i8_array(&mut req.BrokerID, "9999");
copy_str_to_i8_array(&mut req.UserID, &user_id);
copy_str_to_i8_array(&mut req.AppID, "simnow_client_test");
copy_str_to_i8_array(&mut req.AuthCode, "0000000000000000");
self.request_id += 1;
self.tdapi.req_authenticate(&mut req, self.request_id);
}
fn on_front_disconnected(&mut self, n_reason: i32) {
println!("on_front_disconnected: reason{n_reason}")
}
fn on_heart_beat_warning(&mut self, n_time_lapse: i32) {}
fn on_rsp_authenticate(
&mut self,
p_rsp_authenticate_field: Option<&CThostFtdcRspAuthenticateField>,
p_rsp_info: Option<&CThostFtdcRspInfoField>,
n_request_id: i32,
b_is_last: bool,
) {
println!("on_rsp_authenticate");
print_rsp_info!(p_rsp_info);
if let Some(p_rsp_info) = p_rsp_info {
if p_rsp_info.ErrorID != 0 {
return;
}
}
if b_is_last {
let mut req = CThostFtdcReqUserLoginField::default();
let user_id = var("SIMNOW_USER0").unwrap();
let password = var("SIMNOW_PASS0").unwrap();
copy_str_to_i8_array(&mut req.BrokerID, "9999");
copy_str_to_i8_array(&mut req.UserID, &user_id);
copy_str_to_i8_array(&mut req.Password, &password);
self.request_id += 1;
#[cfg(not(target_os = "macos"))]
{
let ret = self.tdapi.req_user_login(&mut req, self.request_id);
println!("req_user_login result: {ret}");
}
#[cfg(target_os = "macos")]
{
let system_info: TThostFtdcClientSystemInfoType = [0; 273];
let ret = self
.tdapi
.req_user_login(&mut req, self.request_id, 0, system_info);
println!("req_user_login result: {ret}");
}
}
}
fn on_rsp_user_login(
&mut self,
p_rsp_user_login: Option<&CThostFtdcRspUserLoginField>,
p_rsp_info: Option<&CThostFtdcRspInfoField>,
n_request_id: i32,
b_is_last: bool,
) {
print_rsp_info!(p_rsp_info);
if b_is_last {
let mut req = CThostFtdcSettlementInfoConfirmField::default();
copy_str_to_i8_array(&mut req.BrokerID, "9999");
let user_id = var("SIMNOW_USER0").unwrap();
copy_str_to_i8_array(&mut req.InvestorID, user_id.as_str());
self.request_id += 1;
let ret = self
.tdapi
.req_settlement_info_confirm(&mut req, self.request_id);
println!("req_user_login result: {ret}");
}
}
fn on_rsp_settlement_info_confirm(
&mut self,
p_settlement_info_confirm: Option<&CThostFtdcSettlementInfoConfirmField>,
p_rsp_info: Option<&CThostFtdcRspInfoField>,
n_request_id: i32,
b_is_last: bool,
) {
print_rsp_info!(p_rsp_info);
if b_is_last {
std::thread::sleep(std::time::Duration::from_secs(1));
self.request_id += 1;
let mut req = CThostFtdcQryInvestorPositionField::default();
let ret = self
.tdapi
.req_qry_investor_position(&mut req, self.request_id);
println!("req_qry_investor_position result: {ret}");
}
}
fn on_rsp_qry_investor_position(
&mut self,
p_investor_position: Option<&CThostFtdcInvestorPositionField>,
p_rsp_info: Option<&CThostFtdcRspInfoField>,
n_request_id: i32,
b_is_last: bool,
) {
print_rsp_info!(p_rsp_info);
if let Some(p) = p_investor_position {
let instrument_id = gb18030_cstr_i8_to_str(&p.InstrumentID).unwrap();
let user_id = gb18030_cstr_i8_to_str(&p.InvestorID).unwrap();
println!("{user_id} holds {instrument_id}");
} else {
println!("position hold None");
}
if b_is_last {
println!("on_rsp_qry_investor_position finish!");
}
}
}
fn sample1() {
println!("tdapi start here!");
let base_dir = var("CARGO_MANIFEST_DIR").unwrap();
println!("base_dir: {base_dir}");
#[cfg(target_os = "macos")]
let dynlib_path =
"./api/v6.7.2/v6.7.2_MacOS_20231016/thosttraderapi_se.framework/Versions/A/thosttraderapi_se";
#[cfg(target_os = "linux")]
let dynlib_path = "./api/v6.7.2/v6.7.2_20230913_api_traderapi_se_linux64/thosttraderapi_se.so";
let dynlib_path = Path::new(&base_dir).join(dynlib_path);
let tdapi = TraderApi::create_api(dynlib_path.as_path(), "./td_");
let tdapi = Arc::new(tdapi);
let base_tdspi = BaseTraderSpi {
tdapi: Arc::clone(&tdapi),
request_id: 0,
};
let tdspi_box = Box::new(base_tdspi);
let tdspi_ptr = Box::into_raw(tdspi_box);
let tdspi_ptr2 = tdspi_ptr.clone();
println!("get_api_version: {}", tdapi.get_api_version());
tdapi.register_front("tcp://180.168.146.187:10130");
tdapi.register_spi(tdspi_ptr);
tdapi.subscribe_private_topic(THOST_TE_RESUME_TYPE::THOST_TERT_QUICK);
tdapi.subscribe_public_topic(THOST_TE_RESUME_TYPE::THOST_TERT_QUICK);
tdapi.init();
println!("tdapi init");
tdapi.join();
let _ = unsafe { Box::from_raw(tdspi_ptr2) };
}
fn main() {
let base_dir = var("CARGO_MANIFEST_DIR").unwrap();
println!("base_dir: {base_dir}");
sample1();
}