1 Star 2 Fork 2

海风 / goXele

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
trade.go 12.92 KB
一键复制 编辑 原始数据 按行查看 历史
海风 提交于 2023-06-12 20:50 . 新增: TradePro Release 函数
package goxele
/*
#cgo CXXFLAGS: -std=C++11
#cgo linux LDFLAGS: -lpthread -lrt -L${SRCDIR}/lib -Wl,-rpath=${SRCDIR}/lib -l trade
void* createApi();
const void *getVersion();
const void *getErrorMessage(int errorCode);
void* createSpi();
int setConfig(void* api, const char* name, const char* value);
int start(void *api, void *spi);
int stop(void *api);
int login(void *api);
int logout(void *api);
int changePassword(void *api, char *password, char *newPassword);
int insertOrder(void *api, void *instrumentID, void *inputOrder);
int cancelOrder(void *api, long orderID);
void *getInstrumentByID(void *api, char *instrumentID);
int findOrders(void *api);
int subscribe(void *api, char *instrumentID);
int unsubscribe(void *api, char *instrumentID);
int updateBook(void *api, char *instrumentID, double lastPrice, double bidPrice, int bidVolume, double askPrice, int askVolume);
void SetOnStart(void *spi, void *onFunc);
void SetOnStop(void *spi, void *onFunc);
void SetOnLogin(void *spi, void *onFunc);
void SetOnLogout(void *spi, void *onFunc);
void SetOnChangePassword(void *spi, void *onFunc);
void SetOnReadyForTrading(void *spi, void *onFunc);
void SetOnLoadFinished(void *spi, void *onFunc);
void SetOnOrder(void *spi, void *onFunc);
void SetOnCancelOrder(void *spi, void *onFunc);
void SetOnTrade(void *spi, void *onFunc);
void SetOnAccount(void *spi, void *onFunc);
void SetOnExchange(void *spi, void *onFunc);
void SetOnInstrument(void *spi, void *onFunc);
void SetOnBookUpdate(void *spi, void *onFunc);
void SetOnEvent(void *spi, void *onFunc);
void SetOnError(void *spi, void *onFunc);
void exOnStart(int errorCode, _Bool isFirstTime);
void exOnStop(int errorCode);
void exOnLogin(int errorCode, int exchangeCount);
void exOnLogout(int errorCode);
void exOnChangePassword(int errorCode);
void exOnReadyForTrading(void *account);
void exOnLoadFinished(void *account);
void exOnOrder(int errorCode, void *order);
void exOnCancelOrder(int errorCode, void *order);
void exOnTrade(void *trade);
void exOnAccount(int event, int action, void *account);
void exOnExchange(int event, int action, void *exchange);
void exOnInstrument(int event, void *instrument);
void exOnBookUpdate(void *book);
void exOnEvent(void* event);
void exOnError(int errorCode, void* data, size_t size);
*/
import "C"
import (
"fmt"
"unsafe"
"golang.org/x/text/encoding/simplifiedchinese"
)
var t *Trade
type Trade struct {
api, spi unsafe.Pointer
Instruments map[string]unsafe.Pointer
OnStart func(errorCode int, isFirstTime bool)
OnStop func(errorCode int)
OnLogin func(errorCode int, exchangeCount int)
OnLogout func(errorCode int)
OnChangePassword func(errorCode int)
OnReadyForTrading func(account *XTFAccount)
OnLoadFinished func(account *XTFAccount)
OnOrder func(errorCode int, order *XTFOrder)
OnCancelOrder func(errorCode int, cancelOrder *XTFOrder)
OnTrade func(trade *XTFTrade)
// 账户信息发生变化时回调该接口,如:出入金变化
OnAccount func(event int, action int, account *XTFAccount)
// 交易所信息发生变化时回调该接口,如:交易所前置变化
OnExchange func(event int, action int, exchange *XTFExchange)
// 合约属性发生变化时回调该接口,如:状态变化
OnInstrument func(event int, instrument *XTFInstrument)
OnBookUpdate func(book *XTFMarketData)
OnEvent func(event *XTFEvent)
OnError func(errorCode int)
}
func NewTrade() *Trade {
ver := C.GoString((*C.char)(C.getVersion()))
fmt.Println("API 版本: ", ver)
t = &Trade{}
t.Instruments = make(map[string]unsafe.Pointer)
t.api = C.createApi()
t.spi = C.createSpi()
t.SetOnLoadFinished()
// t.SetOnReadyForTrading()
t.SetOnStart()
t.SetOnStop()
t.SetOnLogin()
t.SetOnLogout()
t.SetOnChangePassword()
t.SetOnExchange()
t.SetOnInstrument()
t.SetOnAccount()
t.SetOrder()
t.SetOnCancelOrder()
t.SetOnTrade()
t.SetOnError()
t.SetOnEvent()
t.SetOnBookUpdate()
return t
}
func (t *Trade) GetErrorMessage(errorCode int) string {
str := C.GoString((*C.char)(C.getErrorMessage(C.int(errorCode))))
str, _ = simplifiedchinese.GB18030.NewDecoder().String(str)
return str
}
/**
* 设置会话参数
*
* 应在启动会话之前设置参数,启动之后设置的参数不会生效。
*
* 会话参数名称列表:
* "ACCOUNT_ID":资金账户ID
* "ACCOUNT_PWD":资金账户密码
* "APP_ID":应用程序ID
* "AUTH_CODE":认证授权码
* "TRADE_SERVER_IP":交易服务地址
* "TRADE_SERVER_PORT":交易服务端口
* "QUERY_SERVER_IP":查询服务地址
* "QUERY_SERVER_PORT":查询服务端口
* "HEARTBEAT_INTERVAL":心跳间隔时间,单位:毫秒
* "HEARTBEAT_TIMEOUT":心跳超时时间,单位:毫秒
* "TCP_RECONNECT_ENABLED":TCP断开后是否重连
* "TCP_RETRY_INTERVAL":TCP重连最小间隔时间,单位:毫秒
* "TCP_RETRY_INTERVAL_MAX":TCP重连最大间隔时间,单位:毫秒
* "TCP_RETRY_COUNT":TCP重连次数
* "TCP_WORKER_CORE_ID":数据收发线程绑核
* "TCP_WORKER_BUSY_LOOP_ENABLED":数据收发线程是否启用BusyLoop模式运行
* "TRADE_WORKER_CORE_ID":报单处理线程绑核
* "TASK_WORKER_CORE_ID":通用任务线程绑核
* "POSITION_CALC_ENABLED":是否计算仓位
* "MONEY_CALC_ENABLED":是否计算资金,如果启用资金计算,会默认启用仓位计算
* "HISTORY_ONLY_CALC_ENABLED":是否仅计算历史流水的资金和仓位,如果启用,那么历史流水追平后,将不再计算资金和仓位
* "WARM_INTERVAL":预热时间间隔,取值范围:[10,50],单位:毫秒
* "ORDER_MT_ENABLED":是否启用多线程报单功能
*
* 用户也可以设置自己的参数,以便在需要的地方使用 getConfig() 接口进行获取。
* 会话内部不使用这部分用户参数,仅对其临时存储。
*
* @param name 参数名称
* @param value 参数值
* @return 参数配置成功或失败
*/
func (t *Trade) SetConfig(name, value string) int {
return int(C.setConfig(t.api, C.CString(name), C.CString(value)))
}
func (t *Trade) Start() int {
return int(C.start(t.api, t.spi))
}
func (t *Trade) Stop() int {
return int(C.stop(t.api))
}
func (t *Trade) Login() int {
return int(C.login(t.api))
}
func (t *Trade) Logout() int {
return int(C.logout(t.api))
}
func (t *Trade) GetInstrumentByID(instrumentID string) unsafe.Pointer {
return C.getInstrumentByID(t.api, C.CString(instrumentID))
}
func (t *Trade) ChangePassword(password, newPassword string) int {
return int(C.changePassword(t.api, C.CString(password), C.CString(newPassword)))
}
func (t *Trade) Subscribe(instrumentID string) int {
return int(C.subscribe(t.api, C.CString(instrumentID)))
}
func (t *Trade) UnSubscribe(instrumentID string) int {
return int(C.unsubscribe(t.api, C.CString(instrumentID)))
}
func (t *Trade) UpdateBook(instrumentID string, lastPrice float64, bidPrice float64, bidVolume int, askPrice float64, askVolume int) int {
return int(C.updateBook(t.api, C.CString(instrumentID), C.double(lastPrice), C.double(bidPrice), C.int(bidVolume), C.double(askPrice), C.int(askVolume)))
}
/**
* 发送报单
*
* 说明:
* - 该接口是线程不安全的,不能在多线程调用同一个API实例对象的报单接口;
* - 在 XTFSpi::onOrder() 接口中通知用户插入报单的结果和报单状态;
*
* @param inputOrder 待插入的报单参数
* @param inputOrders 待批量插入的报单参数数组
* @param orderCount 批量插入数量
* @return 接口调用成功返回0,否则返回错误码
* 调用成功并不表示报单操作的结果。
* ERRXTFAPI_InvalidImp
* ERRXTFAPI_NotStarted
* ERRXTFAPI_NotLoggedIn
* ERRXTFAPI_InvalidInstrument
* ERRXTFAPI_OrderCountExceeded
* 以及网络发送可能出现的错误码
*/
// InsertOrder 委托
//
// @receiver t
// @param instrument 合约指针(需要用 t.GetInstrumentByID("合约代码") 获取)
// @param order 委托参数
// @return int 返回值:0 正确,其他 错误
func (t *Trade) InsertOrder(instrument unsafe.Pointer, order XTFInputOrder) int {
return int(C.insertOrder(t.api, instrument, unsafe.Pointer(&order)))
}
func (t *Trade) CancelOrder(localID int32) int {
return int(C.cancelOrder(t.api, C.long(localID)))
}
func (t *Trade) FindOrders() int {
return int(C.findOrders(t.api))
}
//export exOnStart
func exOnStart(errorCode C.int, isFirstTime C._Bool) {
if t.OnStart == nil {
fmt.Println("exOnStart")
} else {
t.OnStart(int(errorCode), bool(isFirstTime))
}
}
//export exOnStop
func exOnStop(errorCode C.int) {
if t.OnStop == nil {
fmt.Println("exOnStop")
} else {
t.OnStop(int(errorCode))
}
}
//export exOnLogin
func exOnLogin(errorCode C.int, exchangeCount C.int) {
if t.OnLogin == nil {
fmt.Println("exOnLogin")
} else {
t.OnLogin(int(errorCode), int(exchangeCount))
}
}
//export exOnLogout
func exOnLogout(errorCode C.int) {
if t.OnLogout == nil {
fmt.Println("exOnLogout")
} else {
t.OnLogout(int(errorCode))
}
}
//export exOnChangePassword
func exOnChangePassword(errorCode C.int) {
if t.OnChangePassword == nil {
fmt.Println("exOnChangePassword")
} else {
t.OnChangePassword(int(errorCode))
}
}
//export exOnReadyForTrading
func exOnReadyForTrading(account unsafe.Pointer) {
if t.OnReadyForTrading == nil {
fmt.Println("exOnReadyForTrading")
} else {
t.OnReadyForTrading((*XTFAccount)(unsafe.Pointer(account)))
}
}
//export exOnLoadFinished
func exOnLoadFinished(account unsafe.Pointer) {
if t.OnLoadFinished == nil {
fmt.Println("exOnLoadFinished")
} else {
t.OnLoadFinished((*XTFAccount)(unsafe.Pointer(account)))
}
}
//export exOnOrder
func exOnOrder(errorCode C.int, order unsafe.Pointer) {
if t.OnOrder == nil {
fmt.Println("exOnOrder")
} else {
t.OnOrder(int(errorCode), (*XTFOrder)(unsafe.Pointer(order)))
}
}
//export exOnCancelOrder
func exOnCancelOrder(errorCode C.int, cancelOrder unsafe.Pointer) {
if t.OnCancelOrder == nil {
fmt.Println("exOnCancelOrder")
} else {
t.OnCancelOrder(int(errorCode), (*XTFOrder)(unsafe.Pointer(cancelOrder)))
}
}
//export exOnTrade
func exOnTrade(trade unsafe.Pointer) {
if t.OnTrade == nil {
fmt.Println("exOnTrade")
} else {
t.OnTrade((*XTFTrade)(unsafe.Pointer(trade)))
}
}
//export exOnAccount
func exOnAccount(event C.int, action C.int, account unsafe.Pointer) {
if t.OnAccount == nil {
fmt.Println("exOnAccount")
} else {
t.OnAccount(int(event), int(action), (*XTFAccount)(unsafe.Pointer(account)))
}
}
//export exOnExchange
func exOnExchange(event C.int, channelID C.int, exchange unsafe.Pointer) {
if t.OnExchange == nil {
exc := (*XTFExchange)(unsafe.Pointer(exchange))
fmt.Printf("exOnExchange: %s, event: %v, channelID: %v\n", exc.ExchangeID.String(), event, channelID)
} else {
t.OnExchange(int(event), int(channelID), (*XTFExchange)(unsafe.Pointer(exchange)))
}
}
//export exOnInstrument
func exOnInstrument(event C.int, instrument unsafe.Pointer) {
inst := (*XTFInstrument)(unsafe.Pointer(instrument))
t.Instruments[inst.InstrumentID.String()] = instrument
if t.OnInstrument != nil {
t.OnInstrument(int(event), inst)
}
}
//export exOnBookUpdate
func exOnBookUpdate(marketData unsafe.Pointer) {
if t.OnBookUpdate == nil {
fmt.Println("exOnBookUpdate")
} else {
t.OnBookUpdate((*XTFMarketData)(unsafe.Pointer(marketData)))
}
}
//export exOnEvent
func exOnEvent(event unsafe.Pointer) {
if t.OnEvent == nil {
e := (*XTFEvent)(unsafe.Pointer(event))
fmt.Printf("exOnEvent: time: %v, eventID: %v, eventType: %v\n", e.EventTime, e.EventID, e.EventType)
} else {
t.OnEvent((*XTFEvent)(unsafe.Pointer(event)))
}
}
//export exOnError
func exOnError(errorCode C.int, data unsafe.Pointer, size C.ulong) {
if t.OnError == nil {
fmt.Printf("exOnError: id: %v\n", errorCode)
} else {
t.OnError(int(errorCode))
}
}
// --------- 响应 -------------
func (t *Trade) SetOnStart() {
C.SetOnStart(t.spi, C.exOnStart)
}
func (t *Trade) SetOnStop() {
C.SetOnStop(t.spi, C.exOnStop)
}
func (t *Trade) SetOnLogin() {
C.SetOnLogin(t.spi, C.exOnLogin)
}
func (t *Trade) SetOnLogout() {
C.SetOnLogout(t.spi, C.exOnLogout)
}
func (t *Trade) SetOnChangePassword() {
C.SetOnChangePassword(t.spi, C.exOnChangePassword)
}
func (t *Trade) SetOnReadyForTrading() {
C.SetOnReadyForTrading(t.spi, C.exOnReadyForTrading)
}
func (t *Trade) SetOnLoadFinished() {
C.SetOnLoadFinished(t.spi, C.exOnLoadFinished)
}
func (t *Trade) SetOrder() {
C.SetOnOrder(t.spi, C.exOnOrder)
}
func (t *Trade) SetOnCancelOrder() {
C.SetOnCancelOrder(t.spi, C.exOnCancelOrder)
}
func (t *Trade) SetOnTrade() {
C.SetOnTrade(t.spi, C.exOnTrade)
}
func (t *Trade) SetOnAccount() {
C.SetOnAccount(t.spi, C.exOnAccount)
}
func (t *Trade) SetOnExchange() {
C.SetOnExchange(t.spi, C.exOnExchange)
}
func (t *Trade) SetOnInstrument() {
C.SetOnInstrument(t.spi, C.exOnInstrument)
}
func (t *Trade) SetOnBookUpdate() {
C.SetOnBookUpdate(t.spi, C.exOnBookUpdate)
}
func (t *Trade) SetOnEvent() {
C.SetOnEvent(t.spi, C.exOnEvent)
}
func (t *Trade) SetOnError() {
C.SetOnError(t.spi, C.exOnError)
}
Go
1
https://gitee.com/haifengat/goxele.git
git@gitee.com:haifengat/goxele.git
haifengat
goxele
goXele
v0.0.7

搜索帮助