#!/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有冲突?