├── .gitignore ├── .gitattributes ├── ctp ├── lib │ └── v6.7.11_20250617_api_traderapi_se_linux64 │ │ ├── thostmduserapi_se.so │ │ ├── thosttraderapi_se.so │ │ ├── error.dtd │ │ ├── ThostFtdcMdApi.h │ │ └── error.xml ├── lib.go ├── mdapi_wrap.h ├── mdspi_base.go ├── mdapi_wrap.cxx └── mdapi_impl.go ├── go.mod ├── ctp_dyn ├── lib_tts.go ├── lib.go ├── mdapi_wrap.h ├── mdspi_base.go ├── mdapi_impl.go └── mdapi_wrap.cxx ├── CHANGELOG.md ├── go.sum ├── thost ├── mdapi.go └── traderapi.go ├── sample ├── simple_market │ └── main.go └── simple_trader │ └── main.go ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.go linguist-language=Go 2 | *.h linguist-language=Go 3 | -------------------------------------------------------------------------------- /ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64/thostmduserapi_se.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pseudocodes/go2ctp/HEAD/ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64/thostmduserapi_se.so -------------------------------------------------------------------------------- /ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64/thosttraderapi_se.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pseudocodes/go2ctp/HEAD/ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64/thosttraderapi_se.so -------------------------------------------------------------------------------- /ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64/error.dtd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/pseudocodes/go2ctp 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/gookit/goutil v0.6.12 7 | golang.org/x/text v0.12.0 8 | ) 9 | 10 | require ( 11 | github.com/gookit/color v1.5.4 // indirect 12 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect 13 | golang.org/x/sys v0.10.0 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /ctp_dyn/lib_tts.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | //go:build tts || openctp 14 | 15 | package ctp_dyn 16 | 17 | /* 18 | #cgo linux LDFLAGS: -fPIC -ldl 19 | #cgo linux CXXFLAGS: -std=c++11 20 | #cgo linux CPPFLAGS: -fPIC -I. -I${SRCDIR}/../ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64 21 | 22 | // #cgo darwin LDFLAGS: -L. -ldl 23 | // #cgo darwin CXXFLAGS: -std=c++11 24 | // #cgo darwin CPPFLAGS: -I. -I${SRCDIR}/../ctp/lib/v6.7.7_20240607_api_traderapi_se_linux64/ -D__OPENCTP__ 25 | 26 | */ 27 | import "C" 28 | -------------------------------------------------------------------------------- /ctp_dyn/lib.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | //go:build !(tts || openctp) 14 | 15 | package ctp_dyn 16 | 17 | /* 18 | #cgo linux LDFLAGS: -fPIC -L. -L${SRCDIR}/../ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64 -ldl 19 | #cgo linux CXXFLAGS: -std=c++11 20 | #cgo linux CPPFLAGS: -fPIC -I. -I${SRCDIR}/../ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64 21 | 22 | // #cgo darwin LDFLAGS: -L. -L${SRCDIR}/../ctp/lib/v6.7.7_MacOS_20240716/ -ldl 23 | // #cgo darwin CXXFLAGS: -std=c++11 24 | // #cgo darwin CPPFLAGS: -I. -I${SRCDIR}/../ctp/lib/v6.7.7_MacOS_20240716/include 25 | 26 | */ 27 | import "C" 28 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | ## [Unreleased] - 2025-08-13 3 | - 更新分支 6.7.11 对应官方 CTP 库版本 4 | - 更新封装代码 5 | - master 分支对应最新 CTP 版本 6 | - 更新 README 文档 7 | 8 | 9 | ## [Unreleased] - 2024-09-13 10 | 11 | ### Changed 12 | 13 | - 更新分支 6.7.7 对应官方 CTP 库版本 14 | - 更新封装代码 15 | - master 分支对应最新 CTP 版本 16 | - 更新 README 文档 17 | 18 | ### comment 19 | - 采用 libclang 重写了封装代码生成脚本 20 | - 取消 ctp-mini golang 封装计划 21 | 22 | 23 | ## [Unreleased] - 2024-07-07 24 | 25 | ### Changed 26 | 27 | - 更新分支 6.7.2 对应官方 CTP 版本 28 | - 删除 ctp_cp 评测 package 目录,评测接入采用 ctp_dyn 29 | - ctp_tts 更名为 ctp_dyn 30 | - master 分支对应最新 CTP 版本 31 | - 更新 README 文档 32 | 33 | ### comment 34 | - 为精简项目,除 CTP 头文件,非必要不再提供对应版本的库文件 35 | - openctp 以及 CTP_CP 评测库请自行下载 36 | - 推荐使用 ctp_dyn,不强制依赖库文件以及库文件路径,动态库可配置 37 | - openctp 编译需添加参数,详见 FAQ 38 | 39 | 40 | ## [Unreleased] - 2024-04-05 41 | 42 | ### Changed 43 | 44 | - Release 接口增加清空 RegisterSpi 操作 45 | - 更新 README 文档 46 | 47 | 48 | ## [Unreleased] - 2024-03-11 49 | 50 | ### Changed 51 | 52 | - 更新 README 文档,添加同类项目对比说明 53 | 54 | ## [Unreleased] - 2024-02-26 55 | 56 | ### Changed 57 | 58 | - 修复某些 Linux 环境下 `uintptr_t` 在编译中无法识别的问题 59 | - 调整 `linguist-language` 60 | 61 | 62 | ## [Unreleased] - 2024-01-29 63 | 64 | ### Changed 65 | 66 | - TdApi 与 MdApi 接口定义文件移入 thost 目录, 各子目录对外接口统一 67 | - 调整 Sample 样例代码 68 | 69 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= 3 | github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= 4 | github.com/gookit/goutil v0.6.12 h1:73vPUcTtVGXbhSzBOFcnSB1aJl7Jq9np3RAE50yIDZc= 5 | github.com/gookit/goutil v0.6.12/go.mod h1:g6krlFib8xSe3G1h02IETowOtrUGpAmetT8IevDpvpM= 6 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 7 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 8 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= 9 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= 10 | golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= 11 | golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= 12 | golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 13 | golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= 14 | golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 15 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 16 | -------------------------------------------------------------------------------- /ctp/lib.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | package ctp 14 | 15 | /* 16 | #cgo linux LDFLAGS: -fPIC -L. -L${SRCDIR}/lib/v6.7.11_20250617_api_traderapi_se_linux64 -Wl,-rpath=${SRCDIR}/lib/v6.7.11_20250617_api_traderapi_se_linux64 -l:thostmduserapi_se.so -l:thosttraderapi_se.so -lstdc++ 17 | #cgo linux CXXFLAGS: -std=c++11 18 | #cgo linux CPPFLAGS: -fPIC -I. -I${SRCDIR}/lib/v6.7.11_20250617_api_traderapi_se_linux64/ 19 | */ 20 | import "C" 21 | import ( 22 | "github.com/pseudocodes/go2ctp/thost" 23 | ) 24 | 25 | const ( 26 | defaultFlowPath = "" 27 | defaultIsUsingUdp = false 28 | defaultIsMulticast = false 29 | defaultIsProductionMode = true 30 | ) 31 | 32 | type MdOption func(api *MdApi) 33 | 34 | func MdFlowPath(path string) MdOption { 35 | return func(api *MdApi) { 36 | api.flowPath = path 37 | } 38 | } 39 | 40 | func MdUsingUDP(usingudp bool) MdOption { 41 | return func(api *MdApi) { 42 | api.usingUDP = usingudp 43 | } 44 | } 45 | 46 | func MdMultiCast(multicast bool) MdOption { 47 | return func(api *MdApi) { 48 | api.multicast = multicast 49 | } 50 | } 51 | 52 | func MdProductionMode(production bool) MdOption { 53 | return func(api *MdApi) { 54 | api.production = production 55 | } 56 | } 57 | 58 | type MdApi struct { 59 | apiPtr uintptr 60 | spi thost.MdSpi 61 | 62 | flowPath string 63 | usingUDP bool 64 | multicast bool 65 | production bool 66 | } 67 | 68 | type TraderOption func(api *TraderApi) 69 | 70 | func TraderFlowPath(path string) TraderOption { 71 | return func(api *TraderApi) { 72 | api.flowPath = path 73 | } 74 | } 75 | 76 | func TraderSystemInfo(systemInfo []byte, length int) TraderOption { 77 | return func(api *TraderApi) { 78 | api.length = length 79 | copy(api.systemInfo[:], systemInfo) 80 | } 81 | } 82 | 83 | func TraderProductionMode(production bool) TraderOption { 84 | return func(api *TraderApi) { 85 | api.production = production 86 | } 87 | } 88 | 89 | type TraderApi struct { 90 | apiPtr uintptr 91 | spi thost.TraderSpi 92 | 93 | length int 94 | systemInfo [273]byte 95 | 96 | flowPath string 97 | production bool 98 | } 99 | -------------------------------------------------------------------------------- /thost/mdapi.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | package thost 14 | 15 | type MdSpi interface { 16 | 17 | /// 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 18 | OnFrontConnected() 19 | 20 | /// 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 21 | ///@param nReason 错误原因 22 | /// 0x1001 网络读失败 23 | /// 0x1002 网络写失败 24 | /// 0x2001 接收心跳超时 25 | /// 0x2002 发送心跳失败 26 | /// 0x2003 收到错误报文 27 | OnFrontDisconnected(nReason int) 28 | 29 | /// 心跳超时警告。当长时间未收到报文时,该方法被调用。 30 | ///@param nTimeLapse 距离上次接收报文的时间 31 | OnHeartBeatWarning(nTimeLapse int) 32 | 33 | /// 登录请求响应 34 | OnRspUserLogin(pRspUserLogin *CThostFtdcRspUserLoginField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 35 | 36 | /// 登出请求响应 37 | OnRspUserLogout(pUserLogout *CThostFtdcUserLogoutField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 38 | 39 | /// 请求查询组播合约响应 40 | OnRspQryMulticastInstrument(pMulticastInstrument *CThostFtdcMulticastInstrumentField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 41 | 42 | /// 错误应答 43 | OnRspError(pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 44 | 45 | /// 订阅行情应答 46 | OnRspSubMarketData(pSpecificInstrument *CThostFtdcSpecificInstrumentField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 47 | 48 | /// 取消订阅行情应答 49 | OnRspUnSubMarketData(pSpecificInstrument *CThostFtdcSpecificInstrumentField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 50 | 51 | /// 订阅询价应答 52 | OnRspSubForQuoteRsp(pSpecificInstrument *CThostFtdcSpecificInstrumentField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 53 | 54 | /// 取消订阅询价应答 55 | OnRspUnSubForQuoteRsp(pSpecificInstrument *CThostFtdcSpecificInstrumentField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 56 | 57 | /// 深度行情通知 58 | OnRtnDepthMarketData(pDepthMarketData *CThostFtdcDepthMarketDataField) 59 | 60 | /// 询价通知 61 | OnRtnForQuoteRsp(pForQuoteRsp *CThostFtdcForQuoteRspField) 62 | } 63 | 64 | type MdApi interface { 65 | 66 | /// 获取API的版本信息 67 | ///@retrun 获取到的版本号 68 | GetApiVersion() string 69 | 70 | /// 删除接口对象本身 71 | ///@remark 不再使用本接口对象时,调用该函数删除接口对象 72 | Release() 73 | 74 | /// 初始化 75 | ///@remark 初始化运行环境,只有调用后,接口才开始工作 76 | Init() 77 | 78 | /// 等待接口线程结束运行 79 | ///@return 线程退出代码 80 | Join() int 81 | 82 | /// 获取当前交易日 83 | ///@retrun 获取到的交易日 84 | ///@remark 只有登录成功后,才能得到正确的交易日 85 | GetTradingDay() string 86 | 87 | /// 注册前置机网络地址 88 | ///@param pszFrontAddress:前置机网络地址。 89 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:17001”。 90 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。 91 | RegisterFront(pszFrontAddress string) 92 | 93 | /// 注册名字服务器网络地址 94 | ///@param pszNsAddress:名字服务器网络地址。 95 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:12001”。 96 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”12001”代表服务器端口号。 97 | ///@remark RegisterNameServer优先于RegisterFront 98 | RegisterNameServer(pszNsAddress string) 99 | 100 | /// 注册名字服务器用户信息 101 | ///@param pFensUserInfo:用户信息。 102 | RegisterFensUserInfo(pFensUserInfo *CThostFtdcFensUserInfoField) 103 | 104 | /// 注册回调接口 105 | ///@param pSpi 派生自回调接口类的实例 106 | RegisterSpi(pSpi MdSpi) 107 | 108 | /// 订阅行情。 109 | ///@param ppInstrumentID 合约ID 110 | ///@param nCount 要订阅/退订行情的合约个数 111 | ///@remark 112 | SubscribeMarketData(instrumentIDs ...string) int 113 | 114 | /// 退订行情。 115 | ///@param ppInstrumentID 合约ID 116 | ///@param nCount 要订阅/退订行情的合约个数 117 | ///@remark 118 | UnSubscribeMarketData(instrumentIDs ...string) int 119 | 120 | /// 订阅询价。 121 | ///@param ppInstrumentID 合约ID 122 | ///@param nCount 要订阅/退订行情的合约个数 123 | ///@remark 124 | SubscribeForQuoteRsp(instrumentIDs ...string) int 125 | 126 | /// 退订询价。 127 | ///@param ppInstrumentID 合约ID 128 | ///@param nCount 要订阅/退订行情的合约个数 129 | ///@remark 130 | UnSubscribeForQuoteRsp(instrumentIDs ...string) int 131 | 132 | /// 用户登录请求 133 | ReqUserLogin(pReqUserLoginField *CThostFtdcReqUserLoginField, nRequestID int) int 134 | 135 | /// 登出请求 136 | ReqUserLogout(pUserLogout *CThostFtdcUserLogoutField, nRequestID int) int 137 | 138 | /// 请求查询组播合约 139 | ReqQryMulticastInstrument(pQryMulticastInstrument *CThostFtdcQryMulticastInstrumentField, nRequestID int) int 140 | } 141 | -------------------------------------------------------------------------------- /ctp/mdapi_wrap.h: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | #ifndef _MDAPI_WRAP_H_ 14 | #define _MDAPI_WRAP_H_ 15 | 16 | #include "ThostFtdcMdApi.h" 17 | #include "ThostFtdcTraderApi.h" 18 | #include "ThostFtdcUserApiDataType.h" 19 | #include "ThostFtdcUserApiStruct.h" 20 | 21 | class QCTPMdSpi : public CThostFtdcMdSpi { 22 | public: 23 | QCTPMdSpi(CThostFtdcMdApi* pUserApi); 24 | QCTPMdSpi(CThostFtdcMdApi* pUserApi, uintptr_t gUserApi); 25 | QCTPMdSpi(); 26 | 27 | /// 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 28 | void OnFrontConnected(); 29 | 30 | /// 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 31 | ///@param nReason 错误原因 32 | /// 0x1001 网络读失败 33 | /// 0x1002 网络写失败 34 | /// 0x2001 接收心跳超时 35 | /// 0x2002 发送心跳失败 36 | /// 0x2003 收到错误报文 37 | void OnFrontDisconnected(int nReason); 38 | 39 | /// 心跳超时警告。当长时间未收到报文时,该方法被调用。 40 | ///@param nTimeLapse 距离上次接收报文的时间 41 | void OnHeartBeatWarning(int nTimeLapse); 42 | 43 | /// 登录请求响应 44 | void OnRspUserLogin(CThostFtdcRspUserLoginField* pRspUserLogin, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 45 | 46 | /// 登出请求响应 47 | void OnRspUserLogout(CThostFtdcUserLogoutField* pUserLogout, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 48 | 49 | /// 请求查询组播合约响应 50 | void OnRspQryMulticastInstrument(CThostFtdcMulticastInstrumentField* pMulticastInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 51 | 52 | /// 错误应答 53 | void OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 54 | 55 | /// 订阅行情应答 56 | void OnRspSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 57 | 58 | /// 取消订阅行情应答 59 | void OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 60 | 61 | /// 订阅询价应答 62 | void OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 63 | 64 | /// 取消订阅询价应答 65 | void OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 66 | 67 | /// 深度行情通知 68 | void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField* pDepthMarketData); 69 | 70 | /// 询价通知 71 | void OnRtnForQuoteRsp(CThostFtdcForQuoteRspField* pForQuoteRsp); 72 | 73 | /// 获取API的版本信息 74 | ///@retrun 获取到的版本号 75 | const char* GetApiVersion(); 76 | 77 | /// 删除接口对象本身 78 | ///@remark 不再使用本接口对象时,调用该函数删除接口对象 79 | void Release(); 80 | 81 | /// 初始化 82 | ///@remark 初始化运行环境,只有调用后,接口才开始工作 83 | void Init(); 84 | 85 | /// 等待接口线程结束运行 86 | ///@return 线程退出代码 87 | int Join(); 88 | 89 | /// 获取当前交易日 90 | ///@retrun 获取到的交易日 91 | ///@remark 只有登录成功后,才能得到正确的交易日 92 | const char* GetTradingDay(); 93 | 94 | /// 注册前置机网络地址 95 | ///@param pszFrontAddress:前置机网络地址。 96 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:17001”。 97 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。 98 | void RegisterFront(char* pszFrontAddress); 99 | 100 | /// 注册名字服务器网络地址 101 | ///@param pszNsAddress:名字服务器网络地址。 102 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:12001”。 103 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”12001”代表服务器端口号。 104 | ///@remark RegisterNameServer优先于RegisterFront 105 | void RegisterNameServer(char* pszNsAddress); 106 | 107 | /// 注册名字服务器用户信息 108 | ///@param pFensUserInfo:用户信息。 109 | void RegisterFensUserInfo(CThostFtdcFensUserInfoField* pFensUserInfo); 110 | 111 | /// 注册回调接口 112 | ///@param pSpi 派生自回调接口类的实例 113 | void RegisterSpi(CThostFtdcMdSpi* pSpi); 114 | 115 | /// 订阅行情。 116 | ///@param ppInstrumentID 合约ID 117 | ///@param nCount 要订阅/退订行情的合约个数 118 | ///@remark 119 | int SubscribeMarketData(char** ppInstrumentID, int nCount); 120 | 121 | /// 退订行情。 122 | ///@param ppInstrumentID 合约ID 123 | ///@param nCount 要订阅/退订行情的合约个数 124 | ///@remark 125 | int UnSubscribeMarketData(char** ppInstrumentID, int nCount); 126 | 127 | /// 订阅询价。 128 | ///@param ppInstrumentID 合约ID 129 | ///@param nCount 要订阅/退订行情的合约个数 130 | ///@remark 131 | int SubscribeForQuoteRsp(char** ppInstrumentID, int nCount); 132 | 133 | /// 退订询价。 134 | ///@param ppInstrumentID 合约ID 135 | ///@param nCount 要订阅/退订行情的合约个数 136 | ///@remark 137 | int UnSubscribeForQuoteRsp(char** ppInstrumentID, int nCount); 138 | 139 | /// 用户登录请求 140 | int ReqUserLogin(CThostFtdcReqUserLoginField* pReqUserLoginField, int nRequestID); 141 | 142 | /// 登出请求 143 | int ReqUserLogout(CThostFtdcUserLogoutField* pUserLogout, int nRequestID); 144 | 145 | /// 请求查询组播合约 146 | int ReqQryMulticastInstrument(CThostFtdcQryMulticastInstrumentField* pQryMulticastInstrument, int nRequestID); 147 | 148 | private: 149 | CThostFtdcMdApi* pUserApi; 150 | uintptr_t gUserApi; 151 | }; 152 | 153 | #endif // end _MDAPI_WRAP_H_ 154 | -------------------------------------------------------------------------------- /ctp_dyn/mdapi_wrap.h: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | #ifndef _MDAPI_WRAP_H_ 14 | #define _MDAPI_WRAP_H_ 15 | 16 | class TTSCTPMdSpi : public CThostFtdcMdSpi { 17 | public: 18 | TTSCTPMdSpi(CThostFtdcMdApi* pUserApi); 19 | TTSCTPMdSpi(CThostFtdcMdApi* pUserApi, uintptr_t gUserApi); 20 | TTSCTPMdSpi(uintptr_t gUserApi, const char* pszDLLPath, const char* pszFlowPath, const bool bIsUsingUdp, const bool bIsMulticast, bool bIsProductionMode); 21 | TTSCTPMdSpi(); 22 | virtual ~TTSCTPMdSpi(); 23 | 24 | // 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 25 | void OnFrontConnected(); 26 | 27 | // 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 28 | ///@param nReason 错误原因 29 | /// 0x1001 网络读失败 30 | /// 0x1002 网络写失败 31 | /// 0x2001 接收心跳超时 32 | /// 0x2002 发送心跳失败 33 | /// 0x2003 收到错误报文 34 | void OnFrontDisconnected(int nReason); 35 | 36 | // 心跳超时警告。当长时间未收到报文时,该方法被调用。 37 | ///@param nTimeLapse 距离上次接收报文的时间 38 | void OnHeartBeatWarning(int nTimeLapse); 39 | 40 | // 登录请求响应 41 | void OnRspUserLogin(CThostFtdcRspUserLoginField* pRspUserLogin, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 42 | 43 | // 登出请求响应 44 | void OnRspUserLogout(CThostFtdcUserLogoutField* pUserLogout, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 45 | 46 | // 请求查询组播合约响应 47 | void OnRspQryMulticastInstrument(CThostFtdcMulticastInstrumentField* pMulticastInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 48 | 49 | // 错误应答 50 | void OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 51 | 52 | // 订阅行情应答 53 | void OnRspSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 54 | 55 | // 取消订阅行情应答 56 | void OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 57 | 58 | // 订阅询价应答 59 | void OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 60 | 61 | // 取消订阅询价应答 62 | void OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast); 63 | 64 | // 深度行情通知 65 | void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField* pDepthMarketData); 66 | 67 | // 询价通知 68 | void OnRtnForQuoteRsp(CThostFtdcForQuoteRspField* pForQuoteRsp); 69 | 70 | // 获取API的版本信息 71 | ///@retrun 获取到的版本号 72 | const char* GetApiVersion(); 73 | 74 | // 删除接口对象本身 75 | ///@remark 不再使用本接口对象时,调用该函数删除接口对象 76 | void Release(); 77 | 78 | // 初始化 79 | ///@remark 初始化运行环境,只有调用后,接口才开始工作 80 | void Init(); 81 | 82 | // 等待接口线程结束运行 83 | ///@return 线程退出代码 84 | int Join(); 85 | 86 | // 获取当前交易日 87 | ///@retrun 获取到的交易日 88 | ///@remark 只有登录成功后,才能得到正确的交易日 89 | const char* GetTradingDay(); 90 | 91 | // 注册前置机网络地址 92 | ///@param pszFrontAddress:前置机网络地址。 93 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:17001”。 94 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。 95 | void RegisterFront(char* pszFrontAddress); 96 | 97 | // 注册名字服务器网络地址 98 | ///@param pszNsAddress:名字服务器网络地址。 99 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:12001”。 100 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”12001”代表服务器端口号。 101 | ///@remark RegisterNameServer优先于RegisterFront 102 | void RegisterNameServer(char* pszNsAddress); 103 | 104 | // 注册名字服务器用户信息 105 | ///@param pFensUserInfo:用户信息。 106 | void RegisterFensUserInfo(CThostFtdcFensUserInfoField* pFensUserInfo); 107 | 108 | // 注册回调接口 109 | ///@param pSpi 派生自回调接口类的实例 110 | void RegisterSpi(CThostFtdcMdSpi* pSpi); 111 | 112 | // 订阅行情。 113 | ///@param ppInstrumentID 合约ID 114 | ///@param nCount 要订阅/退订行情的合约个数 115 | ///@remark 116 | int SubscribeMarketData(char* ppInstrumentID[], int nCount); 117 | 118 | // 退订行情。 119 | ///@param ppInstrumentID 合约ID 120 | ///@param nCount 要订阅/退订行情的合约个数 121 | ///@remark 122 | int UnSubscribeMarketData(char* ppInstrumentID[], int nCount); 123 | 124 | // 订阅询价。 125 | ///@param ppInstrumentID 合约ID 126 | ///@param nCount 要订阅/退订行情的合约个数 127 | ///@remark 128 | int SubscribeForQuoteRsp(char* ppInstrumentID[], int nCount); 129 | 130 | // 退订询价。 131 | ///@param ppInstrumentID 合约ID 132 | ///@param nCount 要订阅/退订行情的合约个数 133 | ///@remark 134 | int UnSubscribeForQuoteRsp(char* ppInstrumentID[], int nCount); 135 | 136 | // 用户登录请求 137 | int ReqUserLogin(CThostFtdcReqUserLoginField* pReqUserLoginField, int nRequestID); 138 | 139 | // 登出请求 140 | int ReqUserLogout(CThostFtdcUserLogoutField* pUserLogout, int nRequestID); 141 | 142 | // 请求查询组播合约 143 | int ReqQryMulticastInstrument(CThostFtdcQryMulticastInstrumentField* pQryMulticastInstrument, int nRequestID); 144 | 145 | private: 146 | CThostFtdcMdApi* pUserApi; 147 | uintptr_t gUserApi; 148 | void* dllHandle; 149 | }; 150 | 151 | #endif // end _MDAPI_WRAP_H_ 152 | -------------------------------------------------------------------------------- /ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64/ThostFtdcMdApi.h: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////////// 2 | ///@system 新一代交易所系统 3 | ///@company 上海期货信息技术有限公司 4 | ///@file ThostFtdcMdApi.h 5 | ///@brief 定义了客户端接口 6 | ///@history 7 | /// 20060106 赵鸿昊 创建该文件 8 | ///////////////////////////////////////////////////////////////////////// 9 | 10 | #if !defined(THOST_FTDCMDAPI_H) 11 | #define THOST_FTDCMDAPI_H 12 | 13 | #if _MSC_VER > 1000 14 | #pragma once 15 | #endif // _MSC_VER > 1000 16 | 17 | #include "ThostFtdcUserApiStruct.h" 18 | 19 | #if defined(ISLIB) && defined(WIN32) 20 | #ifdef LIB_MD_API_EXPORT 21 | #define MD_API_EXPORT __declspec(dllexport) 22 | #else 23 | #define MD_API_EXPORT __declspec(dllimport) 24 | #endif 25 | #else 26 | #define MD_API_EXPORT 27 | #endif 28 | 29 | class CThostFtdcMdSpi { 30 | public: 31 | /// 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 32 | virtual void OnFrontConnected() { }; 33 | 34 | /// 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 35 | ///@param nReason 错误原因 36 | /// 0x1001 网络读失败 37 | /// 0x1002 网络写失败 38 | /// 0x2001 接收心跳超时 39 | /// 0x2002 发送心跳失败 40 | /// 0x2003 收到错误报文 41 | virtual void OnFrontDisconnected(int nReason) { }; 42 | 43 | /// 心跳超时警告。当长时间未收到报文时,该方法被调用。 44 | ///@param nTimeLapse 距离上次接收报文的时间 45 | virtual void OnHeartBeatWarning(int nTimeLapse) { }; 46 | 47 | /// 登录请求响应 48 | virtual void OnRspUserLogin(CThostFtdcRspUserLoginField* pRspUserLogin, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) { }; 49 | 50 | /// 登出请求响应 51 | virtual void OnRspUserLogout(CThostFtdcUserLogoutField* pUserLogout, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) { }; 52 | 53 | /// 请求查询组播合约响应 54 | virtual void OnRspQryMulticastInstrument(CThostFtdcMulticastInstrumentField* pMulticastInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) { }; 55 | 56 | /// 错误应答 57 | virtual void OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) { }; 58 | 59 | /// 订阅行情应答 60 | virtual void OnRspSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) { }; 61 | 62 | /// 取消订阅行情应答 63 | virtual void OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) { }; 64 | 65 | /// 订阅询价应答 66 | virtual void OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) { }; 67 | 68 | /// 取消订阅询价应答 69 | virtual void OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) { }; 70 | 71 | /// 深度行情通知 72 | virtual void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField* pDepthMarketData) { }; 73 | 74 | /// 询价通知 75 | virtual void OnRtnForQuoteRsp(CThostFtdcForQuoteRspField* pForQuoteRsp) { }; 76 | }; 77 | 78 | class MD_API_EXPORT CThostFtdcMdApi { 79 | public: 80 | /// 创建MdApi 81 | ///@param pszFlowPath 存贮订阅信息文件的目录,默认为当前目录 82 | ///@param bIsProductionMode true:使用生产版本的API false:使用测评版本API 83 | ///@return 创建出的UserApi 84 | /// modify for udp marketdata 85 | static CThostFtdcMdApi* CreateFtdcMdApi(const char* pszFlowPath = "", const bool bIsUsingUdp = false, const bool bIsMulticast = false, bool bIsProductionMode = true); 86 | 87 | /// 获取API的版本信息 88 | ///@retrun 获取到的版本号 89 | static const char* GetApiVersion(); 90 | 91 | /// 删除接口对象本身 92 | ///@remark 不再使用本接口对象时,调用该函数删除接口对象 93 | virtual void Release() = 0; 94 | 95 | /// 初始化 96 | ///@remark 初始化运行环境,只有调用后,接口才开始工作 97 | virtual void Init() = 0; 98 | 99 | /// 等待接口线程结束运行 100 | ///@return 线程退出代码 101 | virtual int Join() = 0; 102 | 103 | /// 获取当前交易日 104 | ///@retrun 获取到的交易日 105 | ///@remark 只有登录成功后,才能得到正确的交易日 106 | virtual const char* GetTradingDay() = 0; 107 | 108 | /// 注册前置机网络地址 109 | ///@param pszFrontAddress:前置机网络地址。 110 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:17001”。 111 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。 112 | virtual void RegisterFront(char* pszFrontAddress) = 0; 113 | 114 | /// 注册名字服务器网络地址 115 | ///@param pszNsAddress:名字服务器网络地址。 116 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:12001”。 117 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”12001”代表服务器端口号。 118 | ///@remark RegisterNameServer优先于RegisterFront 119 | virtual void RegisterNameServer(char* pszNsAddress) = 0; 120 | 121 | /// 注册名字服务器用户信息 122 | ///@param pFensUserInfo:用户信息。 123 | virtual void RegisterFensUserInfo(CThostFtdcFensUserInfoField* pFensUserInfo) = 0; 124 | 125 | /// 注册回调接口 126 | ///@param pSpi 派生自回调接口类的实例 127 | virtual void RegisterSpi(CThostFtdcMdSpi* pSpi) = 0; 128 | 129 | /// 订阅行情。 130 | ///@param ppInstrumentID 合约ID 131 | ///@param nCount 要订阅/退订行情的合约个数 132 | ///@remark 133 | virtual int SubscribeMarketData(char* ppInstrumentID[], int nCount) = 0; 134 | 135 | /// 退订行情。 136 | ///@param ppInstrumentID 合约ID 137 | ///@param nCount 要订阅/退订行情的合约个数 138 | ///@remark 139 | virtual int UnSubscribeMarketData(char* ppInstrumentID[], int nCount) = 0; 140 | 141 | /// 订阅询价。 142 | ///@param ppInstrumentID 合约ID 143 | ///@param nCount 要订阅/退订行情的合约个数 144 | ///@remark 145 | virtual int SubscribeForQuoteRsp(char* ppInstrumentID[], int nCount) = 0; 146 | 147 | /// 退订询价。 148 | ///@param ppInstrumentID 合约ID 149 | ///@param nCount 要订阅/退订行情的合约个数 150 | ///@remark 151 | virtual int UnSubscribeForQuoteRsp(char* ppInstrumentID[], int nCount) = 0; 152 | 153 | /// 用户登录请求 154 | virtual int ReqUserLogin(CThostFtdcReqUserLoginField* pReqUserLoginField, int nRequestID) = 0; 155 | 156 | /// 登出请求 157 | virtual int ReqUserLogout(CThostFtdcUserLogoutField* pUserLogout, int nRequestID) = 0; 158 | 159 | /// 请求查询组播合约 160 | virtual int ReqQryMulticastInstrument(CThostFtdcQryMulticastInstrumentField* pQryMulticastInstrument, int nRequestID) = 0; 161 | 162 | protected: 163 | ~CThostFtdcMdApi() { }; 164 | }; 165 | 166 | #endif 167 | -------------------------------------------------------------------------------- /ctp_dyn/mdspi_base.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | package ctp_dyn 14 | 15 | import ( 16 | "github.com/pseudocodes/go2ctp/thost" 17 | ) 18 | 19 | var _ thost.MdSpi = &BaseMdSpi{} 20 | 21 | type BaseMdSpi struct { 22 | 23 | // 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 24 | OnFrontConnectedCallback func() 25 | 26 | // 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 27 | ///@param nReason 错误原因 28 | /// 0x1001 网络读失败 29 | /// 0x1002 网络写失败 30 | /// 0x2001 接收心跳超时 31 | /// 0x2002 发送心跳失败 32 | /// 0x2003 收到错误报文 33 | OnFrontDisconnectedCallback func(int) 34 | 35 | // 心跳超时警告。当长时间未收到报文时,该方法被调用。 36 | ///@param nTimeLapse 距离上次接收报文的时间 37 | OnHeartBeatWarningCallback func(int) 38 | 39 | // 登录请求响应 40 | OnRspUserLoginCallback func(*thost.CThostFtdcRspUserLoginField, *thost.CThostFtdcRspInfoField, int, bool) 41 | 42 | // 登出请求响应 43 | OnRspUserLogoutCallback func(*thost.CThostFtdcUserLogoutField, *thost.CThostFtdcRspInfoField, int, bool) 44 | 45 | // 请求查询组播合约响应 46 | OnRspQryMulticastInstrumentCallback func(*thost.CThostFtdcMulticastInstrumentField, *thost.CThostFtdcRspInfoField, int, bool) 47 | 48 | // 错误应答 49 | OnRspErrorCallback func(*thost.CThostFtdcRspInfoField, int, bool) 50 | 51 | // 订阅行情应答 52 | OnRspSubMarketDataCallback func(*thost.CThostFtdcSpecificInstrumentField, *thost.CThostFtdcRspInfoField, int, bool) 53 | 54 | // 取消订阅行情应答 55 | OnRspUnSubMarketDataCallback func(*thost.CThostFtdcSpecificInstrumentField, *thost.CThostFtdcRspInfoField, int, bool) 56 | 57 | // 订阅询价应答 58 | OnRspSubForQuoteRspCallback func(*thost.CThostFtdcSpecificInstrumentField, *thost.CThostFtdcRspInfoField, int, bool) 59 | 60 | // 取消订阅询价应答 61 | OnRspUnSubForQuoteRspCallback func(*thost.CThostFtdcSpecificInstrumentField, *thost.CThostFtdcRspInfoField, int, bool) 62 | 63 | // 深度行情通知 64 | OnRtnDepthMarketDataCallback func(*thost.CThostFtdcDepthMarketDataField) 65 | 66 | // 询价通知 67 | OnRtnForQuoteRspCallback func(*thost.CThostFtdcForQuoteRspField) 68 | } 69 | 70 | // 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 71 | func (s *BaseMdSpi) OnFrontConnected() { 72 | if s.OnFrontConnectedCallback != nil { 73 | s.OnFrontConnectedCallback() 74 | } 75 | } 76 | 77 | // 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 78 | // /@param nReason 错误原因 79 | // / 0x1001 网络读失败 80 | // / 0x1002 网络写失败 81 | // / 0x2001 接收心跳超时 82 | // / 0x2002 发送心跳失败 83 | // / 0x2003 收到错误报文 84 | func (s *BaseMdSpi) OnFrontDisconnected(nReason int) { 85 | if s.OnFrontDisconnectedCallback != nil { 86 | s.OnFrontDisconnectedCallback(nReason) 87 | } 88 | } 89 | 90 | // 心跳超时警告。当长时间未收到报文时,该方法被调用。 91 | // /@param nTimeLapse 距离上次接收报文的时间 92 | func (s *BaseMdSpi) OnHeartBeatWarning(nTimeLapse int) { 93 | if s.OnHeartBeatWarningCallback != nil { 94 | s.OnHeartBeatWarningCallback(nTimeLapse) 95 | } 96 | } 97 | 98 | // 登录请求响应 99 | func (s *BaseMdSpi) OnRspUserLogin(pRspUserLogin *thost.CThostFtdcRspUserLoginField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 100 | if s.OnRspUserLoginCallback != nil { 101 | s.OnRspUserLoginCallback(pRspUserLogin, pRspInfo, nRequestID, bIsLast) 102 | } 103 | } 104 | 105 | // 登出请求响应 106 | func (s *BaseMdSpi) OnRspUserLogout(pUserLogout *thost.CThostFtdcUserLogoutField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 107 | if s.OnRspUserLogoutCallback != nil { 108 | s.OnRspUserLogoutCallback(pUserLogout, pRspInfo, nRequestID, bIsLast) 109 | } 110 | } 111 | 112 | // 请求查询组播合约响应 113 | func (s *BaseMdSpi) OnRspQryMulticastInstrument(pMulticastInstrument *thost.CThostFtdcMulticastInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 114 | if s.OnRspQryMulticastInstrumentCallback != nil { 115 | s.OnRspQryMulticastInstrumentCallback(pMulticastInstrument, pRspInfo, nRequestID, bIsLast) 116 | } 117 | } 118 | 119 | // 错误应答 120 | func (s *BaseMdSpi) OnRspError(pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 121 | if s.OnRspErrorCallback != nil { 122 | s.OnRspErrorCallback(pRspInfo, nRequestID, bIsLast) 123 | } 124 | } 125 | 126 | // 订阅行情应答 127 | func (s *BaseMdSpi) OnRspSubMarketData(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 128 | if s.OnRspSubMarketDataCallback != nil { 129 | s.OnRspSubMarketDataCallback(pSpecificInstrument, pRspInfo, nRequestID, bIsLast) 130 | } 131 | } 132 | 133 | // 取消订阅行情应答 134 | func (s *BaseMdSpi) OnRspUnSubMarketData(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 135 | if s.OnRspUnSubMarketDataCallback != nil { 136 | s.OnRspUnSubMarketDataCallback(pSpecificInstrument, pRspInfo, nRequestID, bIsLast) 137 | } 138 | } 139 | 140 | // 订阅询价应答 141 | func (s *BaseMdSpi) OnRspSubForQuoteRsp(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 142 | if s.OnRspSubForQuoteRspCallback != nil { 143 | s.OnRspSubForQuoteRspCallback(pSpecificInstrument, pRspInfo, nRequestID, bIsLast) 144 | } 145 | } 146 | 147 | // 取消订阅询价应答 148 | func (s *BaseMdSpi) OnRspUnSubForQuoteRsp(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 149 | if s.OnRspUnSubForQuoteRspCallback != nil { 150 | s.OnRspUnSubForQuoteRspCallback(pSpecificInstrument, pRspInfo, nRequestID, bIsLast) 151 | } 152 | } 153 | 154 | // 深度行情通知 155 | func (s *BaseMdSpi) OnRtnDepthMarketData(pDepthMarketData *thost.CThostFtdcDepthMarketDataField) { 156 | if s.OnRtnDepthMarketDataCallback != nil { 157 | s.OnRtnDepthMarketDataCallback(pDepthMarketData) 158 | } 159 | } 160 | 161 | // 询价通知 162 | func (s *BaseMdSpi) OnRtnForQuoteRsp(pForQuoteRsp *thost.CThostFtdcForQuoteRspField) { 163 | if s.OnRtnForQuoteRspCallback != nil { 164 | s.OnRtnForQuoteRspCallback(pForQuoteRsp) 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /ctp/mdspi_base.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | package ctp 14 | 15 | import ( 16 | "github.com/pseudocodes/go2ctp/thost" 17 | ) 18 | 19 | var _ thost.MdSpi = &BaseMdSpi{} 20 | 21 | type BaseMdSpi struct { 22 | /// 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 23 | OnFrontConnectedCallback func() 24 | 25 | /// 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 26 | ///@param nReason 错误原因 27 | /// 0x1001 网络读失败 28 | /// 0x1002 网络写失败 29 | /// 0x2001 接收心跳超时 30 | /// 0x2002 发送心跳失败 31 | /// 0x2003 收到错误报文 32 | OnFrontDisconnectedCallback func(int) 33 | 34 | /// 心跳超时警告。当长时间未收到报文时,该方法被调用。 35 | ///@param nTimeLapse 距离上次接收报文的时间 36 | OnHeartBeatWarningCallback func(int) 37 | 38 | /// 登录请求响应 39 | OnRspUserLoginCallback func(*thost.CThostFtdcRspUserLoginField, *thost.CThostFtdcRspInfoField, int, bool) 40 | 41 | /// 登出请求响应 42 | OnRspUserLogoutCallback func(*thost.CThostFtdcUserLogoutField, *thost.CThostFtdcRspInfoField, int, bool) 43 | 44 | /// 请求查询组播合约响应 45 | OnRspQryMulticastInstrumentCallback func(*thost.CThostFtdcMulticastInstrumentField, *thost.CThostFtdcRspInfoField, int, bool) 46 | 47 | /// 错误应答 48 | OnRspErrorCallback func(*thost.CThostFtdcRspInfoField, int, bool) 49 | 50 | /// 订阅行情应答 51 | OnRspSubMarketDataCallback func(*thost.CThostFtdcSpecificInstrumentField, *thost.CThostFtdcRspInfoField, int, bool) 52 | 53 | /// 取消订阅行情应答 54 | OnRspUnSubMarketDataCallback func(*thost.CThostFtdcSpecificInstrumentField, *thost.CThostFtdcRspInfoField, int, bool) 55 | 56 | /// 订阅询价应答 57 | OnRspSubForQuoteRspCallback func(*thost.CThostFtdcSpecificInstrumentField, *thost.CThostFtdcRspInfoField, int, bool) 58 | 59 | /// 取消订阅询价应答 60 | OnRspUnSubForQuoteRspCallback func(*thost.CThostFtdcSpecificInstrumentField, *thost.CThostFtdcRspInfoField, int, bool) 61 | 62 | /// 深度行情通知 63 | OnRtnDepthMarketDataCallback func(*thost.CThostFtdcDepthMarketDataField) 64 | 65 | /// 询价通知 66 | OnRtnForQuoteRspCallback func(*thost.CThostFtdcForQuoteRspField) 67 | } 68 | 69 | // / 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 70 | func (s *BaseMdSpi) OnFrontConnected() { 71 | if s.OnFrontConnectedCallback != nil { 72 | s.OnFrontConnectedCallback() 73 | } 74 | } 75 | 76 | // / 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 77 | // /@param nReason 错误原因 78 | // / 0x1001 网络读失败 79 | // / 0x1002 网络写失败 80 | // / 0x2001 接收心跳超时 81 | // / 0x2002 发送心跳失败 82 | // / 0x2003 收到错误报文 83 | func (s *BaseMdSpi) OnFrontDisconnected(nReason int) { 84 | if s.OnFrontDisconnectedCallback != nil { 85 | s.OnFrontDisconnectedCallback(nReason) 86 | } 87 | } 88 | 89 | // / 心跳超时警告。当长时间未收到报文时,该方法被调用。 90 | // /@param nTimeLapse 距离上次接收报文的时间 91 | func (s *BaseMdSpi) OnHeartBeatWarning(nTimeLapse int) { 92 | if s.OnHeartBeatWarningCallback != nil { 93 | s.OnHeartBeatWarningCallback(nTimeLapse) 94 | } 95 | } 96 | 97 | // / 登录请求响应 98 | func (s *BaseMdSpi) OnRspUserLogin(pRspUserLogin *thost.CThostFtdcRspUserLoginField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 99 | if s.OnRspUserLoginCallback != nil { 100 | s.OnRspUserLoginCallback(pRspUserLogin, pRspInfo, nRequestID, bIsLast) 101 | } 102 | } 103 | 104 | // / 登出请求响应 105 | func (s *BaseMdSpi) OnRspUserLogout(pUserLogout *thost.CThostFtdcUserLogoutField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 106 | if s.OnRspUserLogoutCallback != nil { 107 | s.OnRspUserLogoutCallback(pUserLogout, pRspInfo, nRequestID, bIsLast) 108 | } 109 | } 110 | 111 | // / 请求查询组播合约响应 112 | func (s *BaseMdSpi) OnRspQryMulticastInstrument(pMulticastInstrument *thost.CThostFtdcMulticastInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 113 | if s.OnRspQryMulticastInstrumentCallback != nil { 114 | s.OnRspQryMulticastInstrumentCallback(pMulticastInstrument, pRspInfo, nRequestID, bIsLast) 115 | } 116 | } 117 | 118 | // / 错误应答 119 | func (s *BaseMdSpi) OnRspError(pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 120 | if s.OnRspErrorCallback != nil { 121 | s.OnRspErrorCallback(pRspInfo, nRequestID, bIsLast) 122 | } 123 | } 124 | 125 | // / 订阅行情应答 126 | func (s *BaseMdSpi) OnRspSubMarketData(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 127 | if s.OnRspSubMarketDataCallback != nil { 128 | s.OnRspSubMarketDataCallback(pSpecificInstrument, pRspInfo, nRequestID, bIsLast) 129 | } 130 | } 131 | 132 | // / 取消订阅行情应答 133 | func (s *BaseMdSpi) OnRspUnSubMarketData(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 134 | if s.OnRspUnSubMarketDataCallback != nil { 135 | s.OnRspUnSubMarketDataCallback(pSpecificInstrument, pRspInfo, nRequestID, bIsLast) 136 | } 137 | } 138 | 139 | // / 订阅询价应答 140 | func (s *BaseMdSpi) OnRspSubForQuoteRsp(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 141 | if s.OnRspSubForQuoteRspCallback != nil { 142 | s.OnRspSubForQuoteRspCallback(pSpecificInstrument, pRspInfo, nRequestID, bIsLast) 143 | } 144 | } 145 | 146 | // / 取消订阅询价应答 147 | func (s *BaseMdSpi) OnRspUnSubForQuoteRsp(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 148 | if s.OnRspUnSubForQuoteRspCallback != nil { 149 | s.OnRspUnSubForQuoteRspCallback(pSpecificInstrument, pRspInfo, nRequestID, bIsLast) 150 | } 151 | } 152 | 153 | // / 深度行情通知 154 | func (s *BaseMdSpi) OnRtnDepthMarketData(pDepthMarketData *thost.CThostFtdcDepthMarketDataField) { 155 | if s.OnRtnDepthMarketDataCallback != nil { 156 | s.OnRtnDepthMarketDataCallback(pDepthMarketData) 157 | } 158 | } 159 | 160 | // / 询价通知 161 | func (s *BaseMdSpi) OnRtnForQuoteRsp(pForQuoteRsp *thost.CThostFtdcForQuoteRspField) { 162 | if s.OnRtnForQuoteRspCallback != nil { 163 | s.OnRtnForQuoteRspCallback(pForQuoteRsp) 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /sample/simple_market/main.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | package main 14 | 15 | import ( 16 | "log" 17 | "os" 18 | "runtime" 19 | "time" 20 | 21 | "github.com/pseudocodes/go2ctp/ctp" 22 | "github.com/pseudocodes/go2ctp/ctp_dyn" 23 | "github.com/pseudocodes/go2ctp/thost" 24 | ) 25 | 26 | /* 27 | Simnow是上期技术提供的CTP程序测试、模拟、学习的模拟平台。 28 | 2025.06.19 收盘后环境 29 | 7x24环境: 30 | 交易前置: tcp://182.254.243.31:40001 31 | 行情前置: tcp://182.254.243.31:40011 32 | 33 | 仿真环境1:交易时段同实盘 34 | 交易前置: tcp://182.254.243.31:30001 35 | 行情前置: tcp://182.254.243.31:30011 36 | 37 | 仿真环境2:交易时段同实盘 38 | 交易前置: tcp://182.254.243.31:30002 39 | 行情前置: tcp://182.254.243.31:30012 40 | 41 | 仿真环境3:交易时段同实盘 42 | 交易前置: tcp://182.254.243.31:30003 43 | 行情前置: tcp://182.254.243.31:30013 44 | */ 45 | var SimnowEnv map[string]map[string]string = map[string]map[string]string{ 46 | "td": { 47 | "7x24": "tcp://182.254.243.31:40001", 48 | "sim1": "tcp://182.254.243.31:30001", 49 | "sim2": "tcp://182.254.243.31:30002", 50 | "sim3": "tcp://182.254.243.31:30003", 51 | }, 52 | "md": { 53 | "7x24": "tcp://182.254.243.31:40011", 54 | "sim1": "tcp://182.254.243.31:30011", 55 | "sim2": "tcp://182.254.243.31:30012", 56 | "sim3": "tcp://182.254.243.31:30013", 57 | }, 58 | } 59 | 60 | func init() { 61 | log.SetFlags(log.LstdFlags | log.Lshortfile) 62 | } 63 | 64 | type baseSpi struct { 65 | ctp_dyn.BaseMdSpi 66 | // ctp.BaseMdSpi 67 | mdapi thost.MdApi 68 | } 69 | 70 | func CreateBaseSpi() *baseSpi { 71 | s := &baseSpi{} 72 | return s 73 | } 74 | 75 | func (s *baseSpi) OnFrontConnected() { 76 | log.Printf("OnFrontConnected\n") 77 | 78 | loginR := &thost.CThostFtdcReqUserLoginField{} 79 | copy(loginR.BrokerID[:], "9999") 80 | copy(loginR.UserID[:], os.Getenv("SIMNOW_USER_ID")) 81 | 82 | ret := s.mdapi.ReqUserLogin(loginR, 1) 83 | 84 | log.Printf("user log: %v\n", ret) 85 | } 86 | 87 | func (s *baseSpi) OnHeartBeatWarning(timelapse int) { 88 | log.Printf("OnHeartBeatWarning: %v\n", timelapse) 89 | } 90 | 91 | func (s *baseSpi) OnFrontDisconnected(nReason int) { 92 | log.Printf("OnFrontDisconnected: %v\n", nReason) 93 | } 94 | 95 | func (s *baseSpi) OnRspUserLogin(pRspUserLogin *thost.CThostFtdcRspUserLoginField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 96 | log.Printf("RspUserLogin: %+v\nRspInfo: %+v\n", pRspUserLogin, nil) 97 | log.Println(s.mdapi.GetTradingDay()) 98 | s.mdapi.SubscribeMarketData("ag2512") 99 | } 100 | 101 | func (s *baseSpi) OnRspSubMarketData(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 102 | 103 | log.Printf("instrumentID: %+v\n RspInfo: %+v\n", pSpecificInstrument, nil) 104 | } 105 | 106 | func (s *baseSpi) OnRtnDepthMarketData(pDepthMarketData *thost.CThostFtdcDepthMarketDataField) { 107 | log.Printf("OnRtnDeptMarketData: %s UpdateTime: %s, UpdateMillisec: %d\n", string(pDepthMarketData.InstrumentID[:7]), pDepthMarketData.UpdateTime.String(), pDepthMarketData.UpdateMillisec) 108 | } 109 | 110 | func (s *baseSpi) OnRspError(pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 111 | log.Printf("RspInfo: %+v\n", pRspInfo.ErrorID) 112 | } 113 | 114 | type baseSpi2 struct { 115 | ctp.BaseMdSpi 116 | mdapi thost.MdApi 117 | } 118 | 119 | func CreateBaseSpi2() *baseSpi2 { 120 | s := &baseSpi2{} 121 | 122 | s.OnFrontConnectedCallback = func() { 123 | log.Printf("OnFrontConnected\n") 124 | 125 | loginR := &thost.CThostFtdcReqUserLoginField{} 126 | copy(loginR.BrokerID[:], "9999") 127 | copy(loginR.UserID[:], os.Getenv("SIMNOW_USER_ID")) 128 | 129 | ret := s.mdapi.ReqUserLogin(loginR, 1) 130 | 131 | log.Printf("user log: %v\n", ret) 132 | } 133 | s.OnFrontDisconnectedCallback = func(nReason int) { 134 | log.Printf("OnFrontDisconnected: %v\n", nReason) 135 | } 136 | s.OnRspUserLoginCallback = func(pRspUserLogin *thost.CThostFtdcRspUserLoginField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 137 | log.Printf("RspUserLogin: %+v\nRspInfo: %+v\n", pRspUserLogin, nil) 138 | log.Println(s.mdapi.GetTradingDay()) 139 | s.mdapi.SubscribeMarketData("ag2512") 140 | } 141 | s.OnRtnDepthMarketDataCallback = func(pDepthMarketData *thost.CThostFtdcDepthMarketDataField) { 142 | // log.Printf("tick {%+v}\n", quote) 143 | log.Printf("OnRtnDeptMarketData 222\n") 144 | } 145 | return s 146 | 147 | } 148 | 149 | var ( 150 | CTPLibPathLinux = "../../ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64/thostmduserapi_se.so" 151 | CTPLibPathMacos = "../../ctp/lib/v6.7.7_MacOS_20240716/thostmduserapi_se.framework/Versions/A/thostmduserapi_se" 152 | 153 | // TTSLibPathDarwin = "This/Is/Sample/PathToOpenCTP.dylib" 154 | // TTSLibPathLinux = "This/Is/Sample/PathToOpenCTP.so" 155 | 156 | TTSFront = "tcp://trading.openctp.cn:30011" 157 | SimnowFront = SimnowEnv["md"]["7x24"] 158 | // SimnowFront = SimnowEnv["md"]["sim1"] 159 | ) 160 | 161 | func sample1() { 162 | var ( 163 | mdapi thost.MdApi 164 | frontAddr string 165 | ) 166 | 167 | if runtime.GOOS == "darwin" { 168 | mdapi = ctp_dyn.CreateMdApi(ctp_dyn.MdDynamicLibPath(CTPLibPathMacos), ctp_dyn.MdFlowPath("./data/"), ctp_dyn.MdUsingUDP(false), ctp_dyn.MdMultiCast(false)) 169 | 170 | // frontAddr = TTSFront 171 | frontAddr = SimnowFront 172 | 173 | } else if runtime.GOOS == "linux" { 174 | // mdapi = ctp_dyn.CreateMdApi(ctp_dyn.MdDynamicLibPath(TTSLibPathLinux), ctp_dyn.MdFlowPath("./data/"), ctp_dyn.MdUsingUDP(false), ctp_dyn.MdMultiCast(false)) 175 | mdapi = ctp_dyn.CreateMdApi(ctp_dyn.MdDynamicLibPath(CTPLibPathLinux), ctp_dyn.MdFlowPath("./data/"), ctp_dyn.MdUsingUDP(false), ctp_dyn.MdMultiCast(false)) 176 | // frontAddr = TTSFront 177 | frontAddr = SimnowFront 178 | 179 | } 180 | log.Printf("frontAddr: %s\n", frontAddr) 181 | 182 | baseSpi := CreateBaseSpi() 183 | baseSpi.mdapi = mdapi 184 | mdapi.RegisterSpi(baseSpi) 185 | 186 | mdapi.RegisterFront(frontAddr) 187 | 188 | mdapi.Init() 189 | 190 | println(mdapi.GetApiVersion()) 191 | 192 | // mdapi.Join() 193 | for { 194 | time.Sleep(10 * time.Second) 195 | } 196 | 197 | } 198 | 199 | func sample2() { 200 | mdapi := ctp.CreateMdApi(ctp.MdFlowPath("./data/"), ctp.MdUsingUDP(false), ctp.MdMultiCast(false)) 201 | baseSpi2 := CreateBaseSpi2() 202 | baseSpi2.mdapi = mdapi 203 | mdapi.RegisterSpi(baseSpi2) 204 | 205 | // mdapi.RegisterFront("tcp://140.206.244.33:11616") 206 | // mdapi.RegisterFront("tcp://182.254.243.31:40011") 207 | mdapi.RegisterFront(SimnowEnv["md"]["sim1"]) 208 | 209 | mdapi.Init() 210 | 211 | println(mdapi.GetTradingDay()) 212 | println(mdapi.GetApiVersion()) 213 | 214 | mdapi.Join() 215 | // for { 216 | // time.Sleep(10 * time.Second) 217 | // } 218 | 219 | } 220 | 221 | func main() { 222 | sample1() 223 | // sample2() 224 | } 225 | -------------------------------------------------------------------------------- /sample/simple_trader/main.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | package main 14 | 15 | import ( 16 | "bytes" 17 | "log" 18 | "os" 19 | "runtime" 20 | "strings" 21 | "sync/atomic" 22 | "time" 23 | 24 | "github.com/gookit/goutil/dump" 25 | "github.com/pseudocodes/go2ctp/ctp" 26 | "github.com/pseudocodes/go2ctp/ctp_dyn" 27 | "github.com/pseudocodes/go2ctp/thost" 28 | "golang.org/x/text/encoding/simplifiedchinese" 29 | ) 30 | 31 | var SimnowEnv map[string]map[string]string = map[string]map[string]string{ 32 | "td": { 33 | "7x24": "tcp://182.254.243.31:40001", 34 | "sim1": "tcp://182.254.243.31:30001", 35 | "sim2": "tcp://182.254.243.31:30002", 36 | "sim3": "tcp://182.254.243.31:30003", 37 | }, 38 | "md": { 39 | "7x24": "tcp://182.254.243.31:40011", 40 | "sim1": "tcp://182.254.243.31:30011", 41 | "sim2": "tcp://182.254.243.31:30012", 42 | "sim3": "tcp://182.254.243.31:30013", 43 | }, 44 | } 45 | 46 | func init() { 47 | log.SetFlags(log.LstdFlags | log.Lshortfile) 48 | } 49 | 50 | type baseSpi struct { 51 | brokerID string 52 | investorID string 53 | password string 54 | appid string 55 | authCode string 56 | 57 | requestID atomic.Int32 58 | 59 | ctp.BaseTraderSpi 60 | tdapi thost.TraderApi 61 | } 62 | 63 | func CreateBaseSpi() *baseSpi { 64 | 65 | s := &baseSpi{ 66 | // tdapi: tdapi, 67 | brokerID: "9999", 68 | investorID: os.Getenv("SIMNOW_USER_ID"), // <- 环境变量设置 69 | password: os.Getenv("SIMNOW_USER_PASSWORD"), // <- 环境变量设置 70 | 71 | appid: "simnow_client_test", 72 | authCode: "0000000000000000", 73 | } 74 | 75 | if len(s.investorID) == 0 || len(s.password) == 0 { 76 | panic("investorID or password is empty") 77 | } 78 | return s 79 | } 80 | 81 | func (s *baseSpi) OnFrontDisconnected(nReason int) { 82 | log.Printf("OnFrontDissconnected: %v\n", nReason) 83 | } 84 | 85 | func (p *baseSpi) OnHeartBeatWarning(nTimeLapse int) { 86 | log.Println("(OnHeartBeatWarning) nTimerLapse=", nTimeLapse) 87 | } 88 | 89 | func (s *baseSpi) OnFrontConnected() { 90 | var ret int 91 | log.Printf("OnFrontConnected\n") 92 | req := &thost.CThostFtdcReqAuthenticateField{} 93 | copy(req.BrokerID[:], []byte(s.brokerID)) 94 | copy(req.UserID[:], []byte(s.investorID)) 95 | copy(req.AppID[:], []byte(s.appid)) 96 | copy(req.AuthCode[:], []byte(s.authCode)) 97 | ret = s.tdapi.ReqAuthenticate(req, int(s.requestID.Add(1))) 98 | 99 | log.Printf("user auth: %v\n", ret) 100 | } 101 | 102 | func (s *baseSpi) OnRspAuthenticate(pRspAuthenticateField *thost.CThostFtdcRspAuthenticateField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 103 | req := &thost.CThostFtdcReqUserLoginField{} 104 | copy(req.BrokerID[:], []byte(s.brokerID)) 105 | copy(req.UserID[:], []byte(s.investorID)) 106 | copy(req.Password[:], []byte(s.password)) 107 | 108 | ret := s.tdapi.ReqUserLogin(req, int(s.requestID.Add(1))) 109 | log.Printf("user login: %v\n", ret) 110 | } 111 | 112 | func (s *baseSpi) OnRspUserLogin(pRspUserLogin *thost.CThostFtdcRspUserLoginField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 113 | if s.isErrorRspInfo(pRspInfo) { 114 | return 115 | } 116 | 117 | req := &thost.CThostFtdcSettlementInfoConfirmField{} 118 | copy(req.BrokerID[:], []byte(s.brokerID)) 119 | copy(req.InvestorID[:], []byte(s.investorID)) 120 | 121 | ret := s.tdapi.ReqSettlementInfoConfirm(req, int(s.requestID.Add(1))) 122 | log.Printf("req_settlement_info_confirm : %v\n", ret) 123 | 124 | } 125 | 126 | // OnRspSettlementInfoConfirm 发送投资者结算单确认响应 127 | func (s *baseSpi) OnRspSettlementInfoConfirm(pSettlementInfoConfirm *thost.CThostFtdcSettlementInfoConfirmField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 128 | 129 | if bIsLast && !s.isErrorRspInfo(pRspInfo) { 130 | req := &thost.CThostFtdcQryTradingAccountField{} 131 | copy(req.BrokerID[:], []byte(s.brokerID)) 132 | copy(req.InvestorID[:], []byte(s.investorID)) 133 | ret := s.tdapi.ReqQryTradingAccount(req, int(s.requestID.Add(1))) 134 | if ret != 0 { 135 | log.Printf("req_qry_trading_account failed %v\n", ret) 136 | } 137 | } 138 | 139 | } 140 | 141 | func (s *baseSpi) OnRspQryInstrument(pInstrument *thost.CThostFtdcInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 142 | } 143 | 144 | // OnRspQryTradingAccount 请求查询资金账户响应 145 | func (s *baseSpi) OnRspQryTradingAccount(pTradingAccount *thost.CThostFtdcTradingAccountField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 146 | if bIsLast && !s.isErrorRspInfo(pRspInfo) { 147 | accountID := bytesToString2(pTradingAccount.AccountID[:]) 148 | balance := pTradingAccount.Balance 149 | log.Printf("Account[%v] Balance[%.2f]\n", accountID, balance) 150 | 151 | req := &thost.CThostFtdcQryInstrumentCommissionRateField{} 152 | copy(req.BrokerID[:], "9999") 153 | copy(req.InstrumentID[:], "ag2512") 154 | 155 | ret := s.tdapi.ReqQryInstrumentCommissionRate(req, int(s.requestID.Add(1))) 156 | if ret != 0 { 157 | log.Printf("req_qry_ins_commission_rate failed: %v\n", ret) 158 | } 159 | } 160 | } 161 | 162 | func (s *baseSpi) OnRspQryInstrumentCommissionRate(pInstrumentCommissionRate *thost.CThostFtdcInstrumentCommissionRateField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 163 | if s.isErrorRspInfo(pRspInfo) { 164 | return 165 | } 166 | if pInstrumentCommissionRate != nil { 167 | dump.P(pInstrumentCommissionRate.OpenRatioByMoney) 168 | } 169 | if bIsLast { 170 | log.Println("last") 171 | req := &thost.CThostFtdcQryClassifiedInstrumentField{ 172 | TradingType: thost.THOST_FTDC_TD_TRADE, 173 | ClassType: thost.THOST_FTDC_INS_FUTURE, 174 | } 175 | copy(req.InstrumentID[:], "ag2512") 176 | 177 | ret := s.tdapi.ReqQryClassifiedInstrument(req, int(s.requestID.Add(1))) 178 | if ret != 0 { 179 | log.Printf("req_qry_classifyed_instrument failed: %v\n", ret) 180 | } 181 | } 182 | } 183 | 184 | // // 合约交易状态通知 185 | // func (s *baseSpi) OnRtnInstrumentStatus(pInstrumentStatus *goctp.InstrumentStatusField) { 186 | // // dump.P(pInstrumentStatus) 187 | // } 188 | 189 | // func (s *baseSpi) OnRspQryOrder(pOrder *goctp.OrderField, pRspInfo *goctp.RspInfoField, nRequestID int, bIsLast bool) { 190 | 191 | // } 192 | 193 | // func (s *baseSpi) OnRspQryInvestorPosition(pInvestorPosition *goctp.InvestorPositionField, pRspInfo *goctp.RspInfoField, nRequestID int, bIsLast bool) { 194 | 195 | // } 196 | 197 | // 错误应答 198 | func (s *baseSpi) OnRspError(pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 199 | s.isErrorRspInfo(pRspInfo) 200 | } 201 | 202 | // 请求查询分类合约响应 203 | func (s *baseSpi) OnRspQryClassifiedInstrument(pInstrument *thost.CThostFtdcInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 204 | if s.isErrorRspInfo(pRspInfo) { 205 | return 206 | } 207 | ins := bytesToString2(pInstrument.InstrumentID[:]) 208 | log.Printf("[%s] prictick[%v] create_date[%s] open_date[%s] expire_date[%s] long_margin_ratio %.2f\n", 209 | ins, pInstrument.PriceTick, 210 | bytesToString2(pInstrument.CreateDate[:]), 211 | bytesToString2(pInstrument.OpenDate[:]), 212 | bytesToString2(pInstrument.ExpireDate[:]), 213 | pInstrument.LongMarginRatio, 214 | ) 215 | } 216 | 217 | // // 报单操作错误回报 218 | // func (s *baseSpi) OnErrRtnOrderAction(pOrderAction *goctp.OrderActionField, pRspInfo *goctp.RspInfoField) { 219 | // s.isErrorRspInfo(pRspInfo) 220 | // } 221 | 222 | // // 报单操作请求响应(撤单失败会触发) 223 | // func (s *baseSpi) OnRspOrderAction(pInputOrderAction *goctp.InputOrderActionField, pRspInfo *goctp.RspInfoField, nRequestID int, bIsLast bool) { 224 | // s.isErrorRspInfo(pRspInfo) 225 | // } 226 | 227 | // OnRtnTrade 成交通知(委托单在交易所成交了) 228 | func (s *baseSpi) OnRtnTrade(pTrade *thost.CThostFtdcTradeField) { 229 | } 230 | 231 | // OnRtnOrder 报单通知(委托单) 232 | func (s *baseSpi) OnRtnOrder(pOrder *thost.CThostFtdcOrderField) { 233 | 234 | } 235 | 236 | func (s *baseSpi) isErrorRspInfo(pRspInfo *thost.CThostFtdcRspInfoField) bool { 237 | 238 | // 容错处理 pRspInfo ,部分响应函数中,pRspInfo 为 0 239 | if pRspInfo == nil { 240 | return false 241 | } 242 | // 如果ErrorID != 0, 说明收到了错误的响应 243 | bResult := (pRspInfo.ErrorID != 0) 244 | if bResult { 245 | log.Printf("ErrorID=%v ErrorMsg=%v\n", pRspInfo.ErrorID, Bytes2StringGBK(pRspInfo.ErrorMsg[:])) 246 | } 247 | return bResult 248 | 249 | } 250 | 251 | func bytesToString2(b []byte) string { 252 | before, _, _ := bytes.Cut(b, []byte{'\x00'}) 253 | if len(before) > 0 { 254 | return string(before) 255 | } 256 | return "" 257 | } 258 | 259 | func Bytes2StringGBK(t []byte) string { 260 | msg, _ := simplifiedchinese.GB18030.NewDecoder().Bytes(bytes.Split(t, []byte{'\x00'})[0]) 261 | return strings.Trim(string(msg), "\u0000") 262 | } 263 | 264 | var ( 265 | CTPLibPathLinux = "../../ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64/thosttraderapi_se.so" 266 | CTPLibPathMacos = "../../ctp/lib/v6.7.7_MacOS_20240716/thosttraderapi_se.framework/Versions/A/thosttraderapi_se" 267 | ) 268 | 269 | func sample1() { 270 | var tdapi thost.TraderApi 271 | if runtime.GOOS == "darwin" { 272 | tdapi = ctp_dyn.CreateTraderApi(ctp_dyn.TraderDynamicLibPath(CTPLibPathMacos), ctp_dyn.TraderFlowPath("./data/")) 273 | 274 | } else if runtime.GOOS == "linux" { 275 | tdapi = ctp_dyn.CreateTraderApi(ctp_dyn.TraderDynamicLibPath(CTPLibPathLinux), ctp_dyn.TraderFlowPath("./data/")) 276 | } 277 | 278 | baseSpi := CreateBaseSpi() 279 | baseSpi.tdapi = tdapi 280 | 281 | tdapi.RegisterSpi(baseSpi) 282 | // tdapi.RegisterFront("tcp://121.37.90.193:20002") 283 | tdapi.RegisterFront(SimnowEnv["td"]["sim1"]) 284 | // tdapi.RegisterFront(SimnowEnv["td"]["7x24"]) 285 | 286 | tdapi.Init() 287 | 288 | println(tdapi.GetApiVersion()) 289 | 290 | tdapi.Join() 291 | select {} 292 | } 293 | 294 | func sample2() { 295 | 296 | tdapi := ctp.CreateTraderApi(ctp.TraderFlowPath("./data/td_")) 297 | baseSpi := CreateBaseSpi() 298 | baseSpi.tdapi = tdapi 299 | 300 | tdapi.RegisterSpi(baseSpi) 301 | 302 | // tdapi.RegisterFront(SimnowEnv["td"]["7x24"]) 303 | tdapi.RegisterFront(SimnowEnv["td"]["sim1"]) 304 | 305 | tdapi.Init() 306 | time.Sleep(time.Second) 307 | // frontInfo := &thost.CThostFtdcFrontInfoField{} 308 | // tdapi.GetFrontInfo(frontInfo) 309 | 310 | // dump.V(frontInfo.FrontAddr.String()) 311 | // dump.V(frontInfo.QryFreq) 312 | println(tdapi.GetTradingDay()) 313 | println(tdapi.GetApiVersion()) 314 | 315 | tdapi.Join() 316 | 317 | } 318 | 319 | func main() { 320 | sample1() 321 | // sample2() 322 | } 323 | -------------------------------------------------------------------------------- /ctp/mdapi_wrap.cxx: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include "mdapi_wrap.h" 23 | 24 | typedef long long intgo; 25 | typedef struct 26 | { 27 | char* p; 28 | int64_t n; 29 | } _gostring_; 30 | 31 | typedef struct 32 | { 33 | void* array; 34 | int64_t len; 35 | int64_t cap; 36 | } _goslice_; 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | QCTPMdSpi* _wrap_CThostFtdcMdApi_CreateFtdcMdApi() 42 | { 43 | CThostFtdcMdApi* pUserApi = CThostFtdcMdApi::CreateFtdcMdApi("./data/", false); 44 | QCTPMdSpi* pUserSpi = new QCTPMdSpi(pUserApi); 45 | pUserSpi->RegisterSpi(pUserSpi); 46 | return pUserSpi; 47 | } 48 | 49 | QCTPMdSpi* _wrap_CThostFtdcMdApi_CreateFtdcMdApi2(uintptr_t gUserApi, const char* pszFlowPath, const bool bIsUsingUdp, const bool bIsMulticast, bool bIsProductionMode) 50 | { 51 | // printf("go_user_api %lu\n", gUserApi); 52 | CThostFtdcMdApi* pUserApi = CThostFtdcMdApi::CreateFtdcMdApi(pszFlowPath, bIsUsingUdp, bIsMulticast, bIsProductionMode); 53 | QCTPMdSpi* pUserSpi = new QCTPMdSpi(pUserApi, gUserApi); 54 | pUserSpi->RegisterSpi(pUserSpi); 55 | return pUserSpi; 56 | } 57 | 58 | const char* _wrap_CThostFtdcMdApi_GetApiVersion(QCTPMdSpi* ptr) 59 | { 60 | return ptr->GetApiVersion(); 61 | } 62 | 63 | void _wrap_CThostFtdcMdApi_Release(QCTPMdSpi* ptr) 64 | { 65 | return ptr->Release(); 66 | } 67 | 68 | void _wrap_CThostFtdcMdApi_Init(QCTPMdSpi* ptr) 69 | { 70 | return ptr->Init(); 71 | } 72 | 73 | int _wrap_CThostFtdcMdApi_Join(QCTPMdSpi* ptr) 74 | { 75 | return ptr->Join(); 76 | } 77 | 78 | const char* _wrap_CThostFtdcMdApi_GetTradingDay(QCTPMdSpi* ptr) 79 | { 80 | return ptr->GetTradingDay(); 81 | } 82 | 83 | void _wrap_CThostFtdcMdApi_RegisterFront(QCTPMdSpi* ptr, char* pszFrontAddress) 84 | { 85 | return ptr->RegisterFront(pszFrontAddress); 86 | } 87 | 88 | void _wrap_CThostFtdcMdApi_RegisterNameServer(QCTPMdSpi* ptr, char* pszNsAddress) 89 | { 90 | return ptr->RegisterNameServer(pszNsAddress); 91 | } 92 | 93 | void _wrap_CThostFtdcMdApi_RegisterFensUserInfo(QCTPMdSpi* ptr, CThostFtdcFensUserInfoField* pFensUserInfo) 94 | { 95 | return ptr->RegisterFensUserInfo(pFensUserInfo); 96 | } 97 | 98 | void _wrap_CThostFtdcMdApi_RegisterSpi(QCTPMdSpi* ptr, CThostFtdcMdSpi* pSpi) 99 | { 100 | return ptr->RegisterSpi(pSpi); 101 | } 102 | 103 | int _wrap_CThostFtdcMdApi_SubscribeMarketData(QCTPMdSpi* ptr, char** ppInstrumentID, int nCount) 104 | { 105 | return ptr->SubscribeMarketData(ppInstrumentID, nCount); 106 | } 107 | 108 | int _wrap_CThostFtdcMdApi_UnSubscribeMarketData(QCTPMdSpi* ptr, char** ppInstrumentID, int nCount) 109 | { 110 | return ptr->UnSubscribeMarketData(ppInstrumentID, nCount); 111 | } 112 | 113 | int _wrap_CThostFtdcMdApi_SubscribeForQuoteRsp(QCTPMdSpi* ptr, char** ppInstrumentID, int nCount) 114 | { 115 | return ptr->SubscribeForQuoteRsp(ppInstrumentID, nCount); 116 | } 117 | 118 | int _wrap_CThostFtdcMdApi_UnSubscribeForQuoteRsp(QCTPMdSpi* ptr, char** ppInstrumentID, int nCount) 119 | { 120 | return ptr->UnSubscribeForQuoteRsp(ppInstrumentID, nCount); 121 | } 122 | 123 | int _wrap_CThostFtdcMdApi_ReqUserLogin(QCTPMdSpi* ptr, CThostFtdcReqUserLoginField* pReqUserLoginField, int nRequestID) 124 | { 125 | return ptr->ReqUserLogin(pReqUserLoginField, nRequestID); 126 | } 127 | 128 | int _wrap_CThostFtdcMdApi_ReqUserLogout(QCTPMdSpi* ptr, CThostFtdcUserLogoutField* pUserLogout, int nRequestID) 129 | { 130 | return ptr->ReqUserLogout(pUserLogout, nRequestID); 131 | } 132 | 133 | int _wrap_CThostFtdcMdApi_ReqQryMulticastInstrument(QCTPMdSpi* ptr, CThostFtdcQryMulticastInstrumentField* pQryMulticastInstrument, int nRequestID) 134 | { 135 | return ptr->ReqQryMulticastInstrument(pQryMulticastInstrument, nRequestID); 136 | } 137 | 138 | #ifdef __cplusplus 139 | } 140 | #endif 141 | 142 | extern "C" void wrapMdOnFrontConnected(uintptr_t); 143 | void QCTPMdSpi::OnFrontConnected() 144 | { 145 | wrapMdOnFrontConnected(gUserApi); 146 | } 147 | 148 | extern "C" void wrapMdOnFrontDisconnected(uintptr_t, int); 149 | void QCTPMdSpi::OnFrontDisconnected(int nReason) 150 | { 151 | wrapMdOnFrontDisconnected(gUserApi, nReason); 152 | } 153 | 154 | extern "C" void wrapMdOnHeartBeatWarning(uintptr_t, int); 155 | void QCTPMdSpi::OnHeartBeatWarning(int nTimeLapse) 156 | { 157 | wrapMdOnHeartBeatWarning(gUserApi, nTimeLapse); 158 | } 159 | 160 | extern "C" void wrapMdOnRspUserLogin(uintptr_t, CThostFtdcRspUserLoginField*, CThostFtdcRspInfoField*, int, bool); 161 | void QCTPMdSpi::OnRspUserLogin(CThostFtdcRspUserLoginField* pRspUserLogin, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 162 | { 163 | wrapMdOnRspUserLogin(gUserApi, pRspUserLogin, pRspInfo, nRequestID, bIsLast); 164 | } 165 | 166 | extern "C" void wrapMdOnRspUserLogout(uintptr_t, CThostFtdcUserLogoutField*, CThostFtdcRspInfoField*, int, bool); 167 | void QCTPMdSpi::OnRspUserLogout(CThostFtdcUserLogoutField* pUserLogout, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 168 | { 169 | wrapMdOnRspUserLogout(gUserApi, pUserLogout, pRspInfo, nRequestID, bIsLast); 170 | } 171 | 172 | extern "C" void wrapMdOnRspQryMulticastInstrument(uintptr_t, CThostFtdcMulticastInstrumentField*, CThostFtdcRspInfoField*, int, bool); 173 | void QCTPMdSpi::OnRspQryMulticastInstrument(CThostFtdcMulticastInstrumentField* pMulticastInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 174 | { 175 | wrapMdOnRspQryMulticastInstrument(gUserApi, pMulticastInstrument, pRspInfo, nRequestID, bIsLast); 176 | } 177 | 178 | extern "C" void wrapMdOnRspError(uintptr_t, CThostFtdcRspInfoField*, int, bool); 179 | void QCTPMdSpi::OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 180 | { 181 | wrapMdOnRspError(gUserApi, pRspInfo, nRequestID, bIsLast); 182 | } 183 | 184 | extern "C" void wrapMdOnRspSubMarketData(uintptr_t, CThostFtdcSpecificInstrumentField*, CThostFtdcRspInfoField*, int, bool); 185 | void QCTPMdSpi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 186 | { 187 | wrapMdOnRspSubMarketData(gUserApi, pSpecificInstrument, pRspInfo, nRequestID, bIsLast); 188 | } 189 | 190 | extern "C" void wrapMdOnRspUnSubMarketData(uintptr_t, CThostFtdcSpecificInstrumentField*, CThostFtdcRspInfoField*, int, bool); 191 | void QCTPMdSpi::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 192 | { 193 | wrapMdOnRspUnSubMarketData(gUserApi, pSpecificInstrument, pRspInfo, nRequestID, bIsLast); 194 | } 195 | 196 | extern "C" void wrapMdOnRspSubForQuoteRsp(uintptr_t, CThostFtdcSpecificInstrumentField*, CThostFtdcRspInfoField*, int, bool); 197 | void QCTPMdSpi::OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 198 | { 199 | wrapMdOnRspSubForQuoteRsp(gUserApi, pSpecificInstrument, pRspInfo, nRequestID, bIsLast); 200 | } 201 | 202 | extern "C" void wrapMdOnRspUnSubForQuoteRsp(uintptr_t, CThostFtdcSpecificInstrumentField*, CThostFtdcRspInfoField*, int, bool); 203 | void QCTPMdSpi::OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 204 | { 205 | wrapMdOnRspUnSubForQuoteRsp(gUserApi, pSpecificInstrument, pRspInfo, nRequestID, bIsLast); 206 | } 207 | 208 | extern "C" void wrapMdOnRtnDepthMarketData(uintptr_t, CThostFtdcDepthMarketDataField*); 209 | void QCTPMdSpi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField* pDepthMarketData) 210 | { 211 | wrapMdOnRtnDepthMarketData(gUserApi, pDepthMarketData); 212 | } 213 | 214 | extern "C" void wrapMdOnRtnForQuoteRsp(uintptr_t, CThostFtdcForQuoteRspField*); 215 | void QCTPMdSpi::OnRtnForQuoteRsp(CThostFtdcForQuoteRspField* pForQuoteRsp) 216 | { 217 | wrapMdOnRtnForQuoteRsp(gUserApi, pForQuoteRsp); 218 | } 219 | 220 | QCTPMdSpi::QCTPMdSpi(CThostFtdcMdApi* pUserApi) 221 | { 222 | this->pUserApi = pUserApi; 223 | } 224 | 225 | QCTPMdSpi::QCTPMdSpi(CThostFtdcMdApi* pUserApi, uintptr_t gUserApi) 226 | { 227 | this->pUserApi = pUserApi; 228 | this->gUserApi = gUserApi; 229 | } 230 | 231 | uintptr_t _wrap_CThostFtdcMdApi_DestroyUserMdApi(QCTPMdSpi* pMdApi) 232 | { 233 | delete (pMdApi); 234 | return 0; 235 | } 236 | 237 | const char* QCTPMdSpi::GetApiVersion() 238 | { 239 | return this->pUserApi->GetApiVersion(); 240 | } 241 | 242 | void QCTPMdSpi::Release() 243 | { 244 | return this->pUserApi->Release(); 245 | } 246 | 247 | void QCTPMdSpi::Init() 248 | { 249 | return this->pUserApi->Init(); 250 | } 251 | 252 | int QCTPMdSpi::Join() 253 | { 254 | return this->pUserApi->Join(); 255 | } 256 | 257 | const char* QCTPMdSpi::GetTradingDay() 258 | { 259 | return this->pUserApi->GetTradingDay(); 260 | } 261 | 262 | void QCTPMdSpi::RegisterFront(char* pszFrontAddress) 263 | { 264 | return this->pUserApi->RegisterFront(pszFrontAddress); 265 | } 266 | 267 | void QCTPMdSpi::RegisterNameServer(char* pszNsAddress) 268 | { 269 | return this->pUserApi->RegisterNameServer(pszNsAddress); 270 | } 271 | 272 | void QCTPMdSpi::RegisterFensUserInfo(CThostFtdcFensUserInfoField* pFensUserInfo) 273 | { 274 | return this->pUserApi->RegisterFensUserInfo(pFensUserInfo); 275 | } 276 | 277 | void QCTPMdSpi::RegisterSpi(CThostFtdcMdSpi* pSpi) 278 | { 279 | return this->pUserApi->RegisterSpi(pSpi); 280 | } 281 | 282 | int QCTPMdSpi::SubscribeMarketData(char** ppInstrumentID, int nCount) 283 | { 284 | return this->pUserApi->SubscribeMarketData(ppInstrumentID, nCount); 285 | } 286 | 287 | int QCTPMdSpi::UnSubscribeMarketData(char** ppInstrumentID, int nCount) 288 | { 289 | return this->pUserApi->UnSubscribeMarketData(ppInstrumentID, nCount); 290 | } 291 | 292 | int QCTPMdSpi::SubscribeForQuoteRsp(char** ppInstrumentID, int nCount) 293 | { 294 | return this->pUserApi->SubscribeForQuoteRsp(ppInstrumentID, nCount); 295 | } 296 | 297 | int QCTPMdSpi::UnSubscribeForQuoteRsp(char** ppInstrumentID, int nCount) 298 | { 299 | return this->pUserApi->UnSubscribeForQuoteRsp(ppInstrumentID, nCount); 300 | } 301 | 302 | int QCTPMdSpi::ReqUserLogin(CThostFtdcReqUserLoginField* pReqUserLoginField, int nRequestID) 303 | { 304 | return this->pUserApi->ReqUserLogin(pReqUserLoginField, nRequestID); 305 | } 306 | 307 | int QCTPMdSpi::ReqUserLogout(CThostFtdcUserLogoutField* pUserLogout, int nRequestID) 308 | { 309 | return this->pUserApi->ReqUserLogout(pUserLogout, nRequestID); 310 | } 311 | 312 | int QCTPMdSpi::ReqQryMulticastInstrument(CThostFtdcQryMulticastInstrumentField* pQryMulticastInstrument, int nRequestID) 313 | { 314 | return this->pUserApi->ReqQryMulticastInstrument(pQryMulticastInstrument, nRequestID); 315 | } 316 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go2ctp 2 | 3 | 上海期货信息技术 CTP 接口 go 语言原生封装,支持生产,测评,OpenCTP, LocalCTP 版本, 适配 Linux, MacOS 4 | 5 | 对应 Rust 语言封装查看 **[Ctp2rs](https://github.com/pseudocodes/ctp2rs/)** 项目 6 | 7 | 当前主分支对应 CTP 版本为 `v6.7.11` 8 | 9 | ## Sample 10 | 11 | ### 静态依赖 12 | ```go 13 | 14 | package main 15 | 16 | import ( 17 | "log" 18 | "os" 19 | "time" 20 | 21 | "github.com/pseudocodes/go2ctp/ctp" 22 | "github.com/pseudocodes/go2ctp/thost" 23 | ) 24 | 25 | func init() { 26 | log.SetFlags(log.LstdFlags | log.Lshortfile) 27 | } 28 | 29 | type baseSpi struct { 30 | brokerID string 31 | investorID string 32 | password string 33 | 34 | ctp.BaseMdSpi 35 | mdapi thost.MdApi 36 | } 37 | 38 | func CreateBaseSpi() *baseSpi { 39 | s := &baseSpi{ 40 | brokerID: "9999", 41 | investorID: os.Getenv("SIMNOW_USER_ID"), // <- 环境变量设置 42 | password: os.Getenv("SIMNOW_USER_PASSWORD"), // <- 环境变量设置 43 | } 44 | return s 45 | } 46 | 47 | func (s *baseSpi) OnFrontConnected() { 48 | log.Printf("OnFrontConnected\n") 49 | 50 | loginR := &thost.CThostFtdcReqUserLoginField{} 51 | copy(loginR.BrokerID[:], []byte(s.brokerID)) 52 | copy(loginR.UserID[:], []byte(s.investorID)) 53 | 54 | ret := s.mdapi.ReqUserLogin(loginR, 1) 55 | 56 | log.Printf("user log: %v\n", ret) 57 | } 58 | 59 | func (s *baseSpi) OnHeartBeatWarning(timelapse int) { 60 | log.Printf("OnHeartBeatWarning: %v\n", timelapse) 61 | } 62 | 63 | func (s *baseSpi) OnFrontDisconnected(nReason int) { 64 | log.Printf("OnFrontDisconnected: %v\n", nReason) 65 | } 66 | 67 | func (s *baseSpi) OnRspUserLogin(pRspUserLogin *thost.CThostFtdcRspUserLoginField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 68 | log.Printf("RspUserLogin: %+v\nRspInfo: %+v\n", pRspUserLogin, nil) 69 | s.mdapi.SubscribeMarketData("ag2408") 70 | } 71 | 72 | func (s *baseSpi) OnRspSubMarketData(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 73 | log.Printf("instrumentID: %+v\n RspInfo: %+v\n", pSpecificInstrument, nil) 74 | } 75 | 76 | func (s *baseSpi) OnRtnDepthMarketData(pDepthMarketData *thost.CThostFtdcDepthMarketDataField) { 77 | log.Printf("OnRtnDeptMarketData: %s\n", string(pDepthMarketData.InstrumentID[:7])) 78 | } 79 | 80 | func (s *baseSpi) OnRspError(pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 81 | log.Printf("RspInfo: %+v\n", pRspInfo.ErrorID) 82 | } 83 | 84 | func main() { 85 | mdapi := ctp.CreateMdApi(ctp.MdFlowPath("./data/"), ctp.MdUsingUDP(false), ctp.MdMultiCast(false)) 86 | baseSpi := CreateBaseSpi() 87 | baseSpi.mdapi = mdapi 88 | mdapi.RegisterSpi(baseSpi) 89 | 90 | mdapi.RegisterFront("tcp://180.168.146.187:10211") 91 | 92 | mdapi.Init() 93 | 94 | println(mdapi.GetApiVersion()) 95 | println(mdapi.GetTradingDay()) 96 | // mdapi.Join() 97 | // 98 | for { 99 | time.Sleep(10 * time.Second) 100 | } 101 | } 102 | 103 | ``` 104 | 105 | ### 动态库 106 | ```go 107 | package main 108 | 109 | import ( 110 | "log" 111 | "os" 112 | "time" 113 | "runtime" 114 | 115 | "github.com/pseudocodes/go2ctp/ctp_dyn" 116 | "github.com/pseudocodes/go2ctp/thost" 117 | ) 118 | 119 | func init() { 120 | log.SetFlags(log.LstdFlags | log.Lshortfile) 121 | } 122 | 123 | type baseSpi struct { 124 | brokerID string 125 | investorID string 126 | password string 127 | 128 | ctp.BaseMdSpi 129 | mdapi thost.MdApi 130 | } 131 | 132 | func CreateBaseSpi() *baseSpi { 133 | s := &baseSpi{ 134 | brokerID: "9999", 135 | investorID: os.Getenv("SIMNOW_USER_ID"), // <- 环境变量设置 136 | password: os.Getenv("SIMNOW_USER_PASSWORD"), // <- 环境变量设置 137 | } 138 | return s 139 | } 140 | 141 | func (s *baseSpi) OnFrontConnected() { 142 | log.Printf("OnFrontConnected\n") 143 | 144 | loginR := &thost.CThostFtdcReqUserLoginField{} 145 | copy(loginR.BrokerID[:], []byte(s.brokerID)) 146 | copy(loginR.UserID[:], []byte(s.investorID)) 147 | 148 | ret := s.mdapi.ReqUserLogin(loginR, 1) 149 | 150 | log.Printf("user log: %v\n", ret) 151 | } 152 | 153 | func (s *baseSpi) OnHeartBeatWarning(timelapse int) { 154 | log.Printf("OnHeartBeatWarning: %v\n", timelapse) 155 | } 156 | 157 | func (s *baseSpi) OnFrontDisconnected(nReason int) { 158 | log.Printf("OnFrontDisconnected: %v\n", nReason) 159 | } 160 | 161 | func (s *baseSpi) OnRspUserLogin(pRspUserLogin *thost.CThostFtdcRspUserLoginField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 162 | log.Printf("RspUserLogin: %+v\nRspInfo: %+v\n", pRspUserLogin, nil) 163 | s.mdapi.SubscribeMarketData("ag2408") 164 | } 165 | 166 | func (s *baseSpi) OnRspSubMarketData(pSpecificInstrument *thost.CThostFtdcSpecificInstrumentField, pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 167 | log.Printf("instrumentID: %+v\n RspInfo: %+v\n", pSpecificInstrument, nil) 168 | } 169 | 170 | func (s *baseSpi) OnRtnDepthMarketData(pDepthMarketData *thost.CThostFtdcDepthMarketDataField) { 171 | log.Printf("OnRtnDeptMarketData: %s\n", string(pDepthMarketData.InstrumentID[:7])) 172 | } 173 | 174 | func (s *baseSpi) OnRspError(pRspInfo *thost.CThostFtdcRspInfoField, nRequestID int, bIsLast bool) { 175 | log.Printf("RspInfo: %+v\n", pRspInfo.ErrorID) 176 | } 177 | 178 | func main() { 179 | var ( 180 | mdapi thost.MdApi 181 | frontAddr string 182 | 183 | CTPLibPathMacos = "/the/user/path/to/thostmduserapi_se.framework/thostmduserapi_se" 184 | CTPLibPathLinux = "/the/user/path/to/thostmduserapi_se.so" 185 | TTSLibPathMacos = "/the/user/path/to/openctp/thostmduserapi_se.dylib" 186 | ) 187 | if runtime.GOOS == "darwin" { 188 | mdapi = ctp_dyn.CreateMdApi(ctp_dyn.MdDynamicLibPath(CTPLibPathMacos), ctp_dyn.MdFlowPath("./data/"), ctp_dyn.MdUsingUDP(false), ctp_dyn.MdMultiCast(false)) 189 | frontAddr = SimnowFront 190 | } else if runtime.GOOS == "linux" { 191 | mdapi = ctp_dyn.CreateMdApi(ctp_dyn.MdDynamicLibPath(CTPLibPathLinux), ctp_dyn.MdFlowPath("./data/"), ctp_dyn.MdUsingUDP(false), ctp_dyn.MdMultiCast(false)) 192 | frontAddr = SimnowFront 193 | } 194 | 195 | baseSpi := CreateBaseSpi() 196 | baseSpi.mdapi = mdapi 197 | mdapi.RegisterSpi(baseSpi) 198 | 199 | mdapi.RegisterFront(frontAddr) 200 | 201 | mdapi.Init() 202 | 203 | println(mdapi.GetApiVersion()) 204 | println(mdapi.GetTradingDay()) 205 | 206 | // mdapi.Join() 207 | for { 208 | time.Sleep(10 * time.Second) 209 | } 210 | } 211 | ``` 212 | 213 | 214 | 215 | 216 | ## FAQ 217 | **Q.01**: 为什么在有了 [*pseudocodes/goctp*](https://github.com/pseudocodes/goctp) 项目之后又开启了 *go2ctp* 项目 218 | 219 | **A.01**: 发现前项目使用后切换平台 (MacOS), 使用 OpenCTP TTS 系统,以及穿透式认证时(使用 CP 版本) 比较不方便,在静态编译封装的方式下只能将不同的平台库放在不同的分支下,再加上未来对 *ctp-mini* 的支持,就在本项目集中对不同平台的 CTP 库进行集中提供 220 | 221 | **Q.02**: 与 [*github.com/hankchan/goctp*](https://github.com/hankchan/goctp) 项目有什么区别 222 | 223 | **A.02**: 该项目最早来自 *github.com/qerio/goctp*,是最早可用的完整 golang 版本 ctp 封装,利用 *go build* 对 *swig* 的自动化编译支持,对 CTP 的头文件进行解析并生成中间代码参与编译,一般大家使用的 goctp 封装 **80%** 都来自该项目的衍生品 224 | > 该项目的问题: 225 | > 1. swig 展开后的中间代码高达十几万行,编译比较慢,约超过 5 分钟 226 | > 2. 早期更新 CTP 库版本时,需要修改部分 CTP 头文件内容,例如行情接口 `SubscribeMarketData` 的合约参数声明方式需要修改,否则 *swig* 在生成接口时无法生成 `__goslice__` 模式的参数,该问题 [#749](https://github.com/swig/swig/issues/749) 2016 年提出, 直到 2022 年 swig 才修复 227 | > 3. 由于(1) 中的原因,在开发时 IDE 的提示无法及时给出,同时 `swig` 生成的接口代码以及使用方式并不友好 228 | > 4. Debug 跟踪困难; 229 | 230 | > 本项目解决的问题: 231 | > * 简洁封装代码,不采用 swig,不对原始 API 文件进行修改; 232 | > * 完全原生 go 语法类型支持,编译速度快,接口提示友好,保留原始文档注释说明; 233 | > * Debug 跟踪方便; 234 | 235 | **Q.03**: 与 [*github.com/haifengat/goctp*](https://github.com/haifengat/goctp) 项目有什么区别 236 | 237 | **A.03**: 海风提供的 goctp 的封装对 golang 的特性应用得最好, [*pseudocodes/goctp*](https://github.com/pseudocodes/goctp) 也参考了该项目的一些细节, 提供 lite 接口的封装; 感谢这个项目在 golang 封装 ctp api 方向的探索 238 | 239 | > 该项目的问题: 240 | > * v1 版本的封装比较乱,使用方式与传统的调用方式有出入; 241 | > * v1 版本一个进程程序只能创建一个 mdapi 和 traderapi 实例,这是该版本最大的问题 ; 242 | > * v2 版本对一些交易基础功能提供了进一步的抽象封装; 243 | > * v2 版本在 v1 版本的基础上做了增强,改用 map 来存储实例指针与对应对象 [quote.go](https://github.com/haifengat/goctp/blob/4f6f9df33fba15d28bf55209fc8111057c9546c7/quote.go#L113C14-L113C45), 可能出于使用频度的考虑,该 map 并未上锁,而 swig 展开代码对使用的 map 进行了并发锁处理; 244 | > * 切换平台库依然不方便,v1 与 v2 版本都是通过拓展 clang 代码二次封装 so 库,绑定官方版本 API 库,如涉及切换平台库或穿透式认证场景时,还需用户自行编译动态库以及维护该 repo 的分支,对开发能力较弱的用户不友好;该项目对进一步的平台化开发支持有限; 245 | 246 | > 本项目解决问题: 247 | > * 封装层数低,只提供一次 cgo 桥接转换,不涉及数据深拷贝 248 | > * 运行时多个 API 实例共存,不同平台的 API 实例可以同时存在一个进程空间中,例如可以同时连接实盘, SIMNOW, OPENCTP 249 | > * 全局指针 map 采用了标准库中的 cgo.Handle 无并发问题 250 | 251 | **Q.04**: 为什么不提供 Windows 平台支持 252 | 253 | **A.04**: 开发者没有 Windows 环境,不想装虚拟机,有兴趣的开发者可以提 PR 254 | 255 | **Q.05**: ctp 目录和 ctp_dyn 目录的封装有什么不同 256 | 257 | **A.05**: 258 | > * ctp 的封装来自 [*pseudocodes/goctp*](https://github.com/pseudocodes/goctp), 剔除了 *lite* 和 *convert* 相关代码,原则上只提供一层封装,直接桥接 cgo 空间回调过来的数据 259 | > * ctp 目录属于静态编译链接,其他项目采用该目录下的代码,依赖的动态库的路径会在编译构建期完成初始绑定,默认路径为 go2ctp 库的存放路径,只部署二进制程序在 Linux 环境需要设置 LD_LIBRARY_PATH 环境变量来提供依赖的 ctp 动态库路径; MacOS 环境一般不用再独立设置 `@rpath`,推荐 MacOS 环境采用 ctp_dyn 依赖 260 | > * ctp_dyn 封装方式采用了读取动态库符号的方式,通过在运行时提供动态库的路径,完成 API 实例对象的生成和绑定,理论上 ctp_dyn 的封装方式更灵活方便,可以通过配置的方式动态的替换 linux 下不同平台的库,包括官方生产和测评版本,rohan(融航),openctp-tts 平台,无需再编译项目代码. ctp_dyn 同时支持 openctp 的 MacOS 版本 dylib 261 | > * ctp_dyn 使用需要用户明确提供动态库地址,部署时需要动态库与二进制程序一起部署 262 | > 263 | 264 | **Q.06**: MacOS 环境下上期 CTP 编译运行问题 265 | 266 | **A.06**: 相关信息如下 267 | > * 官方从 CTP 6.7.0 版本开始提供 `.framework` 的动态库,而不像 OpenCTP 那样采用 `.dylib` 来提供支持 268 | > * 官方打包发布的 `framework` 包可能有设置问题,包中软连接变成文本文件,如果直接引入该 `framework` 至 `Xcode` 项目会造成无法编译 269 | > * `framework` 静态编译时就需要设定 `@rpath` 路径,运行二进制文件时才能获得动态库的路径,在这种场景下,更合适的方式还是采用动态库 `dlopen` 方式, 270 | > * MacOS 命令行下可以直接编译源代码程序并链接 `framework`,首次运行启动之后请到`系统设置->隐私与安全性->安全性` 标签中对 `thostmduserapi_se` 以及 `thosttraderapi_se` 这两个文件进行信任允许操作 271 | 272 | **Q.07**: OpenCTP 与上期 CTP 在 MacOS 环境的区别 273 | 274 | **A.07**: 相关信息如下 275 | > * 上期 CTP MacOS 环境与 Linux 环境的区别主要在于 `CThostFtdcTraderApi` 中的 `ReqUserLogin` 接口参数不同, MacOS 对应接口比 Linux 多了两个穿透式信息的参数 276 | ```cpp 277 | // Linux 接口 278 | virtual int ReqUserLogin(CThostFtdcReqUserLoginField* pReqUserLoginField, int nRequestID) = 0; 279 | 280 | // MacOS 接口 281 | virtual int ReqUserLogin(CThostFtdcReqUserLoginField* pReqUserLoginField, int nRequestID, TThostFtdcSystemInfoLenType length, TThostFtdcClientSystemInfoType systemInfo) = 0; 282 | ``` 283 | > * OpenCTP 提供的 MacOS 的头文件接口与 Linux 统一,即 `ReqUserLogin` 采用两参数接口,封装 `go2ctp` 过程中与 [@krenx](https://github.com/krenx1983) 沟通过这个问题,对方当时未有计划提供对标接口支持, 因此本项目在 MacOS 环境下编译 OpenCTP 相关库时,请采用 ctp_dyn pacakge,编译指令如下 284 | 285 | ```shell 286 | ?> cd sample/simple_trader && go build -tags openctp 287 | 288 | # 或者 289 | ?> cd sample/simple_trader && go build -tags tts 290 | ``` 291 | 292 | **Q.08**: ctp_dyn 高版本的封装(6.7.7) 是否兼容低版本 (6.7.2) 的动态库 293 | 294 | **A.08**: 相关信息 295 | * CTP `v6.7.7` 版本在 `RegisterFront` 增加了新方法,破坏了 `v6.7.2` 版本之前的类方法的内存布局排序, 因此 `v6.7.7` 的封装不兼容 `v6.7.2` 296 | * 实测 linux 环境中 `v6.7.2` 封装文件能支持 CTP 动态库版本到 `v6.5.1`, 高版本的 API 无法在低版本动态库调用时使用 297 | * `6.7.7` 分支 `ctp_dyn` 不兼容 `6.7.2` 版本的 ctp/openctp 的动态库, 如果高版本封装加载了低版本动态库,程序编译运行之后会发生卡死或提示出错; 298 | * `6.7.11` 分支 `ctp_dyn` 不兼容之前任何版本; 299 | * 存在能够强制加载低版本动态库函数的封装方案,但是考虑到生产环境下应不隐藏风险,尽早抛出错误的原则,未采用强制加载的封装方案. 300 | * 此外,请注意开发环境的区别,不要在 Macosx 环境下加载 so 动态库 301 | 302 | 303 | ## 注意事项 304 | * 使用 ctp_dyn 时请对齐分支版本以及动态库版本 305 | * Macosx 环境下如出现编译后运行无响应,可以排查系统以及 Go 版本 306 | 307 | 308 | ## 同类项目 309 | 310 | | 项目地址 | Description | 推荐指数 | 311 | | --------- | ----------- |---------| 312 | | https://github.com/gaxxx/ctp | 最早 golang 版本的 ctp 封装,作者发布在水木论坛,在这个项目中
可以观察到 go 早期版本的封装编译指令 | ☆☆☆☆☆ | 313 | | https://github.com/pseudocodes/goctp | 含 DataCollect 封装支持,提供 go 类型结构的 convert 转换方法 | ★★★★☆ | 314 | | https://github.com/haifengat/goctp
[https://gitee.com/haifengat/goctp/v2](https://gitee.com/haifengat/goctp/tree/v2/) | 描述见 FAQ. | ★★★★☆| 315 | | https://github.com/hankchan/goctp | 描述见 FAQ. | ★★★☆☆ | 316 | | https://github.com/mayiweb/goctp | 源自 https://github.com/hankchan/goctp | ★★★☆☆ | 317 | | https://github.com/kkqy/ctp-go | a. 对 CTP 的版本处理与 `A.01` 中的描述相同,不同版本放置于不同分支下
b. 该项目将 Swig 编译后展开的代码直接放置于项目中,有 FAQ 中 `A.02` 中描述的问题,该项目文档也说明了编译速度慢的问题
c. CTP 结构体创建在 c 内存空间侧,需要手动自行回收 |★★☆☆☆| 318 | | https://github.com/ztrade/ctp| a. 项目整体布局类似 https://github.com/pseudocodes/goctp, 细节在于 wrapper 代码中将 Api 和 Spi 的 C++ 类分别进行了独立封装,与 SWIG 的展开代码类似
b. 调用 Api 接口时 C 内存空间侧申请一次内存并拷贝结构体数据,Spi 回调侧 go 内存空间侧申请一次内存并拷贝结构体,相较本项目整体多了两次内存申请以及数据深拷贝 | ★★★★☆ | 319 | 320 | 321 | ## Base on `go2ctp` 322 | * https://github.com/pseudocodes/goctp_l3_estimate 323 | * 订单簿可视化展示 324 | * https://github.com/pseudocodes/light-trader 325 | * https://github.com/pseudocodes/open-md-gateway-go 326 | * 高性能期货行情数据网关,兼容 [`DIFF`](https://doc.shinnytech.com/diff/latest/general.html) 协议 327 | * alpha-trade-gateway (incoming) 328 | 329 | ## TODO 330 | * 更丰富的使用样例 331 | * 扩展封装,提供高阶功能 332 | * CTP 版本与 GO 项目大版本同步 ? 333 | 334 | 335 | 336 | ## Reference 337 | 【1】[*github.com/pseudocodes/goctp*](https://github.com/pseudocodes/goctp) 338 | 339 | 【2】[*github.com/haifengat/goctp*](https://github.com/haifengat/goctp) 340 | 341 | 【3】[*github.com/hankchan/goctp*](https://github.com/hankchan/goctp) 342 | 343 | ## 免责声明 344 | 本项目明确拒绝对产品做任何明示或暗示的担保。由于软件系统开发本身的复杂性,无法保证本项目完全没有错误。如选择使用本项目表示您同意错误和/或遗漏的存在,在任何情况下本项目对于直接、间接、特殊的、偶然的、或间接产生的、使用或无法使用本项目进行交易和投资造成的盈亏、直接或间接引起的赔偿、损失、债务或是任何交易中止均不承担责任和义务。 345 | -------------------------------------------------------------------------------- /ctp/mdapi_impl.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | package ctp 14 | 15 | /* 16 | #include 17 | #include 18 | 19 | #include "ThostFtdcUserApiDataType.h" 20 | #include "ThostFtdcUserApiStruct.h" 21 | 22 | // typedef long long intgo; 23 | 24 | typedef struct { char *p; int64_t n; } _gostring_; 25 | typedef struct { void* array; int64_t len; int64_t cap; } _goslice_; 26 | 27 | extern uintptr_t _wrap_CThostFtdcMdApi_CreateFtdcMdApi(); 28 | extern uintptr_t _wrap_CThostFtdcMdApi_CreateFtdcMdApi2(uintptr_t, char*, _Bool, _Bool, _Bool); 29 | 30 | extern const char * _wrap_CThostFtdcMdApi_GetApiVersion(uintptr_t); 31 | 32 | extern void _wrap_CThostFtdcMdApi_Release(uintptr_t); 33 | 34 | extern void _wrap_CThostFtdcMdApi_Init(uintptr_t); 35 | 36 | extern int _wrap_CThostFtdcMdApi_Join(uintptr_t); 37 | 38 | extern const char * _wrap_CThostFtdcMdApi_GetTradingDay(uintptr_t); 39 | 40 | extern void _wrap_CThostFtdcMdApi_RegisterFront(uintptr_t, char *); 41 | 42 | extern void _wrap_CThostFtdcMdApi_RegisterNameServer(uintptr_t, char *); 43 | 44 | extern void _wrap_CThostFtdcMdApi_RegisterFensUserInfo(uintptr_t, struct CThostFtdcFensUserInfoField *); 45 | 46 | extern void _wrap_CThostFtdcMdApi_RegisterSpi(uintptr_t, uintptr_t); 47 | 48 | extern int _wrap_CThostFtdcMdApi_SubscribeMarketData(uintptr_t, char **, int); 49 | 50 | extern int _wrap_CThostFtdcMdApi_UnSubscribeMarketData(uintptr_t, char **, int); 51 | 52 | extern int _wrap_CThostFtdcMdApi_SubscribeForQuoteRsp(uintptr_t, char **, int); 53 | 54 | extern int _wrap_CThostFtdcMdApi_UnSubscribeForQuoteRsp(uintptr_t, char **, int); 55 | 56 | extern int _wrap_CThostFtdcMdApi_ReqUserLogin(uintptr_t, struct CThostFtdcReqUserLoginField *, int); 57 | 58 | extern int _wrap_CThostFtdcMdApi_ReqUserLogout(uintptr_t, struct CThostFtdcUserLogoutField *, int); 59 | 60 | extern int _wrap_CThostFtdcMdApi_ReqQryMulticastInstrument(uintptr_t, struct CThostFtdcQryMulticastInstrumentField *, int); 61 | 62 | */ 63 | import "C" 64 | import ( 65 | "os" 66 | "path/filepath" 67 | "runtime/cgo" 68 | "strings" 69 | "unsafe" 70 | 71 | "github.com/pseudocodes/go2ctp/thost" 72 | ) 73 | 74 | func CreateMdApi(options ...MdOption) thost.MdApi { 75 | api := &MdApi{ 76 | flowPath: defaultFlowPath, 77 | usingUDP: defaultIsUsingUdp, 78 | multicast: defaultIsMulticast, 79 | production: defaultIsProductionMode, 80 | } 81 | handle := cgo.NewHandle(api) 82 | for _, opt := range options { 83 | opt(api) 84 | } 85 | if api.flowPath != "" { 86 | var err error 87 | if strings.HasSuffix(api.flowPath, "/") { 88 | err = os.MkdirAll(api.flowPath, os.ModePerm) 89 | } else { 90 | parentDir := filepath.Dir(api.flowPath) 91 | err = os.MkdirAll(parentDir, os.ModePerm) 92 | } 93 | if err != nil && !os.IsExist(err) { 94 | panic(err) 95 | } 96 | } 97 | cflowPath := C.CString(api.flowPath) 98 | defer C.free(unsafe.Pointer(cflowPath)) 99 | 100 | api.apiPtr = uintptr(C._wrap_CThostFtdcMdApi_CreateFtdcMdApi2(C.uintptr_t(handle), cflowPath, C._Bool(api.usingUDP), C._Bool(api.multicast), C._Bool(api.production))) 101 | 102 | return api 103 | } 104 | 105 | // 获取API的版本信息 106 | // /@retrun 获取到的版本号 107 | func (s *MdApi) GetApiVersion() string { 108 | cstr := C._wrap_CThostFtdcMdApi_GetApiVersion(C.uintptr_t(s.apiPtr)) 109 | return C.GoString(cstr) 110 | } 111 | 112 | // 删除接口对象本身 113 | // /@remark 不再使用本接口对象时,调用该函数删除接口对象 114 | func (s *MdApi) Release() { 115 | C._wrap_CThostFtdcMdApi_RegisterSpi(C.uintptr_t(s.apiPtr), C.uintptr_t(0)) 116 | C._wrap_CThostFtdcMdApi_Release(C.uintptr_t(s.apiPtr)) 117 | 118 | } 119 | 120 | // 初始化 121 | // /@remark 初始化运行环境,只有调用后,接口才开始工作 122 | func (s *MdApi) Init() { 123 | C._wrap_CThostFtdcMdApi_Init(C.uintptr_t(s.apiPtr)) 124 | } 125 | 126 | // 等待接口线程结束运行 127 | // /@return 线程退出代码 128 | func (s *MdApi) Join() int { 129 | return (int)(C._wrap_CThostFtdcMdApi_Join(C.uintptr_t(s.apiPtr))) 130 | } 131 | 132 | // 获取当前交易日 133 | // /@retrun 获取到的交易日 134 | // /@remark 只有登录成功后,才能得到正确的交易日 135 | func (s *MdApi) GetTradingDay() string { 136 | cstr := C._wrap_CThostFtdcMdApi_GetTradingDay(C.uintptr_t(s.apiPtr)) 137 | return C.GoString(cstr) 138 | } 139 | 140 | // 注册前置机网络地址 141 | // /@param pszFrontAddress:前置机网络地址。 142 | // /@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:17001”。 143 | // /@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。 144 | func (s *MdApi) RegisterFront(pszFrontAddress string) { 145 | addr := C.CString(pszFrontAddress) 146 | defer C.free(unsafe.Pointer(addr)) 147 | C._wrap_CThostFtdcMdApi_RegisterFront(C.uintptr_t(s.apiPtr), addr) 148 | } 149 | 150 | // 注册名字服务器网络地址 151 | // /@param pszNsAddress:名字服务器网络地址。 152 | // /@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:12001”。 153 | // /@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”12001”代表服务器端口号。 154 | // /@remark RegisterNameServer优先于RegisterFront 155 | func (s *MdApi) RegisterNameServer(pszNsAddress string) { 156 | addr := C.CString(pszNsAddress) 157 | defer C.free(unsafe.Pointer(addr)) 158 | C._wrap_CThostFtdcMdApi_RegisterNameServer(C.uintptr_t(s.apiPtr), addr) 159 | } 160 | 161 | // 注册名字服务器用户信息 162 | // /@param pFensUserInfo:用户信息。 163 | func (s *MdApi) RegisterFensUserInfo(pFensUserInfo *thost.CThostFtdcFensUserInfoField) { 164 | C._wrap_CThostFtdcMdApi_RegisterFensUserInfo(C.uintptr_t(s.apiPtr), (*C.struct_CThostFtdcFensUserInfoField)(unsafe.Pointer(pFensUserInfo))) 165 | } 166 | 167 | // 注册回调接口 168 | // /@param pSpi 派生自回调接口类的实例 169 | func (s *MdApi) RegisterSpi(pSpi thost.MdSpi) { 170 | s.spi = pSpi 171 | } 172 | 173 | // 订阅行情。 174 | // /@param ppInstrumentID 合约ID 175 | // /@param nCount 要订阅/退订行情的合约个数 176 | // /@remark 177 | func (s *MdApi) SubscribeMarketData(instrumentIDs ...string) int { 178 | cinlist := []*C.char{} 179 | for _, ins := range instrumentIDs { 180 | cinlist = append(cinlist, C.CString(ins)) 181 | } 182 | defer func() { 183 | for i := range cinlist { 184 | C.free(unsafe.Pointer(cinlist[i])) 185 | } 186 | }() 187 | return (int)(C._wrap_CThostFtdcMdApi_SubscribeMarketData(C.uintptr_t(s.apiPtr), (**C.char)(unsafe.Pointer(&cinlist[0])), C.int(len(cinlist)))) 188 | } 189 | 190 | // 退订行情。 191 | // /@param ppInstrumentID 合约ID 192 | // /@param nCount 要订阅/退订行情的合约个数 193 | // /@remark 194 | func (s *MdApi) UnSubscribeMarketData(instrumentIDs ...string) int { 195 | cinlist := []*C.char{} 196 | for _, ins := range instrumentIDs { 197 | cinlist = append(cinlist, C.CString(ins)) 198 | } 199 | defer func() { 200 | for i := range cinlist { 201 | C.free(unsafe.Pointer(cinlist[i])) 202 | } 203 | }() 204 | return (int)(C._wrap_CThostFtdcMdApi_UnSubscribeMarketData(C.uintptr_t(s.apiPtr), (**C.char)(unsafe.Pointer(&cinlist[0])), C.int(len(cinlist)))) 205 | } 206 | 207 | // 订阅询价。 208 | // /@param ppInstrumentID 合约ID 209 | // /@param nCount 要订阅/退订行情的合约个数 210 | // /@remark 211 | func (s *MdApi) SubscribeForQuoteRsp(instrumentIDs ...string) int { 212 | cinlist := []*C.char{} 213 | for _, ins := range instrumentIDs { 214 | cinlist = append(cinlist, C.CString(ins)) 215 | } 216 | defer func() { 217 | for i := range cinlist { 218 | C.free(unsafe.Pointer(cinlist[i])) 219 | } 220 | }() 221 | return (int)(C._wrap_CThostFtdcMdApi_SubscribeForQuoteRsp(C.uintptr_t(s.apiPtr), (**C.char)(unsafe.Pointer(&cinlist[0])), C.int(len(cinlist)))) 222 | } 223 | 224 | // 退订询价。 225 | // /@param ppInstrumentID 合约ID 226 | // /@param nCount 要订阅/退订行情的合约个数 227 | // /@remark 228 | func (s *MdApi) UnSubscribeForQuoteRsp(instrumentIDs ...string) int { 229 | cinlist := []*C.char{} 230 | for _, ins := range instrumentIDs { 231 | cinlist = append(cinlist, C.CString(ins)) 232 | } 233 | defer func() { 234 | for i := range cinlist { 235 | C.free(unsafe.Pointer(cinlist[i])) 236 | } 237 | }() 238 | return (int)(C._wrap_CThostFtdcMdApi_UnSubscribeForQuoteRsp(C.uintptr_t(s.apiPtr), (**C.char)(unsafe.Pointer(&cinlist[0])), C.int(len(cinlist)))) 239 | } 240 | 241 | // 用户登录请求 242 | func (s *MdApi) ReqUserLogin(pReqUserLoginField *thost.CThostFtdcReqUserLoginField, nRequestID int) int { 243 | return (int)(C._wrap_CThostFtdcMdApi_ReqUserLogin(C.uintptr_t(s.apiPtr), (*C.struct_CThostFtdcReqUserLoginField)(unsafe.Pointer(pReqUserLoginField)), C.int(nRequestID))) 244 | } 245 | 246 | // 登出请求 247 | func (s *MdApi) ReqUserLogout(pUserLogout *thost.CThostFtdcUserLogoutField, nRequestID int) int { 248 | return (int)(C._wrap_CThostFtdcMdApi_ReqUserLogout(C.uintptr_t(s.apiPtr), (*C.struct_CThostFtdcUserLogoutField)(unsafe.Pointer(pUserLogout)), C.int(nRequestID))) 249 | } 250 | 251 | // 请求查询组播合约 252 | func (s *MdApi) ReqQryMulticastInstrument(pQryMulticastInstrument *thost.CThostFtdcQryMulticastInstrumentField, nRequestID int) int { 253 | return (int)(C._wrap_CThostFtdcMdApi_ReqQryMulticastInstrument(C.uintptr_t(s.apiPtr), (*C.struct_CThostFtdcQryMulticastInstrumentField)(unsafe.Pointer(pQryMulticastInstrument)), C.int(nRequestID))) 254 | } 255 | 256 | //export wrapMdOnFrontConnected 257 | func wrapMdOnFrontConnected(v uintptr) { 258 | api := cgo.Handle(v).Value().(*MdApi) 259 | api.spi.OnFrontConnected() 260 | } 261 | 262 | //export wrapMdOnFrontDisconnected 263 | func wrapMdOnFrontDisconnected(v uintptr, nReason C.int) { 264 | api := cgo.Handle(v).Value().(*MdApi) 265 | api.spi.OnFrontDisconnected(int(nReason)) 266 | } 267 | 268 | //export wrapMdOnHeartBeatWarning 269 | func wrapMdOnHeartBeatWarning(v uintptr, nTimeLapse C.int) { 270 | api := cgo.Handle(v).Value().(*MdApi) 271 | api.spi.OnHeartBeatWarning(int(nTimeLapse)) 272 | } 273 | 274 | //export wrapMdOnRspUserLogin 275 | func wrapMdOnRspUserLogin(v uintptr, pRspUserLogin *C.struct_CThostFtdcRspUserLoginField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 276 | api := cgo.Handle(v).Value().(*MdApi) 277 | api.spi.OnRspUserLogin((*thost.CThostFtdcRspUserLoginField)(unsafe.Pointer(pRspUserLogin)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 278 | } 279 | 280 | //export wrapMdOnRspUserLogout 281 | func wrapMdOnRspUserLogout(v uintptr, pUserLogout *C.struct_CThostFtdcUserLogoutField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 282 | api := cgo.Handle(v).Value().(*MdApi) 283 | api.spi.OnRspUserLogout((*thost.CThostFtdcUserLogoutField)(unsafe.Pointer(pUserLogout)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 284 | } 285 | 286 | //export wrapMdOnRspQryMulticastInstrument 287 | func wrapMdOnRspQryMulticastInstrument(v uintptr, pMulticastInstrument *C.struct_CThostFtdcMulticastInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 288 | api := cgo.Handle(v).Value().(*MdApi) 289 | api.spi.OnRspQryMulticastInstrument((*thost.CThostFtdcMulticastInstrumentField)(unsafe.Pointer(pMulticastInstrument)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 290 | } 291 | 292 | //export wrapMdOnRspError 293 | func wrapMdOnRspError(v uintptr, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 294 | api := cgo.Handle(v).Value().(*MdApi) 295 | api.spi.OnRspError((*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 296 | } 297 | 298 | //export wrapMdOnRspSubMarketData 299 | func wrapMdOnRspSubMarketData(v uintptr, pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 300 | api := cgo.Handle(v).Value().(*MdApi) 301 | api.spi.OnRspSubMarketData((*thost.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 302 | } 303 | 304 | //export wrapMdOnRspUnSubMarketData 305 | func wrapMdOnRspUnSubMarketData(v uintptr, pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 306 | api := cgo.Handle(v).Value().(*MdApi) 307 | api.spi.OnRspUnSubMarketData((*thost.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 308 | } 309 | 310 | //export wrapMdOnRspSubForQuoteRsp 311 | func wrapMdOnRspSubForQuoteRsp(v uintptr, pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 312 | api := cgo.Handle(v).Value().(*MdApi) 313 | api.spi.OnRspSubForQuoteRsp((*thost.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 314 | } 315 | 316 | //export wrapMdOnRspUnSubForQuoteRsp 317 | func wrapMdOnRspUnSubForQuoteRsp(v uintptr, pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 318 | api := cgo.Handle(v).Value().(*MdApi) 319 | api.spi.OnRspUnSubForQuoteRsp((*thost.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 320 | } 321 | 322 | //export wrapMdOnRtnDepthMarketData 323 | func wrapMdOnRtnDepthMarketData(v uintptr, pDepthMarketData *C.struct_CThostFtdcDepthMarketDataField) { 324 | api := cgo.Handle(v).Value().(*MdApi) 325 | api.spi.OnRtnDepthMarketData((*thost.CThostFtdcDepthMarketDataField)(unsafe.Pointer(pDepthMarketData))) 326 | } 327 | 328 | //export wrapMdOnRtnForQuoteRsp 329 | func wrapMdOnRtnForQuoteRsp(v uintptr, pForQuoteRsp *C.struct_CThostFtdcForQuoteRspField) { 330 | api := cgo.Handle(v).Value().(*MdApi) 331 | api.spi.OnRtnForQuoteRsp((*thost.CThostFtdcForQuoteRspField)(unsafe.Pointer(pForQuoteRsp))) 332 | } 333 | 334 | // ----------------------------------------------------- 335 | -------------------------------------------------------------------------------- /ctp_dyn/mdapi_impl.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | package ctp_dyn 14 | 15 | /* 16 | #include 17 | #include 18 | 19 | #include "ThostFtdcUserApiDataType.h" 20 | #include "ThostFtdcUserApiStruct.h" 21 | 22 | // typedef long long intgo; 23 | 24 | typedef struct { char *p; int64_t n; } _gostring_; 25 | typedef struct { void* array; int64_t len; int64_t cap; } _goslice_; 26 | 27 | extern uintptr_t _wrap_tts_CThostFtdcMdApi_CreateFtdcMdApi(); 28 | extern uintptr_t _wrap_tts_CThostFtdcMdApi_CreateFtdcMdApi2(uintptr_t goUserApi, char*, _Bool, _Bool); 29 | extern uintptr_t _wrap_tts_CThostFtdcMdApi_CreateFtdcMdApi3(uintptr_t goUserApi, char*, char*, _Bool, _Bool, _Bool); 30 | 31 | 32 | extern const char * _wrap_tts_CThostFtdcMdApi_GetApiVersion(uintptr_t); 33 | 34 | extern void _wrap_tts_CThostFtdcMdApi_Release(uintptr_t); 35 | 36 | extern void _wrap_tts_CThostFtdcMdApi_Init(uintptr_t); 37 | 38 | extern int64_t _wrap_tts_CThostFtdcMdApi_Join(uintptr_t); 39 | 40 | extern const char * _wrap_tts_CThostFtdcMdApi_GetTradingDay(uintptr_t); 41 | 42 | extern void _wrap_tts_CThostFtdcMdApi_RegisterFront(uintptr_t, char *); 43 | 44 | extern void _wrap_tts_CThostFtdcMdApi_RegisterNameServer(uintptr_t, char *); 45 | 46 | extern void _wrap_tts_CThostFtdcMdApi_RegisterFensUserInfo(uintptr_t, struct CThostFtdcFensUserInfoField *); 47 | 48 | extern void _wrap_tts_CThostFtdcMdApi_RegisterSpi(uintptr_t, uintptr_t); 49 | 50 | extern int64_t _wrap_tts_CThostFtdcMdApi_SubscribeMarketData(uintptr_t, char **, int); 51 | 52 | extern int64_t _wrap_tts_CThostFtdcMdApi_UnSubscribeMarketData(uintptr_t, char **, int); 53 | 54 | extern int64_t _wrap_tts_CThostFtdcMdApi_SubscribeForQuoteRsp(uintptr_t, char **, int); 55 | 56 | extern int64_t _wrap_tts_CThostFtdcMdApi_UnSubscribeForQuoteRsp(uintptr_t, char **, int); 57 | 58 | extern int64_t _wrap_tts_CThostFtdcMdApi_ReqUserLogin(uintptr_t, struct CThostFtdcReqUserLoginField *, int); 59 | 60 | extern int64_t _wrap_tts_CThostFtdcMdApi_ReqUserLogout(uintptr_t, struct CThostFtdcUserLogoutField *, int); 61 | 62 | extern int64_t _wrap_tts_CThostFtdcMdApi_ReqQryMulticastInstrument(uintptr_t, struct CThostFtdcQryMulticastInstrumentField *, int); 63 | 64 | */ 65 | import "C" 66 | import ( 67 | "os" 68 | "path/filepath" 69 | "runtime/cgo" 70 | "strings" 71 | "unsafe" 72 | 73 | "github.com/pseudocodes/go2ctp/thost" 74 | ) 75 | 76 | const ( 77 | defaultFlowPath = "" 78 | defaultIsUsingUdp = false 79 | defaultIsMulticast = false 80 | defaultIsProductionMode = true 81 | ) 82 | 83 | type MdOption func(api *MdApi) 84 | 85 | type MdApi struct { 86 | apiPtr uintptr 87 | spi thost.MdSpi 88 | 89 | dllPath string 90 | flowPath string 91 | usingUDP bool 92 | multicast bool 93 | production bool 94 | } 95 | 96 | func CreateMdApi(options ...MdOption) thost.MdApi { 97 | api := &MdApi{ 98 | flowPath: defaultFlowPath, 99 | usingUDP: defaultIsUsingUdp, 100 | multicast: defaultIsMulticast, 101 | production: defaultIsProductionMode, 102 | } 103 | handle := cgo.NewHandle(api) 104 | for _, opt := range options { 105 | opt(api) 106 | } 107 | if api.flowPath != "" { 108 | var err error 109 | if strings.HasSuffix(api.flowPath, "/") { 110 | err = os.MkdirAll(api.flowPath, os.ModePerm) 111 | } else { 112 | parentDir := filepath.Dir(api.flowPath) 113 | err = os.MkdirAll(parentDir, os.ModePerm) 114 | } 115 | if err != nil && !os.IsExist(err) { 116 | panic(err) 117 | } 118 | } 119 | 120 | cflowPath := C.CString(api.flowPath) 121 | defer C.free(unsafe.Pointer(cflowPath)) 122 | 123 | cdllPath := C.CString(api.dllPath) 124 | defer C.free(unsafe.Pointer(cdllPath)) 125 | 126 | api.apiPtr = uintptr(C._wrap_tts_CThostFtdcMdApi_CreateFtdcMdApi3(C.uintptr_t(handle), cdllPath, cflowPath, C._Bool(api.usingUDP), C._Bool(api.multicast), C._Bool(api.production))) 127 | 128 | return api 129 | } 130 | 131 | // /获取API的版本信息 132 | // /@retrun 获取到的版本号 133 | func (c *MdApi) GetApiVersion() string { 134 | cString := C._wrap_tts_CThostFtdcMdApi_GetApiVersion(C.uintptr_t(c.apiPtr)) 135 | return C.GoString(cString) 136 | } 137 | 138 | // 删除接口对象本身 139 | // /@remark 不再使用本接口对象时,调用该函数删除接口对象 140 | func (c *MdApi) Release() { 141 | C._wrap_tts_CThostFtdcMdApi_RegisterSpi(C.uintptr_t(c.apiPtr), C.uintptr_t(0)) 142 | C._wrap_tts_CThostFtdcMdApi_Release(C.uintptr_t(c.apiPtr)) 143 | } 144 | 145 | // 初始化 146 | // /@remark 初始化运行环境,只有调用后,接口才开始工作 147 | func (c *MdApi) Init() { 148 | C._wrap_tts_CThostFtdcMdApi_Init(C.uintptr_t(c.apiPtr)) 149 | } 150 | 151 | // 等待接口线程结束运行 152 | // /@return 线程退出代码 153 | func (c *MdApi) Join() int { 154 | return (int)(C._wrap_tts_CThostFtdcMdApi_Join(C.uintptr_t(c.apiPtr))) 155 | } 156 | 157 | // /获取当前交易日 158 | // /@retrun 获取到的交易日 159 | // /@remark 只有登录成功后,才能得到正确的交易日 160 | func (c *MdApi) GetTradingDay() string { 161 | cString := C._wrap_tts_CThostFtdcMdApi_GetTradingDay(C.uintptr_t(c.apiPtr)) 162 | return C.GoString(cString) 163 | } 164 | 165 | func (c *MdApi) RegisterFront(frontAddress string) { 166 | addr := C.CString(frontAddress) 167 | defer C.free(unsafe.Pointer(addr)) 168 | C._wrap_tts_CThostFtdcMdApi_RegisterFront(C.uintptr_t(c.apiPtr), addr) 169 | } 170 | 171 | // 注册名字服务器用户信息 172 | func (c *MdApi) RegisterNameServer(nsAddress string) { 173 | addr := C.CString(nsAddress) 174 | defer C.free(unsafe.Pointer(addr)) 175 | C._wrap_tts_CThostFtdcMdApi_RegisterNameServer(C.uintptr_t(c.apiPtr), addr) 176 | } 177 | 178 | // /@param pFensUserInfo:用户信息。 179 | func (c *MdApi) RegisterFensUserInfo(pFensUserInfo *thost.CThostFtdcFensUserInfoField) { 180 | C._wrap_tts_CThostFtdcMdApi_RegisterFensUserInfo(C.uintptr_t(c.apiPtr), (*C.struct_CThostFtdcFensUserInfoField)(unsafe.Pointer(pFensUserInfo))) 181 | } 182 | 183 | // 注册回调接口 184 | // /@param pSpi 派生自回调接口类的实例 185 | func (c *MdApi) RegisterSpi(pSpi thost.MdSpi) { 186 | c.spi = pSpi 187 | } 188 | 189 | // /订阅行情。 190 | // /@param ppInstrumentID 合约ID 191 | // /@param nCount 要订阅/退订行情的合约个数 192 | // /@remark 193 | func (c *MdApi) SubscribeMarketData(instrumentIDs ...string) int { 194 | cinlist := []*C.char{} 195 | for _, ins := range instrumentIDs { 196 | cinlist = append(cinlist, C.CString(ins)) 197 | } 198 | defer func() { 199 | for i := range cinlist { 200 | C.free(unsafe.Pointer(cinlist[i])) 201 | } 202 | }() 203 | 204 | return (int)(C._wrap_tts_CThostFtdcMdApi_SubscribeMarketData(C.uintptr_t(c.apiPtr), (**C.char)(unsafe.Pointer(&cinlist[0])), C.int(len(cinlist)))) 205 | } 206 | 207 | // /退订行情。 208 | // /@param ppInstrumentID 合约ID 209 | // /@param nCount 要订阅/退订行情的合约个数 210 | // /@remark 211 | func (c *MdApi) UnSubscribeMarketData(instrumentIDs ...string) int { 212 | cinlist := []*C.char{} 213 | for _, ins := range instrumentIDs { 214 | cinlist = append(cinlist, C.CString(ins)) 215 | } 216 | defer func() { 217 | for i := range cinlist { 218 | C.free(unsafe.Pointer(cinlist[i])) 219 | } 220 | }() 221 | 222 | return (int)(C._wrap_tts_CThostFtdcMdApi_UnSubscribeMarketData(C.uintptr_t(c.apiPtr), (**C.char)(unsafe.Pointer(&cinlist[0])), C.int(len(cinlist)))) 223 | } 224 | 225 | // /订阅询价。 226 | // /@param ppInstrumentID 合约ID 227 | // /@param nCount 要订阅/退订行情的合约个数 228 | // /@remark 229 | func (c *MdApi) SubscribeForQuoteRsp(instrumentIDs ...string) int { 230 | cinlist := []*C.char{} 231 | for _, ins := range instrumentIDs { 232 | cinlist = append(cinlist, C.CString(ins)) 233 | } 234 | defer func() { 235 | for i := range cinlist { 236 | C.free(unsafe.Pointer(cinlist[i])) 237 | } 238 | }() 239 | 240 | return (int)(C._wrap_tts_CThostFtdcMdApi_SubscribeForQuoteRsp(C.uintptr_t(c.apiPtr), (**C.char)(unsafe.Pointer(&cinlist[0])), C.int(len(cinlist)))) 241 | } 242 | 243 | // /退订询价。 244 | // /@param ppInstrumentID 合约ID 245 | // /@param nCount 要订阅/退订行情的合约个数 246 | // /@remark 247 | func (c *MdApi) UnSubscribeForQuoteRsp(instrumentIDs ...string) int { 248 | cinlist := []*C.char{} 249 | for _, ins := range instrumentIDs { 250 | cinlist = append(cinlist, C.CString(ins)) 251 | } 252 | defer func() { 253 | for i := range cinlist { 254 | C.free(unsafe.Pointer(cinlist[i])) 255 | } 256 | }() 257 | 258 | return (int)(C._wrap_tts_CThostFtdcMdApi_UnSubscribeForQuoteRsp(C.uintptr_t(c.apiPtr), (**C.char)(unsafe.Pointer(&cinlist[0])), C.int(len(cinlist)))) 259 | } 260 | 261 | // 用户登录请求 262 | func (c *MdApi) ReqUserLogin(pReqUserLoginField *thost.CThostFtdcReqUserLoginField, nRequestID int) int { 263 | return (int)(C._wrap_tts_CThostFtdcMdApi_ReqUserLogin(C.uintptr_t(c.apiPtr), (*C.struct_CThostFtdcReqUserLoginField)(unsafe.Pointer(pReqUserLoginField)), C.int(nRequestID))) 264 | } 265 | 266 | // 登出请求 267 | func (c *MdApi) ReqUserLogout(pUserLogout *thost.CThostFtdcUserLogoutField, nRequestID int) int { 268 | return (int)(C._wrap_tts_CThostFtdcMdApi_ReqUserLogout(C.uintptr_t(c.apiPtr), (*C.struct_CThostFtdcUserLogoutField)(unsafe.Pointer(pUserLogout)), C.int(nRequestID))) 269 | } 270 | 271 | // 请求查询组播合约 272 | func (c *MdApi) ReqQryMulticastInstrument(pQryMulticastInstrument *thost.CThostFtdcQryMulticastInstrumentField, nRequestID int) int { 273 | return (int)(C._wrap_tts_CThostFtdcMdApi_ReqQryMulticastInstrument(C.uintptr_t(c.apiPtr), (*C.struct_CThostFtdcQryMulticastInstrumentField)(unsafe.Pointer(pQryMulticastInstrument)), C.int(nRequestID))) 274 | } 275 | 276 | //export wrap_tts_MdOnFrontConnected 277 | func wrap_tts_MdOnFrontConnected(v uintptr) { 278 | api := cgo.Handle(v).Value().(*MdApi) 279 | api.spi.OnFrontConnected() 280 | } 281 | 282 | //export wrap_tts_MdOnFrontDisconnected 283 | func wrap_tts_MdOnFrontDisconnected(v uintptr, nReason C.int) { 284 | api := cgo.Handle(v).Value().(*MdApi) 285 | api.spi.OnFrontDisconnected(int(nReason)) 286 | } 287 | 288 | //export wrap_tts_MdOnHeartBeatWarning 289 | func wrap_tts_MdOnHeartBeatWarning(v uintptr, nTimeLapse C.int) { 290 | api := cgo.Handle(v).Value().(*MdApi) 291 | api.spi.OnHeartBeatWarning(int(nTimeLapse)) 292 | } 293 | 294 | //export wrap_tts_MdOnRspUserLogin 295 | func wrap_tts_MdOnRspUserLogin(v uintptr, pRspUserLogin *C.struct_CThostFtdcRspUserLoginField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 296 | api := cgo.Handle(v).Value().(*MdApi) 297 | api.spi.OnRspUserLogin((*thost.CThostFtdcRspUserLoginField)(unsafe.Pointer(pRspUserLogin)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 298 | } 299 | 300 | //export wrap_tts_MdOnRspUserLogout 301 | func wrap_tts_MdOnRspUserLogout(v uintptr, pUserLogout *C.struct_CThostFtdcUserLogoutField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 302 | api := cgo.Handle(v).Value().(*MdApi) 303 | api.spi.OnRspUserLogout((*thost.CThostFtdcUserLogoutField)(unsafe.Pointer(pUserLogout)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 304 | } 305 | 306 | //export wrap_tts_MdOnRspQryMulticastInstrument 307 | func wrap_tts_MdOnRspQryMulticastInstrument(v uintptr, pMulticastInstrument *C.struct_CThostFtdcMulticastInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 308 | api := cgo.Handle(v).Value().(*MdApi) 309 | api.spi.OnRspQryMulticastInstrument((*thost.CThostFtdcMulticastInstrumentField)(unsafe.Pointer(pMulticastInstrument)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 310 | } 311 | 312 | //export wrap_tts_MdOnRspError 313 | func wrap_tts_MdOnRspError(v uintptr, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 314 | api := cgo.Handle(v).Value().(*MdApi) 315 | api.spi.OnRspError((*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 316 | } 317 | 318 | //export wrap_tts_MdOnRspSubMarketData 319 | func wrap_tts_MdOnRspSubMarketData(v uintptr, pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 320 | api := cgo.Handle(v).Value().(*MdApi) 321 | api.spi.OnRspSubMarketData((*thost.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 322 | } 323 | 324 | //export wrap_tts_MdOnRspUnSubMarketData 325 | func wrap_tts_MdOnRspUnSubMarketData(v uintptr, pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 326 | api := cgo.Handle(v).Value().(*MdApi) 327 | api.spi.OnRspUnSubMarketData((*thost.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 328 | } 329 | 330 | //export wrap_tts_MdOnRspSubForQuoteRsp 331 | func wrap_tts_MdOnRspSubForQuoteRsp(v uintptr, pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 332 | api := cgo.Handle(v).Value().(*MdApi) 333 | api.spi.OnRspSubForQuoteRsp((*thost.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 334 | } 335 | 336 | //export wrap_tts_MdOnRspUnSubForQuoteRsp 337 | func wrap_tts_MdOnRspUnSubForQuoteRsp(v uintptr, pSpecificInstrument *C.struct_CThostFtdcSpecificInstrumentField, pRspInfo *C.struct_CThostFtdcRspInfoField, nRequestID C.int, bIsLast C._Bool) { 338 | api := cgo.Handle(v).Value().(*MdApi) 339 | api.spi.OnRspUnSubForQuoteRsp((*thost.CThostFtdcSpecificInstrumentField)(unsafe.Pointer(pSpecificInstrument)), (*thost.CThostFtdcRspInfoField)(unsafe.Pointer(pRspInfo)), int(nRequestID), bool(bIsLast)) 340 | } 341 | 342 | //export wrap_tts_MdOnRtnDepthMarketData 343 | func wrap_tts_MdOnRtnDepthMarketData(v uintptr, pDepthMarketData *C.struct_CThostFtdcDepthMarketDataField) { 344 | api := cgo.Handle(v).Value().(*MdApi) 345 | api.spi.OnRtnDepthMarketData((*thost.CThostFtdcDepthMarketDataField)(unsafe.Pointer(pDepthMarketData))) 346 | } 347 | 348 | //export wrap_tts_MdOnRtnForQuoteRsp 349 | func wrap_tts_MdOnRtnForQuoteRsp(v uintptr, pForQuoteRsp *C.struct_CThostFtdcForQuoteRspField) { 350 | api := cgo.Handle(v).Value().(*MdApi) 351 | api.spi.OnRtnForQuoteRsp((*thost.CThostFtdcForQuoteRspField)(unsafe.Pointer(pForQuoteRsp))) 352 | } 353 | 354 | // ----------------------------------------------------- 355 | func MdFlowPath(path string) MdOption { 356 | return func(api *MdApi) { 357 | api.flowPath = path 358 | } 359 | } 360 | 361 | func MdUsingUDP(usingudp bool) MdOption { 362 | return func(api *MdApi) { 363 | api.usingUDP = usingudp 364 | } 365 | } 366 | 367 | func MdMultiCast(multicast bool) MdOption { 368 | return func(api *MdApi) { 369 | api.multicast = multicast 370 | } 371 | } 372 | 373 | func MdDynamicLibPath(path string) MdOption { 374 | return func(api *MdApi) { 375 | api.dllPath = path 376 | } 377 | } 378 | 379 | func MdProductionMode(production bool) MdOption { 380 | return func(api *MdApi) { 381 | api.production = production 382 | } 383 | } 384 | -------------------------------------------------------------------------------- /ctp_dyn/mdapi_wrap.cxx: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include "ThostFtdcMdApi.h" 25 | #include "ThostFtdcTraderApi.h" 26 | #include "ThostFtdcUserApiDataType.h" 27 | #include "ThostFtdcUserApiStruct.h" 28 | 29 | #include "mdapi_wrap.h" 30 | 31 | const char* MdApiCreateSymbol = "_ZN15CThostFtdcMdApi15CreateFtdcMdApiEPKcbbb"; 32 | const char* MdApiVersionSymbol = "_ZN15CThostFtdcMdApi13GetApiVersionEv"; 33 | 34 | typedef long long intgo; 35 | typedef struct 36 | { 37 | char* p; 38 | int64_t n; 39 | } _gostring_; 40 | 41 | typedef struct 42 | { 43 | void* array; 44 | int64_t len; 45 | int64_t cap; 46 | } _goslice_; 47 | 48 | #ifdef __cplusplus 49 | extern "C" { 50 | #endif 51 | TTSCTPMdSpi* _wrap_tts_CThostFtdcMdApi_CreateFtdcMdApi() 52 | { 53 | // CThostFtdcMdApi* pUserApi = CThostFtdcMdApi::CreateFtdcMdApi("./data/", false); 54 | // TTSCTPMdSpi* pUserSpi = new TTSCTPMdSpi(pUserApi); 55 | // pUserSpi->RegisterSpi(pUserSpi); 56 | // return pUserSpi; 57 | return nullptr; 58 | } 59 | 60 | TTSCTPMdSpi* _wrap_tts_CThostFtdcMdApi_CreateFtdcMdApi2(uintptr_t gUserApi, const char* pszFlowPath, const bool bIsUsingUdp, const bool bIsMulticast) 61 | { 62 | // printf("go_user_api %lu\n", gUserApi); 63 | // CThostFtdcMdApi* pUserApi = CThostFtdcMdApi::CreateFtdcMdApi(pszFlowPath, bIsUsingUdp, bIsMulticast); 64 | // TTSCTPMdSpi* pUserSpi = new TTSCTPMdSpi(pUserApi, gUserApi); 65 | // TTSCTPMdSpi* pUserSpi = new TTSCTPMdSpi(gUserApi, pszDLLPath, pszFlowPath, bIsUsingUdp, bIsMulticast); 66 | // pUserSpi->RegisterSpi(pUserSpi); 67 | return nullptr; 68 | } 69 | 70 | TTSCTPMdSpi* _wrap_tts_CThostFtdcMdApi_CreateFtdcMdApi3(uintptr_t gUserApi, const char* pszDLLPath, const char* pszFlowPath, const bool bIsUsingUdp, const bool bIsMulticast, bool bIsProductionMode) 71 | { 72 | // printf("go_user_api %lu\n", gUserApi); 73 | // CThostFtdcMdApi* pUserApi = CThostFtdcMdApi::CreateFtdcMdApi(pszFlowPath, bIsUsingUdp, bIsMulticast); 74 | // TTSCTPMdSpi* pUserSpi = new TTSCTPMdSpi(pUserApi, gUserApi); 75 | TTSCTPMdSpi* pUserSpi = new TTSCTPMdSpi(gUserApi, pszDLLPath, pszFlowPath, bIsUsingUdp, bIsMulticast, bIsProductionMode); 76 | pUserSpi->RegisterSpi(pUserSpi); 77 | return pUserSpi; 78 | } 79 | 80 | // 获取API的版本信息 81 | ///@retrun 获取到的版本号 82 | const char* _wrap_tts_CThostFtdcMdApi_GetApiVersion(TTSCTPMdSpi* pMdApi) 83 | { 84 | return pMdApi->GetApiVersion(); 85 | } 86 | 87 | // 删除接口对象本身 88 | ///@remark 不再使用本接口对象时,调用该函数删除接口对象 89 | void _wrap_tts_CThostFtdcMdApi_Release(TTSCTPMdSpi* pMdApi) 90 | { 91 | return pMdApi->Release(); 92 | } 93 | 94 | // 初始化 95 | ///@remark 初始化运行环境,只有调用后,接口才开始工作 96 | void _wrap_tts_CThostFtdcMdApi_Init(TTSCTPMdSpi* pMdApi) 97 | { 98 | return pMdApi->Init(); 99 | } 100 | 101 | // 等待接口线程结束运行 102 | ///@return 线程退出代码 103 | int _wrap_tts_CThostFtdcMdApi_Join(TTSCTPMdSpi* pMdApi) 104 | { 105 | return pMdApi->Join(); 106 | } 107 | 108 | // 获取当前交易日 109 | ///@retrun 获取到的交易日 110 | ///@remark 只有登录成功后,才能得到正确的交易日 111 | const char* _wrap_tts_CThostFtdcMdApi_GetTradingDay(TTSCTPMdSpi* pMdApi) 112 | { 113 | return pMdApi->GetTradingDay(); 114 | } 115 | 116 | // 注册前置机网络地址 117 | ///@param pszFrontAddress:前置机网络地址。 118 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:17001”。 119 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。 120 | void _wrap_tts_CThostFtdcMdApi_RegisterFront(TTSCTPMdSpi* pMdApi, char* pszFrontAddress) 121 | { 122 | return pMdApi->RegisterFront(pszFrontAddress); 123 | } 124 | 125 | // 注册名字服务器网络地址 126 | ///@param pszNsAddress:名字服务器网络地址。 127 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:12001”。 128 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”12001”代表服务器端口号。 129 | ///@remark RegisterNameServer优先于RegisterFront 130 | void _wrap_tts_CThostFtdcMdApi_RegisterNameServer(TTSCTPMdSpi* pMdApi, char* pszNsAddress) 131 | { 132 | return pMdApi->RegisterNameServer(pszNsAddress); 133 | } 134 | 135 | // 注册名字服务器用户信息 136 | ///@param pFensUserInfo:用户信息。 137 | void _wrap_tts_CThostFtdcMdApi_RegisterFensUserInfo(TTSCTPMdSpi* pMdApi, CThostFtdcFensUserInfoField* pFensUserInfo) 138 | { 139 | return pMdApi->RegisterFensUserInfo(pFensUserInfo); 140 | } 141 | 142 | /// 注册回调接口 143 | ///@param pSpi 派生自回调接口类的实例 144 | void _wrap_tts_CThostFtdcMdApi_RegisterSpi(TTSCTPMdSpi* pMdApi, CThostFtdcMdSpi* pSpi) 145 | { 146 | return pMdApi->RegisterSpi(pSpi); 147 | } 148 | 149 | // 订阅行情。 150 | ///@param ppInstrumentID 合约ID 151 | ///@param nCount 要订阅/退订行情的合约个数 152 | ///@remark 153 | int _wrap_tts_CThostFtdcMdApi_SubscribeMarketData(TTSCTPMdSpi* pMdApi, char** ppInstrumentID, int nCount) 154 | { 155 | return pMdApi->SubscribeMarketData(ppInstrumentID, nCount); 156 | } 157 | 158 | // 退订行情。 159 | ///@param ppInstrumentID 合约ID 160 | ///@param nCount 要订阅/退订行情的合约个数 161 | ///@remark 162 | int _wrap_tts_CThostFtdcMdApi_UnSubscribeMarketData(TTSCTPMdSpi* pMdApi, char** ppInstrumentID, int nCount) 163 | { 164 | return pMdApi->UnSubscribeMarketData(ppInstrumentID, nCount); 165 | } 166 | 167 | // 订阅询价。 168 | ///@param ppInstrumentID 合约ID 169 | ///@param nCount 要订阅/退订行情的合约个数 170 | ///@remark 171 | int _wrap_tts_CThostFtdcMdApi_SubscribeForQuoteRsp(TTSCTPMdSpi* pMdApi, char** ppInstrumentID, int nCount) 172 | { 173 | return pMdApi->SubscribeForQuoteRsp(ppInstrumentID, nCount); 174 | } 175 | 176 | // 退订询价。 177 | ///@param ppInstrumentID 合约ID 178 | ///@param nCount 要订阅/退订行情的合约个数 179 | ///@remark 180 | int _wrap_tts_CThostFtdcMdApi_UnSubscribeForQuoteRsp(TTSCTPMdSpi* pMdApi, char** ppInstrumentID, int nCount) 181 | { 182 | return pMdApi->UnSubscribeForQuoteRsp(ppInstrumentID, nCount); 183 | } 184 | 185 | // 用户登录请求 186 | int _wrap_tts_CThostFtdcMdApi_ReqUserLogin(TTSCTPMdSpi* pMdApi, CThostFtdcReqUserLoginField* pReqUserLoginField, int nRequestID) 187 | { 188 | int ret = pMdApi->ReqUserLogin(pReqUserLoginField, nRequestID); 189 | printf("req_user_login: %d", ret); 190 | return ret; 191 | } 192 | 193 | // 登出请求 194 | int _wrap_tts_CThostFtdcMdApi_ReqUserLogout(TTSCTPMdSpi* pMdApi, CThostFtdcUserLogoutField* pUserLogout, int nRequestID) 195 | { 196 | return pMdApi->ReqUserLogout(pUserLogout, nRequestID); 197 | } 198 | 199 | // 请求查询组播合约 200 | int _wrap_tts_CThostFtdcMdApi_ReqQryMulticastInstrument(TTSCTPMdSpi* pMdApi, CThostFtdcQryMulticastInstrumentField* pQryMulticastInstrument, int nRequestID) 201 | { 202 | return pMdApi->ReqQryMulticastInstrument(pQryMulticastInstrument, nRequestID); 203 | } 204 | 205 | #ifdef __cplusplus 206 | } 207 | #endif 208 | 209 | // 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 210 | extern "C" void wrap_tts_MdOnFrontConnected(uintptr_t); 211 | void TTSCTPMdSpi::OnFrontConnected() 212 | { 213 | wrap_tts_MdOnFrontConnected(gUserApi); 214 | } 215 | 216 | // 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 217 | ///@param nReason 错误原因 218 | /// 0x1001 网络读失败 219 | /// 0x1002 网络写失败 220 | /// 0x2001 接收心跳超时 221 | /// 0x2002 发送心跳失败 222 | /// 0x2003 收到错误报文 223 | extern "C" void wrap_tts_MdOnFrontDisconnected(uintptr_t, int); 224 | void TTSCTPMdSpi::OnFrontDisconnected(int nReason) 225 | { 226 | wrap_tts_MdOnFrontDisconnected(gUserApi, nReason); 227 | } 228 | 229 | // 心跳超时警告。当长时间未收到报文时,该方法被调用。 230 | ///@param nTimeLapse 距离上次接收报文的时间 231 | extern "C" void wrap_tts_MdOnHeartBeatWarning(uintptr_t, int); 232 | void TTSCTPMdSpi::OnHeartBeatWarning(int nTimeLapse) 233 | { 234 | wrap_tts_MdOnHeartBeatWarning(gUserApi, nTimeLapse); 235 | } 236 | 237 | // 登录请求响应 238 | extern "C" void wrap_tts_MdOnRspUserLogin(uintptr_t, CThostFtdcRspUserLoginField*, CThostFtdcRspInfoField*, int, bool); 239 | void TTSCTPMdSpi::OnRspUserLogin(CThostFtdcRspUserLoginField* pRspUserLogin, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 240 | { 241 | wrap_tts_MdOnRspUserLogin(gUserApi, pRspUserLogin, pRspInfo, nRequestID, bIsLast); 242 | } 243 | 244 | // 登出请求响应 245 | extern "C" void wrap_tts_MdOnRspUserLogout(uintptr_t, CThostFtdcUserLogoutField*, CThostFtdcRspInfoField*, int, bool); 246 | void TTSCTPMdSpi::OnRspUserLogout(CThostFtdcUserLogoutField* pUserLogout, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 247 | { 248 | wrap_tts_MdOnRspUserLogout(gUserApi, pUserLogout, pRspInfo, nRequestID, bIsLast); 249 | } 250 | 251 | // 请求查询组播合约响应 252 | extern "C" void wrap_tts_MdOnRspQryMulticastInstrument(uintptr_t, CThostFtdcMulticastInstrumentField*, CThostFtdcRspInfoField*, int, bool); 253 | void TTSCTPMdSpi::OnRspQryMulticastInstrument(CThostFtdcMulticastInstrumentField* pMulticastInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 254 | { 255 | wrap_tts_MdOnRspQryMulticastInstrument(gUserApi, pMulticastInstrument, pRspInfo, nRequestID, bIsLast); 256 | } 257 | 258 | // 错误应答 259 | extern "C" void wrap_tts_MdOnRspError(uintptr_t, CThostFtdcRspInfoField*, int, bool); 260 | void TTSCTPMdSpi::OnRspError(CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 261 | { 262 | wrap_tts_MdOnRspError(gUserApi, pRspInfo, nRequestID, bIsLast); 263 | } 264 | 265 | // 订阅行情应答 266 | extern "C" void wrap_tts_MdOnRspSubMarketData(uintptr_t, CThostFtdcSpecificInstrumentField*, CThostFtdcRspInfoField*, int, bool); 267 | void TTSCTPMdSpi::OnRspSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 268 | { 269 | wrap_tts_MdOnRspSubMarketData(gUserApi, pSpecificInstrument, pRspInfo, nRequestID, bIsLast); 270 | } 271 | 272 | // 取消订阅行情应答 273 | extern "C" void wrap_tts_MdOnRspUnSubMarketData(uintptr_t, CThostFtdcSpecificInstrumentField*, CThostFtdcRspInfoField*, int, bool); 274 | void TTSCTPMdSpi::OnRspUnSubMarketData(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 275 | { 276 | wrap_tts_MdOnRspUnSubMarketData(gUserApi, pSpecificInstrument, pRspInfo, nRequestID, bIsLast); 277 | } 278 | 279 | // 订阅询价应答 280 | extern "C" void wrap_tts_MdOnRspSubForQuoteRsp(uintptr_t, CThostFtdcSpecificInstrumentField*, CThostFtdcRspInfoField*, int, bool); 281 | void TTSCTPMdSpi::OnRspSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 282 | { 283 | wrap_tts_MdOnRspSubForQuoteRsp(gUserApi, pSpecificInstrument, pRspInfo, nRequestID, bIsLast); 284 | } 285 | 286 | // 取消订阅询价应答 287 | extern "C" void wrap_tts_MdOnRspUnSubForQuoteRsp(uintptr_t, CThostFtdcSpecificInstrumentField*, CThostFtdcRspInfoField*, int, bool); 288 | void TTSCTPMdSpi::OnRspUnSubForQuoteRsp(CThostFtdcSpecificInstrumentField* pSpecificInstrument, CThostFtdcRspInfoField* pRspInfo, int nRequestID, bool bIsLast) 289 | { 290 | wrap_tts_MdOnRspUnSubForQuoteRsp(gUserApi, pSpecificInstrument, pRspInfo, nRequestID, bIsLast); 291 | } 292 | 293 | // 深度行情通知 294 | extern "C" void wrap_tts_MdOnRtnDepthMarketData(uintptr_t, CThostFtdcDepthMarketDataField*); 295 | void TTSCTPMdSpi::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField* pDepthMarketData) 296 | { 297 | wrap_tts_MdOnRtnDepthMarketData(gUserApi, pDepthMarketData); 298 | } 299 | 300 | // 询价通知 301 | extern "C" void wrap_tts_MdOnRtnForQuoteRsp(uintptr_t, CThostFtdcForQuoteRspField*); 302 | void TTSCTPMdSpi::OnRtnForQuoteRsp(CThostFtdcForQuoteRspField* pForQuoteRsp) 303 | { 304 | wrap_tts_MdOnRtnForQuoteRsp(gUserApi, pForQuoteRsp); 305 | } 306 | 307 | TTSCTPMdSpi::TTSCTPMdSpi(CThostFtdcMdApi* pUserApi) 308 | { 309 | this->pUserApi = pUserApi; 310 | } 311 | 312 | TTSCTPMdSpi::TTSCTPMdSpi(CThostFtdcMdApi* pUserApi, uintptr_t gUserApi) 313 | { 314 | this->pUserApi = pUserApi; 315 | this->gUserApi = gUserApi; 316 | } 317 | 318 | TTSCTPMdSpi::TTSCTPMdSpi(uintptr_t gUserApi, const char* pszDLLPath, const char* pszFlowPath, const bool bIsUsingUdp, const bool bIsMulticast, bool bIsProductionMode) 319 | { 320 | typedef CThostFtdcMdApi* (*MdApiCreator)(const char*, const bool, const bool, bool); 321 | dllHandle = dlopen(pszDLLPath, RTLD_NOW); 322 | if (dllHandle == nullptr) { 323 | fprintf(stderr, "[%s] dlopen error: %s\n", pszDLLPath, dlerror()); 324 | exit(-1); 325 | } 326 | MdApiCreator mdcreator = (MdApiCreator)dlsym(dllHandle, MdApiCreateSymbol); 327 | if (mdcreator == nullptr) { 328 | fprintf(stderr, "[%s] dlsym error: %s\n", pszDLLPath, dlerror()); 329 | exit(-1); 330 | } 331 | printf("bIsUsingUdp: %d, bIsMulticast: %d, bIsProductionMode: %d\n", bIsUsingUdp, bIsMulticast, bIsProductionMode); 332 | this->pUserApi = mdcreator(pszFlowPath, bIsUsingUdp, bIsMulticast, bIsProductionMode); 333 | this->gUserApi = gUserApi; 334 | } 335 | 336 | TTSCTPMdSpi::~TTSCTPMdSpi() 337 | { 338 | if (this->pUserApi) { 339 | this->pUserApi->RegisterSpi(nullptr); 340 | this->pUserApi->Release(); 341 | this->pUserApi = nullptr; 342 | dlclose(dllHandle); 343 | } 344 | } 345 | 346 | uintptr_t _wrap_tts_CThostFtdcMdApi_DestroyUserMdApi(TTSCTPMdSpi* pMdApi) 347 | { 348 | delete (pMdApi); 349 | return 0; 350 | } 351 | 352 | // 获取API的版本信息 353 | ///@retrun 获取到的版本号 354 | const char* TTSCTPMdSpi::GetApiVersion() 355 | { 356 | typedef const char* (*GetApiVersion)(); 357 | GetApiVersion getVersion = (GetApiVersion)dlsym(this->dllHandle, MdApiVersionSymbol); 358 | // return this->pUserApi->GetApiVersion(); 359 | return getVersion(); 360 | } 361 | 362 | // 删除接口对象本身 363 | ///@remark 不再使用本接口对象时,调用该函数删除接口对象 364 | void TTSCTPMdSpi::Release() 365 | { 366 | this->pUserApi->RegisterSpi(NULL); 367 | return this->pUserApi->Release(); 368 | } 369 | 370 | // 初始化 371 | ///@remark 初始化运行环境,只有调用后,接口才开始工作 372 | void TTSCTPMdSpi::Init() 373 | { 374 | this->pUserApi->Init(); 375 | } 376 | 377 | // 等待接口线程结束运行 378 | ///@return 线程退出代码 379 | int TTSCTPMdSpi::Join() 380 | { 381 | return this->pUserApi->Join(); 382 | } 383 | 384 | // 获取当前交易日 385 | ///@retrun 获取到的交易日 386 | ///@remark 只有登录成功后,才能得到正确的交易日 387 | const char* TTSCTPMdSpi::GetTradingDay() 388 | { 389 | return this->pUserApi->GetTradingDay(); 390 | } 391 | 392 | // 注册前置机网络地址 393 | ///@param pszFrontAddress:前置机网络地址。 394 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:17001”。 395 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。 396 | void TTSCTPMdSpi::RegisterFront(char* pszFrontAddress) 397 | { 398 | this->pUserApi->RegisterFront(pszFrontAddress); 399 | } 400 | 401 | // 注册名字服务器网络地址 402 | ///@param pszNsAddress:名字服务器网络地址。 403 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:12001”。 404 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”12001”代表服务器端口号。 405 | ///@remark RegisterNameServer优先于RegisterFront 406 | void TTSCTPMdSpi::RegisterNameServer(char* pszNsAddress) 407 | { 408 | this->pUserApi->RegisterNameServer(pszNsAddress); 409 | } 410 | 411 | // 注册名字服务器用户信息 412 | ///@param pFensUserInfo:用户信息。 413 | void TTSCTPMdSpi::RegisterFensUserInfo(CThostFtdcFensUserInfoField* pFensUserInfo) 414 | { 415 | this->pUserApi->RegisterFensUserInfo(pFensUserInfo); 416 | } 417 | 418 | // 注册回调接口 419 | ///@param pSpi 派生自回调接口类的实例 420 | void TTSCTPMdSpi::RegisterSpi(CThostFtdcMdSpi* pSpi) 421 | { 422 | this->pUserApi->RegisterSpi(pSpi); 423 | } 424 | 425 | // 订阅行情。 426 | ///@param ppInstrumentID 合约ID 427 | ///@param nCount 要订阅/退订行情的合约个数 428 | ///@remark 429 | int TTSCTPMdSpi::SubscribeMarketData(char** ppInstrumentID, int nCount) 430 | { 431 | return this->pUserApi->SubscribeMarketData(ppInstrumentID, nCount); 432 | } 433 | 434 | // 退订行情。 435 | ///@param ppInstrumentID 合约ID 436 | ///@param nCount 要订阅/退订行情的合约个数 437 | ///@remark 438 | int TTSCTPMdSpi::UnSubscribeMarketData(char** ppInstrumentID, int nCount) 439 | { 440 | return this->pUserApi->UnSubscribeMarketData(ppInstrumentID, nCount); 441 | } 442 | 443 | // 订阅询价。 444 | ///@param ppInstrumentID 合约ID 445 | ///@param nCount 要订阅/退订行情的合约个数 446 | ///@remark 447 | int TTSCTPMdSpi::SubscribeForQuoteRsp(char** ppInstrumentID, int nCount) 448 | { 449 | return this->pUserApi->SubscribeForQuoteRsp(ppInstrumentID, nCount); 450 | } 451 | 452 | // 退订询价。 453 | ///@param ppInstrumentID 合约ID 454 | ///@param nCount 要订阅/退订行情的合约个数 455 | ///@remark 456 | int TTSCTPMdSpi::UnSubscribeForQuoteRsp(char** ppInstrumentID, int nCount) 457 | { 458 | return this->pUserApi->UnSubscribeForQuoteRsp(ppInstrumentID, nCount); 459 | } 460 | 461 | // 用户登录请求 462 | int TTSCTPMdSpi::ReqUserLogin(CThostFtdcReqUserLoginField* pReqUserLoginField, int nRequestID) 463 | { 464 | return this->pUserApi->ReqUserLogin(pReqUserLoginField, nRequestID); 465 | } 466 | 467 | // 登出请求 468 | int TTSCTPMdSpi::ReqUserLogout(CThostFtdcUserLogoutField* pUserLogout, int nRequestID) 469 | { 470 | return this->pUserApi->ReqUserLogout(pUserLogout, nRequestID); 471 | } 472 | 473 | // 请求查询组播合约 474 | int TTSCTPMdSpi::ReqQryMulticastInstrument(CThostFtdcQryMulticastInstrumentField* pQryMulticastInstrument, int nRequestID) 475 | { 476 | return this->pUserApi->ReqQryMulticastInstrument(pQryMulticastInstrument, nRequestID); 477 | } 478 | -------------------------------------------------------------------------------- /ctp/lib/v6.7.11_20250617_api_traderapi_se_linux64/error.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | -------------------------------------------------------------------------------- /thost/traderapi.go: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"); 2 | // you may not use this file except in compliance with the License. 3 | // You may obtain a copy of the License at 4 | // 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | // Unless required by applicable law or agreed to in writing, software 8 | // distributed under the License is distributed on an "AS IS" BASIS, 9 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 | // See the License for the specific language governing permissions and 11 | // limitations under the License. 12 | 13 | package thost 14 | 15 | type TraderSpi interface { 16 | 17 | /// 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 18 | OnFrontConnected() 19 | 20 | /// 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 21 | ///@param nReason 错误原因 22 | /// 0x1001 网络读失败 23 | /// 0x1002 网络写失败 24 | /// 0x2001 接收心跳超时 25 | /// 0x2002 发送心跳失败 26 | /// 0x2003 收到错误报文 27 | OnFrontDisconnected(nReason int) 28 | 29 | /// 心跳超时警告。当长时间未收到报文时,该方法被调用。 30 | ///@param nTimeLapse 距离上次接收报文的时间 31 | OnHeartBeatWarning(nTimeLapse int) 32 | 33 | /// 客户端认证响应 34 | OnRspAuthenticate(pRspAuthenticateField *CThostFtdcRspAuthenticateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 35 | 36 | /// 登录请求响应 37 | OnRspUserLogin(pRspUserLogin *CThostFtdcRspUserLoginField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 38 | 39 | /// 登出请求响应 40 | OnRspUserLogout(pUserLogout *CThostFtdcUserLogoutField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 41 | 42 | /// 用户口令更新请求响应 43 | OnRspUserPasswordUpdate(pUserPasswordUpdate *CThostFtdcUserPasswordUpdateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 44 | 45 | /// 资金账户口令更新请求响应 46 | OnRspTradingAccountPasswordUpdate(pTradingAccountPasswordUpdate *CThostFtdcTradingAccountPasswordUpdateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 47 | 48 | /// 查询用户当前支持的认证模式的回复 49 | OnRspUserAuthMethod(pRspUserAuthMethod *CThostFtdcRspUserAuthMethodField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 50 | 51 | /// 获取图形验证码请求的回复 52 | OnRspGenUserCaptcha(pRspGenUserCaptcha *CThostFtdcRspGenUserCaptchaField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 53 | 54 | /// 获取短信验证码请求的回复 55 | OnRspGenUserText(pRspGenUserText *CThostFtdcRspGenUserTextField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 56 | 57 | /// 报单录入请求响应 58 | OnRspOrderInsert(pInputOrder *CThostFtdcInputOrderField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 59 | 60 | /// 预埋单录入请求响应 61 | OnRspParkedOrderInsert(pParkedOrder *CThostFtdcParkedOrderField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 62 | 63 | /// 预埋撤单录入请求响应 64 | OnRspParkedOrderAction(pParkedOrderAction *CThostFtdcParkedOrderActionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 65 | 66 | /// 报单操作请求响应 67 | OnRspOrderAction(pInputOrderAction *CThostFtdcInputOrderActionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 68 | 69 | /// 查询最大报单数量响应 70 | OnRspQryMaxOrderVolume(pQryMaxOrderVolume *CThostFtdcQryMaxOrderVolumeField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 71 | 72 | /// 投资者结算结果确认响应 73 | OnRspSettlementInfoConfirm(pSettlementInfoConfirm *CThostFtdcSettlementInfoConfirmField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 74 | 75 | /// 删除预埋单响应 76 | OnRspRemoveParkedOrder(pRemoveParkedOrder *CThostFtdcRemoveParkedOrderField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 77 | 78 | /// 删除预埋撤单响应 79 | OnRspRemoveParkedOrderAction(pRemoveParkedOrderAction *CThostFtdcRemoveParkedOrderActionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 80 | 81 | /// 执行宣告录入请求响应 82 | OnRspExecOrderInsert(pInputExecOrder *CThostFtdcInputExecOrderField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 83 | 84 | /// 执行宣告操作请求响应 85 | OnRspExecOrderAction(pInputExecOrderAction *CThostFtdcInputExecOrderActionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 86 | 87 | /// 询价录入请求响应 88 | OnRspForQuoteInsert(pInputForQuote *CThostFtdcInputForQuoteField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 89 | 90 | /// 报价录入请求响应 91 | OnRspQuoteInsert(pInputQuote *CThostFtdcInputQuoteField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 92 | 93 | /// 报价操作请求响应 94 | OnRspQuoteAction(pInputQuoteAction *CThostFtdcInputQuoteActionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 95 | 96 | /// 批量报单操作请求响应 97 | OnRspBatchOrderAction(pInputBatchOrderAction *CThostFtdcInputBatchOrderActionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 98 | 99 | /// 期权自对冲录入请求响应 100 | OnRspOptionSelfCloseInsert(pInputOptionSelfClose *CThostFtdcInputOptionSelfCloseField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 101 | 102 | /// 期权自对冲操作请求响应 103 | OnRspOptionSelfCloseAction(pInputOptionSelfCloseAction *CThostFtdcInputOptionSelfCloseActionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 104 | 105 | /// 申请组合录入请求响应 106 | OnRspCombActionInsert(pInputCombAction *CThostFtdcInputCombActionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 107 | 108 | /// 请求查询报单响应 109 | OnRspQryOrder(pOrder *CThostFtdcOrderField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 110 | 111 | /// 请求查询成交响应 112 | OnRspQryTrade(pTrade *CThostFtdcTradeField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 113 | 114 | /// 请求查询投资者持仓响应 115 | OnRspQryInvestorPosition(pInvestorPosition *CThostFtdcInvestorPositionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 116 | 117 | /// 请求查询资金账户响应 118 | OnRspQryTradingAccount(pTradingAccount *CThostFtdcTradingAccountField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 119 | 120 | /// 请求查询投资者响应 121 | OnRspQryInvestor(pInvestor *CThostFtdcInvestorField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 122 | 123 | /// 请求查询交易编码响应 124 | OnRspQryTradingCode(pTradingCode *CThostFtdcTradingCodeField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 125 | 126 | /// 请求查询合约保证金率响应 127 | OnRspQryInstrumentMarginRate(pInstrumentMarginRate *CThostFtdcInstrumentMarginRateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 128 | 129 | /// 请求查询合约手续费率响应 130 | OnRspQryInstrumentCommissionRate(pInstrumentCommissionRate *CThostFtdcInstrumentCommissionRateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 131 | 132 | /// 请求查询用户会话响应 133 | OnRspQryUserSession(pUserSession *CThostFtdcUserSessionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 134 | 135 | /// 请求查询交易所响应 136 | OnRspQryExchange(pExchange *CThostFtdcExchangeField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 137 | 138 | /// 请求查询产品响应 139 | OnRspQryProduct(pProduct *CThostFtdcProductField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 140 | 141 | /// 请求查询合约响应 142 | OnRspQryInstrument(pInstrument *CThostFtdcInstrumentField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 143 | 144 | /// 请求查询行情响应 145 | OnRspQryDepthMarketData(pDepthMarketData *CThostFtdcDepthMarketDataField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 146 | 147 | /// 请求查询交易员报盘机响应 148 | OnRspQryTraderOffer(pTraderOffer *CThostFtdcTraderOfferField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 149 | 150 | /// 请求查询投资者结算结果响应 151 | OnRspQrySettlementInfo(pSettlementInfo *CThostFtdcSettlementInfoField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 152 | 153 | /// 请求查询转帐银行响应 154 | OnRspQryTransferBank(pTransferBank *CThostFtdcTransferBankField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 155 | 156 | /// 请求查询投资者持仓明细响应 157 | OnRspQryInvestorPositionDetail(pInvestorPositionDetail *CThostFtdcInvestorPositionDetailField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 158 | 159 | /// 请求查询客户通知响应 160 | OnRspQryNotice(pNotice *CThostFtdcNoticeField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 161 | 162 | /// 请求查询结算信息确认响应 163 | OnRspQrySettlementInfoConfirm(pSettlementInfoConfirm *CThostFtdcSettlementInfoConfirmField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 164 | 165 | /// 请求查询投资者持仓明细响应 166 | OnRspQryInvestorPositionCombineDetail(pInvestorPositionCombineDetail *CThostFtdcInvestorPositionCombineDetailField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 167 | 168 | /// 查询保证金监管系统经纪公司资金账户密钥响应 169 | OnRspQryCFMMCTradingAccountKey(pCFMMCTradingAccountKey *CThostFtdcCFMMCTradingAccountKeyField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 170 | 171 | /// 请求查询仓单折抵信息响应 172 | OnRspQryEWarrantOffset(pEWarrantOffset *CThostFtdcEWarrantOffsetField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 173 | 174 | /// 请求查询投资者品种/跨品种保证金响应 175 | OnRspQryInvestorProductGroupMargin(pInvestorProductGroupMargin *CThostFtdcInvestorProductGroupMarginField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 176 | 177 | /// 请求查询交易所保证金率响应 178 | OnRspQryExchangeMarginRate(pExchangeMarginRate *CThostFtdcExchangeMarginRateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 179 | 180 | /// 请求查询交易所调整保证金率响应 181 | OnRspQryExchangeMarginRateAdjust(pExchangeMarginRateAdjust *CThostFtdcExchangeMarginRateAdjustField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 182 | 183 | /// 请求查询汇率响应 184 | OnRspQryExchangeRate(pExchangeRate *CThostFtdcExchangeRateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 185 | 186 | /// 请求查询二级代理操作员银期权限响应 187 | OnRspQrySecAgentACIDMap(pSecAgentACIDMap *CThostFtdcSecAgentACIDMapField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 188 | 189 | /// 请求查询产品报价汇率 190 | OnRspQryProductExchRate(pProductExchRate *CThostFtdcProductExchRateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 191 | 192 | /// 请求查询产品组 193 | OnRspQryProductGroup(pProductGroup *CThostFtdcProductGroupField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 194 | 195 | /// 请求查询做市商合约手续费率响应 196 | OnRspQryMMInstrumentCommissionRate(pMMInstrumentCommissionRate *CThostFtdcMMInstrumentCommissionRateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 197 | 198 | /// 请求查询做市商期权合约手续费响应 199 | OnRspQryMMOptionInstrCommRate(pMMOptionInstrCommRate *CThostFtdcMMOptionInstrCommRateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 200 | 201 | /// 请求查询报单手续费响应 202 | OnRspQryInstrumentOrderCommRate(pInstrumentOrderCommRate *CThostFtdcInstrumentOrderCommRateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 203 | 204 | /// 请求查询资金账户响应 205 | OnRspQrySecAgentTradingAccount(pTradingAccount *CThostFtdcTradingAccountField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 206 | 207 | /// 请求查询二级代理商资金校验模式响应 208 | OnRspQrySecAgentCheckMode(pSecAgentCheckMode *CThostFtdcSecAgentCheckModeField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 209 | 210 | /// 请求查询二级代理商信息响应 211 | OnRspQrySecAgentTradeInfo(pSecAgentTradeInfo *CThostFtdcSecAgentTradeInfoField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 212 | 213 | /// 请求查询期权交易成本响应 214 | OnRspQryOptionInstrTradeCost(pOptionInstrTradeCost *CThostFtdcOptionInstrTradeCostField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 215 | 216 | /// 请求查询期权合约手续费响应 217 | OnRspQryOptionInstrCommRate(pOptionInstrCommRate *CThostFtdcOptionInstrCommRateField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 218 | 219 | /// 请求查询执行宣告响应 220 | OnRspQryExecOrder(pExecOrder *CThostFtdcExecOrderField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 221 | 222 | /// 请求查询询价响应 223 | OnRspQryForQuote(pForQuote *CThostFtdcForQuoteField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 224 | 225 | /// 请求查询报价响应 226 | OnRspQryQuote(pQuote *CThostFtdcQuoteField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 227 | 228 | /// 请求查询期权自对冲响应 229 | OnRspQryOptionSelfClose(pOptionSelfClose *CThostFtdcOptionSelfCloseField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 230 | 231 | /// 请求查询投资单元响应 232 | OnRspQryInvestUnit(pInvestUnit *CThostFtdcInvestUnitField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 233 | 234 | /// 请求查询组合合约安全系数响应 235 | OnRspQryCombInstrumentGuard(pCombInstrumentGuard *CThostFtdcCombInstrumentGuardField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 236 | 237 | /// 请求查询申请组合响应 238 | OnRspQryCombAction(pCombAction *CThostFtdcCombActionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 239 | 240 | /// 请求查询转帐流水响应 241 | OnRspQryTransferSerial(pTransferSerial *CThostFtdcTransferSerialField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 242 | 243 | /// 请求查询银期签约关系响应 244 | OnRspQryAccountregister(pAccountregister *CThostFtdcAccountregisterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 245 | 246 | /// 错误应答 247 | OnRspError(pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 248 | 249 | /// 报单通知 250 | OnRtnOrder(pOrder *CThostFtdcOrderField) 251 | 252 | /// 成交通知 253 | OnRtnTrade(pTrade *CThostFtdcTradeField) 254 | 255 | /// 报单录入错误回报 256 | OnErrRtnOrderInsert(pInputOrder *CThostFtdcInputOrderField, pRspInfo *CThostFtdcRspInfoField) 257 | 258 | /// 报单操作错误回报 259 | OnErrRtnOrderAction(pOrderAction *CThostFtdcOrderActionField, pRspInfo *CThostFtdcRspInfoField) 260 | 261 | /// 合约交易状态通知 262 | OnRtnInstrumentStatus(pInstrumentStatus *CThostFtdcInstrumentStatusField) 263 | 264 | /// 交易所公告通知 265 | OnRtnBulletin(pBulletin *CThostFtdcBulletinField) 266 | 267 | /// 交易通知 268 | OnRtnTradingNotice(pTradingNoticeInfo *CThostFtdcTradingNoticeInfoField) 269 | 270 | /// 提示条件单校验错误 271 | OnRtnErrorConditionalOrder(pErrorConditionalOrder *CThostFtdcErrorConditionalOrderField) 272 | 273 | /// 执行宣告通知 274 | OnRtnExecOrder(pExecOrder *CThostFtdcExecOrderField) 275 | 276 | /// 执行宣告录入错误回报 277 | OnErrRtnExecOrderInsert(pInputExecOrder *CThostFtdcInputExecOrderField, pRspInfo *CThostFtdcRspInfoField) 278 | 279 | /// 执行宣告操作错误回报 280 | OnErrRtnExecOrderAction(pExecOrderAction *CThostFtdcExecOrderActionField, pRspInfo *CThostFtdcRspInfoField) 281 | 282 | /// 询价录入错误回报 283 | OnErrRtnForQuoteInsert(pInputForQuote *CThostFtdcInputForQuoteField, pRspInfo *CThostFtdcRspInfoField) 284 | 285 | /// 报价通知 286 | OnRtnQuote(pQuote *CThostFtdcQuoteField) 287 | 288 | /// 报价录入错误回报 289 | OnErrRtnQuoteInsert(pInputQuote *CThostFtdcInputQuoteField, pRspInfo *CThostFtdcRspInfoField) 290 | 291 | /// 报价操作错误回报 292 | OnErrRtnQuoteAction(pQuoteAction *CThostFtdcQuoteActionField, pRspInfo *CThostFtdcRspInfoField) 293 | 294 | /// 询价通知 295 | OnRtnForQuoteRsp(pForQuoteRsp *CThostFtdcForQuoteRspField) 296 | 297 | /// 保证金监控中心用户令牌 298 | OnRtnCFMMCTradingAccountToken(pCFMMCTradingAccountToken *CThostFtdcCFMMCTradingAccountTokenField) 299 | 300 | /// 批量报单操作错误回报 301 | OnErrRtnBatchOrderAction(pBatchOrderAction *CThostFtdcBatchOrderActionField, pRspInfo *CThostFtdcRspInfoField) 302 | 303 | /// 期权自对冲通知 304 | OnRtnOptionSelfClose(pOptionSelfClose *CThostFtdcOptionSelfCloseField) 305 | 306 | /// 期权自对冲录入错误回报 307 | OnErrRtnOptionSelfCloseInsert(pInputOptionSelfClose *CThostFtdcInputOptionSelfCloseField, pRspInfo *CThostFtdcRspInfoField) 308 | 309 | /// 期权自对冲操作错误回报 310 | OnErrRtnOptionSelfCloseAction(pOptionSelfCloseAction *CThostFtdcOptionSelfCloseActionField, pRspInfo *CThostFtdcRspInfoField) 311 | 312 | /// 申请组合通知 313 | OnRtnCombAction(pCombAction *CThostFtdcCombActionField) 314 | 315 | /// 申请组合录入错误回报 316 | OnErrRtnCombActionInsert(pInputCombAction *CThostFtdcInputCombActionField, pRspInfo *CThostFtdcRspInfoField) 317 | 318 | /// 请求查询签约银行响应 319 | OnRspQryContractBank(pContractBank *CThostFtdcContractBankField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 320 | 321 | /// 请求查询预埋单响应 322 | OnRspQryParkedOrder(pParkedOrder *CThostFtdcParkedOrderField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 323 | 324 | /// 请求查询预埋撤单响应 325 | OnRspQryParkedOrderAction(pParkedOrderAction *CThostFtdcParkedOrderActionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 326 | 327 | /// 请求查询交易通知响应 328 | OnRspQryTradingNotice(pTradingNotice *CThostFtdcTradingNoticeField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 329 | 330 | /// 请求查询经纪公司交易参数响应 331 | OnRspQryBrokerTradingParams(pBrokerTradingParams *CThostFtdcBrokerTradingParamsField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 332 | 333 | /// 请求查询经纪公司交易算法响应 334 | OnRspQryBrokerTradingAlgos(pBrokerTradingAlgos *CThostFtdcBrokerTradingAlgosField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 335 | 336 | /// 请求查询监控中心用户令牌 337 | OnRspQueryCFMMCTradingAccountToken(pQueryCFMMCTradingAccountToken *CThostFtdcQueryCFMMCTradingAccountTokenField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 338 | 339 | /// 银行发起银行资金转期货通知 340 | OnRtnFromBankToFutureByBank(pRspTransfer *CThostFtdcRspTransferField) 341 | 342 | /// 银行发起期货资金转银行通知 343 | OnRtnFromFutureToBankByBank(pRspTransfer *CThostFtdcRspTransferField) 344 | 345 | /// 银行发起冲正银行转期货通知 346 | OnRtnRepealFromBankToFutureByBank(pRspRepeal *CThostFtdcRspRepealField) 347 | 348 | /// 银行发起冲正期货转银行通知 349 | OnRtnRepealFromFutureToBankByBank(pRspRepeal *CThostFtdcRspRepealField) 350 | 351 | /// 期货发起银行资金转期货通知 352 | OnRtnFromBankToFutureByFuture(pRspTransfer *CThostFtdcRspTransferField) 353 | 354 | /// 期货发起期货资金转银行通知 355 | OnRtnFromFutureToBankByFuture(pRspTransfer *CThostFtdcRspTransferField) 356 | 357 | /// 系统运行时期货端手工发起冲正银行转期货请求,银行处理完毕后报盘发回的通知 358 | OnRtnRepealFromBankToFutureByFutureManual(pRspRepeal *CThostFtdcRspRepealField) 359 | 360 | /// 系统运行时期货端手工发起冲正期货转银行请求,银行处理完毕后报盘发回的通知 361 | OnRtnRepealFromFutureToBankByFutureManual(pRspRepeal *CThostFtdcRspRepealField) 362 | 363 | /// 期货发起查询银行余额通知 364 | OnRtnQueryBankBalanceByFuture(pNotifyQueryAccount *CThostFtdcNotifyQueryAccountField) 365 | 366 | /// 期货发起银行资金转期货错误回报 367 | OnErrRtnBankToFutureByFuture(pReqTransfer *CThostFtdcReqTransferField, pRspInfo *CThostFtdcRspInfoField) 368 | 369 | /// 期货发起期货资金转银行错误回报 370 | OnErrRtnFutureToBankByFuture(pReqTransfer *CThostFtdcReqTransferField, pRspInfo *CThostFtdcRspInfoField) 371 | 372 | /// 系统运行时期货端手工发起冲正银行转期货错误回报 373 | OnErrRtnRepealBankToFutureByFutureManual(pReqRepeal *CThostFtdcReqRepealField, pRspInfo *CThostFtdcRspInfoField) 374 | 375 | /// 系统运行时期货端手工发起冲正期货转银行错误回报 376 | OnErrRtnRepealFutureToBankByFutureManual(pReqRepeal *CThostFtdcReqRepealField, pRspInfo *CThostFtdcRspInfoField) 377 | 378 | /// 期货发起查询银行余额错误回报 379 | OnErrRtnQueryBankBalanceByFuture(pReqQueryAccount *CThostFtdcReqQueryAccountField, pRspInfo *CThostFtdcRspInfoField) 380 | 381 | /// 期货发起冲正银行转期货请求,银行处理完毕后报盘发回的通知 382 | OnRtnRepealFromBankToFutureByFuture(pRspRepeal *CThostFtdcRspRepealField) 383 | 384 | /// 期货发起冲正期货转银行请求,银行处理完毕后报盘发回的通知 385 | OnRtnRepealFromFutureToBankByFuture(pRspRepeal *CThostFtdcRspRepealField) 386 | 387 | /// 期货发起银行资金转期货应答 388 | OnRspFromBankToFutureByFuture(pReqTransfer *CThostFtdcReqTransferField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 389 | 390 | /// 期货发起期货资金转银行应答 391 | OnRspFromFutureToBankByFuture(pReqTransfer *CThostFtdcReqTransferField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 392 | 393 | /// 期货发起查询银行余额应答 394 | OnRspQueryBankAccountMoneyByFuture(pReqQueryAccount *CThostFtdcReqQueryAccountField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 395 | 396 | /// 银行发起银期开户通知 397 | OnRtnOpenAccountByBank(pOpenAccount *CThostFtdcOpenAccountField) 398 | 399 | /// 银行发起银期销户通知 400 | OnRtnCancelAccountByBank(pCancelAccount *CThostFtdcCancelAccountField) 401 | 402 | /// 银行发起变更银行账号通知 403 | OnRtnChangeAccountByBank(pChangeAccount *CThostFtdcChangeAccountField) 404 | 405 | /// 请求查询分类合约响应 406 | OnRspQryClassifiedInstrument(pInstrument *CThostFtdcInstrumentField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 407 | 408 | /// 请求组合优惠比例响应 409 | OnRspQryCombPromotionParam(pCombPromotionParam *CThostFtdcCombPromotionParamField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 410 | 411 | /// 投资者风险结算持仓查询响应 412 | OnRspQryRiskSettleInvstPosition(pRiskSettleInvstPosition *CThostFtdcRiskSettleInvstPositionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 413 | 414 | /// 风险结算产品查询响应 415 | OnRspQryRiskSettleProductStatus(pRiskSettleProductStatus *CThostFtdcRiskSettleProductStatusField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 416 | 417 | /// SPBM期货合约参数查询响应 418 | OnRspQrySPBMFutureParameter(pSPBMFutureParameter *CThostFtdcSPBMFutureParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 419 | 420 | /// SPBM期权合约参数查询响应 421 | OnRspQrySPBMOptionParameter(pSPBMOptionParameter *CThostFtdcSPBMOptionParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 422 | 423 | /// SPBM品种内对锁仓折扣参数查询响应 424 | OnRspQrySPBMIntraParameter(pSPBMIntraParameter *CThostFtdcSPBMIntraParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 425 | 426 | /// SPBM跨品种抵扣参数查询响应 427 | OnRspQrySPBMInterParameter(pSPBMInterParameter *CThostFtdcSPBMInterParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 428 | 429 | /// SPBM组合保证金套餐查询响应 430 | OnRspQrySPBMPortfDefinition(pSPBMPortfDefinition *CThostFtdcSPBMPortfDefinitionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 431 | 432 | /// 投资者SPBM套餐选择查询响应 433 | OnRspQrySPBMInvestorPortfDef(pSPBMInvestorPortfDef *CThostFtdcSPBMInvestorPortfDefField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 434 | 435 | /// 投资者新型组合保证金系数查询响应 436 | OnRspQryInvestorPortfMarginRatio(pInvestorPortfMarginRatio *CThostFtdcInvestorPortfMarginRatioField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 437 | 438 | /// 投资者产品SPBM明细查询响应 439 | OnRspQryInvestorProdSPBMDetail(pInvestorProdSPBMDetail *CThostFtdcInvestorProdSPBMDetailField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 440 | 441 | /// 投资者商品组SPMM记录查询响应 442 | OnRspQryInvestorCommoditySPMMMargin(pInvestorCommoditySPMMMargin *CThostFtdcInvestorCommoditySPMMMarginField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 443 | 444 | /// 投资者商品群SPMM记录查询响应 445 | OnRspQryInvestorCommodityGroupSPMMMargin(pInvestorCommodityGroupSPMMMargin *CThostFtdcInvestorCommodityGroupSPMMMarginField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 446 | 447 | /// SPMM合约参数查询响应 448 | OnRspQrySPMMInstParam(pSPMMInstParam *CThostFtdcSPMMInstParamField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 449 | 450 | /// SPMM产品参数查询响应 451 | OnRspQrySPMMProductParam(pSPMMProductParam *CThostFtdcSPMMProductParamField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 452 | 453 | /// SPBM附加跨品种抵扣参数查询响应 454 | OnRspQrySPBMAddOnInterParameter(pSPBMAddOnInterParameter *CThostFtdcSPBMAddOnInterParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 455 | 456 | /// RCAMS产品组合信息查询响应 457 | OnRspQryRCAMSCombProductInfo(pRCAMSCombProductInfo *CThostFtdcRCAMSCombProductInfoField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 458 | 459 | /// RCAMS同合约风险对冲参数查询响应 460 | OnRspQryRCAMSInstrParameter(pRCAMSInstrParameter *CThostFtdcRCAMSInstrParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 461 | 462 | /// RCAMS品种内风险对冲参数查询响应 463 | OnRspQryRCAMSIntraParameter(pRCAMSIntraParameter *CThostFtdcRCAMSIntraParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 464 | 465 | /// RCAMS跨品种风险折抵参数查询响应 466 | OnRspQryRCAMSInterParameter(pRCAMSInterParameter *CThostFtdcRCAMSInterParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 467 | 468 | /// RCAMS空头期权风险调整参数查询响应 469 | OnRspQryRCAMSShortOptAdjustParam(pRCAMSShortOptAdjustParam *CThostFtdcRCAMSShortOptAdjustParamField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 470 | 471 | /// RCAMS策略组合持仓查询响应 472 | OnRspQryRCAMSInvestorCombPosition(pRCAMSInvestorCombPosition *CThostFtdcRCAMSInvestorCombPositionField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 473 | 474 | /// 投资者品种RCAMS保证金查询响应 475 | OnRspQryInvestorProdRCAMSMargin(pInvestorProdRCAMSMargin *CThostFtdcInvestorProdRCAMSMarginField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 476 | 477 | /// RULE合约保证金参数查询响应 478 | OnRspQryRULEInstrParameter(pRULEInstrParameter *CThostFtdcRULEInstrParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 479 | 480 | /// RULE品种内对锁仓折扣参数查询响应 481 | OnRspQryRULEIntraParameter(pRULEIntraParameter *CThostFtdcRULEIntraParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 482 | 483 | /// RULE跨品种抵扣参数查询响应 484 | OnRspQryRULEInterParameter(pRULEInterParameter *CThostFtdcRULEInterParameterField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 485 | 486 | /// 投资者产品RULE保证金查询响应 487 | OnRspQryInvestorProdRULEMargin(pInvestorProdRULEMargin *CThostFtdcInvestorProdRULEMarginField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 488 | 489 | /// 投资者新型组合保证金开关查询响应 490 | OnRspQryInvestorPortfSetting(pInvestorPortfSetting *CThostFtdcInvestorPortfSettingField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 491 | 492 | /// 投资者申报费阶梯收取记录查询响应 493 | OnRspQryInvestorInfoCommRec(pInvestorInfoCommRec *CThostFtdcInvestorInfoCommRecField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 494 | 495 | /// 组合腿信息查询响应 496 | OnRspQryCombLeg(pCombLeg *CThostFtdcCombLegField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 497 | 498 | /// 对冲设置请求响应 499 | OnRspOffsetSetting(pInputOffsetSetting *CThostFtdcInputOffsetSettingField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 500 | 501 | /// 对冲设置撤销请求响应 502 | OnRspCancelOffsetSetting(pInputOffsetSetting *CThostFtdcInputOffsetSettingField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 503 | 504 | /// 对冲设置通知 505 | OnRtnOffsetSetting(pOffsetSetting *CThostFtdcOffsetSettingField) 506 | 507 | /// 对冲设置错误回报 508 | OnErrRtnOffsetSetting(pInputOffsetSetting *CThostFtdcInputOffsetSettingField, pRspInfo *CThostFtdcRspInfoField) 509 | 510 | /// 对冲设置撤销错误回报 511 | OnErrRtnCancelOffsetSetting(pCancelOffsetSetting *CThostFtdcCancelOffsetSettingField, pRspInfo *CThostFtdcRspInfoField) 512 | 513 | /// 投资者对冲设置查询响应 514 | OnRspQryOffsetSetting(pOffsetSetting *CThostFtdcOffsetSettingField, pRspInfo *CThostFtdcRspInfoField, nRequestID int, bIsLast bool) 515 | } 516 | 517 | type TraderApi interface { 518 | 519 | /// 获取API的版本信息 520 | ///@retrun 获取到的版本号 521 | GetApiVersion() string 522 | 523 | /// 删除接口对象本身 524 | ///@remark 不再使用本接口对象时,调用该函数删除接口对象 525 | Release() 526 | 527 | /// 初始化 528 | ///@remark 初始化运行环境,只有调用后,接口才开始工作 529 | Init() 530 | 531 | /// 等待接口线程结束运行 532 | ///@return 线程退出代码 533 | Join() int 534 | 535 | /// 获取当前交易日 536 | ///@retrun 获取到的交易日 537 | ///@remark 只有登录成功后,才能得到正确的交易日 538 | GetTradingDay() string 539 | 540 | /// 获取已连接的前置的信息 541 | /// @param pFrontInfo:输入输出参数,用于存储获取到的前置信息,不能为空 542 | /// @remark 连接成功后,可获取正确的前置地址信息 543 | /// @remark 登录成功后,可获取正确的前置流控信息 544 | GetFrontInfo(pFrontInfo *CThostFtdcFrontInfoField) 545 | 546 | /// 注册前置机网络地址 547 | ///@param pszFrontAddress:前置机网络地址。 548 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:17001”。 549 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。 550 | RegisterFront(pszFrontAddress string) 551 | 552 | /// 注册名字服务器网络地址 553 | ///@param pszNsAddress:名字服务器网络地址。 554 | ///@remark 网络地址的格式为:“protocol://ipaddress:port”,如:”tcp://127.0.0.1:12001”。 555 | ///@remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”12001”代表服务器端口号。 556 | ///@remark RegisterNameServer优先于RegisterFront 557 | RegisterNameServer(pszNsAddress string) 558 | 559 | /// 注册名字服务器用户信息 560 | ///@param pFensUserInfo:用户信息。 561 | RegisterFensUserInfo(pFensUserInfo *CThostFtdcFensUserInfoField) 562 | 563 | /// 注册回调接口 564 | ///@param pSpi 派生自回调接口类的实例 565 | RegisterSpi(pSpi TraderSpi) 566 | 567 | /// 订阅私有流。 568 | ///@param nResumeType 私有流重传方式 569 | /// THOST_TERT_RESTART:从本交易日开始重传 570 | /// THOST_TERT_RESUME:从上次收到的续传 571 | /// THOST_TERT_QUICK:只传送登录后私有流的内容 572 | ///@remark 该方法要在Init方法前调用。若不调用则不会收到私有流的数据。 573 | SubscribePrivateTopic(nResumeType THOST_TE_RESUME_TYPE) 574 | 575 | /// 订阅公共流。 576 | ///@param nResumeType 公共流重传方式 577 | /// THOST_TERT_RESTART:从本交易日开始重传 578 | /// THOST_TERT_RESUME:从上次收到的续传 579 | /// THOST_TERT_QUICK:只传送登录后公共流的内容 580 | /// THOST_TERT_NONE:取消订阅公共流 581 | ///@remark 该方法要在Init方法前调用。若不调用则不会收到公共流的数据。 582 | SubscribePublicTopic(nResumeType THOST_TE_RESUME_TYPE) 583 | 584 | /// 客户端认证请求 585 | ReqAuthenticate(pReqAuthenticateField *CThostFtdcReqAuthenticateField, nRequestID int) int 586 | 587 | /// 注册用户终端信息,用于中继服务器多连接模式 588 | /// 需要在终端认证成功后,用户登录前调用该接口 589 | RegisterUserSystemInfo(pUserSystemInfo *CThostFtdcUserSystemInfoField) int 590 | 591 | /// 上报用户终端信息,用于中继服务器操作员登录模式 592 | /// 操作员登录后,可以多次调用该接口上报客户信息 593 | SubmitUserSystemInfo(pUserSystemInfo *CThostFtdcUserSystemInfoField) int 594 | 595 | /// 注册用户终端信息,用于中继服务器多连接模式.用于微信小程序等应用上报信息. 596 | RegisterWechatUserSystemInfo(pUserSystemInfo *CThostFtdcWechatUserSystemInfoField) int 597 | 598 | /// 上报用户终端信息,用于中继服务器操作员登录模式.用于微信小程序等应用上报信息. 599 | SubmitWechatUserSystemInfo(pUserSystemInfo *CThostFtdcWechatUserSystemInfoField) int 600 | 601 | /// 用户登录请求 602 | ReqUserLogin(pReqUserLoginField *CThostFtdcReqUserLoginField, nRequestID int) int 603 | 604 | /// 登出请求 605 | ReqUserLogout(pUserLogout *CThostFtdcUserLogoutField, nRequestID int) int 606 | 607 | /// 用户口令更新请求 608 | ReqUserPasswordUpdate(pUserPasswordUpdate *CThostFtdcUserPasswordUpdateField, nRequestID int) int 609 | 610 | /// 资金账户口令更新请求 611 | ReqTradingAccountPasswordUpdate(pTradingAccountPasswordUpdate *CThostFtdcTradingAccountPasswordUpdateField, nRequestID int) int 612 | 613 | /// 查询用户当前支持的认证模式 614 | ReqUserAuthMethod(pReqUserAuthMethod *CThostFtdcReqUserAuthMethodField, nRequestID int) int 615 | 616 | /// 用户发出获取图形验证码请求 617 | ReqGenUserCaptcha(pReqGenUserCaptcha *CThostFtdcReqGenUserCaptchaField, nRequestID int) int 618 | 619 | /// 用户发出获取短信验证码请求 620 | ReqGenUserText(pReqGenUserText *CThostFtdcReqGenUserTextField, nRequestID int) int 621 | 622 | /// 用户发出带有图片验证码的登陆请求 623 | ReqUserLoginWithCaptcha(pReqUserLoginWithCaptcha *CThostFtdcReqUserLoginWithCaptchaField, nRequestID int) int 624 | 625 | /// 用户发出带有短信验证码的登陆请求 626 | ReqUserLoginWithText(pReqUserLoginWithText *CThostFtdcReqUserLoginWithTextField, nRequestID int) int 627 | 628 | /// 用户发出带有动态口令的登陆请求 629 | ReqUserLoginWithOTP(pReqUserLoginWithOTP *CThostFtdcReqUserLoginWithOTPField, nRequestID int) int 630 | 631 | /// 报单录入请求 632 | ReqOrderInsert(pInputOrder *CThostFtdcInputOrderField, nRequestID int) int 633 | 634 | /// 预埋单录入请求 635 | ReqParkedOrderInsert(pParkedOrder *CThostFtdcParkedOrderField, nRequestID int) int 636 | 637 | /// 预埋撤单录入请求 638 | ReqParkedOrderAction(pParkedOrderAction *CThostFtdcParkedOrderActionField, nRequestID int) int 639 | 640 | /// 报单操作请求 641 | ReqOrderAction(pInputOrderAction *CThostFtdcInputOrderActionField, nRequestID int) int 642 | 643 | /// 查询最大报单数量请求 644 | ReqQryMaxOrderVolume(pQryMaxOrderVolume *CThostFtdcQryMaxOrderVolumeField, nRequestID int) int 645 | 646 | /// 投资者结算结果确认 647 | ReqSettlementInfoConfirm(pSettlementInfoConfirm *CThostFtdcSettlementInfoConfirmField, nRequestID int) int 648 | 649 | /// 请求删除预埋单 650 | ReqRemoveParkedOrder(pRemoveParkedOrder *CThostFtdcRemoveParkedOrderField, nRequestID int) int 651 | 652 | /// 请求删除预埋撤单 653 | ReqRemoveParkedOrderAction(pRemoveParkedOrderAction *CThostFtdcRemoveParkedOrderActionField, nRequestID int) int 654 | 655 | /// 执行宣告录入请求 656 | ReqExecOrderInsert(pInputExecOrder *CThostFtdcInputExecOrderField, nRequestID int) int 657 | 658 | /// 执行宣告操作请求 659 | ReqExecOrderAction(pInputExecOrderAction *CThostFtdcInputExecOrderActionField, nRequestID int) int 660 | 661 | /// 询价录入请求 662 | ReqForQuoteInsert(pInputForQuote *CThostFtdcInputForQuoteField, nRequestID int) int 663 | 664 | /// 报价录入请求 665 | ReqQuoteInsert(pInputQuote *CThostFtdcInputQuoteField, nRequestID int) int 666 | 667 | /// 报价操作请求 668 | ReqQuoteAction(pInputQuoteAction *CThostFtdcInputQuoteActionField, nRequestID int) int 669 | 670 | /// 批量报单操作请求 671 | ReqBatchOrderAction(pInputBatchOrderAction *CThostFtdcInputBatchOrderActionField, nRequestID int) int 672 | 673 | /// 期权自对冲录入请求 674 | ReqOptionSelfCloseInsert(pInputOptionSelfClose *CThostFtdcInputOptionSelfCloseField, nRequestID int) int 675 | 676 | /// 期权自对冲操作请求 677 | ReqOptionSelfCloseAction(pInputOptionSelfCloseAction *CThostFtdcInputOptionSelfCloseActionField, nRequestID int) int 678 | 679 | /// 申请组合录入请求 680 | ReqCombActionInsert(pInputCombAction *CThostFtdcInputCombActionField, nRequestID int) int 681 | 682 | /// 请求查询报单 683 | ReqQryOrder(pQryOrder *CThostFtdcQryOrderField, nRequestID int) int 684 | 685 | /// 请求查询成交 686 | ReqQryTrade(pQryTrade *CThostFtdcQryTradeField, nRequestID int) int 687 | 688 | /// 请求查询投资者持仓 689 | ReqQryInvestorPosition(pQryInvestorPosition *CThostFtdcQryInvestorPositionField, nRequestID int) int 690 | 691 | /// 请求查询资金账户 692 | ReqQryTradingAccount(pQryTradingAccount *CThostFtdcQryTradingAccountField, nRequestID int) int 693 | 694 | /// 请求查询投资者 695 | ReqQryInvestor(pQryInvestor *CThostFtdcQryInvestorField, nRequestID int) int 696 | 697 | /// 请求查询交易编码 698 | ReqQryTradingCode(pQryTradingCode *CThostFtdcQryTradingCodeField, nRequestID int) int 699 | 700 | /// 请求查询合约保证金率 701 | ReqQryInstrumentMarginRate(pQryInstrumentMarginRate *CThostFtdcQryInstrumentMarginRateField, nRequestID int) int 702 | 703 | /// 请求查询合约手续费率 704 | ReqQryInstrumentCommissionRate(pQryInstrumentCommissionRate *CThostFtdcQryInstrumentCommissionRateField, nRequestID int) int 705 | 706 | /// 请求查询用户会话 707 | ReqQryUserSession(pQryUserSession *CThostFtdcQryUserSessionField, nRequestID int) int 708 | 709 | /// 请求查询交易所 710 | ReqQryExchange(pQryExchange *CThostFtdcQryExchangeField, nRequestID int) int 711 | 712 | /// 请求查询产品 713 | ReqQryProduct(pQryProduct *CThostFtdcQryProductField, nRequestID int) int 714 | 715 | /// 请求查询合约 716 | ReqQryInstrument(pQryInstrument *CThostFtdcQryInstrumentField, nRequestID int) int 717 | 718 | /// 请求查询行情 719 | ReqQryDepthMarketData(pQryDepthMarketData *CThostFtdcQryDepthMarketDataField, nRequestID int) int 720 | 721 | /// 请求查询交易员报盘机 722 | ReqQryTraderOffer(pQryTraderOffer *CThostFtdcQryTraderOfferField, nRequestID int) int 723 | 724 | /// 请求查询投资者结算结果 725 | ReqQrySettlementInfo(pQrySettlementInfo *CThostFtdcQrySettlementInfoField, nRequestID int) int 726 | 727 | /// 请求查询转帐银行 728 | ReqQryTransferBank(pQryTransferBank *CThostFtdcQryTransferBankField, nRequestID int) int 729 | 730 | /// 请求查询投资者持仓明细 731 | ReqQryInvestorPositionDetail(pQryInvestorPositionDetail *CThostFtdcQryInvestorPositionDetailField, nRequestID int) int 732 | 733 | /// 请求查询客户通知 734 | ReqQryNotice(pQryNotice *CThostFtdcQryNoticeField, nRequestID int) int 735 | 736 | /// 请求查询结算信息确认 737 | ReqQrySettlementInfoConfirm(pQrySettlementInfoConfirm *CThostFtdcQrySettlementInfoConfirmField, nRequestID int) int 738 | 739 | /// 请求查询投资者持仓明细 740 | ReqQryInvestorPositionCombineDetail(pQryInvestorPositionCombineDetail *CThostFtdcQryInvestorPositionCombineDetailField, nRequestID int) int 741 | 742 | /// 请求查询保证金监管系统经纪公司资金账户密钥 743 | ReqQryCFMMCTradingAccountKey(pQryCFMMCTradingAccountKey *CThostFtdcQryCFMMCTradingAccountKeyField, nRequestID int) int 744 | 745 | /// 请求查询仓单折抵信息 746 | ReqQryEWarrantOffset(pQryEWarrantOffset *CThostFtdcQryEWarrantOffsetField, nRequestID int) int 747 | 748 | /// 请求查询投资者品种/跨品种保证金 749 | ReqQryInvestorProductGroupMargin(pQryInvestorProductGroupMargin *CThostFtdcQryInvestorProductGroupMarginField, nRequestID int) int 750 | 751 | /// 请求查询交易所保证金率 752 | ReqQryExchangeMarginRate(pQryExchangeMarginRate *CThostFtdcQryExchangeMarginRateField, nRequestID int) int 753 | 754 | /// 请求查询交易所调整保证金率 755 | ReqQryExchangeMarginRateAdjust(pQryExchangeMarginRateAdjust *CThostFtdcQryExchangeMarginRateAdjustField, nRequestID int) int 756 | 757 | /// 请求查询汇率 758 | ReqQryExchangeRate(pQryExchangeRate *CThostFtdcQryExchangeRateField, nRequestID int) int 759 | 760 | /// 请求查询二级代理操作员银期权限 761 | ReqQrySecAgentACIDMap(pQrySecAgentACIDMap *CThostFtdcQrySecAgentACIDMapField, nRequestID int) int 762 | 763 | /// 请求查询产品报价汇率 764 | ReqQryProductExchRate(pQryProductExchRate *CThostFtdcQryProductExchRateField, nRequestID int) int 765 | 766 | /// 请求查询产品组 767 | ReqQryProductGroup(pQryProductGroup *CThostFtdcQryProductGroupField, nRequestID int) int 768 | 769 | /// 请求查询做市商合约手续费率 770 | ReqQryMMInstrumentCommissionRate(pQryMMInstrumentCommissionRate *CThostFtdcQryMMInstrumentCommissionRateField, nRequestID int) int 771 | 772 | /// 请求查询做市商期权合约手续费 773 | ReqQryMMOptionInstrCommRate(pQryMMOptionInstrCommRate *CThostFtdcQryMMOptionInstrCommRateField, nRequestID int) int 774 | 775 | /// 请求查询报单手续费 776 | ReqQryInstrumentOrderCommRate(pQryInstrumentOrderCommRate *CThostFtdcQryInstrumentOrderCommRateField, nRequestID int) int 777 | 778 | /// 请求查询资金账户 779 | ReqQrySecAgentTradingAccount(pQryTradingAccount *CThostFtdcQryTradingAccountField, nRequestID int) int 780 | 781 | /// 请求查询二级代理商资金校验模式 782 | ReqQrySecAgentCheckMode(pQrySecAgentCheckMode *CThostFtdcQrySecAgentCheckModeField, nRequestID int) int 783 | 784 | /// 请求查询二级代理商信息 785 | ReqQrySecAgentTradeInfo(pQrySecAgentTradeInfo *CThostFtdcQrySecAgentTradeInfoField, nRequestID int) int 786 | 787 | /// 请求查询期权交易成本 788 | ReqQryOptionInstrTradeCost(pQryOptionInstrTradeCost *CThostFtdcQryOptionInstrTradeCostField, nRequestID int) int 789 | 790 | /// 请求查询期权合约手续费 791 | ReqQryOptionInstrCommRate(pQryOptionInstrCommRate *CThostFtdcQryOptionInstrCommRateField, nRequestID int) int 792 | 793 | /// 请求查询执行宣告 794 | ReqQryExecOrder(pQryExecOrder *CThostFtdcQryExecOrderField, nRequestID int) int 795 | 796 | /// 请求查询询价 797 | ReqQryForQuote(pQryForQuote *CThostFtdcQryForQuoteField, nRequestID int) int 798 | 799 | /// 请求查询报价 800 | ReqQryQuote(pQryQuote *CThostFtdcQryQuoteField, nRequestID int) int 801 | 802 | /// 请求查询期权自对冲 803 | ReqQryOptionSelfClose(pQryOptionSelfClose *CThostFtdcQryOptionSelfCloseField, nRequestID int) int 804 | 805 | /// 请求查询投资单元 806 | ReqQryInvestUnit(pQryInvestUnit *CThostFtdcQryInvestUnitField, nRequestID int) int 807 | 808 | /// 请求查询组合合约安全系数 809 | ReqQryCombInstrumentGuard(pQryCombInstrumentGuard *CThostFtdcQryCombInstrumentGuardField, nRequestID int) int 810 | 811 | /// 请求查询申请组合 812 | ReqQryCombAction(pQryCombAction *CThostFtdcQryCombActionField, nRequestID int) int 813 | 814 | /// 请求查询转帐流水 815 | ReqQryTransferSerial(pQryTransferSerial *CThostFtdcQryTransferSerialField, nRequestID int) int 816 | 817 | /// 请求查询银期签约关系 818 | ReqQryAccountregister(pQryAccountregister *CThostFtdcQryAccountregisterField, nRequestID int) int 819 | 820 | /// 请求查询签约银行 821 | ReqQryContractBank(pQryContractBank *CThostFtdcQryContractBankField, nRequestID int) int 822 | 823 | /// 请求查询预埋单 824 | ReqQryParkedOrder(pQryParkedOrder *CThostFtdcQryParkedOrderField, nRequestID int) int 825 | 826 | /// 请求查询预埋撤单 827 | ReqQryParkedOrderAction(pQryParkedOrderAction *CThostFtdcQryParkedOrderActionField, nRequestID int) int 828 | 829 | /// 请求查询交易通知 830 | ReqQryTradingNotice(pQryTradingNotice *CThostFtdcQryTradingNoticeField, nRequestID int) int 831 | 832 | /// 请求查询经纪公司交易参数 833 | ReqQryBrokerTradingParams(pQryBrokerTradingParams *CThostFtdcQryBrokerTradingParamsField, nRequestID int) int 834 | 835 | /// 请求查询经纪公司交易算法 836 | ReqQryBrokerTradingAlgos(pQryBrokerTradingAlgos *CThostFtdcQryBrokerTradingAlgosField, nRequestID int) int 837 | 838 | /// 请求查询监控中心用户令牌 839 | ReqQueryCFMMCTradingAccountToken(pQueryCFMMCTradingAccountToken *CThostFtdcQueryCFMMCTradingAccountTokenField, nRequestID int) int 840 | 841 | /// 期货发起银行资金转期货请求 842 | ReqFromBankToFutureByFuture(pReqTransfer *CThostFtdcReqTransferField, nRequestID int) int 843 | 844 | /// 期货发起期货资金转银行请求 845 | ReqFromFutureToBankByFuture(pReqTransfer *CThostFtdcReqTransferField, nRequestID int) int 846 | 847 | /// 期货发起查询银行余额请求 848 | ReqQueryBankAccountMoneyByFuture(pReqQueryAccount *CThostFtdcReqQueryAccountField, nRequestID int) int 849 | 850 | /// 请求查询分类合约 851 | ReqQryClassifiedInstrument(pQryClassifiedInstrument *CThostFtdcQryClassifiedInstrumentField, nRequestID int) int 852 | 853 | /// 请求组合优惠比例 854 | ReqQryCombPromotionParam(pQryCombPromotionParam *CThostFtdcQryCombPromotionParamField, nRequestID int) int 855 | 856 | /// 投资者风险结算持仓查询 857 | ReqQryRiskSettleInvstPosition(pQryRiskSettleInvstPosition *CThostFtdcQryRiskSettleInvstPositionField, nRequestID int) int 858 | 859 | /// 风险结算产品查询 860 | ReqQryRiskSettleProductStatus(pQryRiskSettleProductStatus *CThostFtdcQryRiskSettleProductStatusField, nRequestID int) int 861 | 862 | /// SPBM期货合约参数查询 863 | ReqQrySPBMFutureParameter(pQrySPBMFutureParameter *CThostFtdcQrySPBMFutureParameterField, nRequestID int) int 864 | 865 | /// SPBM期权合约参数查询 866 | ReqQrySPBMOptionParameter(pQrySPBMOptionParameter *CThostFtdcQrySPBMOptionParameterField, nRequestID int) int 867 | 868 | /// SPBM品种内对锁仓折扣参数查询 869 | ReqQrySPBMIntraParameter(pQrySPBMIntraParameter *CThostFtdcQrySPBMIntraParameterField, nRequestID int) int 870 | 871 | /// SPBM跨品种抵扣参数查询 872 | ReqQrySPBMInterParameter(pQrySPBMInterParameter *CThostFtdcQrySPBMInterParameterField, nRequestID int) int 873 | 874 | /// SPBM组合保证金套餐查询 875 | ReqQrySPBMPortfDefinition(pQrySPBMPortfDefinition *CThostFtdcQrySPBMPortfDefinitionField, nRequestID int) int 876 | 877 | /// 投资者SPBM套餐选择查询 878 | ReqQrySPBMInvestorPortfDef(pQrySPBMInvestorPortfDef *CThostFtdcQrySPBMInvestorPortfDefField, nRequestID int) int 879 | 880 | /// 投资者新型组合保证金系数查询 881 | ReqQryInvestorPortfMarginRatio(pQryInvestorPortfMarginRatio *CThostFtdcQryInvestorPortfMarginRatioField, nRequestID int) int 882 | 883 | /// 投资者产品SPBM明细查询 884 | ReqQryInvestorProdSPBMDetail(pQryInvestorProdSPBMDetail *CThostFtdcQryInvestorProdSPBMDetailField, nRequestID int) int 885 | 886 | /// 投资者商品组SPMM记录查询 887 | ReqQryInvestorCommoditySPMMMargin(pQryInvestorCommoditySPMMMargin *CThostFtdcQryInvestorCommoditySPMMMarginField, nRequestID int) int 888 | 889 | /// 投资者商品群SPMM记录查询 890 | ReqQryInvestorCommodityGroupSPMMMargin(pQryInvestorCommodityGroupSPMMMargin *CThostFtdcQryInvestorCommodityGroupSPMMMarginField, nRequestID int) int 891 | 892 | /// SPMM合约参数查询 893 | ReqQrySPMMInstParam(pQrySPMMInstParam *CThostFtdcQrySPMMInstParamField, nRequestID int) int 894 | 895 | /// SPMM产品参数查询 896 | ReqQrySPMMProductParam(pQrySPMMProductParam *CThostFtdcQrySPMMProductParamField, nRequestID int) int 897 | 898 | /// SPBM附加跨品种抵扣参数查询 899 | ReqQrySPBMAddOnInterParameter(pQrySPBMAddOnInterParameter *CThostFtdcQrySPBMAddOnInterParameterField, nRequestID int) int 900 | 901 | /// RCAMS产品组合信息查询 902 | ReqQryRCAMSCombProductInfo(pQryRCAMSCombProductInfo *CThostFtdcQryRCAMSCombProductInfoField, nRequestID int) int 903 | 904 | /// RCAMS同合约风险对冲参数查询 905 | ReqQryRCAMSInstrParameter(pQryRCAMSInstrParameter *CThostFtdcQryRCAMSInstrParameterField, nRequestID int) int 906 | 907 | /// RCAMS品种内风险对冲参数查询 908 | ReqQryRCAMSIntraParameter(pQryRCAMSIntraParameter *CThostFtdcQryRCAMSIntraParameterField, nRequestID int) int 909 | 910 | /// RCAMS跨品种风险折抵参数查询 911 | ReqQryRCAMSInterParameter(pQryRCAMSInterParameter *CThostFtdcQryRCAMSInterParameterField, nRequestID int) int 912 | 913 | /// RCAMS空头期权风险调整参数查询 914 | ReqQryRCAMSShortOptAdjustParam(pQryRCAMSShortOptAdjustParam *CThostFtdcQryRCAMSShortOptAdjustParamField, nRequestID int) int 915 | 916 | /// RCAMS策略组合持仓查询 917 | ReqQryRCAMSInvestorCombPosition(pQryRCAMSInvestorCombPosition *CThostFtdcQryRCAMSInvestorCombPositionField, nRequestID int) int 918 | 919 | /// 投资者品种RCAMS保证金查询 920 | ReqQryInvestorProdRCAMSMargin(pQryInvestorProdRCAMSMargin *CThostFtdcQryInvestorProdRCAMSMarginField, nRequestID int) int 921 | 922 | /// RULE合约保证金参数查询 923 | ReqQryRULEInstrParameter(pQryRULEInstrParameter *CThostFtdcQryRULEInstrParameterField, nRequestID int) int 924 | 925 | /// RULE品种内对锁仓折扣参数查询 926 | ReqQryRULEIntraParameter(pQryRULEIntraParameter *CThostFtdcQryRULEIntraParameterField, nRequestID int) int 927 | 928 | /// RULE跨品种抵扣参数查询 929 | ReqQryRULEInterParameter(pQryRULEInterParameter *CThostFtdcQryRULEInterParameterField, nRequestID int) int 930 | 931 | /// 投资者产品RULE保证金查询 932 | ReqQryInvestorProdRULEMargin(pQryInvestorProdRULEMargin *CThostFtdcQryInvestorProdRULEMarginField, nRequestID int) int 933 | 934 | /// 投资者新型组合保证金开关查询 935 | ReqQryInvestorPortfSetting(pQryInvestorPortfSetting *CThostFtdcQryInvestorPortfSettingField, nRequestID int) int 936 | 937 | /// 投资者申报费阶梯收取记录查询 938 | ReqQryInvestorInfoCommRec(pQryInvestorInfoCommRec *CThostFtdcQryInvestorInfoCommRecField, nRequestID int) int 939 | 940 | /// 组合腿信息查询 941 | ReqQryCombLeg(pQryCombLeg *CThostFtdcQryCombLegField, nRequestID int) int 942 | 943 | /// 对冲设置请求 944 | ReqOffsetSetting(pInputOffsetSetting *CThostFtdcInputOffsetSettingField, nRequestID int) int 945 | 946 | /// 对冲设置撤销请求 947 | ReqCancelOffsetSetting(pInputOffsetSetting *CThostFtdcInputOffsetSettingField, nRequestID int) int 948 | 949 | /// 投资者对冲设置查询 950 | ReqQryOffsetSetting(pQryOffsetSetting *CThostFtdcQryOffsetSettingField, nRequestID int) int 951 | } 952 | --------------------------------------------------------------------------------