1.创建启动主页面文件(相当于web端的html)
main.py
import sys
from PyQt5.QtWidgets import QTabWidget, QApplication, QVBoxLayout, QHBoxLayout, QFrame
from Main.Views.Easytrade.easytrademanage.Klinematrix import KlineMatrix
from Main.Views.Easytrade.easytrademanage.Limitmove import LimitMove
from Main.Views.Easytrade.easytrademanage.accountmsg import AccountMsg
from Main.Views.Easytrade.easytrademanage.easyorder import EasyOrder
from Main.Views.Easytrade.easytrademanage.marketmsg import MarketMsg
from Main.Views.Easytrade.easytrademanage.qss import Qss
from Main.Views.Easytrade.easytrademanage.recordmsg import RecordMsg
class TradeManage(QTabWidget):
def __init__(self):
super(TradeManage, self).__init__()
self.setObjectName('Branarbitrage')
self.AccountMsg = AccountMsg()
self.EasyOrder = EasyOrder()
self.KlineMatrix = KlineMatrix()
self.LimitMove = LimitMove()
self.MarketMsg = MarketMsg()
self.RecordMsg = RecordMsg()
self.fram1 = QFrame()
self.fram1.setStyleSheet(Qss.blue_frame)
self.fram2 = QFrame()
self.fram2.setStyleSheet(Qss.orange_frame)
self.fram3 = QFrame()
self.fram3.setStyleSheet(Qss.main_frame)
self.fram4 = QFrame()
self.fram4.setStyleSheet(Qss.table_frame)
self.fram5 = QFrame()
self.fram5.setStyleSheet(Qss.green_frame)
self.fram6 = QFrame()
self.fram6.setStyleSheet(Qss.red_frame)
hbox_1 = QHBoxLayout()
hbox_1.addWidget(self.MarketMsg)
hbox_1.setContentsMargins(0, 0, 0, 0)
self.fram1.setLayout(hbox_1)
hbox1 = QHBoxLayout()
hbox1.addWidget(self.fram1, 2)
hbox1.setSpacing(0)
hbox1.setContentsMargins(0, 0, 0, 0)
hbox_2 = QHBoxLayout()
hbox_2.addWidget(self.KlineMatrix)
hbox_2.setContentsMargins(0, 0, 0, 0)
self.fram2.setLayout(hbox_2)
hbox2 = QHBoxLayout()
hbox2.addWidget(self.fram2, 2)
hbox2.setSpacing(0)
hbox2.setContentsMargins(0, 0, 0, 0)
hbox_3 = QHBoxLayout()
hbox_3.addWidget(self.LimitMove)
hbox_3.setContentsMargins(0, 0, 0, 0)
self.fram3.setLayout(hbox_3)
hbox3 = QHBoxLayout()
hbox3.addWidget(self.fram3, 2)
hbox3.setSpacing(0)
hbox3.setContentsMargins(0, 0, 0, 0)
# 第一行三个布局
hbox4 = QHBoxLayout()
hbox4.addLayout(hbox1, 2)
hbox4.addLayout(hbox2, 2)
hbox4.addLayout(hbox3, 2)
hbox4.setSpacing(0)
hbox4.setContentsMargins(0, 0, 0, 0)
# 账号信息布局
hbox_5 = QHBoxLayout()
hbox_5.addWidget(self.AccountMsg)
hbox_5.setContentsMargins(0, 0, 0, 0)
self.fram4.setLayout(hbox_5)
hbox5 = QHBoxLayout()
hbox5.addWidget(self.fram4, 2)
hbox5.setSpacing(0)
hbox5.setContentsMargins(0, 0, 0, 0)
# 下单记录信息布局
hbox_7 = QHBoxLayout()
hbox_7.addWidget(self.RecordMsg)
hbox_7.setContentsMargins(0, 0, 0, 0)
self.fram5.setLayout(hbox_7)
hbox7 = QHBoxLayout()
hbox7.addWidget(self.fram5, 2)
hbox7.setSpacing(0)
hbox7.setContentsMargins(0, 0, 0, 0)
# 下单布局
hbox_8 = QHBoxLayout()
hbox_8.addWidget(self.EasyOrder)
hbox_8.setContentsMargins(0, 0, 0, 0)
self.fram6.setLayout(hbox_8)
hbox8 = QHBoxLayout()
hbox8.addWidget(self.fram6, 2)
hbox8.setSpacing(0)
hbox8.setContentsMargins(0, 0, 0, 0)
# 交易信息及订单布局设置
hbox9 = QHBoxLayout()
hbox9.addLayout(hbox7, 2)
hbox9.addLayout(hbox8, 1)
hbox9.setSpacing(0)
hbox9.setContentsMargins(0, 0, 0, 0)
hbox10 = QVBoxLayout()
hbox10.addLayout(hbox4, 10)
hbox10.addLayout(hbox5, 1)
hbox10.addLayout(hbox9, 9)
hbox10.setSpacing(0)
hbox10.setContentsMargins(0, 0, 0, 0)
self.setLayout(hbox10)
if __name__ == '__main__':
# 创建应用程序和对象
app = QApplication(sys.argv)
ex = TradeManage()
ex.show()
sys.exit(app.exec_())
2.创建数据处理逻辑文件(相当于web端的js)
recordmsgJs.py
import json
import sys
import threading
import time
import win32gui
import win32print
import win32con
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QWidget, QApplication, QHBoxLayout, QFrame, QAbstractItemView, QTableWidget, QTabWidget, \
QTableWidgetItem
from Log.logg import logger
from Main.Views.Easytrade.easytrademanage.qss import Qss
from Resources.Variable import returnexchid, returntradeunit
class RecordMsg(QWidget):
tlock = threading.RLock()
def __init__(self):
super(RecordMsg, self).__init__()
# 建立ws
self.Recvmsg = "RecordMsg"
self.setWindowTitle("记录")
self.holding_table_data = []
self.entrust_table_data = []
self.deal_table_data = []
self.startTreadingFlag = 1
self.accountmsgComboFutures = None
# self.brokerid = None
self.initUi()
def initUi(self):
self.setStyleSheet("QWidget{background:#f0f0f0;}")
# 获取屏幕的缩放比例
hDC = win32gui.GetDC(0)
self.dpi = win32print.GetDeviceCaps(hDC, win32con.LOGPIXELSX)
dpi = win32print.GetDeviceCaps(hDC, win32con.LOGPIXELSX)
# 获取显示器分辨率大小
self.desktop = QApplication.desktop()
self.screenRect = self.desktop.screenGeometry()
self.height = self.screenRect.height()
self.width = self.screenRect.width()
self.font5 = QFont("微软雅黑")
pointsize5 = self.font5.pointSize()
self.font5.setPixelSize(pointsize5 * 90 / 72)
self.abitragerecore = QTabWidget()
self.abitrageposition = QWidget()
self.abitrageentrust = QWidget()
self.accountposition = QWidget()
self.correlationentrust = QWidget()
self.abitragerecore.addTab(self.abitrageposition, "持仓")
self.abitragerecore.addTab(self.abitrageentrust, "委托")
self.abitragerecore.addTab(self.accountposition, "成交")
# self.abitragerecore.addTab(self.correlationentrust, "条件单")
self.abitragerecore.setStyleSheet(Qss.abitragerecoreStyle)
holdingColumnName = ['品种', '合约', '多空', '总仓', '可用', '今仓', '今可用', '开仓均价', '逐笔浮盈', '保证金', '持仓均价', '盯市浮盈', '投保',
'']
self.holding_column_list = ['instrumentid', 'instrumentid', 'direct', 'sum_holding', 'sum_useful',
'now_holding', 'now_useful',
'opencost', 'closeprofitbytrade', 'usemargin', 'positioncost',
'closeprofitbydate', 'hedge']
holdingDictWidthList = {144: [88, 109, 70, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96],
120: [88, 104, 60, 94, 94, 94, 94, 99, 86, 94, 94, 94, 95],
96: [87, 89, 55, 89, 89, 89, 89, 94, 96, 89, 89, 89, 89]}
# 生成持仓表格
self.holding_table = TableWidget(holdingColumnName, holdingDictWidthList)
entrustColumnName = ['时间', '合约', '状态', '买卖', '开平', '委托价', '委托量', '可撤', '已成交', '已撤单', '投保', '报单编号', '']
self.entrust_column_list = ['inserttime', 'instrumentid', 'orderstatus', 'side', 'direct',
'price', 'amount', 'can_return', 'bizvolume', 'had_return',
'hedge', 'orderid']
entrustDictWidthList = {144: [153, 93, 93, 70, 70, 96, 96, 96, 96, 96, 96, 136],
120: [160, 93, 93, 60, 60, 96, 96, 94, 93, 93, 93, 123],
96: [150, 84, 80, 60, 60, 89, 89, 90, 94, 94, 94, 136]}
# 生成委托表格
self.entrust_table = TableWidget(entrustColumnName, entrustDictWidthList)
dealColumnName = ['时间', '合约', '买卖', '开平', '成交价', '成交量', '报单编号', '']
self.deal_column_list = ['tradetime', 'instrumentid', 'side', 'direct', 'price', 'volume', 'orderid']
dealDictWidthList = {144: [153, 96, 70, 70, 96, 140, 140, 100],
120: [160, 96, 60, 60, 96, 140, 140, 100],
96: [150, 120, 120, 120, 160, 120, 160, 150]}
# 生成成交表格
self.deal_table = TableWidget(dealColumnName, dealDictWidthList)
self.frame = QFrame()
self.frame.setObjectName('frame')
self.frame.setStyleSheet(Qss.record_frame_style)
hbox1 = QHBoxLayout(self.abitrageposition)
hbox1.addWidget(self.holding_table)
hbox1.setContentsMargins(0, 0, 0, 0)
hbox2 = QHBoxLayout(self.abitrageentrust)
hbox2.addWidget(self.entrust_table)
hbox2.setContentsMargins(0, 0, 0, 0)
hbox3 = QHBoxLayout(self.accountposition)
hbox3.addWidget(self.deal_table)
hbox3.setContentsMargins(0, 0, 0, 0)
hbox = QHBoxLayout()
hbox.addWidget(self.abitragerecore)
hbox.setContentsMargins(0, 0, 0, 0)
self.frame.setLayout(hbox)
hbox4 = QHBoxLayout()
hbox4.addWidget(self.frame)
hbox4.setContentsMargins(0, 0, 0, 0)
self.setLayout(hbox4)
self.setContentsMargins(2, 2, 0, 0)
self.abitragerecore.currentChanged.connect(self.getTableData)
def getTableData(self):
try:
cmdDict = {0: 'queryinvestposition', 1: 'queryentrustorders', 2: 'querybizorder'}
cmd = cmdDict[self.abitragerecore.currentIndex()]
send_data = {
"head": {"cmd": cmd, "seq": 1, "recvhandle": self.Recvmsg, "myClickedFuturename": self.beClickedFuturename},
"body": [{"brokerid": self.brokerid, "accountname": self.accountname, "accountid": self.accountid}]
}
send_data = json.dumps(send_data)
SendCmd("{}".format(send_data))
except Exception as e:
logger.info(e)
def handlePushMSG(self, code, msg):
try:
msg = eval(msg)
print('msg', msg)
if msg["head"]["type"] in ["futureorderdata", "orderdata"]:
# 委托挂单推送接口,报单编号(orderid)
a = 0
for i in range(len(self.self.holding_table_data)):
if self.entrust_table_data[i]["orderid"] == msg["body"][0]['order']["orderid"]:
self.entrust_table_data[i] = msg["body"][0]['order'][0]
if a == 0:
self.entrust_table_data.insert(0, msg["body"][0]['order'][0])
self.updateTable(self.entrust_table_data, self.entrust_column_list, tableType='entrust')
elif msg["head"]["type"] == "bizdata":
# 成交推送接口,只会增加不会修改
self.deal_table_data.insert(0, msg["body"][0]['order'][0])
self.updateTable(self.deal_table_data, self.deal_column_list, tableType='deal')
except Exception as e:
logger.info(e)
def handleMSG(self, code, msg):
'''回调'''
try:
dict = eval(msg)
# print(dict)
if dict['head']['cmd'] == "queryinvestposition":
# 获取持仓数据
if len(dict['body']) > 0:
if 'position' in dict['body'][0]:
if 'forholdingloop' == dict['head'].get('forholdingloop'):
# print('beClickedFuturename', self.beClickedFuturename)
# print('accountMsg.comboFutures.currentText', self.accountMsg.comboFutures.currentText())
if self.holding_table_data == dict['body'][0]['position'] \
or self.accountMsg.comboFutures.currentText() != self.beClickedFuturename \
or dict['head'].get('loopFuturename') != self.beClickedFuturename:
# print('same as holding data')
pass
else:
holdingData = CaculateHoldingData(dict['body'][0]['position'])
self.holding_table_data = holdingData.getList()
self.updateTable(self.holding_table_data, self.holding_column_list, tableType='holding')
# print('update holding date')
else:
if self.holding_table_data == dict['body'][0]['position'] \
or dict['head'].get('myClickedFuturename') != self.beClickedFuturename:
# print('same as holding data')
pass
else:
holdingData = CaculateHoldingData(dict['body'][0]['position'])
self.holding_table_data = holdingData.getList()
self.updateTable(self.holding_table_data, self.holding_column_list, tableType='holding')
# print('zhudong update holding date')
elif dict['head']['cmd'] == "queryentrustorders":
# 获取委托数据
if len(dict['body']) > 0:
if 'order' in dict['body'][0]:
if 'forenstrustloop' == dict['head'].get('forenstrustloop'):
if self.entrust_table_data == dict['body'][0]['order'] \
or self.accountMsg.comboFutures.currentText() != self.beClickedFuturename \
or dict['head'].get('loopFuturename') != self.beClickedFuturename:
# print('same as deal data')
pass
else:
self.entrust_table_data = dict['body'][0]['order']
self.updateTable(self.entrust_table_data, self.entrust_column_list, tableType='entrust')
else:
if self.entrust_table_data == dict['body'][0]['order'] \
or dict['head'].get('myClickedFuturename') != self.beClickedFuturename:
# print('same as deal data')
pass
else:
self.entrust_table_data = dict['body'][0]['order']
self.updateTable(self.entrust_table_data, self.entrust_column_list, tableType='entrust')
elif dict['head']['cmd'] == "querybizorder":
# 获取成交数据
if len(dict['body']) > 0:
if 'biz' in dict['body'][0]:
if 'fordealloop' == dict['head'].get('fordealloop'):
if self.deal_table_data == dict['body'][0]['biz'] \
or self.accountMsg.comboFutures.currentText() != self.beClickedFuturename \
or dict['head'].get('loopFuturename') != self.beClickedFuturename:
pass
else:
self.deal_table_data = dict['body'][0]['biz']
self.updateTable(self.deal_table_data, self.deal_column_list, tableType='deal')
else:
if self.deal_table_data == dict['body'][0]['biz'] \
or dict['head'].get('myClickedFuturename') != self.beClickedFuturename:
pass
else:
self.deal_table_data = dict['body'][0]['biz']
self.updateTable(self.deal_table_data, self.deal_column_list, tableType='deal')
if dict["head"]["cmd"] == "accountmsg":
# 获取期货账号信息数据
if len(dict['body']) > 0:
self.tlock.acquire()
self.brokerid = dict["body"][0]["brokerid"]
self.accountname = dict["body"][0]["accountname"]
self.accountid = dict["body"][0]["accountid"]
self.beClickedFuturename = dict["body"][0]["futurename"]
# print('beClickedFuturename', self.beClickedFuturename)
# print('before currentText', self.accountMsg.comboFutures.currentText())
self.tlock.release()
self.clearTable()
self.getTableData()
if self.startTreadingFlag == 1:
self.startTreadingFlag += 1
# self.realTimerefreshData()
if dict["head"]["cmd"] == "refreshTableData":
self.clearTable()
self.getTableData()
time.sleep(1)
AccountMsg.getcapital(self.accountid, self.brokerid, self.accountname)
except Exception as e:
logger.info(e)
def clearTable(self):
"""清空表格"""
if self.abitragerecore.currentIndex() == 0:
self.updateTable([], self.holding_column_list, tableType='holding')
elif self.abitragerecore.currentIndex() == 1:
self.updateTable([], self.entrust_column_list, tableType='entrust')
elif self.abitragerecore.currentIndex() == 2:
self.updateTable([], self.deal_column_list, tableType='deal')
def realTimerefreshData(self):
t1 = threading.Thread(target=self.ThreadingRefreshCurrentData)
t1.setDaemon(True)
t1.start()
def ThreadingRefreshCurrentData(self):
"""refresh data"""
while True:
try:
if self.brokerid and self.accountname and self.accountid:
self.ThreadingRefreshData()
time.sleep(1.5)
except Exception as e:
logger.info(e)
def ThreadingRefreshData(self):
"""refresh data"""
cmdDict = {0: 'queryinvestposition', 1: 'queryentrustorders', 2: 'querybizorder'}
cmd = cmdDict[self.abitragerecore.currentIndex()]
send_data = {
"head": {"cmd": cmd, "seq": 1, "recvhandle": self.Recvmsg,
"fordealloop": "fordealloop", "loopFuturename": self.beClickedFuturename},
"body": [{"brokerid": self.brokerid, "accountname": self.accountname, "accountid": self.accountid}]
}
data = json.dumps(send_data)
SendCmd(data)
def updateTable(self, data_list=None, columnNameList=None, tableType=None):
"""
:function: set the table text
:return: None
"""
if tableType == 'holding':
self.holding_table.setRowCount(len(data_list))
# print('holding data_list', data_list)
for i in range(len(data_list)):
for j in range(len(columnNameList)):
if columnNameList[j] == 'sum_holding': # 总仓
res = data_list[i]['sum_holding']
elif columnNameList[j] == 'sum_useful': # 可用
res = data_list[i]['sum_holding']
elif columnNameList[j] == 'now_holding': # 今仓
if data_list[i].get('exchangeid') in ['shfe', 'ine']:
if data_list[i]['datetype'] == '1':
res = data_list[i]['position']
else:
res = 0
else:
res = data_list[i].get('todayposition')
elif columnNameList[j] == 'now_useful': # 今可用
if data_list[i].get('exchangeid') in ['shfe', 'ine']:
if data_list[i]['datetype'] == '1':
res = data_list[i]['position']
else:
res = 0
else:
res = data_list[i].get('todayposition')
else:
res = self.TransformData(columnNameList[j], data_list[i][columnNameList[j]],
tableType=tableType)
newitem = QTableWidgetItem('{}'.format(res))
newitem.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
# 为持仓表格内添加数据
self.holding_table.setItem(i, j, newitem)
self.holding_table.setRowHeight(i, 35)
elif tableType == 'entrust':
self.entrust_table.setRowCount(len(data_list))
# print('entrust data_list', data_list)
for i in range(len(data_list)):
for j in range(len(columnNameList)):
if columnNameList[j] == 'can_return':
# 可撤
if data_list[i]['orderstatus'] != 4:
res = data_list[i]['amount'] - data_list[i]['bizvolume']
else:
res = 0
elif columnNameList[j] == 'had_return':
# 已撤单
if data_list[i]['orderstatus'] in [1, 3]:
res = data_list[i]['amount'] - data_list[i]['bizvolume']
else:
res = 0
else:
res = self.TransformData(columnNameList[j], data_list[i][columnNameList[j]], tableType=tableType)
newitem = QTableWidgetItem('{}'.format(res))
newitem.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
# 为委托表格内添加数据
self.entrust_table.setItem(i, j, newitem)
self.entrust_table.setRowHeight(i, 35)
elif tableType == 'deal':
self.deal_table.setRowCount(len(data_list))
# print('deal data_list', data_list)
for i in range(len(data_list)):
for j in range(len(columnNameList)):
res = self.TransformData(columnNameList[j], data_list[i][columnNameList[j]], tableType=tableType)
newitem = QTableWidgetItem('{}'.format(res))
newitem.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
# 为成交表格内添加数据
self.deal_table.setItem(i, j, newitem)
self.deal_table.setRowHeight(i, 35)
def TransformData(self, k, v, tableType=None):
"""根据数据状态转换格式"""
orderStatusMap = {-1: '初始状态', 0: '挂单中', 1: '全撤', 2: '部分成交', 3: '全部成交', 4: '废单', 5: '过期', 6: '部分撤单'}
dirMap = {'open': '开仓', 'close': '平仓', 'closetoday': '今平', 'closeyesterday': '平昨',
'autoclose': '自动平仓', 'autoopenclose': '自动开平'}
hedgeMap = {'speculation': '投机', 'hedge': '套保'}
sideMap = {'buy': '买入', 'sell': '卖出'}
if tableType == 'holding':
directMap = {2: '多', 3: '空'}
hedgeMap = {1: '投机', 3: '套保'}
if k == 'direct':
return directMap[int(v)]
elif k == 'hedge':
return hedgeMap[int(v)]
elif k == 'varityid':
return 'CF'
else:
return v
elif tableType in ['entrust', 'deal']:
if k == 'direct':
return dirMap[v]
elif k == 'hedge':
return hedgeMap[v]
elif k == 'side':
return sideMap[v]
elif k == 'orderstatus':
return orderStatusMap[int(v)]
else:
return v
class CaculateHoldingData():
def __init__(self, data=None):
self.returnList = []
self.data = data
self.exchangeName = None
while self.data.__len__() > 1:
self.handle()
if self.data.__len__() != 0:
self.data[0]['sum_holding'] = self.data[0]['position']
self.caculte(data[0])
self.returnList.extend(self.data)
# print(len(self.returnList), self.returnList)
def getList(self):
return [self.returnList[i] for i in range(len(self.returnList)) if self.returnList[i]['sum_holding'] != 0]
# return self.returnList
def handle(self):
for i in range(1, len(self.data)):
self.data[i]['sum_holding'] = self.data[i]['position']
if self.data[0]['instrumentid'] == self.data[i]['instrumentid'] and \
self.data[0]['direct'] == self.data[i]['direct'] and self.data[0]['hedge'] == self.data[i]['hedge']:
res = self.caculte(self.data[i], self.data[0])
self.returnList.append(res)
self.data.remove(self.data[i])
self.data.remove(self.data[0])
return
self.data[0]['sum_holding'] = self.data[0]['position']
res = self.caculte(self.data[0])
self.returnList.append(res)
self.data.remove(self.data[0])
def caculte(self, data1=None, data2=None):
import re
st = data1['instrumentid']
instrumentName = ''.join(re.findall(r'[A-Za-z]', st))
instrumenNum = returntradeunit(instrumentName)
self.exchangeName = returnexchid(instrumentName)
# print('instrumentName', instrumentName, 'exchangeName', self.exchangeName, 'instrumenNum', instrumenNum)
if self.exchangeName in ['SHFE', 'INE']:
# if data1['exchangeid'] in ['shfe', 'ine']:
# 上期,能源
if data1 and data2:
# 总仓 = 今仓 + 昨仓
sum_holding = data1['position'] + data2['position']
data1['sum_holding'] = sum_holding
# 开仓均价
if sum_holding != 0 and instrumenNum != 0:
data1['opencost'] = round((data1['opencost'] + data2['opencost']) / sum_holding / instrumenNum, 2)
# 持仓均价
data1['positioncost'] = round((data1['positioncost'] + data2['positioncost']) / sum_holding / instrumenNum, 2)
# 持仓盈亏
data1['positionprofit'] = data1['positionprofit'] + data2['positionprofit']
# 平仓盈亏
data1['closeprofit'] = data1['closeprofit'] + data2['closeprofit']
# 盯市盈亏
data1['closeprofitbydate'] = data1['closeprofitbydate'] + data2['closeprofitbydate']
# 逐笔盈亏
data1['closeprofitbytrade'] = data1['closeprofitbytrade'] + data2['closeprofitbytrade']
# 保证金
data1['usemargin'] = data1['usemargin'] + data2['usemargin']
# 手续费
data1['commission'] = data1['commission'] + data2['commission']
# 总可用
# data1['sum_useful'] = sum_holding
# 今仓
data1['position'] = data1['position'] if data1['datetype'] == '1' else data2['position']
# 今可用
data1['shortfrozen'] = data1['shortfrozen'] if data1['datetype'] == '1' else data2['shortfrozen']
data1['longfrozen'] = data1['longfrozen'] if data1['datetype'] == '1' else data2['longfrozen']
data1['datetype'] = '1'
# data1['now_useful'] = data1['position']
# data1['now_holding'] = data1['position']
else:
# 总仓 = 今仓 + 昨仓
sum_holding = data1['position']
data1['sum_holding'] = sum_holding
# 开仓均价
if sum_holding != 0 and instrumenNum != 0:
data1['opencost'] = round(data1['opencost'] / sum_holding / instrumenNum, 2)
# 持仓均价
data1['positioncost'] = round(data1['positioncost'] / sum_holding / instrumenNum, 2)
# data1['sum_useful'] = data1['position']
# data1['now_useful'] = data1['position']
# data1['now_holding'] = data1['position']
else:
# 总仓 = 今仓 + 昨仓
sum_holding = data1['position']
data1['sum_holding'] = sum_holding
# 开仓均价
if sum_holding != 0 and instrumenNum != 0:
data1['opencost'] = round(data1['opencost'] / sum_holding / instrumenNum, 2)
# 持仓均价
data1['positioncost'] = round(data1['positioncost'] / sum_holding / instrumenNum, 2)
# data1['sum_useful'] = data1['position']
# data1['now_useful'] = data1['position']
# data1['now_holding'] = data1['position']
return data1
class TableWidget(QTableWidget):
def __init__(self, ColumnName=None, dictWidthList=None):
super(TableWidget, self).__init__()
self.ColumnName = ColumnName
self.dictWidthList = dictWidthList
self.initUi()
def initUi(self):
self.font5 = QFont("微软雅黑")
pointsize5 = self.font5.pointSize()
self.font5.setPixelSize(pointsize5 * 90 / 72)
self.setAlternatingRowColors(True) # 隔行换色
self.setStyleSheet(Qss.table_style) # 设置样式
self.horizontalHeader().setStyleSheet(Qss.table_header_style) # 设置表头背景色和字体颜色
# self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.verticalScrollBar().setStyleSheet(Qss.table_vertical_style)
self.horizontalScrollBar().setStyleSheet(Qss.table_horizontal_style)
self.setFrameShape(QFrame.NoFrame) # 无边框
self.setShowGrid(1) # 无网格
self.setFont(self.font5)
self.verticalHeader().setVisible(0) # 隐藏表头
# deal_table.horizontalHeader().setVisible(0) # 隐藏表头
self.setEditTriggers(QAbstractItemView.NoEditTriggers) # 禁止对表格编辑
# self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.setSelectionBehavior(QAbstractItemView.SelectRows) # 单行选择
self.horizontalHeader().setDefaultAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.horizontalHeader().setMinimumHeight(35)
self.setFocusPolicy(Qt.NoFocus) # 去除选中虚线
self.setSelectionMode(QAbstractItemView.SingleSelection) # 单选
self.horizontalHeader().setSectionsClickable(False) # 水平方向表头不可点击
self.horizontalHeader().setStretchLastSection(True)
# table.setShowGrid(0) # 去表格线
column1 = self.setColumnCount(len(self.ColumnName)) # 设置列数
self.setHorizontalHeaderLabels(self.ColumnName) # 设置行名称
# 滚动条以像素滚动
self.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
self.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
# 获取屏幕的缩放比例
hDC = win32gui.GetDC(0)
dpi = win32print.GetDeviceCaps(hDC, win32con.LOGPIXELSX)
self.desktop = QApplication.desktop()
self.screenRect = self.desktop.screenGeometry()
self.height = self.screenRect.height()
self.width = self.screenRect.width()
# 设置列宽
if dpi >= 144:
widthList = self.dictWidthList[144]
for i in range(len(widthList)):
self.setColumnWidth(i, widthList[i])
elif dpi >= 120:
widthList = self.dictWidthList[120]
for i in range(len(widthList)):
self.setColumnWidth(i, widthList[i])
elif dpi == 96:
widthList = self.dictWidthList[96]
for i in range(len(widthList)):
self.setColumnWidth(i, widthList[i])
if __name__ == '__main__':
# 创建应用程序和对象
app = QApplication(sys.argv)
ex = RecordMsg()
ex.show()
sys.exit(app.exec_())
import json
import sys
from PyQt5.QtWidgets import QTabWidget, QWidget, QApplication, QComboBox, QHBoxLayout, QLabel
from Log.logg import logger
from Main.Views.Easytrade.easytrademanage.recordmsg import RecordMsg
from Main.WebsocketClient.setting import sendToLocalHost, SendCmd, CBEvent, setCB
class AccountMsg(QWidget, CBEvent):
def __init__(self):
super(AccountMsg, self).__init__()
self.setWindowTitle("账户信息")
# 建立ws
self.Recvmsg = "AccountMsg"
setCB(self.Recvmsg, self.recvmsgSign) # 设置回调
self.brokerid_list = []
self.accountname_list = []
self.accountid_list = []
self.futurename_list = []
self.initUi()
def initUi(self):
self.equityLabel = QLabel()
self.equityLabel.setText('权益:')
self.equityNumLabel = QLabel()
self.equityNumLabel.setText('')
self.usefulLabel = QLabel()
self.usefulLabel.setText('可用:')
self.usefulNumLabel = QLabel()
self.usefulNumLabel.setText('')
self.comboFutures = QComboBox() # 期货账户信息下拉框
self.comboFutures.setStyleSheet("min-width:50px;")
hbox = QHBoxLayout()
hbox.addStretch(10)
hbox.addWidget(self.equityLabel)
hbox.addWidget(self.equityNumLabel)
hbox.addStretch(3)
hbox.addWidget(self.usefulLabel)
hbox.addWidget(self.usefulNumLabel)
hbox.addStretch(4)
hbox.addWidget(self.comboFutures)
hbox.addStretch(2)
self.setLayout(hbox)
self.setContentsMargins(0, 0, 0, 0)
self.get_all_futures_account()
self.comboFutures.currentIndexChanged.connect(self.sendDataListToRecordmsg)
def get_all_futures_account(self):
"""
查询所有的期货账户信息
:return:
"""
self.futureAccounts = {
"head": {"cmd": "queryaccountmsg", "seq": 1, "recvhandle": self.Recvmsg, "dis": "queryfuture"},
"body": [{"querymsg": 'queryfuturetradeaccount'}]
}
self.futureAccounts = json.dumps(self.futureAccounts)
SendCmd('{}'.format(self.futureAccounts))
def handleMSG(self, code, msg):
'''回调'''
try:
dict = eval(msg)
# print(dict)
if dict['head']['cmd'] == "queryaccountmsg" and dict['body']:
self.brokerid_list = [dict['body'][i]['brokerid'] for i in range(len(dict['body']))]
self.accountname_list = [dict['body'][i]['accountname'] for i in range(len(dict['body']))]
self.accountid_list = [dict['body'][i]['accountid'] for i in range(len(dict['body']))]
self.futurename_list = [dict['body'][i]['futurename'] for i in range(len(dict['body']))]
addItems_list = [str(self.futurename_list[i]) + '-' + str(self.brokerid_list[i]) for i in
range(len(self.brokerid_list))]
self.comboFutures.addItems(addItems_list)
if dict["head"]["cmd"] == "querycapital":
if "available" in dict["body"][0]:
self.equityNumLabel.setText(str(dict["body"][0]['available'] + dict["body"][0]['currmargin'] + dict["body"][0]['frozencash']))
self.usefulNumLabel.setText(str(dict["body"][0]['available']))
except Exception as e:
logger.info(e)
def getcapital(self, accountid, brokerid, accountname):
SendCmd('{}'.format(json.dumps({
"head": {"cmd": "querycapital", "seq": 1, "recvhandle": self.Recvmsg},
"body": [{"accountid": accountid, "brokerid": brokerid, "accountname": accountname,
"password": 123}]})))
def sendDataListToRecordmsg(self):
currentIndex = self.comboFutures.currentIndex()
brokerid = self.brokerid_list[currentIndex]
accountname = self.accountname_list[currentIndex]
accountid = self.accountid_list[currentIndex]
sendToLocalHost("{}".format({"head": {"cmd": "accountmsg", "seq": 1, "recvhandle": "RecordMsg"},
"body": [
{"brokerid": brokerid, "accountname": accountname, "accountid": accountid}]}))
self.getcapital(accountid, brokerid, accountname)
if __name__ == '__main__':
# 创建应用程序和对象
app = QApplication(sys.argv)
ex = AccountMsg()
ex.show()
sys.exit(app.exec_())
3.创建Qss文件(相当于web端的css)
Qss.py
class Qss:
main_frame = "background-color:#fff;"
red_frame = "background-color:red;"
green_frame = "background-color:green;"
blue_frame = "background-color:bule;"
orange_frame = "background-color:orange;"
table_frame = 'background-color:#f0f0f0'
record_frame_style = "#frame{background-color:#e2e2e2;border-left:1px solid #828790;border-top:1px solid #828790;}"
abitragerecoreStyle = "QTabBar::tab{min-height: 30px; min-width: 80px;background-color:#e2e2e2;margin-top:0px;border-bottom:0px;border-right:1px solid #828790;}" \
"QTabBar::tab:hover {background: rgb(0, 180, 255);}" \
"QTabBar::tab:selected{background-color:#fff;color:#000;}" \
"QWidget{border:0px;}"
table_style = "QTableWidget{alternate-background-color:#DDE4EB;background:#f1f8ff;color:#000;selection-background-color:grey;border:1px solid #828790;border-left:0px;gridline-color:#f0f0f0;}" \
"QTableCornerButton::section{background-color:#161B2E;}" \
"QTableView::item:selected{background:#9ecee7;border:0px solid red;border-left:0px;border-right:0px;}"
table_header_style = "QHeaderView::section" \
"{background:#f0f0f0;color:#000;border:0px;font:15px '微软雅黑';}"
table_vertical_style = "QScrollBar{background:transparent; width: 10px;}" \
"QScrollBar::handle{background:lightgray; border:2px solid transparent; border-radius:5px;}" \
"QScrollBar::handle:hover{background:gray;}" \
"QScrollBar::sub-line{background:transparent;}" \
"QScrollBar::add-line{background:transparent;}"
table_horizontal_style = "QScrollBar{background:transparent; height: 15px;}" \
"QScrollBar::handle{background:gray; border:2px solid transparent; border-radius:5px;}" \
"QScrollBar::handle:hover{background:gray;}" \
"QScrollBar::sub-line{background:transparent;}" \
"QScrollBar::add-line{background:transparent;}"