Python-CTP PyCTP 接口
调用参考
https://github.com/shizhuolin/PyCTP/blob/master/tests/test_PyCTP.py
具体参数可参考ctp头文件
git clone https://github.com/shizhuolin/PyCTP.git
cd PyCTP
python setup.py build
这是程序化期货交易上期ctp接口版本. 为方便数值计算.将其包装为python版本.
支持python 2.7+, 3.x, windows/linux/gcc/vs2022
绝大部分代码是直接从ctp源码转换而来.
- char[x] 均用 pybytes代替
- char用pybyte代替,bool使用pybool或int
调用示范:
# -*- coding: utf-8 -*-
"""
Created on Sat Jul 30 17:19:21 2025
@author: zhuolin
"""
from __future__ import print_function
import sys
import threading
import PyCTP
class ReadonlyModuleWrapper(object):
def __init__(self, wrapped):
self._wrapped = wrapped
def __getattr__(self, key):
return getattr(self._wrapped, key)
def __setattr__(self, key, value):
if key == "_wrapped":
super(ReadonlyModuleWrapper, self).__setattr__(key, value)
else:
raise AttributeError("Module attributes are read-only")
def __delattr__(self, key):
raise AttributeError("Module attributes are read-only")
def user_input(prompt=''):
if sys.version_info[0] < 3:
# Python 2
return raw_input(prompt)
else:
# Python 3
return input(prompt)
def bytes2unicode(data, encoding='gb2312', errors='replace'):
if sys.version_info[0] < 3:
# Python 2
return data if isinstance(data, unicode) else data.decode(encoding, errors)
else:
# Python 3
return data if isinstance(data, str) else data.decode(encoding, errors)
def unicode2bytes(data, encoding='gb2312', errors='replace'):
if sys.version_info[0] < 3:
# Python 2
return data.encode(encoding, errors) if isinstance(data, unicode) else data
else:
# Python 3
return data.encode(encoding, errors) if isinstance(data, str) else data
PyCTP = ReadonlyModuleWrapper(PyCTP)
class PyCTP_Market_API(PyCTP.CThostFtdcMdApi):
TIMEOUT = 30
__RequestID = 0
__isLogined = False
def __IncRequestID(self):
""" 自增并返回请求ID """
# self.__RequestID += 1
return self.__RequestID
def Connect(self, frontAddr):
""" 连接前置服务器 """
self.RegisterSpi(self)
self.RegisterFront(frontAddr)
self.Init()
self.__rsp_Connect_event = threading.Event()
self.__rsp_Connect_event.clear()
return 0 if self.__rsp_Connect_event.wait(self.TIMEOUT) else -4
def Login(self, BrokerID, UserID, Password):
""" 用户登录请求 """
reqUserLogin = PyCTP.CThostFtdcReqUserLoginField()
reqUserLogin.BrokerID = BrokerID
reqUserLogin.UserID = UserID
reqUserLogin.Password = Password
self.__rsp_Login_event = threading.Event()
self.__rsp_Login_RequestID = self.__IncRequestID()
ret = self.ReqUserLogin(reqUserLogin, self.__rsp_Login_RequestID)
if ret == 0:
self.__rsp_Login_event.clear()
if self.__rsp_Login_event.wait(self.TIMEOUT):
if self.__rsp_Login_RspInfo.ErrorID == 0:
self.__isLogined = True
self.__BrokerID = BrokerID
self.__UserID = UserID
self.__Password = Password
else:
sys.stderr.write(bytes2unicode(self.__rsp_Login_ErrorMsg) + '\n')
return self.__rsp_Login_RspInfo.ErrorID
else:
return -4
return ret
def Logout(self):
""" 登出请求 """
reqUserLogout = PyCTP.CThostFtdcUserLogoutField(BrokerID = self.__BrokerID
,UserID = self.__UserID)
self.__rsp_Logout_event = threading.Event()
self.__rsp_Logout_RequestID = self.__IncRequestID()
ret = self.ReqUserLogout(reqUserLogout, self.__rsp_Logout_RequestID)
if ret == 0:
self.__rsp_Logout_event.clear()
if self.__rsp_Logout_event.wait(self.TIMEOUT):
if self.__rsp_Logout_RspInfo.ErrorID == 0:
self.__isLogined = False
return self.__rsp_Logout_RspInfo.ErrorID
else:
return -4
return ret
def SubMarketData(self, InstrumentID):
""" 订阅行情 """
self.__rsp_SubMarketData_results=[]
self.__rsp_SubMarketData_event=threading.Event()
self.__rsp_SubMarketData_RequestID=self.__IncRequestID()
ret = self.SubscribeMarketData(InstrumentID, len(InstrumentID))
if ret == 0:
self.__rsp_SubMarketData_event.clear()
if self.__rsp_SubMarketData_event.wait(self.TIMEOUT):
if self.__rsp_SubMarketData_RspInfo.ErrorID != 0:
return self.__rsp_SubMarketData_RspInfo.ErrorID
return self.__rsp_SubMarketData_results
else:
return -4
return ret
def UnSubMarketData(self, InstrumentID):
""" 退订行情 """
self.__rsp_UnSubMarketData_results = []
self.__rsp_UnSubMarketData_event = threading.Event()
self.__rsp_UnSubMarketData_RequestID = self.__IncRequestID()
ret = self.UnSubscribeMarketData(InstrumentID, len(InstrumentID))
if ret == 0:
self.__rsp_UnSubMarketData_event.clear()
if self.__rsp_UnSubMarketData_event.wait(self.TIMEOUT):
if self.__rsp_UnSubMarketData_RspInfo.ErrorID != 0:
return self.__rsp_UnSubMarketData_RspInfo.ErrorID
return self.__rsp_UnSubMarketData_results
else:
return -4
return ret
def SubForQuoteRsp(self, InstrumentID):
""" 订阅询价 """
self.__rsp_SubForQuoteRsp_results = []
self.__rsp_SubForQuoteRsp_event = threading.Event()
self.__rsp_SubForQuoteRsp_RequestID = self.__IncRequestID()
ret = self.SubscribeForQuoteRsp(InstrumentID, len(InstrumentID))
if ret == 0:
self.__rsp_SubForQuoteRsp_event.clear()
if self.__rsp_SubForQuoteRsp_event.wait(self.TIMEOUT):
if self.__rsp_SubForQuoteRsp_RspInfo.ErrorID != 0:
return self.__rsp_SubForQuoteRsp_RspInfo.ErrorID
return self.__rsp_SubForQuoteRsp_results
else:
return -4
return ret
def UnSubForQuoteRsp(self, InstrumentID):
""" 订阅询价 """
self.__rsp_UnSubForQuoteRsp_results = []
self.__rsp_UnSubForQuoteRsp_event = threading.Event()
self.__rsp_UnSubForQuoteRsp_RequestID = self.__IncRequestID()
ret = self.UnSubscribeForQuoteRsp(InstrumentID, len(InstrumentID))
if ret == 0:
self.__rsp_UnSubForQuoteRsp_event.clear()
if self.__rsp_UnSubForQuoteRsp_event.wait(self.TIMEOUT):
if self.__rsp_UnSubForQuoteRsp_RspInfo.ErrorID != 0:
return self.__rsp_UnSubForQuoteRsp_RspInfo.ErrorID
return self.__rsp_UnSubForQuoteRsp_results
else:
return -4
return ret
def OnFrontConnected(self):
""" 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 """
self.__rsp_Connect_event.set()
def OnFrontDisconnected(self, nReason):
""" 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。
nReason 错误原因
0x1001 网络读失败
0x1002 网络写失败
0x2001 接收心跳超时
0x2002 发送心跳失败
0x2003 收到错误报文
"""
sys.stderr.write('前置连接中断: %s' % hex(nReason))
def OnRspError(self, RspInfo, RequestID, IsLast):
""" 错误信息 """
sys.stderr.write(repr(([RspInfo.ErrorID, bytes2unicode(RspInfo.ErrorMsg)], RequestID, IsLast))+'\n')
def OnRspUserLogin(self, RspUserLogin, RspInfo, RequestID, IsLast):
""" 登录请求响应 """
if RequestID == self.__rsp_Login_RequestID and IsLast:
self.__BrokerID = RspUserLogin.BrokerID
self.__UserID = RspUserLogin.UserID
self.__SystemName = RspUserLogin.SystemName
self.__TradingDay = RspUserLogin.TradingDay
self.__DCETime = RspUserLogin.DCETime
self.__SessionID = RspUserLogin.SessionID
self.__MaxOrderRef = RspUserLogin.MaxOrderRef
self.__INETime = RspUserLogin.INETime
self.__LoginTime = RspUserLogin.LoginTime
self.__FrontID = RspUserLogin.FrontID
self.__FFEXTime = RspUserLogin.FFEXTime
self.__CZCETime = RspUserLogin.CZCETime
self.__SHFETime = RspUserLogin.SHFETime
self.__rsp_Login_RspInfo = RspInfo
self.__rsp_Login_event.set()
def OnRspUserLogout(self, RspUserLogout, RspInfo, RequestID, IsLast):
""" 登出请求响应 """
if RequestID == self.__rsp_Logout_RequestID and IsLast:
self.__rsp_Logout_RspInfo = RspInfo
self.__rsp_Logout_event.set()
def OnRspSubMarketData(self, SpecificInstrument, RspInfo, RequestID, IsLast):
""" 订阅行情应答 """
if RequestID == self.__rsp_SubMarketData_RequestID:
if RspInfo is not None:
self.__rsp_SubMarketData_RspInfo = RspInfo
if SpecificInstrument is not None:
self.__rsp_SubMarketData_results.append(SpecificInstrument)
if IsLast:
self.__rsp_SubMarketData_event.set()
def OnRspUnSubMarketData(self, SpecificInstrument, RspInfo, RequestID, IsLast):
""" 取消订阅行情应答 """
if RequestID == self.__rsp_UnSubMarketData_RequestID:
if RspInfo is not None:
self.__rsp_UnSubMarketData_RspInfo = RspInfo
if SpecificInstrument is not None:
self.__rsp_UnSubMarketData_results.append(SpecificInstrument)
if IsLast:
self.__rsp_UnSubMarketData_event.set()
def OnRspSubForQuoteRsp(self, SpecificInstrument, RspInfo, RequestID, IsLast):
""" 订阅询价应答 """
if RequestID == self.__rsp_SubForQuoteRsp_RequestID:
if RspInfo is not None:
self.__rsp_SubForQuoteRsp_RspInfo = RspInfo
if SpecificInstrument is not None:
self.__rsp_SubForQuoteRsp_results.append(SpecificInstrument)
if IsLast:
self.__rsp_SubForQuoteRsp_event.set()
def OnRspUnSubForQuoteRsp(self, SpecificInstrument, RspInfo, RequestID, IsLast):
""" 订阅询价应答 """
if RequestID == self.__rsp_UnSubForQuoteRsp_RequestID:
if RspInfo is not None:
self.__rsp_UnSubForQuoteRsp_RspInfo = RspInfo
if SpecificInstrument is not None:
self.__rsp_UnSubForQuoteRsp_results.append(SpecificInstrument)
if IsLast:
self.__rsp_UnSubForQuoteRsp_event.set()
class PyCTP_Trader_API(PyCTP.CThostFtdcTraderApi):
TIMEOUT = 30
__RequestID = 0
__isLogined = False
def __IncRequestID(self):
""" 自增并返回请求ID """
self.__RequestID += 1
return self.__RequestID
def __IncOrderRef(self):
""" 递增报单引用 """
OrderRef = self.__OrderRef
self.__OrderRef += 1
return OrderRef
def setInvestorID(self, InvestorID):
self.__InvestorID = InvestorID
return self.__InvestorID
def Connect(self, frontAddr):
""" 连接前置服务器 """
self.RegisterSpi(self)
self.SubscribePrivateTopic(PyCTP.THOST_TERT_RESUME)
self.SubscribePublicTopic(PyCTP.THOST_TERT_RESUME)
self.RegisterFront(frontAddr)
self.Init()
self.__rsp_Connect_event = threading.Event()
self.__rsp_Connect_event.clear()
return 0 if self.__rsp_Connect_event.wait(self.TIMEOUT) else -4
def Authenticate(self, BrokerID, UserID, UserProductInfo, AuthCode, AppID):
""" 客户端认证 """
pReqAuthenticateField = PyCTP.CThostFtdcReqAuthenticateField()
pReqAuthenticateField.BrokerID = BrokerID
pReqAuthenticateField.UserID = UserID
#pReqAuthenticateField.UserProductInfo = UserProductInfo
pReqAuthenticateField.AuthCode = AuthCode
pReqAuthenticateField.AppID = AppID
self.__rsp_Authenticate_event = threading.Event()
self.__rsp_Authenticate_RequestID = self.__IncRequestID()
self.__rsp_Authenticate_RspInfo = None
ret = self.ReqAuthenticate(pReqAuthenticateField, self.__rsp_Authenticate_RequestID)
if ret == 0:
self.__rsp_Authenticate_event.clear()
if self.__rsp_Authenticate_event.wait(self.TIMEOUT):
if self.__rsp_Authenticate_RspInfo and self.__rsp_Authenticate_RspInfo.ErrorID != 0:
return self.__rsp_Authenticate_RspInfo.ErrorID
return bytes2unicode(self.__rsp_Authenticate_RspInfo.ErrorMsg)
else:
return -4
return ret
def Login(self, BrokerID, UserID, Password):
""" 用户登录请求 """
reqUserLogin = PyCTP.CThostFtdcReqUserLoginField()
reqUserLogin.BrokerID = BrokerID
reqUserLogin.UserID = UserID
reqUserLogin.Password = Password
reqUserLogin.LoginRemark = b'test'
self.__rsp_Login_event = threading.Event()
self.__rsp_Login_RequestID = self.__IncRequestID()
self.__rsp_Login_RspInfo = None
ret = self.ReqUserLogin(reqUserLogin, self.__rsp_Login_RequestID)
if ret == 0:
self.__rsp_Login_event.clear()
if self.__rsp_Login_event.wait(self.TIMEOUT):
if self.__rsp_Login_RspInfo and self.__rsp_Login_RspInfo.ErrorID == 0:
self.__isLogined = True
self.__Password = Password
else:
sys.stderr.write(bytes2unicode(self.__rsp_Login_RspInfo.ErrorMsg)+'\n')
return self.__rsp_Login_RspInfo.ErrorID
else:
return -4
return ret
def Logout(self):
""" 登出请求 """
reqUserLogout = PyCTP.CThostFtdcUserLogoutField(BrokerID = self.__BrokerID
,UserID = self.__UserID)
self.__rsp_Logout_event = threading.Event()
self.__rsp_Logout_RequestID = self.__IncRequestID()
self.__rsp_Logout_RspInfo = None
ret = self.ReqUserLogout(reqUserLogout, self.__rsp_Logout_RequestID)
if ret == 0:
self.__rsp_Logout_event.clear()
if self.__rsp_Logout_event.wait(self.TIMEOUT):
if self.__rsp_Logout_RspInfo and self.__rsp_Logout_RspInfo.ErrorID == 0:
self.__isLogined = False
return self.__rsp_Logout_RspInfo.ErrorID
else:
return -4
return ret
def SubUserSystemInfo(self, BrokerID, UserID, AppID):
"""
///上报用户终端信息,用于中继服务器操作员登录模式
///操作员登录后,可以多次调用该接口上报客户信息
"""
userSystemInfo = PyCTP.CThostFtdcUserSystemInfoField()
userSystemInfo.BrokerID = BrokerID
userSystemInfo.UserID = UserID
systemInfo = PyCTP.CTP_GetSystemInfo()
Return = systemInfo['Return']
userSystemInfo.ClientSystemInfo = systemInfo['SystemInfo']
userSystemInfo.ClientSystemInfoLen = systemInfo['Length']
userSystemInfo.ClientPublicIP = b'192.168.0.1'
userSystemInfo.ClientIPPort = 51305
userSystemInfo.ClientLoginTime = b'20190121'
userSystemInfo.ClientAppID = AppID
ret = self.SubmitUserSystemInfo(userSystemInfo)
return ret
def RegUserSystemInfo(self, BrokerID, UserID, AppID):
"""
///注册用户终端信息,用于中继服务器多连接模式
///需要在终端认证成功后,用户登录前调用该接口
"""
userSystemInfo = PyCTP.CThostFtdcUserSystemInfoField()
userSystemInfo.BrokerID = BrokerID
userSystemInfo.UserID = UserID
systemInfo = PyCTP.CTP_GetSystemInfo()
Return = systemInfo['Return']
userSystemInfo.ClientSystemInfo = systemInfo['SystemInfo']
userSystemInfo.ClientSystemInfoLen = systemInfo['Length']
userSystemInfo.ClientPublicIP = b'192.168.0.1'
userSystemInfo.ClientIPPort = 51305
userSystemInfo.ClientLoginTime = b'20190121'
userSystemInfo.ClientAppID = AppID
ret = self.RegisterUserSystemInfo(userSystemInfo)
return ret
def SettlementInfoConfirm(self):
""" 请求确认结算单 """
confirm = PyCTP.CThostFtdcSettlementInfoConfirmField()
confirm.BrokerID = self.__BrokerID
confirm.InvestorID = self.__InvestorID
self.__rsp_SettlementInfoConfirm_RequestID = self.__IncRequestID()
self.__rsp_SettlementInfoConfirm_event = threading.Event()
self.__rsp_SettlementInfoConfirm_RspInfo = None
self.__rsp_SettlementInfoConfirm_results = []
ret = self.ReqSettlementInfoConfirm(confirm, self.__rsp_SettlementInfoConfirm_RequestID)
if ret == 0:
self.__rsp_SettlementInfoConfirm_event.clear()
if self.__rsp_SettlementInfoConfirm_event.wait(self.TIMEOUT):
if self.__rsp_SettlementInfoConfirm_RspInfo and self.__rsp_SettlementInfoConfirm_RspInfo.ErrorID != 0:
return self.__rsp_SettlementInfoConfirm_RspInfo.ErrorID
return self.__rsp_SettlementInfoConfirm_results
else:
return -4
return ret
def QryExchange(self, ExchangeID=b''):
""" 请求查询交易所 """
QryExchangeField = PyCTP.CThostFtdcQryExchangeField(ExchangeID=ExchangeID)
self.__rsp_QryExchange_results = []
self.__rsp_QryExchange_RequestID = self.__IncRequestID()
self.__rsp_QryExchange_event = threading.Event()
self.__rsp_QryExchange_RspInfo = None
ret = self.ReqQryExchange(QryExchangeField, self.__rsp_QryExchange_RequestID)
if ret == 0:
self.__rsp_QryExchange_event.clear()
if self.__rsp_QryExchange_event.wait(self.TIMEOUT):
if self.__rsp_QryExchange_RspInfo and self.__rsp_QryExchange_RspInfo.ErrorID != 0:
return self.__rsp_QryExchange_RspInfo.ErrorID
return self.__rsp_QryExchange_results
else:
return -4
return ret
def QryInvestor(self):
""" 请求查询投资者 """
InvestorField = PyCTP.CThostFtdcQryInvestorField(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID)
self.__rsp_QryInvestor_results = []
self.__rsp_QryInvestor_RequestID = self.__IncRequestID()
self.__rsp_QryInvestor_event=threading.Event()
self.__rsp_QryInvestor_RspInfo = None
ret = self.ReqQryInvestor(InvestorField, self.__rsp_QryInvestor_RequestID)
if ret == 0:
self.__rsp_QryInvestor_event.clear()
if self.__rsp_QryInvestor_event.wait(self.TIMEOUT):
if self.__rsp_QryInvestor_RspInfo and self.__rsp_QryInvestor_RspInfo.ErrorID != 0:
return self.__rsp_QryInvestor_RspInfo.ErrorID
return self.__rsp_QryInvestor_results
else:
return -4
return ret
def QryTradingAccount(self):
""" 请求查询资金账户 """
QryTradingAccountField = PyCTP.CThostFtdcQryTradingAccountField(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID)
self.__rsp_QryTradingAccount_results = []
self.__rsp_QryTradingAccount_RequestID = self.__IncRequestID()
self.__rsp_QryTradingAccount_event = threading.Event()
self.__rsp_QryTradingAccount_RspInfo = None
ret = self.ReqQryTradingAccount(QryTradingAccountField, self.__rsp_QryTradingAccount_RequestID)
if ret == 0:
self.__rsp_QryTradingAccount_event.clear()
if self.__rsp_QryTradingAccount_event.wait(self.TIMEOUT):
if self.__rsp_QryTradingAccount_RspInfo and self.__rsp_QryTradingAccount_RspInfo.ErrorID != 0:
return self.__rsp_QryTradingAccount_RspInfo.ErrorID
return self.__rsp_QryTradingAccount_results
else:
return -4
return ret
def QryInstrument(self, ExchangeID=b'', InstrumentID=b''):
""" 查询和约 """
QryInstrument = PyCTP.CThostFtdcQryInstrumentField(ExchangeID = ExchangeID, InstrumentID = InstrumentID)
self.__rsp_QryInstrument_event = threading.Event()
self.__rsp_QryInstrument_RequestID = self.__IncRequestID()
self.__rsp_QryInstrument_results = []
self.__rsp_QryInstrument_RspInfo = None
ret = self.ReqQryInstrument(QryInstrument, self.__rsp_QryInstrument_RequestID)
if ret == 0:
self.__rsp_QryInstrument_event.clear()
if self.__rsp_QryInstrument_event.wait(self.TIMEOUT):
if self.__rsp_QryInstrument_RspInfo and self.__rsp_QryInstrument_RspInfo.ErrorID != 0:
return self.__rsp_QryInstrument_RspInfo.ErrorID
return self.__rsp_QryInstrument_results
else:
return -4
return ret
def QryDepthMarketData(self, InstrumentID):
""" 请求查询行情 """
QryDepthMarketData = PyCTP.CThostFtdcQryDepthMarketDataField()
QryDepthMarketData.ProductClass = PyCTP.THOST_FTDC_PC_Futures
QryDepthMarketData.InstrumentID = InstrumentID
self.__rsp_QryDepthMarketData_results = []
self.__rsp_QryDepthMarketData_RequestID = self.__IncRequestID()
self.__rsp_QryDepthMarketData_event = threading.Event()
self.__rsp_QryDepthMarketData_RspInfo = None
ret = self.ReqQryDepthMarketData(QryDepthMarketData, self.__rsp_QryDepthMarketData_RequestID)
if ret == 0:
self.__rsp_QryDepthMarketData_event.clear()
if self.__rsp_QryDepthMarketData_event.wait(self.TIMEOUT):
if self.__rsp_QryDepthMarketData_RspInfo and self.__rsp_QryDepthMarketData_RspInfo.ErrorID != 0:
return self.__rsp_QryDepthMarketData_RspInfo.ErrorID
return self.__rsp_QryDepthMarketData_results
else:
return -4
return ret
def QryInstrumentCommissionRate(self, InstrumentID):
""" 请求查询合约手续费率 """
QryInstrumentCommissionRate = PyCTP.CThostFtdcQryInstrumentCommissionRateField()
QryInstrumentCommissionRate.BrokerID = self.__BrokerID
QryInstrumentCommissionRate.InvestorID = self.__InvestorID
QryInstrumentCommissionRate.InstrumentID = InstrumentID
self.__rsp_QryInstrumentCommissionRate_results = []
self.__rsp_QryInstrumentCommissionRate_RequestID = self.__IncRequestID()
self.__rsp_QryInstrumentCommissionRate_RspInfo = None
self.__rsp_QryInstrumentCommissionRate_event = threading.Event()
ret = self.ReqQryInstrumentCommissionRate(QryInstrumentCommissionRate, self.__rsp_QryInstrumentCommissionRate_RequestID)
if ret == 0:
self.__rsp_QryInstrumentCommissionRate_event.clear()
if self.__rsp_QryInstrumentCommissionRate_event.wait(self.TIMEOUT):
if self.__rsp_QryInstrumentCommissionRate_RspInfo and self.__rsp_QryInstrumentCommissionRate_RspInfo.ErrorID != 0:
return self.__rsp_QryInstrumentCommissionRate_RspInfo.ErrorID
return self.__rsp_QryInstrumentCommissionRate_results
else:
return -4
return ret
def QryInstrumentMarginRate(self, InstrumentID):
""" 请求查询合约保证金率 """
QryInstrumentMarginRate = PyCTP.CThostFtdcQryInstrumentMarginRateField()
QryInstrumentMarginRate.BrokerID = self.__BrokerID
QryInstrumentMarginRate.InvestorID = self.__InvestorID
QryInstrumentMarginRate.InstrumentID = InstrumentID
self.__rsp_QryInstrumentMarginRate_results = []
self.__rsp_QryInstrumentMarginRate_RequestID = self.__IncRequestID()
self.__rsp_QryInstrumentMarginRate_RspInfo = None
self.__rsp_QryInstrumentMarginRate_event = threading.Event()
ret = self.ReqQryInstrumentMarginRate(QryInstrumentMarginRate, self.__rsp_QryInstrumentMarginRate_RequestID)
if ret == 0:
self.__rsp_QryInstrumentMarginRate_event.clear()
if self.__rsp_QryInstrumentMarginRate_event.wait(self.TIMEOUT):
if self.__rsp_QryInstrumentMarginRate_RspInfo and self.__rsp_QryInstrumentMarginRate_RspInfo.ErrorID != 0:
return self.__rsp_QryInstrumentMarginRate_RspInfo.ErrorID
return self.__rsp_QryInstrumentMarginRate_results
else:
return -4
return ret
def QryInvestorPosition(self, InstrumentID=b''):
""" 请求查询投资者持仓 """
QryInvestorPositionFiel = PyCTP.CThostFtdcQryInvestorPositionField()
QryInvestorPositionFiel.BrokerID = self.__BrokerID
QryInvestorPositionFiel.InvestorID = self.__InvestorID
QryInvestorPositionFiel.InstrumentID = InstrumentID
self.__rsp_QryInvestorPosition_results = []
self.__rsp_QryInvestorPosition_RequestID = self.__IncRequestID()
self.__rsp_QryInvestorPosition_RspInfo = None
self.__rsp_QryInvestorPosition_event = threading.Event()
ret = self.ReqQryInvestorPosition(QryInvestorPositionFiel, self.__rsp_QryInvestorPosition_RequestID)
if ret == 0:
self.__rsp_QryInvestorPosition_event.clear()
if self.__rsp_QryInvestorPosition_event.wait(self.TIMEOUT):
if self.__rsp_QryInvestorPosition_RspInfo and self.__rsp_QryInvestorPosition_RspInfo.ErrorID != 0:
return self.__rsp_QryInvestorPosition_RspInfo.ErrorID
return self.__rsp_QryInvestorPosition_results
else:
return -4
return ret
def QryInvestorPositionDetail(self, InstrumentID=b''):
""" 请求查询投资者持仓明细 """
QryInvestorPositionDetailField = PyCTP.CThostFtdcQryInvestorPositionDetailField()
QryInvestorPositionDetailField.BrokerID = self.__BrokerID
QryInvestorPositionDetailField.InvestorID = self.__InvestorID
QryInvestorPositionDetailField.InstrumentID = InstrumentID
self.__rsp_QryInvestorPositionDetail_results = []
self.__rsp_QryInvestorPositionDetail_RequestID = self.__IncRequestID()
self.__rsp_QryInvestorPositionDetail_RspInfo = None
self.__rsp_QryInvestorPositionDetail_event = threading.Event()
ret = self.ReqQryInvestorPositionDetail(QryInvestorPositionDetailField, self.__rsp_QryInvestorPositionDetail_RequestID)
if ret == 0:
self.__rsp_QryInvestorPositionDetail_event.clear()
if self.__rsp_QryInvestorPositionDetail_event.wait(self.TIMEOUT):
if self.__rsp_QryInvestorPositionDetail_RspInfo and self.__rsp_QryInvestorPositionDetail_RspInfo.ErrorID != 0:
return self.__rsp_QryInvestorPositionDetail_RspInfo.ErrorID
return self.__rsp_QryInvestorPositionDetail_results
else:
return -4
return ret
def OrderInsert(self, InstrumentID, Action, Direction, Volume, Price):
""" 开平仓单申报 """
InputOrder = PyCTP.CThostFtdcInputOrderField()
InputOrder.BrokerID = self.__BrokerID # 经纪公司代码
InputOrder.InvestorID = self.__InvestorID # 投资者代码
InputOrder.InstrumentID = InstrumentID # 合约代码
InputOrder.OrderRef = unicode2bytes(str(self.__IncOrderRef())) # 报单引用
InputOrder.UserID = self.__UserID # 用户代码
InputOrder.OrderPriceType = PyCTP.THOST_FTDC_OPT_LimitPrice # 报单价格条件:限价单
InputOrder.Direction = Direction # 买卖方向
InputOrder.CombOffsetFlag = Action # 组合开平标志
InputOrder.CombHedgeFlag = PyCTP.THOST_FTDC_HF_Speculation # 组合投机套保标志:投机
InputOrder.LimitPrice = Price # 价格
InputOrder.VolumeTotalOriginal = Volume # 数量
InputOrder.TimeCondition = PyCTP.THOST_FTDC_TC_GFD # 有效期类型:立即完成,否则撤销
InputOrder.VolumeCondition = PyCTP.THOST_FTDC_VC_AV # 成交量类型:任意数量
InputOrder.MinVolume = Volume # 最小成交量
InputOrder.ContingentCondition = PyCTP.THOST_FTDC_CC_Immediately # 触发条件:立即
InputOrder.ForceCloseReason = PyCTP.THOST_FTDC_FCC_NotForceClose # 强平原因:非强平
InputOrder.IsAutoSuspend = 0 # 自动挂起标志
InputOrder.UserForceClose = 0 # 用户强平标志
self.__rsp_OrderInsert_FrontID = self.__FrontID
self.__rsp_OrderInsert_SessionID = self.__SessionID
self.__rsp_OrderInsert_InputOrder = InputOrder
self.__rsp_OrderInsert_RequestID = self.__IncRequestID()
self.__rsp_OrderInsert_event = threading.Event()
ret = self.ReqOrderInsert(InputOrder, self.__rsp_OrderInsert_RequestID)
# if ret == 0:
# self.__rsp_OrderInsert_event.clear()
# if self.__rsp_OrderInsert_event.wait(self.TIMEOUT):
# if self.__rsp_OrderInsert_RspInfo and self.__rsp_OrderInsert_RspInfo.ErrorID != 0:
# sys.stderr.write(bytes2unicode(self.__rsp_OrderInsert_RspInfo.ErrorMsg) + '\n')
# return self.__rsp_OrderInsert_RspInfo.ErrorID
# return self.__rsp_OrderInsert.copy()
# else:
# return -4
return ret
def OnFrontConnected(self):
""" 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 """
self.__rsp_Connect_event.set()
def OnFrontDisconnected(self, nReason):
""" 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。
nReason 错误原因
0x1001 网络读失败
0x1002 网络写失败
0x2001 接收心跳超时
0x2002 发送心跳失败
0x2003 收到错误报文
"""
sys.stderr.write('前置连接中断: %s \n' % hex(nReason))
def OnRspError(self, RspInfo, RequestID, IsLast):
""" 错误信息 """
sys.stderr.write(repr(([RspInfo.ErrorID, bytes2unicode(RspInfo.ErrorMsg)], RequestID, IsLast))+'\n')
def OnRspAuthenticate(self, pRspAuthenticateField, RspInfo, RequestID, IsLast):
""" 请求响应 """
if RequestID == self.__rsp_Authenticate_RequestID and IsLast:
self.__rsp_Authenticate_RspInfo = RspInfo
self.__rsp_Authenticate_event.set()
def OnRspUserLogin(self, RspUserLogin, RspInfo, RequestID, IsLast):
""" 登录请求响应 """
if RequestID == self.__rsp_Login_RequestID and IsLast:
self.__BrokerID = RspUserLogin.BrokerID
self.__UserID = RspUserLogin.UserID
self.__SystemName = RspUserLogin.SystemName
self.__TradingDay = RspUserLogin.TradingDay
self.__DCETime = RspUserLogin.DCETime
self.__SessionID = RspUserLogin.SessionID
self.__MaxOrderRef = RspUserLogin.MaxOrderRef
self.__OrderRef = int(bytes2unicode(self.__MaxOrderRef)) # 初始化报单引用
self.__INETime = RspUserLogin.INETime
self.__LoginTime = RspUserLogin.LoginTime
self.__FrontID = RspUserLogin.FrontID
self.__FFEXTime = RspUserLogin.FFEXTime
self.__CZCETime = RspUserLogin.CZCETime
self.__SHFETime = RspUserLogin.SHFETime
self.__rsp_Login_RspInfo = RspInfo
self.__rsp_Login_event.set()
def OnRspUserLogout(self, RspUserLogout, RspInfo, RequestID, IsLast):
""" 登出请求响应 """
if RequestID == self.__rsp_Logout_RequestID and IsLast:
self.__rsp_Logout_RspInfo = RspInfo
self.__rsp_Logout_event.set()
def OnRspSettlementInfoConfirm(self, SettlementInfoConfirm, RspInfo, RequestID, IsLast):
""" 投资者结算结果确认响应 """
if RequestID == self.__rsp_SettlementInfoConfirm_RequestID:
self.__rsp_SettlementInfoConfirm_results.append( SettlementInfoConfirm )
if RspInfo:
self.__rsp_SettlementInfoConfirm_RspInfo = RspInfo
if IsLast:
self.__rsp_SettlementInfoConfirm_event.set()
def OnRspQryExchange(self, Exchange, RspInfo, RequestID, IsLast):
""" 请求查询交易所响应 """
if RequestID == self.__rsp_QryExchange_RequestID:
if RspInfo is not None:
self.__rsp_QryExchange_RspInfo = RspInfo
if Exchange is not None:
self.__rsp_QryExchange_results.append(Exchange)
if IsLast:
self.__rsp_QryExchange_event.set()
def OnRspQryInvestor(self, Investor, RspInfo, RequestID, IsLast):
""" 请求查询投资者响应 """
if RequestID == self.__rsp_QryInvestor_RequestID:
if RspInfo is not None:
self.__rsp_QryInvestor_RspInfo = RspInfo
if Investor is not None:
self.__rsp_QryInvestor_results.append(Investor)
if IsLast:
self.__rsp_QryInvestor_event.set()
def OnRspQryTradingAccount(self, TradingAccount, RspInfo, RequestID, IsLast):
""" 请求查询资金账户响应 """
if RequestID == self.__rsp_QryTradingAccount_RequestID:
if RspInfo is not None:
self.__rsp_QryTradingAccount_RspInfo = RspInfo
if TradingAccount is not None:
self.__rsp_QryTradingAccount_results.append(TradingAccount)
if IsLast:
self.__rsp_QryTradingAccount_event.set()
def OnRspQryInstrument(self, Instrument, RspInfo, RequestID, IsLast):
""" 请求查询合约响应 """
if RequestID == self.__rsp_QryInstrument_RequestID:
if RspInfo is not None:
self.__rsp_QryInstrument_RspInfo = RspInfo
if Instrument is not None:
self.__rsp_QryInstrument_results.append(Instrument)
if IsLast:
self.__rsp_QryInstrument_event.set()
def OnRspQryDepthMarketData(self, DepthMarketData, RspInfo, RequestID, IsLast):
""" 请求查询行情响应 """
if RequestID == self.__rsp_QryDepthMarketData_RequestID:
if RspInfo is not None:
self.__rsp_QryDepthMarketData_RspInfo = RspInfo
if DepthMarketData is not None:
self.__rsp_QryDepthMarketData_results.append(DepthMarketData)
if IsLast:
self.__rsp_QryDepthMarketData_event.set()
def OnRspQryInstrumentCommissionRate(self, InstrumentCommissionRate, RspInfo, RequestID, IsLast):
""" 请求查询合约手续费率响应 """
if RequestID == self.__rsp_QryInstrumentCommissionRate_RequestID:
if RspInfo is not None:
self.__rsp_QryInstrumentCommissionRate_RspInfo = RspInfo
if InstrumentCommissionRate is not None:
self.__rsp_QryInstrumentCommissionRate_results.append(InstrumentCommissionRate)
if IsLast:
self.__rsp_QryInstrumentCommissionRate_event.set()
def OnRspQryInstrumentMarginRate(self, InstrumentMarginRate, RspInfo, RequestID, IsLast):
""" 请求查询合约保证金率响应 """
if RequestID == self.__rsp_QryInstrumentMarginRate_RequestID:
if RspInfo is not None:
self.__rsp_QryInstrumentMarginRate_RspInfo = RspInfo
if InstrumentMarginRate is not None:
self.__rsp_QryInstrumentMarginRate_results.append(InstrumentMarginRate)
if IsLast:
self.__rsp_QryInstrumentMarginRate_event.set()
def OnRspQryInvestorPosition(self, InvestorPosition, RspInfo, RequestID, IsLast):
""" 请求查询投资者持仓响应 """
if RequestID == self.__rsp_QryInvestorPosition_RequestID:
if RspInfo is not None:
self.__rsp_QryInvestorPosition_RspInfo = RspInfo
if InvestorPosition is not None:
self.__rsp_QryInvestorPosition_results.append(InvestorPosition)
if IsLast:
self.__rsp_QryInvestorPosition_event.set()
def OnRspQryInvestorPositionDetail(self, InvestorPositionDetail, RspInfo, RequestID, IsLast):
""" 请求查询投资者持仓明细响应 """
if RequestID == self.__rsp_QryInvestorPositionDetail_RequestID:
if RspInfo is not None:
self.__rsp_QryInvestorPositionDetail_RspInfo = RspInfo
if InvestorPositionDetail is not None:
self.__rsp_QryInvestorPositionDetail_results.append(InvestorPositionDetail)
if IsLast:
self.__rsp_QryInvestorPositionDetail_event.set()
def OnRspOrderInsert(self, InputOrder, RspInfo, RequestID, IsLast):
""" 报单录入请求响应 """
print('OnRspOrderInsert:', InputOrder)
#if self.__rsp_OrderInsert_RequestID == RequestID:
# if RspInfo and RspInfo.ErrorID != 0:
# self.__rsp_OrderInsert_RspInfo = RspInfo
# self.__rsp_OrderInsert_event.set()
def OnErrRtnOrderInsert(self, InputOrder, RspInfo):
""" 报单录入错误回报 """
print( 'OnErrRtnOrderInsert:', bytes2unicode( RspInfo.ErrorMsg ) )
def OnRtnTrade(self, Trade):
""" 成交通知 """
print('OnRtnTrade:', Trade)
# {'BrokerID': b'9999'
# , 'InvestorID': b'245110'
# , 'reserve1': b'cu2510'
# , 'OrderRef': b'6' ///报单引用
# , 'UserID': b'245110'
# , 'ExchangeID': b'SHFE'
# , 'TradeID': b' 173342' ///成交编号
# , 'Direction': b'0' ///买卖方向 ///买 #define THOST_FTDC_D_Buy '0' ///卖 #define THOST_FTDC_D_Sell '1'
# , 'OrderSysID': b' 266549' ///报单编号
# , 'ParticipantID': b'9999' ///会员代码
# , 'ClientID': b'9999245088' ///客户代码
# , 'TradingRole': b'\x00' ///交易角色 ///代理 #define THOST_FTDC_ER_Broker '1' ///自营 #define THOST_FTDC_ER_Host '2' ///做市商 #define THOST_FTDC_ER_Maker '3'
# , 'reserve2': b'cu2510'
# , 'OffsetFlag': b'0' ///开平标志 ///开仓 THOST_FTDC_OF_Open '0' ///平仓 THOST_FTDC_OF_Close '1' ///强平 THOST_FTDC_OF_ForceClose '2' ///平今 THOST_FTDC_OF_CloseToday '3' ///平昨 THOST_FTDC_OF_CloseYesterday '4' ///强减 THOST_FTDC_OF_ForceOff '5' ///本地强平 THOST_FTDC_OF_LocalForceClose '6'
# , 'HedgeFlag': b'1' ///投机套保标志 ///投机 THOST_FTDC_HF_Speculation '1' ///套利 THOST_FTDC_HF_Arbitrage '2' ///套保 THOST_FTDC_HF_Hedge '3' ///做市商 THOST_FTDC_HF_MarketMaker '5' ///第一腿投机第二腿套保 THOST_FTDC_HF_SpecHedge '6' ///第一腿套保第二腿投机 THOST_FTDC_HF_HedgeSpec '7'
# , 'Price': 79380.0
# , 'Volume': 1
# , 'TradeDate': b'20250813'
# , 'TradeTime': b'14:33:46'
# , 'TradeType': b'\x00' ///成交类型 THOST_FTDC_TRDT_SplitCombination '#' ///普通成交 THOST_FTDC_TRDT_Common '0' ///期权执行 THOST_FTDC_TRDT_OptionsExecution '1' ///OTC成交 THOST_FTDC_TRDT_OTC '2' ///期转现衍生成交 THOST_FTDC_TRDT_EFPDerived '3' ///组合衍生成交 THOST_FTDC_TRDT_CombinationDerived '4' ///大宗交易成交 THOST_FTDC_TRDT_BlockTrade '5'
# , 'PriceSource': b'\x00' ///成交价来源 ///前成交价 THOST_FTDC_PSRC_LastPrice '0' ///买委托价 THOST_FTDC_PSRC_Buy '1' ///卖委托价 THOST_FTDC_PSRC_Sell '2' ///场外成交价 THOST_FTDC_PSRC_OTC '3'
# , 'TraderID': b'9999xc6' ///交易所交易员代码
# , 'OrderLocalID': b' 175031' ///本地报单编号
# , 'ClearingPartID': b'9999' ///结算会员编号
# , 'BusinessUnit': b''
# , 'SequenceNo': 192469
# , 'TradingDay': b'20250813'
# , 'SettlementID': 1
# , 'BrokerOrderSeq': 1515922
# , 'TradeSource': b'0' ///成交来源 ///来自交易所普通回报 THOST_FTDC_TSRC_NORMAL '0' ///来自查询 THOST_FTDC_TSRC_QUERY '1'
# , 'InvestUnitID': b''
# , 'InstrumentID': b'cu2510'
# , 'ExchangeInstID': b'cu2510'}
def OnRtnOrder(self, Order):
""" 报单通知 """
print('OnRtnOrder - 报单通知:')
if Order.InvestorID != self.__InvestorID:
return
else:
if Order.OrderStatus == PyCTP.THOST_FTDC_OST_AllTraded:
print('报单全部成交')
if Order.OrderStatus == PyCTP.THOST_FTDC_OST_PartTradedQueueing:
print('部分成交还在队列中')
if Order.OrderStatus == PyCTP.THOST_FTDC_OST_PartTradedNotQueueing:
print('部分成交不在队列中')
if Order.OrderStatus == PyCTP.THOST_FTDC_OST_NoTradeQueueing:
print('未成交还在队列中')
if Order.OrderStatus == PyCTP.THOST_FTDC_OST_NoTradeNotQueueing:
print('未成交不在队列中')
if Order.OrderStatus == PyCTP.THOST_FTDC_OST_Canceled:
print('撤单')
if Order.OrderStatus == PyCTP.THOST_FTDC_OST_Unknown:
print('未知')
if Order.OrderStatus == PyCTP.THOST_FTDC_OST_NotTouched:
print('尚未触发')
if Order.OrderStatus == PyCTP.THOST_FTDC_OST_Touched:
print('已触发')
class PyCTP_Trader(PyCTP_Trader_API):
def OnRtnInstrumentStatus(self, InstrumentStatus):
""" 合约交易状态通知 """
print("合约交易状态通知:", InstrumentStatus)
class PyCTP_Market(PyCTP_Market_API):
def OnRtnDepthMarketData(self, DepthMarketData):
""" 深度行情通知 """
import datetime
tick = dict(InstrumentID=DepthMarketData.InstrumentID
, time=datetime.datetime.strptime(bytes2unicode(DepthMarketData.ActionDay+DepthMarketData.UpdateTime), '%Y%m%d%H:%M:%S').replace(microsecond=DepthMarketData.UpdateMillisec*1000).strftime('%Y-%m-%d %H:%M:%S.%f')
, last=DepthMarketData.LastPrice
, volume=DepthMarketData.Volume
, amount=DepthMarketData.Turnover
, position=DepthMarketData.OpenInterest
, ask1=DepthMarketData.AskPrice1
, bid1=DepthMarketData.BidPrice1
, asize1=DepthMarketData.AskVolume1
, bsize1=DepthMarketData.BidVolume1)
print('深度行情通知:', tick)
def __main__():
import os
import time
BrokerID = unicode2bytes(os.getenv('TEST_BROKERID', 'Your BrokerID'))
UserID = unicode2bytes(os.getenv('TEST_USERID', 'Your UserID'))
Password = unicode2bytes(os.getenv('TEST_PASSWORD', 'Your Password'))
AuthCode = b'0000000000000000'
AppID = b'simnow_client_test'
ProductInfo = b''
ExchangeID = b'SHFE'
InstrumentID = b'cu2509'
FrontAddr = [{'name':'第一套环境 - 第一组', 'tFrontAddr':b'tcp://182.254.243.31:30001', 'mFrontAddr':b'tcp://182.254.243.31:30011'}
,{'name':'第一套环境 - 第二组', 'tFrontAddr':b'tcp://182.254.243.31:30002', 'mFrontAddr':b'tcp://182.254.243.31:30012'}
,{'name':'第一套环境 - 第三组', 'tFrontAddr':b'tcp://182.254.243.31:30003', 'mFrontAddr':b'tcp://182.254.243.31:30013'}
,{'name':'7*24环境', 'tFrontAddr':b'tcp://182.254.243.31:40001', 'mFrontAddr':b'tcp://182.254.243.31:40011'}]
current_dir = os.path.dirname(os.path.abspath(__file__))
tmp_path = os.path.join(current_dir, 'flow/')
if not os.path.exists(tmp_path):
os.makedirs(tmp_path)
flowPath = unicode2bytes(tmp_path)
print('Python版本:', sys.version)
while True:
print('选择环境:')
for idx, front in enumerate(FrontAddr):
print('%d. %s' % (idx+1, front['name']))
print('\t Trade Front:%s \n\t Market Front:%s' % (front['tFrontAddr'], front['mFrontAddr']))
print('100.退出')
try: idx = int(user_input())
except ValueError: continue
if idx > 0 and idx <= len(FrontAddr):
tFrontAddr = FrontAddr[idx-1]['tFrontAddr']
mFrontAddr = FrontAddr[idx-1]['mFrontAddr']
break
if idx == 100: return
while True:
print('选择连接行情/交易:')
print('1.连接交易')
print('2.连接行情')
print('100.退出')
try: trade_md = int(user_input())
except ValueError: continue
if trade_md == 1:
trader = PyCTP_Trader.CreateFtdcTraderApi(flowPath)
print('Api版本:', PyCTP_Trader.GetApiVersion())
print('采集库版本:', PyCTP.CTP_GetDataCollectApiVersion())
print('连接前置:', trader.Connect(tFrontAddr))
print("请确定连接模式:")
print("1.直连模式")
print("2.中继服务器操作员模式(一对多模式)")
print("3.中继服务器非操作员模式(多对多模式)")
while True:
try: mode_num = int(user_input())
except ValueError: continue
if mode_num == 1:
# 1.直连模式
print('客户端认证:', trader.Authenticate(BrokerID, UserID, ProductInfo, AuthCode, AppID))
print('账号登陆:', trader.Login(BrokerID, UserID, Password))
break
elif mode_num == 2:
# 2.中继服务器操作员模式(一对多模式)
print('客户端认证:', trader.Authenticate(BrokerID, UserID, ProductInfo, AuthCode, AppID))
print('账号登陆:', trader.Login(BrokerID, UserID, Password))
print('上报用户终端信息:', trader.SubUserSystemInfo(BrokerID, UserID, AppID))
break
elif mode_num == 3:
# 3.中继服务器非操作员模式(多对多模式)
print('客户端认证:', trader.Authenticate(BrokerID, UserID, ProductInfo, AuthCode, AppID))
print('注册用户终端信息:', trader.RegUserSystemInfo(BrokerID, UserID, AppID) )
print('账号登陆:', trader.Login(BrokerID, UserID, Password))
break
else:
print('选择的模式有误,请重新输入!')
print('交易日:', trader.GetTradingDay())
print('投资者代码:', trader.setInvestorID(UserID))
while True:
print('请输入选择的序号')
print(' 1.请求结算单确认')
print(' 2.请求查询交易所')
print(' 3.请求查询投资者')
print(' 4.请求查询资金账户')
print(' 5.请求查询行情')
print(' 6.请求查询合约')
print(' 7.请求查询合约手续费率')
print(' 8.请求查询合约保证金率')
print(' 9.请求查询投资者持仓')
print(' 10.请求申报开多仓一手')
print(' 11.请求申报开空仓一手')
print(' 12.请求申报平多仓一手')
print(' 13.请求申报平空仓一手')
print('100.退出程序')
try: inp = int(user_input())
except ValueError: continue
if inp == 1:
print('结算单确认:', trader.SettlementInfoConfirm())
if inp == 2:
print('查询交易所:', [(exchange.ExchangeID, bytes2unicode(exchange.ExchangeName), exchange.ExchangeProperty) for exchange in trader.QryExchange()])
elif inp == 3:
print('查询投资者:', trader.QryInvestor())
elif inp == 4:
print('查询账户:', trader.QryTradingAccount())
elif inp == 5:
print('查询行情:')
data = trader.QryDepthMarketData(InstrumentID)
for d in data:
print( d.InstrumentID, d.LastPrice )
elif inp == 6:
print('查询合约:', trader.QryInstrument(ExchangeID, InstrumentID))
elif inp == 7:
print('查询合约手续费率:', trader.QryInstrumentCommissionRate(InstrumentID))
elif inp == 8:
print('查询合约保证金率:', trader.QryInstrumentMarginRate(InstrumentID))
elif inp == 9:
# print('查询投资者持仓:', trader.QryInvestorPosition())
# print('查询投资者持仓明细:', trader.QryInvestorPositionDetail())
# 持仓多空方向
PosiDirection_Dict = {PyCTP.THOST_FTDC_PD_Net: '净', PyCTP.THOST_FTDC_PD_Long:'买', PyCTP.THOST_FTDC_PD_Short: '卖'}
table = [['持仓合约', '买卖', '总仓', '持仓盈亏']]
for position in trader.QryInvestorPosition():
if position.Position:
table.append([ bytes2unicode(position.InstrumentID), PosiDirection_Dict[position.PosiDirection], position.Position, position.PositionProfit])
for row in table:
print('{:<10}{:<10}{:<10}{:<10}'.format(*row))
elif inp == 10:
marketData = trader.QryDepthMarketData(InstrumentID)
price = marketData[0].AskPrice1
print('申报开多仓一手:', trader.OrderInsert(InstrumentID, Action=PyCTP.THOST_FTDC_OF_Open, Direction=PyCTP.THOST_FTDC_D_Buy, Volume = 1, Price=price))
elif inp == 11:
marketData = trader.QryDepthMarketData(InstrumentID)
price = marketData[0].BidPrice1
print('申报开空仓一手:', trader.OrderInsert(InstrumentID, Action=PyCTP.THOST_FTDC_OF_Open, Direction=PyCTP.THOST_FTDC_D_Sell, Volume = 1, Price = price))
elif inp == 12:
marketData = trader.QryDepthMarketData(InstrumentID)
price = marketData[0].BidPrice1
print('申报平多仓一手:', trader.OrderInsert(InstrumentID, Action=PyCTP.THOST_FTDC_OF_CloseToday, Direction=PyCTP.THOST_FTDC_D_Sell, Volume = 1, Price=price))
elif inp == 13:
marketData = trader.QryDepthMarketData(InstrumentID)
price = marketData[0].AskPrice1
print('申报平空仓一手:', trader.OrderInsert(InstrumentID, Action=PyCTP.THOST_FTDC_OF_CloseToday, Direction=PyCTP.THOST_FTDC_D_Buy, Volume = 1, Price=price))
elif inp == 100:
break
else:
print('请输入正确的序号')
print('账号登出:', trader.Logout())
print('删除接口:', trader.Release())
break
elif trade_md == 2:
market = PyCTP_Market.CreateFtdcMdApi(flowPath)
print('Api版本:', PyCTP_Market.GetApiVersion())
print('连接前置:', market.Connect(mFrontAddr))
print('账号登陆:', market.Login(BrokerID, UserID, Password))
print('交易日:', market.GetTradingDay())
print('订阅行情:', market.SubMarketData([InstrumentID]))
#print('订阅询价:', market.SubForQuoteRsp([InstrumentID]))
user_input('按任意键退出:\n')
print('退订行情:', market.UnSubMarketData([InstrumentID]))
#print('退订询价:', market.UnSubForQuoteRsp([InstrumentID]))
#print('账号登出:', market.Logout())
print('删除接口:', market.Release())
break
elif trade_md == 100:
break
else:
print('请输入正确的序号.')
if __name__ == '__main__':
__main__()
user_input('按任意键退出:\n')
请教大佬,看穿式的版本在哪里能修改自己申请到的AppID?
代码方面的修改:
之前做CTP都需要调用ReqUserLogin();这个登录请求,现在如果要接入穿透式监管的流程改变了,将ReqUserLogin();替换为ReqAuthenticate(CThostFtdcReqAuthenticateField *pReqAuthenticateField, int nRequestID) 认证请求,然后在认证回调里添加ReqUserLogin();
调用 pyctp 如何实现这个流程? 谢谢
如何理解 看穿监管?
调用 CTraderApi::ReqAuthenticate()函数填入 AppID和授权码 进行 终端认证 ,通过 ,通过 终端认证后再调用 CTraderApi::ReqUserLogin()函数 登录。 调用 pyctp 怎么实现?
32位的python,在setup里的include & lib 目录还是 v6.3.6_20160606_tradeapi_windows。编译环境是只支持64位的python 吗?
大神 为什么我在调用api的release是出现了段错误,最为关键的是,同样的操作系统/编译器,分别运行,一个报错,一个正常
大神 能不能帮我看看这个帖子的问题
https://bbs.csdn.net/topics/395193839
官方CTP c/c++ 库在linux64bit上release是是存在问题的,无法解决,只能忽略这个错误.
C:\CTP\PyCTP-master>python setup.py install
running install
running build
running build_ext
building 'PyCTP' extension
creating build\temp.win-amd64-3.5
creating build\temp.win-amd64-3.5\Release
creating build\temp.win-amd64-3.5\Release\src
...
Generating code
Finished generating code
running build_scripts
creating build\scripts-3.5
copying src\test_PyCTP.py -> build\scripts-3.5
running install_lib
copying build\lib.win-amd64-3.5\PyCTP.cp35-win_amd64.pyd -> C:\Program Files\Python35\Lib\site-packages
running install_scripts
running install_egg_info
Removing C:\Program Files\Python35\Lib\site-packages\PyCTP-1.1.0-py3.5.egg-info
Writing C:\Program Files\Python35\Lib\site-packages\PyCTP-1.1.0-py3.5.egg-info
编译算是通过啊?
为啥后面执行测试脚本,一直提示ImportError: DLL load failed: 找不到指定的模块。
已经把thostmduserapi_se.dll和thosttraderapi_se.dll复制到相同目录去了
你好,我在按照guidance进行编译,进入VS2013 x86 本机工具命令提示,将地址换到python master这个文件夹(即包含 setup.py 的文件夹),然后输入指令 python setup.py build,但是什么都没有发生,也没有给出任何信息,就直接进入新的一行让我输入指令了,请问是怎么回事呢。我的python版本是3.7.3,请问是否是版本的问题呢?
问一下啊,我按照guidance说的进入 VS2013 x86 本机工具命令提示 将地址转到python-master文件夹下,想要跑 python setup.py build 但是一点反应都没有直接就给出了新的一行让我输入指令,也就是说看起来什么都没有发生。请问是什么原因呢?我的python是3.7.3,请问是否会是python版本影响?
请问博主,现在交易所更新了6.3.13和6.3.15版本,这两个新版本不再向下兼容,且6月份期货公司升级后老版本全部使用不了,之能使用6.3.15版本, 博主你的版本还停留在6.3.6是不是太老了,目前我用博主的代码成功编译封装了6.3.13和6.3.15版本,都能正常调用,但是不知道博主的代码是否对这两个新版本做了支持?
且最新的行情端增加了QryMulticastInstrument接口, 这接口函数暂时没什么用, 但是在封装代码中并没有把这个新函数给封装进去。看了下源码,好像自己写下可以把QryMulticastInstrument给封装进去,想请问博主,源码中的src文件夹下的C++源代码是手动写的么?还是通过什么生成的?APIToPyCTP.py可以正常运行,但是不知道是不是得通过这个py文件生成c++的代码,请问c++的代码的如何生成的?
一直是用博主的代码封装的,非常感谢
已更新到6.3.15穿透版
朋友你好!我相信很多人和我一样,能力有限,只能站在巨人的肩膀上做一点策略小开发,所以非常感谢您封装了这么好的接口,使我们这些小白也能有机会研究量化策略。目前我看到github上面有针对看穿式的更新,但不知怎么用。请问你能更新一下相应的demo吗?非常感谢!
您好,十分感谢您共享的代码,CTP API已经更新到了6.3.11_20180109版本,我通过您的代码重新编译后已经无法正常使用,具体出现问题是前置链接无法登陆所以后续也无法正常使用,我通过您共享的 APIToPyCTP.py 转换代码但是似乎没有成功,不太理解转换代码。
您好,十分感谢您共享的代码,CTP API已经更新到了6.3.11_20180109版本,我通过您的代码重新编译后已经无法正常使用,具体出现问题是前置链接无法登陆所以后续也无法正常使用,我通过您共享的 APIToPyCTP.py 转换代码但是似乎没有成功
您好,windows平台下发送订单出现ValueError: The first arguments is invalid.不知道是什么原因。
用的是OrderInsert函数,第一个参数是InputOrder
InputOrder里面的传参正常输入和bytes处理都是一样的错误。
迫切等待回复,谢谢
必须是python3环境,所有字串均bytes处理.
您好,测试过后还是不行,windows、python3.6环境下
在OrderInsert的传参都进行了bytes(‘xxx’, ‘gb2312’)处理。
错误还是ValueError: The first arguments is invalid
方便给个事例或进一步告知原因么?
trader.OrderInsert(b'pp1602', PyCTP.THOST_FTDC_OF_Open, PyCTP.THOST_FTDC_D_Buy, 0, 0.0)
关于行情数据入Oracle数据库的时候,我遇到了两个问题:
1、由于某些时刻tick数据波动较大,所有推送的数据很快,导致单个tick入库的时间追不上推送时间,达不到数据的时效性。然后我用批量插入:先收集一分钟的tick数据,我用list保存,然后批量插入后立即置list为空,但此时,行情仍在往list里面写,导致某些tick数据有遗漏。请问有没有好的解决办法??
2、在生成分钟tick数据的时候,我拿到一分钟的tick数据,在这数据中多种合约,每一种合约都需要计算最高、最低、开盘、收盘、数量,这里非常耗费时间,请问楼主大大有什么建议吗??
跪求回复!!
使用队列, ontick写入队列就返回, 其它的现成处理队列中的数据.
关于行情数据入Oracle数据库的时候,我遇到了两个问题:
1、由于某些时刻tick数据波动较大,所有推送的数据很快,导致单个tick入库的时间追不上推送时间,达不到数据的时效性。然后我用批量插入:先收集一分钟的tick数据,我用list保存,然后批量插入后立即置list为空,但此时,行情仍在往list里面写,导致某些tick数据有遗漏。请问有没有好的解决办法??
2、在生成分钟tick数据的时候,我拿到一分钟的tick数据,在这数据中多种合约,每一种合约都需要计算最高、最低、开盘、收盘、数量,这里非常耗费时间,请问楼主大大有什么建议吗??
跪求回复!!
释放是这样写的吗:
def ReleaseMarket(self):
""" 删除接口对象本身"""
self.RegisterSpi(None)
self.Release()
self = None
我用maket.ReleaseMarket()直接死机啦
在linux下不用释放,ctp在linux下有内存段错误,但死机是不会的。
晚上好。 看了一晚CTP文档,参考 PyCTP_Trader.py 里面的 函数 OrderInsert(这个函数是限价单),想写一个 开平仓市价单申报 函数,想不出来,可以指点下吗?万分感谢。
行情登陆的时候,为什么无论用户密码怎样输入,都返回一样的结果:
'BrokerID': b'', 'SHFETime': b'', 'MaxOrderRef': b'', 'FrontID': 0, 'CZCETime': b'', 'UserID': b'',
请问一下,使用test.py的时候报dll的错误应该怎么解决呢
Traceback (most recent call last):
File "D:/work/stock/pyctp-master/example/test.py", line 4, in
from ctp.futures import ApiStruct, MdApi
File "D:\work\stock\pyctp-master\example\ctp\futures__init__.py", line 837, in get
value = self.fget()
File "D:\work\stock\pyctp-master\example\ctp\futures__init__.py", line 851, in MdApi
from ._MdApi import _init, MdApi; _init(ApiStruct)
ImportError: DLL load failed: %1 不是有效的 Win32 应用程序。
行情订阅的时候,报错:('OnRspError', [77, 'CTP:无此功能'], 0, True),为啥呢??
行情订阅的时候报错:
('OnRspError', [77, 'CTP:无此功能'], 0, True)为啥呀??
为什么在test_PyCTP_market登陆,无论输入的userId和password正确与否,登陆都能通过呀??
您好,运行脚本test_PyCTP_market.py,登陆输入账号Id和密码之后,返回ret:
登陆: {'LoginTime': b'', 'SHFETime': b'', 'FrontID': 0, 'UserID': b'', 'FFEXTime': b'', 'SystemName': b'', 'BrokerID': b'', 'SessionID': 0, 'DCETime': b'', 'TradingDay': b'20181112', 'MaxOrderRef': b'', 'CZCETime': b'', 'INETime': b''},其中大部分都是空的,请问是登陆成功了还是失败了??
您好, 很感谢您的开源代码, 看到这个函数不太明白, 好像是不用这个去register spi, 而是在 CTP_THOST_FTDC_MD_API_CreateFtdcMdApi 中就注册好了
PyObject *CTP_THOST_FTDC_MD_API_RegisterSpi(PyObject *self, PyObject *args) { CTP_THOST_FTDC_MD_API *api = (CTP_THOST_FTDC_MD_API *) self; PyObject *tmp = api->pySpi; if (!PyArg_ParseTuple(args, "O", &api->pySpi)) { PyErr_SetString(PyExc_ValueError, "parameter invalid."); return nullptr; } Py_XDECREF(tmp); Py_INCREF(api->pySpi); Py_RETURN_NONE; };
只是为了模拟注册效果,总需要有个回调类.
满屏都是下面的错误
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnQuote'
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnQuote'
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnQuote'
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnQuote'
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnQuote'
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnQuote'
故意增加的这个错误信息,目的是避免事件遗漏。请建立空OnRtnQuote方法 。
你好,我使用python2.7 32位的环境编译成功但运行test_PyCTP报错:
tmp_tFile "test_PyCTP.py", line 598, in main
trader = PyCTP_Trader.CreateFtdcTraderApi(b'
')
ValueError: parameter invalid.
请问这是什么原因呢?
您好,请问运行test_PyCTP.py产生
tmp_ttrader = File "test_PyCTP.py", line 598, in main
trader = PyCTP_Trader.CreateFtdcTraderApi(b'
')
ValueError: parameter invalid.
报错是什么原因呢?
必须设置已经存在的文件夹路径,注意看参考代码
您好,请问运行test_PyCTP.py产生
tmp_ttrader = File "test_PyCTP.py", line 598, in main
trader = PyCTP_Trader.CreateFtdcTraderApi(b'
')
ValueError: parameter invalid.
报错是什么原因呢?
PyObject *PyXTP_PyDict_FromStruct(XTPOB *pOB)
{
if(pOB == nullptr) Py_RETURN_NONE;
PyObject *lbid = PyList_New(10); PyObject *lask = PyList_New(10); PyObject *lbid_qty = PyList_New(10); PyObject *lask_qty = PyList_New(10); for(int i=0; i < 10; i++){ PyList_SetItem(lbid, i, PyFloat_FromDouble(pOB->bid[i])); PyList_SetItem(lask, i, PyFloat_FromDouble(pOB->ask[i])); PyList_SetItem(lbid_qty, i, PyLong_FromLongLong(pOB->bid_qty[i])); PyList_SetItem(lask_qty, i, PyLong_FromLongLong(pOB->ask_qty[i])); } PyObject *ret=Py_BuildValue("{s:i,s:y,s:d,s:L,s:d,s:L,s:O,s:O,s:O,s:O,s:L}" , "exchange_id", pOB->exchange_id , "ticker", pOB->ticker , "last_price", pOB->last_price , "qty", pOB->qty , "turnover", pOB->turnover , "trades_count", pOB->trades_count , "bid", lbid , "ask", lask , "bid_qty", lbid_qty , "ask_qty", lask_qty , "data_time", pOB->data_time ); Py_DECREF(lbid); Py_DECREF(lask); Py_DECREF(lbid_qty); Py_DECREF(lask_qty); return ret;
}
另外之前这么写过dict的也不行
python有一个debug模式,在debug模式下,可以直接调试扩展代码。这样更容易发现原因
好的,多谢
struct OrderBookStruct {
XTP_EXCHANGE_TYPE exchange_id;
char ticker[XTP_TICKER_LEN];
double last_price;
int64_t qty;
double turnover;
int64_t trades_count;
///十档申买价
double bid[10];
///十档申卖价
double ask[10];
///十档申买量
int64_t bid_qty[10];
///十档申卖量
int64_t ask_qty[10];
/// 时间类
int64_t data_time;
} ;
类似这样的,请教转换函数该怎么写?。。。我先尝试转成list,没有成功;如果是转换成dict怎么写?
PyObject *PyXTP_PyDict_FromStruct(XTPOB *pOB)
{
if(pOB == nullptr) Py_RETURN_NONE;
PyObject *lbid = PyList_New(10); PyObject *lask = PyList_New(10); PyObject *lbid_qty = PyList_New(10); PyObject *lask_qty = PyList_New(10); for(int i=0; i < 10; i++){ PyList_SetItem(lbid, i, PyFloat_FromDouble(pOB->bid[i])); PyList_SetItem(lask, i, PyFloat_FromDouble(pOB->ask[i])); PyList_SetItem(lbid_qty, i, PyLong_FromLongLong(pOB->bid_qty[i])); PyList_SetItem(lask_qty, i, PyLong_FromLongLong(pOB->ask_qty[i])); } PyObject *ret=Py_BuildValue("[i,y,d,L,d,L,L]" , pOB->exchange_id , pOB->ticker , pOB->last_price , pOB->qty , pOB->turnover , pOB->trades_count , pOB->data_time ); PyList_Append(ret, lbid); PyList_Append(ret, lask); PyList_Append(ret, lbid_qty); PyList_Append(ret, lask_qty); Py_DECREF(lbid); Py_DECREF(lask); Py_DECREF(lbid_qty); Py_DECREF(lask_qty); return ret;
}
请教个扩展的问题,char[x],用pybytes;如果是struct里面有int[x],double[x],用啥做转换啊?
用数组或列表就可以了,在c++中需做一次转换处理. 另外,如是非ctp, 那么python好像提供有直接的c结构类。
您好!非常感谢提供此CTP的python接口,我想把它用到32位的linux系统上运行,请问是否可以自己更改源代码实现?我安装了VS2015社区版,结果报Unable to find vcvarsall.bat错误,请问那两个libthostmduserapi.so和libthosttraderapi.so是在windows下编译出来的吗?我试过linux下如果没有这两个so文件,不能编译出第三个PyCTP.cpython-34m.so。真的非常感谢提供了这个接口!
不可以应用于32位linux,CTP官方只提供了64位的库
你好!刚研究PYCTP,有个问题不是很清楚,可以解答一下不?谢谢。
订阅行情的结果:
{'InstrumentID': 'rb1810', 'time': datetime.datetime(2018, 6, 8, 15, 13, 24, 500000), 'last': 3806.000000000001, 'volume': 3697188, 'amount': 140560926800.0, 'position': 3311490.0, 'ask1': 3807.0, 'bid1': 3806.000000000001, 'asize1': 339, 'bsize1': 333}
这些结果能不能找个变量接收。如果能,怎么接收?
设计pyctp的目的就是为了方便python接收和处理数据,这点需要有python基础. 总的来说就是可以使用队列或列表保存
博主,对于其中的请求行情模块,test_PyCTP.py里的def SubMarketData(self, InstrumentID):这个函数里,ret = self.SubscribeMarketData(InstrumentID, len(InstrumentID))应该是这一行触发了请求行情吧,我如何能把在窗口里的滚动的每秒的数据存成一个个字典,供我别的分析啊,SubscribeMarketData这个函数只返回了个int值,我如何把得到的行情数据存起来哈,谢谢
使用python list或queue对象保存数据. 保存行情只能在回调中实现. 这点需要有python基础
请问博主 在win10(64位)Python3.6环境下运行PyCTP_build_20170122 无法导入PyCTP 是什么问题
Traceback (most recent call last):
File "test_PyCTP_Market.py", line 12, in
from PyCTP_Market import PyCTP_Market
File "C:\Users\Windows\Desktop\PyCTP_build_20170122\PyCTP_Market.py", line 11, in
import PyCTP
ImportError: DLL load failed: 找不到指定的模块。
需要先编译得到pyctp.pyd,编译后把编译得到的 pyctp.pyd文件复制到自己项目根目录,同时把下载文件里面带的ctp官方提供的两个windows ctp dll文件也复制到项目根目录
能不能共享下.h转换h&cpp的新脚本学习下。
因为api不停的更新,所以想着也能跟进更新一下pyctp接口,如果API有变化,我也可以尝试修改正则,然后再共享出来:D
github中已共享出此脚本
我在做web版的ctp 登录的时候发现 ctp有自动掉线重连功能 导致OnFrontDisconnected这个函数会不断的触发 如何才能停止这个函数的调用呢
无法停止调用,要想看不到显示,把函数体留空就是了.
行情退出登录: 显示错误--('OnRspError', [68, 'CTP:无此功能'], 0, True)
此问题无法解决。原因是官方CTP服务器并不存在退出功能. 客户段这个api只是做个样子.
交易退出登录也有问题:登出: {'UserID': b'112769', 'BrokerID': b'9999'}
CThostFtdcUserApiImplBase::OnSessionDisconnected[0000000002B03778][-313393151][ 4097]
其他都很好,就是退出登录行情,及交易都会有问。
此提示信息是官方CTPapi自行产生, 忽视即可. windows上似乎无此信息.
行情退出登录有问题。 ('OnRspError', [68, 'CTP:无此功能'], 0, True)
此问题无法解决。原因是官方CTP服务器并不存在退出功能. 客户api只是做个样子.
求问兄台能不能共享下.h转换h&cpp的新脚本学习下,github的运行结果稍微一点点对不上的。
ctp新版本有变化,需要针对修改一下才行, 其实转换脚本只是一些正则.
请问楼主,查询复数合约怎么写?
单数合约是InstrumentID= b'cu1802'
这里试了很多写法,比如想写2,3个合约,都运行失败啊
多个合约用 list传递 例如 InstrumentID= [b’cu1802′, b’cu1803′]
请问在 OnFrontDisconnected 函数里的 self.__Inst_Interval() 方法是啥?
最初设想如果掉线,就过段时间自动登陆,这个函数是用来延迟的。不过后发现ctp有自动掉线重连功能,也就注释掉了.
非常感谢回复,问题已经解决。代码中的测试部分全部通过,没有问题。但是不知道怎么写开仓,平仓,撤单操作。你的代码中只有限价单(没有市价单、条件单),试了试,可能是传参有问题,限价单也不会用。哈哈哈哈。能不能写个demo。我看上面好多人都在问这个问题。望百忙之中,抽点时间帮助一下我们这样的小白。谢谢!万分感谢!
满屏全是
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnInstrumentStatus'
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnInstrumentStatus'
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnInstrumentStatus'
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnInstrumentStatus'
AttributeError: 'PyCTP_Trader' object has no attribute 'OnRtnInstrumentStatus'
这是默认加的未处理事件提示(此消息是交易所发送的交易和约状态改变通知,比如当前进入竞价,当前进入交易,当前停止交易.....)
具体事件原因描述可以查看 https://github.com/shizhuolin/PyCTP/blob/master/v6.3.6_20160606_tradeapi64_windows/ThostFtdcTraderApi.h 第242行
字段含义查看 https://github.com/shizhuolin/PyCTP/blob/master/v6.3.6_20160606_tradeapi64_windows/ThostFtdcUserApiStruct.h 第4534行
状态描述查看 https://github.com/shizhuolin/PyCTP/blob/master/v6.3.6_20160606_tradeapi64_windows/ThostFtdcUserApiDataType.h 第941-959行
在 PyCTP_Trader 中增加
def OnRtnInstrumentStatus(self, status):
pass
就可屏蔽此事件.
请问想要通过CTP进行开仓,平仓,撤单操作,代码应该怎么写啊,您有写好的吗?
请问要想通过CTP实现开仓,平仓,撤单等操作,代码应该怎么写啊?
参考例子中的python订单操作代码
def QryInstrument(self, ExchangeID=b'', InstrumentID=b''):
""" 查询和约 """
QryInstrument = dict(ExchangeID = ExchangeID
, InstrumentID = InstrumentID)
self.__rsp_QryInstrument = dict(event = threading.Event()
, RequestID = self.__IncRequestID()
, results = []
, ErrorID = 0)
ret = self.ReqQryInstrument(QryInstrument, self.__rsp_QryInstrument['RequestID'])
if ret == 0:
self.__rsp_QryInstrument['event'].clear()
if self.__rsp_QryInstrument['event'].wait(self.TIMEOUT):
if self.__rsp_QryInstrument['ErrorID'] != 0:
return self.__rsp_QryInstrument['ErrorID']
return self.__rsp_QryInstrument['results']
else:
return -4
return ret
我看好几段代码都是这个格式,但是我不太明白,能不能麻烦给解释一下这段代码是什么意思
CTP指令基本都是异步指令. 也就是说发送请求后不等结果返回就会继续执行下一行代码. 这里的目的是事件等待.必须等到查询消息返回结束才会继续执行后续代码. 这么做的目的是为了方便策略编写. 每个def 指令(self,...) 方法都对应有一个 def On指令(self,...)事件处理。
能不能将编译好的dll也放上
好的,我放一份编译好的上来
版主你好,看到了pyctp,感觉挺好的,想使用但需要 vs2013编译, 不过本人未装 vs2013,也不熟悉,将否将编译后的dll也放上,方便直接使用
您好,我运行python setup.py build时提示,查了很多资料都没解决,故此求救,谢谢:
D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\amd64\cl.exe /c /nologo /Ox /MD /W3 /GS- /DNDEBUG -I./v6.3.6_20160606_tradeapi64_windows -IC:\Python27\include -IC:\Python27\PC /Tp.\src\stdafx.cpp /Fobuild\temp.win-amd64-2.7\Release\.\src\stdafx.obj
stdafx.cpp
D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\amd64\cl.exe /c /nologo /Ox /MD /W3 /GS- /DNDEBUG -I./v6.3.6_20160606_tradeapi64_windows -IC:\Python27\include -IC:\Python27\PC /Tp.\src\PyCTP.cpp /Fobuild\temp.win-amd64-2.7\Release\.\src\PyCTP.obj
PyCTP.cpp
.\src\PyCTP.cpp(12) : error C2065: “PyModuleDef_HEAD_INIT”: 未声明的标识符
.\src\PyCTP.cpp(13) : error C2514: “PyModuleDef”: 类没有构造函数
.\src\PyCTP.cpp(10) : 参见“PyModuleDef”的声明
.\src\PyCTP.cpp(21) : error C3861: “PyModule_Create”: 找不到标识符
.\src\PyCTP.cpp(25) : error C2562: “PyInit_PyCTP”:“void”函数返回值
.\src\PyCTP.cpp(16) : 参见“PyInit_PyCTP”的声明
.\src\PyCTP.cpp(31) : error C2562: “PyInit_PyCTP”:“void”函数返回值
.\src\PyCTP.cpp(16) : 参见“PyInit_PyCTP”的声明
.\src\PyCTP.cpp(40) : error C2562: “PyInit_PyCTP”:“void”函数返回值
.\src\PyCTP.cpp(16) : 参见“PyInit_PyCTP”的声明
.\src\PyCTP.cpp(49) : error C2562: “PyInit_PyCTP”:“void”函数返回值
.\src\PyCTP.cpp(16) : 参见“PyInit_PyCTP”的声明
error: command 'D:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\BIN\\amd64\\cl.exe' failed with exit status 2
目前pyctp只支持python3 并在python3.4.3下完美测试通过(windows/linux)
stdafx.h(9): fatal error C1083: 无法打开包括文件: “Python.h”: No such file or directory
提示这个啥原因啊?
已经更改过代码,重新git. 现在可以直接使用setup.py编译, 自动寻找python.h相关配置
可否告知您采用的什么封装方法么?
python 官方c/c++扩展封装, 先手工写好部分函数试验效果,可行后做成py脚本批量转换头文件为c/c++文件