Rust : CTP 中异步处理

21 篇文章 7 订阅

CTP中,client会收到thost发来的不同类型的信息,包括有来自行情、下单,交易,撤单、查持仓和查合约状况等信息:

OnRtnMarketData 
OnRtnOrder 
OnRtnTrade 
OnErrRtnOrderAction 
OnRspOrderInsert 
OnRspOrderAction
OnRspQryInvestorPositionDetail 
OnRtnInstrumentStatus

这些信息是通过以上的函数异步推送的,当然做策略时,需要把他们同步。

一、信息分发与策略下单

需要考虑具体情况:
一个策略或一个策略组(不同参数组)需要与thost交互;这样,就会在不同的线程间产生大量的不同策略的消息。
(1)这些消息要有序地接收和分发,比如,订阅的信息、交易要与策略一 一相匹配;
(2)在策略与thost发送订单时,需要同步处理;

1、接收thost异步的消息
在这里插入图片描述在策略信息分发部分,可以异步是没问题的。这部分可以考虑用异步的Channel来处理。

下面是试验代码:

use std::thread;
use std::sync::mpsc::channel;
use std::collections::VecDeque;
use std::time::Duration;
use rand::Rng;
use std::sync::mpsc::Receiver;

# [derive(Debug)]
struct Md(u32);
# [derive(Debug)]
struct Insertorder(u32);
# [derive(Debug)]
struct Cancelorder(u32);
# [derive(Debug)]

//模拟thost传过来的不同的值;
enum TradeData{
    RtnMarketData(u32),
    RntOrder(u32),
    RtnTrade(u32),
}

//把rx作为参数传入
fn get_data(rx:&Receiver<TradeData>){
    loop{
        println!("recv:{:?}",rx.recv().unwrap());
    }
}
fn main(){
    let (tx,rx) = channel();
    //模拟多线程异步进行接收thost相关的行情等信息
    for i in 0..10{
        let limit = 1050_u32;
        let tx = tx.clone();
        thread::spawn(move||{
            let mut n = 0;
            loop{
                let rand_value:u32 = rand::thread_rng().gen_range(0, 1000);
                n = n +1;
                println!("rand_value:{:?} n:{:?} thread id :{:?}",rand_value,n,i);
                thread::sleep(Duration::from_millis(100));
                match rand_value {
                    0...600 => tx.send(TradeData::RtnMarketData(rand_value)).unwrap(),
                    600...900 => tx.send(TradeData::RntOrder(rand_value)).unwrap(),
                    _ => tx.send(TradeData::RtnTrade(rand_value)).unwrap(),
                };

            }
        });
    }
    println!("main=>");
    get_data(&rx);
    thread::sleep(Duration::from_millis(500000));
}

下面是模拟的效果:异步收thost消息,另一个线程异步处理,可以起分发作用。

在这里插入图片描述

C#中,可以用 PostMessage+窗体消息函数(WndProc),即策略组(strategGroup)PostMessage消息要发给各自策略内的窗口,策略中的WndProc接收相应的消息。

2、同步不同策略的下单/撤单
在这里插入图片描述在下单和撤单部分,是需要进行同步处理的。可以用:

use std::sync::{Arc,Mutex}

比如:取唯一且自增报单引用,下面是试验代码:

use std::thread;
use std::sync::{Arc,Mutex};
use std::time::Duration;
use rand::Rng;

fn main(){
   println!("start!");
   let s = Arc::new(Mutex::new(0_u32));
   for _ in 0..100{
       let s_clone = s.clone();
       let temp = *s_clone.lock().unwrap();
       thread::spawn(move||{
           let rand_value:u64 = rand::thread_rng().gen();
           //thread::sleep(Duration::from_millis(rand_value));
           *s_clone.lock().unwrap()= temp +1 ;
           println!("request_ID:{:?}",*s_clone.lock().unwrap());
       }).join();
   }
   println!("request_id :{:?}",*s.lock().unwrap());
   thread::sleep(Duration::from_millis(500000));
}

可以看出,这个锁在100个线程中是起作用的。

CTPapi_交易开发实例 class CTraderSpi : public CThostFtdcTraderSpi { public: ///当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 virtual void OnFrontConnected(); ///登录请求响应 virtual void OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///投资者结算结果确认响应 virtual void OnRspSettlementInfoConfirm(CThostFtdcSettlementInfoConfirmField *pSettlementInfoConfirm, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///请求查询合约响应 virtual void OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///请求查询资金账户响应 virtual void OnRspQryTradingAccount(CThostFtdcTradingAccountField *pTradingAccount, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///请求查询投资者持仓响应 virtual void OnRspQryInvestorPosition(CThostFtdcInvestorPositionField *pInvestorPosition, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///报单录入请求响应 virtual void OnRspOrderInsert(CThostFtdcInputOrderField *pInputOrder, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///报单操作请求响应 virtual void OnRspOrderAction(CThostFtdcInputOrderActionField *pInputOrderAction, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///错误应答 virtual void OnRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast); ///当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 virtual void OnFrontDisconnected(int nReason); ///心跳超时警告。当长时间未收到报文时,该方法被调用。 virtual void OnHeartBeatWarning(int nTimeLapse); ///报单通知 virtual void OnRtnOrder(CThostFtdcOrderField *pOrder); ///成交通知 virtual void OnRtnTrade(CThostFtdcTradeField *pTrade); private: ///用户登录请求 void ReqUserLogin(); ///投资者结算结果确认 void ReqSettlementInfoConfirm(); ///请求查询合约 void ReqQryInstrument(); ///请求查询资金账户 void ReqQryTradingAccount(); ///请求查询投资者持仓 void ReqQryInvestorPosition(); ///报单录入请求 void ReqOrderInsert(); ///报单操作请求 void ReqOrderAction(CThostFtdcOrderField *pOrder); // 是否收到成功的响应 bool IsErrorRspInfo(CThostFtdcRspInfoField *pRspInfo); // 是否我的报单回报 bool IsMyOrder(CThostFtdcOrderField *pOrder); // 是否正在交易的报单 bool IsTradingOrder(CThostFtdcOrderField *pOrder); };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值