Coder Social home page Coder Social logo

ctp-rs's Introduction

ctp-rs

Build Status

A Rust wrapper of CTP API.

Background

CTP is a popular trading system in Chinese futures market. Finding a CTP trading system to connect to is easy in Chinese futures market. As a result, large portions of individual investors implement their trading strategies against CTP.

CTP API is an offical C++ API that manages connections to CTP trading system. Several language bindings for CTP API ranging from C# to Python have been created. Rust has native FFI support for C, but does not support C++ directly. This wrapper aims to provide an easy to use Rust binding of CTP API.

In contrast to conventional Rust binding for C++ that uses intermediate C wrapper, this Rust wrapper includes a handcrafted C++ calling interface in Rust for virtual function calls and virtual tables in callbacks. This makes the Rust interface cleaner and faster than alternatives.

This git repository contains 3 Rust crates: ctp-common, ctp-md, ctp-trader. ctp-md and ctp-trader both depend on ctp-common, but can be used separately.

ctp-common

Common datatypes including constants, structs in original C++ API, as well as some conversions to idiomatic Rust data types.

ctp-md

Wrapper for market data API. A run-time dependency of thostmduserapi.so is needed for Rust application that uses this crate.

ctp-trader

Wrapper for trader API. A run-time dependency of thosttraderapi.so is needed for Rust application that uses this crate.

OS support

Currently these 3 crates only support Linux x86_64

Minimal Rust version

1.26.0

ctp-rs's People

Contributors

wisagan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

ctp-rs's Issues

Cannot build on my Manjaro 18.1

I have tried to build ctp-trader-v0.8.1 for several time, but always encounter the same error (attached below).
Can you please help me to fix this?

Also, I am a newb to both Rust and CTP. So, sorry if this is a stupid question.

$ cargo build --release
   Compiling libc v0.2.65
   Compiling encoding_index_tests v0.1.4
   Compiling memchr v2.2.1
   Compiling simple-error v0.2.1
   Compiling ctp-trader v0.8.1 (~/ctp-rs-ctp-trader-v0.8.1/ctp-trader)
   Compiling ctp-md v0.8.0 (~/ctp-rs-ctp-trader-v0.8.1/ctp-md)
   Compiling encoding-index-japanese v1.20141219.5
   Compiling encoding-index-simpchinese v1.20141219.5
   Compiling encoding-index-korean v1.20141219.5
   Compiling encoding-index-tradchinese v1.20141219.5
   Compiling encoding-index-singlebyte v1.20141219.5
error: failed to run custom build command for `ctp-trader v0.8.1 (~/ctp-rs-ctp-trader-v0.8.1/ctp-trader)`

Caused by:
  process didn't exit successfully: `~/ctp-rs-ctp-trader-v0.8.1/target/release/build/ctp-trader-5bcd7ca2d0f9ca94/build-script-build` (exit code: 101)
--- stdout
cargo:rustc-link-search=native=~/ctp-rs-ctp-trader-v0.8.1/target/release/build/ctp-trader-204f3bb4f27df520/out

--- stderr
thread 'main' panicked at 'failed to copy so to outdir: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/libcore/result.rs:1084:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

warning: build failed, waiting for other jobs to finish...
error: build failed

能否补充一下这个库的使用说明?

这个库非常不错,做多了很多基础性的工作,填补了rust封装CTP的空白。
能否简单补充描述一下这个库需要如何环境配置和编译,才可以使用的一些前提介绍,谢谢!

为什么on_rtn_depth_market_data收到不数据,但on_rtn_for_quote_rsp却不断收到数据?

            let flow_path = ::std::ffi::CString::new("").unwrap();
            let mut md_api = MdApi::new(flow_path, false, false);
            md_api.register_spi(Box::new(_my_desk.clone()));
            md_api.register_front(std::ffi::CString::new(md_front).unwrap());
            md_api.init();
            std::thread::sleep(std::time::Duration::from_secs(1));
            let login_field = get_login_field(&acc);
            match md_api.req_user_login(&login_field, 1) {
                Ok(()) => println!("md req_user_login =>ok"),
                Err(err) => println!("md req_user_login =>err: {:?}", err),
            };
            let instrument_ids = vec![CString::new("IF2009").unwrap(),
                                      CString::new("au2012").unwrap(),
                                      CString::new("m2009").unwrap()];
            std::thread::sleep(std::time::Duration::from_secs(1));
            match md_api.subscribe_market_data(&instrument_ids.clone()) {
                Ok(()) => println!("subscribe_market_data =>ok instrs :{:?}",&instrument_ids.clone()),
                Err(err) => println!("subscribe_market_data err: {:?}", err),
            };

在impl MdSPI中,

