# -*- coding: utf-8 -*-
"""
Created on Sat Jan 23 21:48:07 2016
@author: Zhuolin
"""
import logging
import threading
import PyCTP
logger = logging.getLogger(__name__)
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 = bytes('%012d' % self.__OrderRef, 'gbk')
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_RESTART)
self.SubscribePublicTopic(PyCTP.THOST_TERT_RESTART)
self.RegisterFront(frontAddr)
self.Init()
self.__rsp_Connect = dict(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 = dict(BrokerID = BrokerID, UserID = UserID, Password = Password)
self.__rsp_Login = dict(event = threading.Event(), 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['ErrorID'] != 0:
logger.error('%s' % str(self.__rsp_Login['ErrorMsg'], encoding='gbk'))
return self.__rsp_Login['ErrorID']
self.__isLogined = True
self.__Password = Password
self.__BrokerID = self.__rsp_Login['result']['BrokerID']
self.__UserID = self.__rsp_Login['result']['UserID']
self.__SystemName = self.__rsp_Login['result']['SystemName']
self.__TradingDay = self.__rsp_Login['result']['TradingDay']
self.__DCETime = self.__rsp_Login['result']['DCETime']
self.__SessionID = self.__rsp_Login['result']['SessionID']
self.__MaxOrderRef = self.__rsp_Login['result']['MaxOrderRef']
self.__OrderRef = int(self.__MaxOrderRef) # 初始化报单引用
self.__INETime = self.__rsp_Login['result']['INETime']
self.__LoginTime = self.__rsp_Login['result']['LoginTime']
self.__FrontID = self.__rsp_Login['result']['FrontID']
self.__FFEXTime = self.__rsp_Login['result']['FFEXTime']
self.__CZCETime = self.__rsp_Login['result']['CZCETime']
self.__SHFETime = self.__rsp_Login['result']['SHFETime']
return self.__rsp_Login['result']
else:
return -4
return ret
def Logout(self):
""" 登出请求 """
if not self.__isLogined:
return 6
reqUserLogout = dict(BrokerID = self.__BrokerID, UserID = self.__UserID)
self.__rsp_Logout = dict(event = threading.Event(), 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['ErrorID'] != 0:
return self.__rsp_Logout['ErrorID']
self.__isLogined = False
return self.__rsp_Logout['result']
else:
return -4
return ret
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
def QryInstrumentMarginRate(self, InstrumentID):
""" 请求查询合约保证金率 """
QryInstrumentMarginRate = dict(BrokerID = self.__BrokerID, InvestorID = self.__InvestorID, InstrumentID = InstrumentID)
self.__rsp_QryInstrumentMarginRate = dict(results = [],
RequestID = self.__IncRequestID(),
ErrorID = 0,
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['ErrorID'] != 0:
return self.__rsp_QryInstrumentMarginRate['ErrorID']
#assert len(self.__rsp_QryInstrumentMarginRate['results']) == 1
return self.__rsp_QryInstrumentMarginRate['results']
else:
return -4
return ret
def QryInstrumentCommissionRate(self, InstrumentID):
""" 请求查询合约手续费率 """
QryInstrumentCommissionRate = dict(BrokerID = self.__BrokerID, InvestorID = self.__InvestorID, InstrumentID = InstrumentID)
self.__rsp_QryInstrumentCommissionRate = dict(results = []
, RequestID = self.__IncRequestID()
, ErrorID = 0
, 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['ErrorID'] != 0:
return self.__rsp_QryInstrumentCommissionRate['ErrorID']
#assert len(self.__rsp_QryInstrumentCommissionRate['results']) == 1
return self.__rsp_QryInstrumentCommissionRate['results']
else:
return -4
return ret
def QryInvestorPosition(self, InstrumentID=b''):
""" 请求查询投资者持仓 """
QryInvestorPositionFiel = dict(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID, InstrumentID=InstrumentID)
self.__rsp_QryInvestorPosition = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, 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['ErrorID'] != 0:
return self.__rsp_QryInvestorPosition['ErrorID']
return self.__rsp_QryInvestorPosition['results']
else:
return -4
return ret
def QryInvestorPositionDetail(self, InstrumentID=b''):
""" 请求查询投资者持仓明细 """
QryInvestorPositionDetail = dict(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID, InstrumentID=InstrumentID)
self.__rsp_QryInvestorPositionDetail = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, event=threading.Event())
ret = self.ReqQryInvestorPositionDetail(QryInvestorPositionDetail, self.__rsp_QryInvestorPositionDetail['RequestID'])
if ret == 0:
self.__rsp_QryInvestorPositionDetail['event'].clear()
if self.__rsp_QryInvestorPositionDetail['event'].wait(self.TIMEOUT):
if self.__rsp_QryInvestorPositionDetail['ErrorID'] != 0:
return self.__rsp_QryInvestorPositionDetail['ErrorID']
return self.__rsp_QryInvestorPositionDetail['results']
else:
return -4
return ret
def QryTradingAccount(self):
""" 请求查询资金账户 """
QryTradingAccountField = dict(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID)
self.__rsp_QryTradingAccount = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, event=threading.Event())
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['ErrorID'] != 0:
return self.__rsp_QryTradingAccount['ErrorID']
assert len(self.__rsp_QryTradingAccount['results']) == 1
return self.__rsp_QryTradingAccount['results'][0]
else:
return -4
return ret
def QryInvestor(self):
""" 请求查询投资者 """
InvestorField = dict(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID)
self.__rsp_QryInvestor = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, event=threading.Event())
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['ErrorID'] != 0:
return self.__rsp_QryInvestor['ErrorID']
assert len(self.__rsp_QryInvestor['results']) == 1
return self.__rsp_QryInvestor['results'][0]
else:
return -4
return ret
def QryExchange(self, ExchangeID=b''):
""" 请求查询交易所 """
QryExchangeField = dict(ExchangeID=ExchangeID)
self.__rsp_QryExchange = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, event=threading.Event())
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['ErrorID'] != 0:
return self.__rsp_QryExchange['ErrorID']
return self.__rsp_QryExchange['results']
else:
return -4
return ret
def QrySettlementInfo(self, TradingDay=b''):
""" 请求查询投资者结算结果 """
QrySettlementInfo = dict(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID, TradingDay=TradingDay)
self.__rsp_QrySettlementInfo = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, event=threading.Event())
ret = self.ReqQrySettlementInfo(QrySettlementInfo, self.__rsp_QrySettlementInfo['RequestID'])
if ret == 0:
self.__rsp_QrySettlementInfo['event'].clear()
if self.__rsp_QrySettlementInfo['event'].wait(self.TIMEOUT):
if self.__rsp_QrySettlementInfo['ErrorID'] != 0:
return self.__rsp_QrySettlementInfo['ErrorID']
result = {'Content':b''}
for item in self.__rsp_QrySettlementInfo['results']:
if result.get('TradingDay') is not None:
assert result['TradingDay'] == item['TradingDay']
if result.get('SettlementID') is not None:
assert result['SettlementID'] == item['SettlementID']
if result.get('BrokerID') is not None:
assert result['BrokerID'] == item['BrokerID']
if result.get('InvestorID') is not None:
assert result['InvestorID'] == item['InvestorID']
if result.get('SequenceNo') is not None:
assert result['SequenceNo'] == item['SequenceNo']
result['TradingDay'] = item['TradingDay']
result['SettlementID'] = item['SettlementID']
result['BrokerID'] = item['BrokerID']
result['InvestorID'] = item['InvestorID']
result['SequenceNo'] = item['SequenceNo']
result['Content'] += item['Content']
return result
else:
return -4
return ret
def QrySettlementInfoConfirm(self):
""" 请求查询结算信息确认 """
QrySettlementInfoConfirm = dict(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID)
self.__rsp_QrySettlementInfoConfirm = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, event=threading.Event())
ret = self.ReqQrySettlementInfoConfirm(QrySettlementInfoConfirm, self.__rsp_QrySettlementInfoConfirm['RequestID'])
if ret == 0:
self.__rsp_QrySettlementInfoConfirm['event'].clear()
if self.__rsp_QrySettlementInfoConfirm['event'].wait(self.TIMEOUT):
if self.__rsp_QrySettlementInfoConfirm['ErrorID'] != 0:
return self.__rsp_QrySettlementInfoConfirm['ErrorID']
#assert len(self.__rsp_QrySettlementInfoConfirm['results']) == 1
return self.__rsp_QrySettlementInfoConfirm['results']
else:
return -4
return ret
def SettlementInfoConfirm(self, ConfirmDate=b'', ConfirmTime=b''):
""" 投资者结算结果确认 """
SettlementInfoConfirm = dict(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID,
ConfirmDate=ConfirmDate, ConfirmTime=ConfirmTime)
self.__rsp_SettlementInfoConfirm = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, event=threading.Event())
ret = self.ReqSettlementInfoConfirm(SettlementInfoConfirm, self.__rsp_SettlementInfoConfirm['RequestID'])
if ret == 0:
self.__rsp_SettlementInfoConfirm['event'].clear()
if self.__rsp_SettlementInfoConfirm['event'].wait(self.TIMEOUT):
if self.__rsp_SettlementInfoConfirm['ErrorID'] != 0:
return self.__rsp_SettlementInfoConfirm['ErrorID']
#assert len(self.__rsp_SettlementInfoConfirm['results']) == 1
return self.__rsp_SettlementInfoConfirm['results']
else:
return -4
return ret
def QryDepthMarketData(self, InstrumentID):
""" 请求查询行情 """
QryDepthMarketData = dict(InstrumentID=InstrumentID)
self.__rsp_QryDepthMarketData = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, event=threading.Event())
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['ErrorID'] != 0:
return self.__rsp_QryDepthMarketData['ErrorID']
#assert len(self.__rsp_QryDepthMarketData['results']) == 1
return self.__rsp_QryDepthMarketData['results']
else:
return -4
return ret
def QryOrder(self, InstrumentID=b'', ExchangeID=b'', OrderSysID=b'', InsertTimeStart=b'', InsertTimeEnd=b''):
""" 请求查询报单 """
QryOrder = dict(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID, InstrumentID=InstrumentID, ExchangeID=ExchangeID, OrderSysID=OrderSysID, InsertTimeStart=InsertTimeStart, InsertTimeEnd=InsertTimeEnd)
self.__rsp_QryOrder = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, event=threading.Event())
ret = self.ReqQryOrder(QryOrder, self.__rsp_QryOrder['RequestID'])
if ret == 0:
self.__rsp_QryOrder['event'].clear()
if self.__rsp_QryOrder['event'].wait(self.TIMEOUT):
if self.__rsp_QryOrder['ErrorID'] != 0:
return self.__rsp_QryOrder['ErrorID']
return self.__rsp_QryOrder['results']
else:
return -4
return ret
def QryTrade(self, InstrumentID=b'', ExchangeID=b'', TradeID=b'', TradeTimeStart=b'', TradeTimeEnd=b''):
""" 请求查询成交 """
QryTrade = dict(BrokerID=self.__BrokerID, InvestorID=self.__InvestorID, InstrumentID=InstrumentID, ExchangeID=ExchangeID, TradeID=TradeID, TradeTimeStart=TradeTimeStart, TradeTimeEnd=TradeTimeEnd)
self.__rsp_QryTrade = dict(results=[], RequestID=self.__IncRequestID(), ErrorID=0, event=threading.Event())
ret = self.ReqQryTrade(QryTrade, self.__rsp_QryTrade['RequestID'])
if ret == 0:
self.__rsp_QryTrade['event'].clear()
if self.__rsp_QryTrade['event'].wait(self.TIMEOUT):
if self.__rsp_QryTrade['ErrorID'] != 0:
return self.__rsp_QryTrade['ErrorID']
return self.__rsp_QryTrade['results']
else:
return -4
return ret
def OrderInsert(self, InstrumentID, Action, Direction, Volume, Price):
""" 开平仓(限价挂单)申报, 注意,这是异步指令 """
InputOrder = {}
InputOrder['BrokerID'] = self.__BrokerID # 经纪公司代码
InputOrder['InvestorID'] = self.__InvestorID # 投资者代码
InputOrder['InstrumentID'] = InstrumentID # 合约代码
InputOrder['OrderRef'] = 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['ContingentCondition'] = PyCTP.THOST_FTDC_CC_Immediately # 触发条件:立即
InputOrder['ForceCloseReason'] = PyCTP.THOST_FTDC_FCC_NotForceClose # 强平原因:非强平
InputOrder['RequestID'] = self.__IncRequestID() # 请求编号
return self.ReqOrderInsert(InputOrder, InputOrder['RequestID'])
def OrderAction(self, ActionFlag, FrontID, SessionID, OrderRef, ExchangeID, OrderSysID):
""" 报单操作请求(撤单), 注意,这是异步指令 """
assert ActionFlag == PyCTP.THOST_FTDC_AF_Delete
InputOrderAction = {}
InputOrderAction['BrokerID'] = self.__BrokerID # 经纪公司代码
InputOrderAction['UserID'] = self.__UserID # 用户代码
InputOrderAction['InvestorID'] = self.__InvestorID # 投资者代码
InputOrderAction['OrderActionRef'] = int(self.__IncOrderRef()) # 操作引用
InputOrderAction['OrderRef'] = OrderRef # 报单引用
InputOrderAction['RequestID'] = self.__IncRequestID() # 请求编号
InputOrderAction['FrontID'] = FrontID # 前置编号
InputOrderAction['SessionID'] = SessionID # 会话编号
InputOrderAction['ExchangeID'] = ExchangeID # 交易所代码
InputOrderAction['OrderSysID'] = OrderSysID # 报单编号
InputOrderAction['ActionFlag'] = ActionFlag # 操作标志:撤单
return self.ReqOrderAction(InputOrderAction, InputOrderAction['RequestID'])
def OnRspError(self, RspInfo, RequestID, IsLast):
""" 错误信息 """
logger.error('%s' % repr(('OnRspError', [RspInfo['ErrorID'], str(RspInfo['ErrorMsg'], encoding='gbk')], RequestID, IsLast)))
def OnFrontConnected(self):
""" 当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。 """
logger.info('CThostFtdcTraderApi::OnFrontConnected()')
self.__rsp_Connect['event'].set()
#if self.__isLogined:
# sys.stderr.write('CThostFtdcTraderApi::ReqUserLogin...')
# result = self.Login(self.__BrokerID, self.__UserID, self.__Password)
def OnFrontDisconnected(self, nReason):
""" 当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。
nReason 错误原因
0x1001 网络读失败
0x1002 网络写失败
0x2001 接收心跳超时
0x2002 发送心跳失败
0x2003 收到错误报文
"""
logger.warn('CThostFtdcTraderApi::OnFrontDisconnected(%s)' % hex(nReason))
def OnRspUserLogin(self, RspUserLogin, RspInfo, RequestID, IsLast):
""" 登录请求响应 """
if RequestID == self.__rsp_Login['RequestID'] and IsLast:
self.__rsp_Login['result'] = RspUserLogin
self.__rsp_Login.update(RspInfo)
self.__rsp_Login['event'].set()
def OnRspUserLogout(self, RspUserLogout, RspInfo, RequestID, IsLast):
""" 登出请求响应 """
if RequestID == self.__rsp_Logout['RequestID'] and IsLast:
self.__rsp_Logout['result'] = RspUserLogout
self.__rsp_Logout.update(RspInfo)
self.__rsp_Logout['event'].set()
def OnRspQryInstrument(self, Instrument, RspInfo, RequestID, IsLast):
""" 请求查询合约响应 """
if RequestID == self.__rsp_QryInstrument['RequestID']:
if RspInfo is not None:
self.__rsp_QryInstrument.update(RspInfo)
if Instrument is not None:
self.__rsp_QryInstrument['results'].append(Instrument)
if IsLast:
self.__rsp_QryInstrument['event'].set()
def OnRspQryInstrumentMarginRate(self, InstrumentMarginRate, RspInfo, RequestID, IsLast):
""" 请求查询合约保证金率响应 """
if RequestID == self.__rsp_QryInstrumentMarginRate['RequestID']:
if RspInfo is not None:
self.__rsp_QryInstrumentMarginRate.update(RspInfo)
if InstrumentMarginRate is not None:
self.__rsp_QryInstrumentMarginRate['results'].append(InstrumentMarginRate)
if IsLast:
self.__rsp_QryInstrumentMarginRate['event'].set()
def OnRspQryInstrumentCommissionRate(self, InstrumentCommissionRate, RspInfo, RequestID, IsLast):
""" 请求查询合约手续费率响应 """
if RequestID == self.__rsp_QryInstrumentCommissionRate['RequestID']:
if RspInfo is not None:
self.__rsp_QryInstrumentCommissionRate.update(RspInfo)
if InstrumentCommissionRate is not None:
self.__rsp_QryInstrumentCommissionRate['results'].append(InstrumentCommissionRate)
if IsLast:
self.__rsp_QryInstrumentCommissionRate['event'].set()
def OnRspQryInvestorPosition(self, InvestorPosition, RspInfo, RequestID, IsLast):
""" 请求查询投资者持仓响应 """
if RequestID == self.__rsp_QryInvestorPosition['RequestID']:
if RspInfo is not None:
self.__rsp_QryInvestorPosition.update(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.update(RspInfo)
if InvestorPositionDetail is not None:
self.__rsp_QryInvestorPositionDetail['results'].append(InvestorPositionDetail)
if IsLast:
self.__rsp_QryInvestorPositionDetail['event'].set()
def OnRspQryTradingAccount(self, TradingAccount, RspInfo, RequestID, IsLast):
""" 请求查询资金账户响应 """
if RequestID == self.__rsp_QryTradingAccount['RequestID']:
if RspInfo is not None:
self.__rsp_QryTradingAccount.update(RspInfo)
if TradingAccount is not None:
self.__rsp_QryTradingAccount['results'].append(TradingAccount)
if IsLast:
self.__rsp_QryTradingAccount['event'].set()
def OnRspQryInvestor(self, Investor, RspInfo, RequestID, IsLast):
""" 请求查询投资者响应 """
if RequestID == self.__rsp_QryInvestor['RequestID']:
if RspInfo is not None:
self.__rsp_QryInvestor.update(RspInfo)
if Investor is not None:
self.__rsp_QryInvestor['results'].append(Investor)
if IsLast:
self.__rsp_QryInvestor['event'].set()
def OnRspQryExchange(self, Exchange, RspInfo, RequestID, IsLast):
""" 请求查询交易所响应 """
if RequestID == self.__rsp_QryExchange['RequestID']:
if RspInfo is not None:
self.__rsp_QryExchange.update(RspInfo)
if Exchange is not None:
self.__rsp_QryExchange['results'].append(Exchange)
if IsLast:
self.__rsp_QryExchange['event'].set()
def OnRspQrySettlementInfo(self, SettlementInfo, RspInfo, RequestID, IsLast):
""" 请求查询投资者结算结果响应 """
if RequestID == self.__rsp_QrySettlementInfo['RequestID']:
if RspInfo is not None:
self.__rsp_QrySettlementInfo.update(RspInfo)
if SettlementInfo is not None:
self.__rsp_QrySettlementInfo['results'].append(SettlementInfo)
if IsLast:
self.__rsp_QrySettlementInfo['event'].set()
def OnRspQrySettlementInfoConfirm(self, SettlementInfoConfirm, RspInfo, RequestID, IsLast):
""" 请求查询结算信息确认响应 """
if RequestID == self.__rsp_QrySettlementInfoConfirm['RequestID']:
if RspInfo is not None:
self.__rsp_QrySettlementInfoConfirm.update(RspInfo)
if SettlementInfoConfirm is not None:
self.__rsp_QrySettlementInfoConfirm['results'].append(SettlementInfoConfirm)
if IsLast:
self.__rsp_QrySettlementInfoConfirm['event'].set()
def OnRspSettlementInfoConfirm(self, SettlementInfoConfirm, RspInfo, RequestID, IsLast):
""" 请求查询结算信息确认响应 """
if RequestID == self.__rsp_SettlementInfoConfirm['RequestID']:
if RspInfo is not None:
self.__rsp_SettlementInfoConfirm.update(RspInfo)
if SettlementInfoConfirm is not None:
self.__rsp_SettlementInfoConfirm['results'].append(SettlementInfoConfirm)
if IsLast:
self.__rsp_SettlementInfoConfirm['event'].set()
def OnRspQryDepthMarketData(self, DepthMarketData, RspInfo, RequestID, IsLast):
""" 请求查询交易所响应 """
if RequestID == self.__rsp_QryDepthMarketData['RequestID']:
if RspInfo is not None:
self.__rsp_QryDepthMarketData.update(RspInfo)
if DepthMarketData is not None:
self.__rsp_QryDepthMarketData['results'].append(DepthMarketData)
if IsLast:
self.__rsp_QryDepthMarketData['event'].set()
def OnRspQryOrder(self, Order, RspInfo, RequestID, IsLast):
""" 请求查询报单响应 """
if RequestID == self.__rsp_QryOrder['RequestID']:
if RspInfo is not None:
self.__rsp_QryOrder.update(RspInfo)
if Order is not None:
self.__rsp_QryOrder['results'].append(Order)
if IsLast:
self.__rsp_QryOrder['event'].set()
def OnRspQryTrade(self, Trade, RspInfo, RequestID, IsLast):
""" 请求查询成交响应 """
if RequestID == self.__rsp_QryTrade['RequestID']:
if RspInfo is not None:
self.__rsp_QryTrade.update(RspInfo)
if Trade is not None:
self.__rsp_QryTrade['results'].append(Trade)
if IsLast:
self.__rsp_QryTrade['event'].set()
def OnRspOrderInsert(self, InputOrder, RspInfo, RequestID, IsLast):
""" 报单录入请求响应 """
if RspInfo is not None and RspInfo['ErrorID'] != 0:
logger.info('%s' % repr(('OnRspOrderInsert', [RspInfo['ErrorID'], str(RspInfo['ErrorMsg'], encoding='gb2312')], RequestID, IsLast)) )
def OnErrRtnOrderInsert(self, InputOrder, RspInfo):
""" 报单录入错误回报 """
if RspInfo is not None and RspInfo['ErrorID'] != 0:
logger.warn('%s' % repr(('OnErrRtnOrderInsert', [RspInfo['ErrorID'], str(RspInfo['ErrorMsg'], encoding='gb2312')] )) )
def OnRspOrderAction(self, InputOrderAction, RspInfo, RequestID, IsLast):
""" 报单操作请求响应 """
if RspInfo is not None and RspInfo['ErrorID'] != 0:
logger.info('%s' % repr(('OnRspOrderAction', [RspInfo['ErrorID'], str(RspInfo['ErrorMsg'], encoding='gb2312')], RequestID, IsLast)) )
def OnErrRtnOrderAction(self, OrderAction, RspInfo):
""" 报单操作错误回报 """
if RspInfo is not None and RspInfo['ErrorID'] != 0:
logger.warn('%s' % repr(('OnErrRtnOrderAction', [RspInfo['ErrorID'], str(RspInfo['ErrorMsg'], encoding='gb2312')] )) )
def OnRtnOrder(self, Order):
""" 报单通知 """
#print('OnRtnOrder:', Order, file=sys.stderr)
logger.info('%s' % repr(('OnRtnOrder', Order['InstrumentID'], Order['FrontID'], Order['SessionID'], Order['OrderRef'], Order['ExchangeID'], Order['OrderSysID'], Order['OrderStatus'])) )
def OnRtnTrade(self, Trade):
""" 成交通知 """
#print('OnRtnTrade:', Trade, file=sys.stderr)
logger.info('%s' % repr(('OnRtnTrade', Trade['InstrumentID'], Trade['ExchangeID'], Trade['TradeID'], Trade['OffsetFlag'], Trade['Direction'] )) )
def OnRtnInstrumentStatus(self, InstrumentStatus):
""" 合约交易状态通知 """
logger.info('%s' % repr(('OnRtnInstrumentStatus', InstrumentStatus['InstrumentID'], InstrumentStatus['InstrumentStatus'])))
def OnRtnFromBankToFutureByFuture(self, RspTransfer):
""" 期货发起银行资金转期货通知 """
logger.info('%s' % repr(('OnRtnFromBankToFutureByFuture', RspTransfer['TradeAmount'])))
def OnRtnFromFutureToBankByFuture(self, RspTransfer):
""" 期货发起期货资金转银行通知 """
logger.info('%s' % repr(('OnRtnFromFutureToBankByFuture', RspTransfer['TradeAmount'])))
def OnRtnCFMMCTradingAccountToken(self, CFMMCTradingAccountToken):
""" 保证金监控中心用户令牌 """
logger.info('OnRtnCFMMCTradingAccountToken')
class PyCTP_Trader(PyCTP_Trader_API):
def OrderActionDelete(self, order):
""" 撤销报单 """
return super().OrderAction(PyCTP.THOST_FTDC_AF_Delete, order['FrontID'], order['SessionID'], order['OrderRef'], order['ExchangeID'], order['OrderSysID']) |
可否告知您采用的什么封装方法么?
python 官方c/c++扩展封装, 先手工写好部分函数试验效果,可行后做成py脚本批量转换头文件为c/c++文件
stdafx.h(9): fatal error C1083: 无法打开包括文件: “Python.h”: No such file or directory
提示这个啥原因啊?
已经更改过代码,重新git. 现在可以直接使用setup.py编译, 自动寻找python.h相关配置
您好,我运行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)
版主你好,看到了pyctp,感觉挺好的,想使用但需要 vs2013编译, 不过本人未装 vs2013,也不熟悉,将否将编译后的dll也放上,方便直接使用
能不能将编译好的dll也放上
好的,我放一份编译好的上来
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,…)事件处理。
请问要想通过CTP实现开仓,平仓,撤单等操作,代码应该怎么写啊?
参考例子中的python订单操作代码
请问想要通过CTP进行开仓,平仓,撤单操作,代码应该怎么写啊,您有写好的吗?
满屏全是
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
就可屏蔽此事件.
非常感谢回复,问题已经解决。代码中的测试部分全部通过,没有问题。但是不知道怎么写开仓,平仓,撤单操作。你的代码中只有限价单(没有市价单、条件单),试了试,可能是传参有问题,限价单也不会用。哈哈哈哈。能不能写个demo。我看上面好多人都在问这个问题。望百忙之中,抽点时间帮助一下我们这样的小白。谢谢!万分感谢!
请问在 OnFrontDisconnected 函数里的 self.__Inst_Interval() 方法是啥?
最初设想如果掉线,就过段时间自动登陆,这个函数是用来延迟的。不过后发现ctp有自动掉线重连功能,也就注释掉了.
请问楼主,查询复数合约怎么写?
单数合约是InstrumentID= b’cu1802′
这里试了很多写法,比如想写2,3个合约,都运行失败啊
多个合约用 list传递 例如 InstrumentID= [b’cu1802′, b’cu1803′]
求问兄台能不能共享下.h转换h&cpp的新脚本学习下,github的运行结果稍微一点点对不上的。
ctp新版本有变化,需要针对修改一下才行, 其实转换脚本只是一些正则.
行情退出登录有问题。 (‘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只是做个样子.
我在做web版的ctp 登录的时候发现 ctp有自动掉线重连功能 导致OnFrontDisconnected这个函数会不断的触发 如何才能停止这个函数的调用呢
无法停止调用,要想看不到显示,把函数体留空就是了.
能不能共享下.h转换h&cpp的新脚本学习下。
因为api不停的更新,所以想着也能跟进更新一下pyctp接口,如果API有变化,我也可以尝试修改正则,然后再共享出来:D
github中已共享出此脚本
请问博主 在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文件也复制到项目根目录
博主,对于其中的请求行情模块,test_PyCTP.py里的def SubMarketData(self, InstrumentID):这个函数里,ret = self.SubscribeMarketData(InstrumentID, len(InstrumentID))应该是这一行触发了请求行情吧,我如何能把在窗口里的滚动的每秒的数据存成一个个字典,供我别的分析啊,SubscribeMarketData这个函数只返回了个int值,我如何把得到的行情数据存起来哈,谢谢
使用python list或queue对象保存数据. 保存行情只能在回调中实现. 这点需要有python基础
你好!刚研究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基础. 总的来说就是可以使用队列或列表保存
您好!非常感谢提供此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位的库
请教个扩展的问题,char[x],用pybytes;如果是struct里面有int[x],double[x],用啥做转换啊?
用数组或列表就可以了,在c++中需做一次转换处理. 另外,如是非ctp, 那么python好像提供有直接的c结构类。
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;
}
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模式下,可以直接调试扩展代码。这样更容易发现原因
好的,多谢
您好,请问运行test_PyCTP.py产生
trader = File “test_PyCTP.py”, line 598, in main
trader = PyCTP_Trader.CreateFtdcTraderApi(b’tmp_t‘)
ValueError: parameter invalid.
报错是什么原因呢?
您好,请问运行test_PyCTP.py产生
trader = File “test_PyCTP.py”, line 598, in main
trader = PyCTP_Trader.CreateFtdcTraderApi(b’tmp_t‘)
ValueError: parameter invalid.
报错是什么原因呢?
必须设置已经存在的文件夹路径,注意看参考代码
你好,我使用python2.7 32位的环境编译成功但运行test_PyCTP报错:
File “test_PyCTP.py”, line 598, in main
trader = PyCTP_Trader.CreateFtdcTraderApi(b’tmp_t‘)
ValueError: parameter invalid.
请问这是什么原因呢?
满屏都是下面的错误
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方法 。
您好, 很感谢您的开源代码, 看到这个函数不太明白, 好像是不用这个去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;
};
只是为了模拟注册效果,总需要有个回调类.
您好,运行脚本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”},其中大部分都是空的,请问是登陆成功了还是失败了??
为什么在test_PyCTP_market登陆,无论输入的userId和password正确与否,登陆都能通过呀??
行情订阅的时候报错:
(‘OnRspError’, [77, ‘CTP:无此功能’], 0, True)为啥呀??
行情订阅的时候,报错:(‘OnRspError’, [77, ‘CTP:无此功能’], 0, True),为啥呢??
请问一下,使用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 应用程序。
行情登陆的时候,为什么无论用户密码怎样输入,都返回一样的结果:
‘BrokerID’: b”, ‘SHFETime’: b”, ‘MaxOrderRef’: b”, ‘FrontID’: 0, ‘CZCETime’: b”, ‘UserID’: b”,
晚上好。 看了一晚CTP文档,参考 PyCTP_Trader.py 里面的 函数 OrderInsert(这个函数是限价单),想写一个 开平仓市价单申报 函数,想不出来,可以指点下吗?万分感谢。
释放是这样写的吗:
def ReleaseMarket(self):
“”” 删除接口对象本身”””
self.RegisterSpi(None)
self.Release()
self = None
我用maket.ReleaseMarket()直接死机啦
在linux下不用释放,ctp在linux下有内存段错误,但死机是不会的。
关于行情数据入Oracle数据库的时候,我遇到了两个问题:
1、由于某些时刻tick数据波动较大,所有推送的数据很快,导致单个tick入库的时间追不上推送时间,达不到数据的时效性。然后我用批量插入:先收集一分钟的tick数据,我用list保存,然后批量插入后立即置list为空,但此时,行情仍在往list里面写,导致某些tick数据有遗漏。请问有没有好的解决办法??
2、在生成分钟tick数据的时候,我拿到一分钟的tick数据,在这数据中多种合约,每一种合约都需要计算最高、最低、开盘、收盘、数量,这里非常耗费时间,请问楼主大大有什么建议吗??
跪求回复!!
关于行情数据入Oracle数据库的时候,我遇到了两个问题:
1、由于某些时刻tick数据波动较大,所有推送的数据很快,导致单个tick入库的时间追不上推送时间,达不到数据的时效性。然后我用批量插入:先收集一分钟的tick数据,我用list保存,然后批量插入后立即置list为空,但此时,行情仍在往list里面写,导致某些tick数据有遗漏。请问有没有好的解决办法??
2、在生成分钟tick数据的时候,我拿到一分钟的tick数据,在这数据中多种合约,每一种合约都需要计算最高、最低、开盘、收盘、数量,这里非常耗费时间,请问楼主大大有什么建议吗??
跪求回复!!
使用队列, ontick写入队列就返回, 其它的现成处理队列中的数据.
您好,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)
您好,十分感谢您共享的代码,CTP API已经更新到了6.3.11_20180109版本,我通过您的代码重新编译后已经无法正常使用,具体出现问题是前置链接无法登陆所以后续也无法正常使用,我通过您共享的 APIToPyCTP.py 转换代码但是似乎没有成功
您好,十分感谢您共享的代码,CTP API已经更新到了6.3.11_20180109版本,我通过您的代码重新编译后已经无法正常使用,具体出现问题是前置链接无法登陆所以后续也无法正常使用,我通过您共享的 APIToPyCTP.py 转换代码但是似乎没有成功,不太理解转换代码。
朋友你好!我相信很多人和我一样,能力有限,只能站在巨人的肩膀上做一点策略小开发,所以非常感谢您封装了这么好的接口,使我们这些小白也能有机会研究量化策略。目前我看到github上面有针对看穿式的更新,但不知怎么用。请问你能更新一下相应的demo吗?非常感谢!
请问博主,现在交易所更新了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穿透版
问一下啊,我按照guidance说的进入 VS2013 x86 本机工具命令提示 将地址转到python-master文件夹下,想要跑 python setup.py build 但是一点反应都没有直接就给出了新的一行让我输入指令,也就是说看起来什么都没有发生。请问是什么原因呢?我的python是3.7.3,请问是否会是python版本影响?
你好,我在按照guidance进行编译,进入VS2013 x86 本机工具命令提示,将地址换到python master这个文件夹(即包含 setup.py 的文件夹),然后输入指令 python setup.py build,但是什么都没有发生,也没有给出任何信息,就直接进入新的一行让我输入指令了,请问是怎么回事呢。我的python版本是3.7.3,请问是否是版本的问题呢?
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复制到相同目录去了
大神 能不能帮我看看这个帖子的问题
https://bbs.csdn.net/topics/395193839
官方CTP c/c++ 库在linux64bit上release是是存在问题的,无法解决,只能忽略这个错误.
大神 为什么我在调用api的release是出现了段错误,最为关键的是,同样的操作系统/编译器,分别运行,一个报错,一个正常
32位的python,在setup里的include & lib 目录还是 v6.3.6_20160606_tradeapi_windows。编译环境是只支持64位的python 吗?
如何理解 看穿监管?
调用 CTraderApi::ReqAuthenticate()函数填入 AppID和授权码 进行 终端认证 ,通过 ,通过 终端认证后再调用 CTraderApi::ReqUserLogin()函数 登录。 调用 pyctp 怎么实现?
代码方面的修改:
之前做CTP都需要调用ReqUserLogin();这个登录请求,现在如果要接入穿透式监管的流程改变了,将ReqUserLogin();替换为ReqAuthenticate(CThostFtdcReqAuthenticateField *pReqAuthenticateField, int nRequestID) 认证请求,然后在认证回调里添加ReqUserLogin();
调用 pyctp 如何实现这个流程? 谢谢
请教大佬,看穿式的版本在哪里能修改自己申请到的AppID?