// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved. package gocctp /* #cgo CFLAGS: -I./include #cgo LDFLAGS: -L./lib -lm -lcctp -lthosttraderapi -lthostmduserapi #include #include ///行情登录请求响应 extern void GoOnMdRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx); ///行情登出请求响应 extern void GoOnMdRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx); ///行情错误应答 extern void GoOnMdRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx); ///交易登录请求响应 extern void GoOnTdRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx); ///交易登出请求响应 extern void GoOnTdRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx); ///交易错误应答 extern void GoOnTdRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx); ///深度行情通知 extern void GoOnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData, void* ctx); ///请求查询交易所响应 extern void GoOnRspQryExchange(CThostFtdcExchangeField *pExchange, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx); ///请求查询合约响应 extern void GoOnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx); ///行情登录请求响应 void OnMdRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx) { GoOnMdRspUserLogin(pRspUserLogin, pRspInfo, nRequestID, bIsLast, ctx); } ///行情登出请求响应 void OnMdRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx) { GoOnMdRspUserLogout(pUserLogout, pRspInfo, nRequestID, bIsLast, ctx); } ///行情错误应答 void OnMdRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx) { GoOnMdRspError(pRspInfo, nRequestID, bIsLast, ctx); } ///交易登录请求响应 void OnTdRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx) { GoOnTdRspUserLogin(pRspUserLogin, pRspInfo, nRequestID, bIsLast, ctx); } ///交易登出请求响应 void OnTdRspUserLogout(CThostFtdcUserLogoutField *pUserLogout, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx) { GoOnTdRspUserLogout(pUserLogout, pRspInfo, nRequestID, bIsLast, ctx); } ///交易错误应答 void OnTdRspError(CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx) { GoOnTdRspError(pRspInfo, nRequestID, bIsLast, ctx); } ///深度行情通知 void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData, void* ctx) { GoOnRtnDepthMarketData(pDepthMarketData, ctx); } ///请求查询交易所响应 void OnRspQryExchange(CThostFtdcExchangeField *pExchange, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx) { GoOnRspQryExchange(pExchange, pRspInfo, nRequestID, bIsLast, ctx); } ///请求查询合约响应 void OnRspQryInstrument(CThostFtdcInstrumentField *pInstrument, CThostFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast, void* ctx) { GoOnRspQryInstrument(pInstrument, pRspInfo, nRequestID, bIsLast, ctx); } */ import "C" import ( "unsafe" ) type Spi interface { OnRspUserLogin(errMsg string) OnRspUserLogout(errMsg string) OnRspError(errMsg string) } type SpiBase struct{} func (sb *SpiBase) OnRspUserLogout(errMsg string) {} func (sb *SpiBase) OnRspError(errMsg string) {} type MdSpi interface { Spi OnRtnDepthMarketData(field *CThostFtdcDepthMarketDataField) } type TdSpi interface { Spi OnRspQryExchange(field *CThostFtdcExchangeField, errMsg string, isLast bool) OnRspQryInstrument(field *CThostFtdcInstrumentField, errMsg string, isLast bool) } type MdApi struct { MdSpi cmdApi unsafe.Pointer } func NewMdApi(spi MdSpi, dir string) *MdApi { csdir := C.CString(dir) defer C.free(unsafe.Pointer(csdir)) cmdApi := C.CCTP_MdApiCreate(csdir) mdApi := &MdApi{spi, cmdApi} f1 := C.fnOnRspUserLogin(C.OnMdRspUserLogin) C.CCTP_RegOnMdRspUserLogin(cmdApi, f1, unsafe.Pointer(mdApi)) f2 := C.fnOnRspUserLogout(C.OnMdRspUserLogout) C.CCTP_RegOnMdRspUserLogout(cmdApi, f2, unsafe.Pointer(mdApi)) f3 := C.fnOnRspError(C.OnMdRspError) C.CCTP_RegOnMdRspError(cmdApi, f3, unsafe.Pointer(mdApi)) f4 := C.fnOnRtnDepthMarketData(C.OnRtnDepthMarketData) C.CCTP_RegOnRtnDepthMarketData(cmdApi, f4, unsafe.Pointer(mdApi)) return mdApi } func (md *MdApi) Release() { C.CCTP_MdRelease(unsafe.Pointer(md.cmdApi)) } func (md *MdApi) Login(saddr, brokerId, userId, password string) { csaddr := C.CString(saddr) defer C.free(unsafe.Pointer(csaddr)) cbrokerId := C.CString(brokerId) defer C.free(unsafe.Pointer(cbrokerId)) cuserId := C.CString(userId) defer C.free(unsafe.Pointer(cuserId)) cpassword := C.CString(password) defer C.free(unsafe.Pointer(cpassword)) C.CCTP_MdLogin(md.cmdApi, csaddr, cbrokerId, cuserId, cpassword) } func (md *MdApi) Logout(brokerId, userId string) { cbrokerId := C.CString(brokerId) defer C.free(unsafe.Pointer(cbrokerId)) cuserId := C.CString(userId) defer C.free(unsafe.Pointer(cuserId)) C.CCTP_MdLogout(md.cmdApi, cbrokerId, cuserId) } func (md *MdApi) SubscribeMarketData(instrumentIds []string) { n := len(instrumentIds) if n == 0 { return } cinsIds := make([](*C.char), n) for i, id := range instrumentIds { cid := C.CString(id) cinsIds[i] = cid } C.CCTP_SubscribeMarketData(md.cmdApi, (**C.char)((unsafe.Pointer)(&cinsIds[0])), C.int(n)) for _, x := range cinsIds { C.free(unsafe.Pointer(x)) } } func (md *MdApi) UnSubscribeMarketData(instrumentIds []string) { n := len(instrumentIds) if n == 0 { return } cinsIds := make([](*C.char), n) for i, id := range instrumentIds { cid := C.CString(id) cinsIds[i] = cid } C.CCTP_UnSubscribeMarketData(md.cmdApi, (**C.char)((unsafe.Pointer)(&cinsIds[0])), C.int(n)) for _, x := range cinsIds { C.free(unsafe.Pointer(x)) } } type TdApi struct { TdSpi ctdApi unsafe.Pointer } func NewTdApi(spi TdSpi, dir string) *TdApi { csdir := C.CString(dir) defer C.free(unsafe.Pointer(csdir)) ctdApi := C.CCTP_TdApiCreate(csdir) tdApi := &TdApi{spi, ctdApi} f1 := C.fnOnRspUserLogin(C.OnTdRspUserLogin) C.CCTP_RegOnTdRspUserLogin(ctdApi, f1, unsafe.Pointer(tdApi)) f2 := C.fnOnRspUserLogout(C.OnTdRspUserLogout) C.CCTP_RegOnTdRspUserLogout(ctdApi, f2, unsafe.Pointer(tdApi)) f3 := C.fnOnRspError(C.OnTdRspError) C.CCTP_RegOnTdRspError(ctdApi, f3, unsafe.Pointer(tdApi)) f4 := C.fnOnRspQryExchange(C.OnRspQryExchange) C.CCTP_RegOnRspQryExchange(ctdApi, f4, unsafe.Pointer(tdApi)) f5 := C.fnOnRspQryInstrument(C.OnRspQryInstrument) C.CCTP_RegOnRspQryInstrument(ctdApi, f5, unsafe.Pointer(tdApi)) return tdApi } func (td *TdApi) Release() { C.CCTP_TdRelease(unsafe.Pointer(td.ctdApi)) } func (td *TdApi) Login(saddr, brokerId, userId, password, authCode, userProductInfo string) { csaddr := C.CString(saddr) defer C.free(unsafe.Pointer(csaddr)) cbrokerId := C.CString(brokerId) defer C.free(unsafe.Pointer(cbrokerId)) cuserId := C.CString(userId) defer C.free(unsafe.Pointer(cuserId)) cpassword := C.CString(password) defer C.free(unsafe.Pointer(cpassword)) cauthCode := C.CString(authCode) defer C.free(unsafe.Pointer(cauthCode)) cuserProductInfo := C.CString(userProductInfo) defer C.free(unsafe.Pointer(cuserProductInfo)) C.CCTP_TdLogin(td.ctdApi, csaddr, cbrokerId, cuserId, cpassword, cauthCode, cuserProductInfo) } func (td *TdApi) Logout(brokerId, userId string) { cbrokerId := C.CString(brokerId) defer C.free(unsafe.Pointer(cbrokerId)) cuserId := C.CString(userId) defer C.free(unsafe.Pointer(cuserId)) C.CCTP_TdLogout(td.ctdApi, cbrokerId, cuserId) } func (td *TdApi) QryInstrument(instrumentId string) { cinsId := C.CString(instrumentId) if instrumentId == "" { cinsId = (*C.char)(unsafe.Pointer(nil)) } else { defer C.free(unsafe.Pointer(cinsId)) } C.CCTP_ReqQryInstrument(td.ctdApi, cinsId) } func (td *TdApi) QryExchange(exchangeId string) { cexid := C.CString(exchangeId) if exchangeId == "" { cexid = (*C.char)(unsafe.Pointer(nil)) } else { defer C.free(unsafe.Pointer(cexid)) } C.CCTP_ReqQryExchange(td.ctdApi, cexid) }