fn on_rtn_depth_market_data(&mut self, depth_market_data: Option<&CThostFtdcDepthMarketDataField>) {
     println!("desk => depth_market_data:{:?}",depth_market_data);
     self.sender_to_manager.send(SpiData::DepthMarketData(MdSpiOnRtnDepthMarketData{ depth_market_data: *depth_market_data.expect("depth_market_data is none") })).expect("cannot send md spi")
 }

 fn on_rtn_for_quote_rsp(&mut self, for_quote_rsp: Option<&CThostFtdcForQuoteRspField>) {
     println!("desk => on_rtn_for_quote_rsp:{:?}",for_quote_rsp);
     self.sender_to_manager.send(SpiData::ForQuoteRsp(MdSpiOnRtnForQuoteRsp{ for_quote_rsp: *for_quote_rsp.expect("for_quote_rsp is none") })).expect("cannot send md spi");
 }

``
下面是我打印的:
desk=> on_rtn_for_quote_rsp:Some(CThostFtdcForQuoteRspField { TradingDay: "20200807", InstrumentID: "IF2009",
ForQuoteSysID: "", ForQuoteTime: "", ActionDay: "", ExchangeID: "" })
desk => on_rtn_for_quote_rsp:Some(CThostFtdcForQuoteRspField { TradingDay: "20200807", InstrumentID: "m2009", ForQuoteSysID: "", ForQuoteTime: "", ActionDay: "", ExchangeID: "" })
......

谢谢!

Remove bindgen dependency

CTP headers rarely changes, thus the generated binding. It is a bit wasteful to build bindgen every time, and generate the same bindings. bindgen also requires libclang.

We would like to remove bindgen, and check in the generated code directly. And moving the build.rs script to a Rust script to update the generated the file. It should be detailed on we can use that script (cargo script?), and what dependency we need to run it. This script is only used when header changes, and we want to regenerate, it is not needed by the user.

subscribe_market_data成功后,如何触发on_rsp_sub_market_data

请教下,订阅成功后,没有推送行情数据是因为?

let (tx, rx) = crossbeam_channel::unbounded();
md_api.register_spi(Box::new(ChannelMdSpi::new(tx)));
...

let instrument_ids = vec!(CString::new("FU2005").unwrap(), CString::new("IC8888").unwrap());
match md_api.subscribe_market_data(&instrument_ids.clone()) {
    Ok(()) => println!("subscribe_market_data ok"),
    Err(err) => println!("subscribe_market_data err: {:?}", err),
};

for received in rx {
    println!("received: {:?}", received);
}

登录成功后,只能从 channel 中收到 行情订阅响应,按下面的流程图,订阅成功后应该会自动推送行情

image

但是后面就一直处于等待状态

subscribe_market_data ok

received: (SubMarketData(MdSpiOnRspSubMarketData { specific_instrument: Some(CThostFtdcSpecificInstrumentField { InstrumentID: "FU2005" }), result: Ok(()), request_id: 0, is_last: false }), SystemTime { tv_sec: 1585709336, tv_nsec: 876154074 })

received: (SubMarketData(MdSpiOnRspSubMarketData { specific_instrument: Some(CThostFtdcSpecificInstrumentField { InstrumentID: "IC8888" }), result: Ok(()), request_id: 0, is_last: true }), SystemTime { tv_sec: 1585709336, tv_nsec: 876156269 })

// 一直等待,没有任何输出信息

多谢了。

failed to create new symlink

Compiling ctp-md v0.10.0 (/home/sg/ctp_rs/ctp-md)
error: failed to run custom build command for ctp-md v0.10.0 (/home/sg/ctp_rs/ctp-md)

Caused by:
process didn't exit successfully: /home/sg/ctp_rs/target/release/build/ctp-md-ffc752198c8da060/build-script-build (exit code: 101)
--- stderr
thread 'main' panicked at 'failed to create new symlink: Os { code: 17, kind: AlreadyExists, message: "File exists" }', src/libcore/result.rs:1188:5
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace.

How to call trader_api in traderSPI?

Hi,

Thanks for your hard working! Finally we have a rust-ctp framework. I could run the demo well and learned a lot.
I have a problem when I try to call "trader_api" in SPI. For example, call reqAuthenticate() and reqUserLogin() when onFrontConnected callback. Or try to cancel orders inside on_rsp_order_insert()

I tried to pass trader_api into SPI's structure but it seems not work.

struct Spi<'a>{
    trader_api: &'a ctp_trader::TraderApi,
}

impl TraderSpi for Spi {
    //On trading front end connected
    fn on_front_connected(&mut self) {
        println!("on_front_connected");
    }
}
...
let mut trader_api = TraderApi::new(std::ffi::CString::new("").unwrap());
trader_api.register_spi(Box::new(Spi{trader_api: &trader_api}));

with error
main.rs(12, 6): *mut std::ffi::c_void cannot be shared between threads

Do you have any good suggestions?
Thanks you!

How does the `#[link_name = ]` thing work?

Such as

#[link_name = "_ZN14CFtdcMdApiImpl13GetTradingDayEv"]
fn CFtdcMdApiImplGetTradingDay(api: *mut c_void) -> *const c_char;

Why the name "_ZN14CFtdcMdApiImpl13GetTradingDayEv", any guidance?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.