#!/usr/bin/env python # -*- coding: utf-8 -*- import sys,os from threading import Thread from itertools import zip_longest from datetime import datetime #from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import Qt,pyqtSignal,QThread,QSize from PyQt5.QtGui import QStandardItem, QStandardItemModel from PyQt5.QtWidgets import * from contextlib import closing from tqsdk import TqApi, TqAccount api,BrID,Usname,Psword,account,position,trade=None,None,None,None,None,None,None api = TqApi(TqAccount('快期模拟', 'laoren', 'laoren')) account = api.get_account() position = api.get_position() trade = api.get_trade() class GengXin_ShuJu(QThread): my_signal = pyqtSignal() def __init__(self): super(GengXin_ShuJu, self).__init__() def run(self):#更新发送信号 while True: api.wait_update() self.my_signal.emit() class MingXi(QWidget): def __init__(self): super(MingXi, self).__init__() self.resize(1300, 700) self.setWindowTitle('分笔明细') self.table_mingxi = QTableWidget(self) self.table_mingxi.setRowCount(0) # 2 self.table_mingxi.setColumnCount(12) self.table_mingxi.setHorizontalHeaderLabels(['成交号','时间','品种代码', '多/空', '手数', '成交价', '现价','盈利价差','止损','止盈','平仓','删除']) self.chengjiao_list = [] #成交号列表 self.shanchu_list = [] #删除成交号列表 self.mingxi_list = [] #成交列表 self.table_mingxi.clicked.connect(self.show_info) h_layout = QHBoxLayout() h_layout.addWidget(self.table_mingxi) self.setLayout(h_layout) #self.show() def pingcang(self): ping_cang = QPushButton('平仓') #ping_cang.clicked.connect(self.zhixing_pingcang) return ping_cang #函数返回值为创建的控件 def shanchu(self): shan_chu = QPushButton('删除') #shan_chu.clicked.connect(self.zhixing_shanchu) return shan_chu #函数返回值为创建的控件 def gengxin_mingxi(self): mingxi_row=0 for mingxi in trade.values(): #计算开仓成交笔数 if mingxi.offset == 'OPEN' and mingxi.trade_id not in self.chengjiao_list and mingxi.trade_id not in self.shanchu_list: #新增开仓成交单 print('成交号',mingxi.trade_id) print('chengjiao_list',self.chengjiao_list) mingxi_row += 1 self.chengjiao_list.append(mingxi.trade_id) dingdanhao = mingxi.trade_id mingxi_daima = mingxi.exchange_id + '.' + mingxi.instrument_id #品种代码 quote = api.get_quote(mingxi_daima) if mingxi.direction =='BUY' : fangxiang = '多' else : fangxiang = '空' mingxi_chengjiaojia = mingxi.price mingxi_shoushu = mingxi.volume dt = datetime.fromtimestamp(mingxi.trade_date_time // 1000000000) mingxi_time = dt.strftime('%Y-%m-%d %H:%M:%S') print(mingxi_daima) print('quote的值:',quote) #quote2 = api.get_quote('CZCE.TA009') #print('quote2的值:',quote2) zuixinjia = quote.last_price #zuixinjia = quote.close print('quote.last_price:',quote.last_price) print('quote.close',quote.close) #pinzhong_lots += mingxi_shoushu mingxi_fuying = quote.last_price - mingxi.price chengjiaolist = [dingdanhao,mingxi_time,mingxi_daima,fangxiang,mingxi_shoushu,mingxi_chengjiaojia,zuixinjia,mingxi_fuying] self.mingxi_list.append(chengjiaolist) print('增加了几个成交',mingxi_row) self.table_mingxi.setRowCount(self.table_mingxi.rowCount() + mingxi_row) #增加行数 print('最新行数',self.table_mingxi.rowCount()) for row in range(self.table_mingxi.rowCount()): #循环调用函数可创建多个控件 self.table_mingxi.setCellWidget(row, 10, self.pingcang()) self.table_mingxi.setCellWidget(row, 11, self.shanchu()) if row < self.mingxi_list.__len__() : for column , cj in zip(range(8),self.mingxi_list[row]) : item_mingxi = QTableWidgetItem(str(cj)) item_mingxi.setTextAlignment(Qt.AlignCenter) self.table_mingxi.setItem(row, column, item_mingxi) def showEvent(self,QShowEvent): print('分笔持仓窗口显示了') self.gengxin_mingxi() GengXin_ShuJu.my_signal.connect(self.gengxin_mingxi) def closeEvent(self, QCloseEvent): print('分笔持仓窗口关闭了') GengXin_ShuJu.my_signal.disconnect(self.gengxin_mingxi) def show_info(self): # 7 row = self.table_mingxi.currentIndex().row() column = self.table_mingxi.currentIndex().column() print('({}, {})'.format(row, column)) if __name__ == '__main__': app = QApplication(sys.argv) GengXin_ShuJu=GengXin_ShuJu() GengXin_ShuJu.start() MingXi = MingXi() MingXi.show() sys.exit(app.exec_())
全部代码在上方,上传后缩进发生了点变化,不知您还能不能复现
如下代码
def gengxin_mingxi(self):
mingxi_row=0
#self.chengjiao_list=[]
#self.shanchu_list=[]
for mingxi in trade.values(): #计算开仓成交笔数
if mingxi.offset == ‘OPEN’ and mingxi.trade_id not in self.chengjiao_list and mingxi.trade_id not in self.shanchu_list: #新增开仓成交单
print(‘成交号’,mingxi.trade_id)
mingxi_row += 1
self.chengjiao_list.append(mingxi.trade_id)
dingdanhao = mingxi.trade_id
mingxi_daima = mingxi.exchange_id + ‘.’ + mingxi.instrument_id #品种代码
quote = api.get_quote(mingxi_daima)
print(mingxi_daima)
print(‘quote的值:’,quote)
在类的初始化函数里定义了两个空列表,self.chengjiao_list=[] 和self.shanchu_list=[] ,在函数def gengxin_mingxi(self)中用for循环遍历成交数据,如果没有把两个空列表放在函数中重新赋值一次,quote打印出的都是nan值,datetime为空,但如果把if语句后的 and mingxi.trade_id not in self.chengjiao_list and mingxi.trade_id not in self.shanchu_list删掉,则可以正常打印quote。把quote定义放在for循环之外,在for外打印quote,同样需删除两个and判断或者先对两个空列表赋值一次,否则也不能正常打印quote。而且以上情况下直接使用语句quote = api.get_quote(‘CZCE.TA009’),同样无法正常打印quote值,比较奇怪,请问可能是什么原因造成的呢
以下是输出的一个值,品种代码正常,为CZCE.TA009,但输出内容值为nan或空
{‘datetime’: ”, ‘ask_price1’: nan, ‘ask_volume1’: 0, ‘bid_price1’: nan, ‘bid_volume1’: 0, ‘ask_price2’: nan, ‘ask_volume2’: 0, ‘bid_price2’: nan, ‘bid_volume2’: 0, ‘ask_price3’: nan, ‘ask_volume3’: 0,
‘bid_price3’: nan, ‘bid_volume3’: 0, ‘ask_price4’: nan, ‘ask_volume4’: 0, ‘bid_price4’: nan, ‘bid_volume4’: 0, ‘ask_price5’: nan, ‘ask_volume5’: 0, ‘bid_price5’: nan, ‘bid_volume5’: 0, ‘last_price’: nan, ‘highest’: nan, ‘lowest’: nan, ‘open’: nan, ‘close’: nan, ‘average’: nan, ‘volume’: 0, ‘amount’: nan, ‘open_interest’: 0, ‘settlement’: nan, ‘upper_limit’: nan, ‘lower_limit’: nan, ‘pre_open_interest’: 0, ‘pre_settlement’: nan, ‘pre_close’: nan, ‘price_tick’: 2, ‘price_decs’: 0, ‘volume_multiple’: 5, ‘max_limit_order_volume’: 1000, ‘max_market_order_volume’: 200, ‘min_limit_order_volume’: 0, ‘min_market_order_volume’: 0, ‘underlying_symbol’: ”, ‘strike_price’: nan, ‘ins_class’: ‘FUTURE’, ‘instrument_id’: ‘CZCE.TA009’, ‘expired’: False, ‘trading_time’: <tqsdk.objs.TradingTime object at 0x0D9AB730>, D({‘day’: [[’09:00:00′, ’10:15:00′], [’10:30:00′, ’11:30:00′], [’13:30:00′, ’15:00:00′]], ‘night’: []}), ‘expire_datetime’: 1600066800.0, ‘delivery_month’: 9, ‘delivery_year’: 2020, ‘option_class’: ”, ‘product_id’: ‘TA’, ‘margin’: 1026.0, ‘commission’: 3.0}
我发现了问题所在,线程类class GengXin_ShuJu(QThread)导致quote在第一次打印时值为nan,但之后的循环打印输出正常,但我后面代码获得的值都是第一次的nan,没有动态更新(quote的值不应是动态引用吗?)。如果把线程类去掉(不start即可),第一次打印便正常了。为什么线程类会导致quote第一次输出为nan,获得的quote动态引用为什么没有动态更新,不知是不是pyqt5的线程类和get_quote有冲突?