python写炒股软件_Python桌面股票工具

5f0bfb060597

微信图片_20190725142216.png

开发一个桌面显示股票、可转债、ETF行情信息的桌面工具,这样你再也不用一直拿着手机不放了。

需要用到的python库:

tkinter 绘制界面

requests 网络请求(如果没有这个库,就pip install requests)

思路:

主要是通过

程序不知道怎么上传,就贴一下代码吧。

app.py

import tkinter as tk

from controls import *

from fileutil import *

# from tray import *

import json

lass Application(tk.Frame):

def __init__(self, master=None, file=''):

super().__init__(master)

self.file = file

self.rendered = False

self.items = []

self.config = {}

self.width = 500

self.height = 500

self.master = master

self.childrenFrame = []

self.master.geometry( str(self.width) + "x" + str(self.height))

self.init()

self.bind('', self.destoryEvent)

# self.bind('', self.createEvent)

self.pack(ipadx=0, ipady=0, padx=0, pady=0, fill='both')

def create_widgets(self):

for i in range(len(self.items)):

item = self.items[i]

frame = ItemFrame(self, text= item['name'], labelanchor='n')

frame.name = item['name']

frame.setItems(item['items'])

frame.pack(fill='both')

self.childrenFrame.append(frame)

def init(self):

print("------------create------------------")

if self.rendered:

return

if self.file != '':

txt = readFile(self.file)

self.config = json.loads(txt)

self.items = self.config['items']

self.master.geometry(self.config['geometry'])

self.create_widgets()

self.rendered = True

#托盘

# menu_options = (

# # ('Say Hello', icons.next(), hello),

# # ('Switch Icon', None, switch_icon),

# ('A sub-menu', None, None),

# )

# self.tray = SysTrayIcon('./icon.ico', 'Yinc', menu_options, on_quit= self.quit, default_menu_index=1)

def quit(self, event):

pass

def destoryEvent(self, event):

config = {}

items = []

for i in range(len(self.childrenFrame)):

_frame = self.childrenFrame[i]

item = {}

item['name'] = _frame.name

item['items'] = _frame.items

items.append(item)

config['geometry'] = self.master.winfo_geometry()

config['title'] = self.master.winfo_name()

config['items'] = items

txt = json.dumps(config)

print(txt)

writeToFile(self.file, txt)

print("------------destory------------------")

root = tk.Tk()

_file = 'config.txt'

app = Application(master=root, file=_file)

app.mainloop()

controls.py

########################################

# TODO: 1、增加成本显示

# 2、增加提醒功能

#

########################################

import tkinter as tk

import net as httpNet

import threading

import time

from item import *

from log import *

log = Logger(level='debug')

class ItemFrame(tk.LabelFrame):

def __init__(self, master=None, cnf={}, **kw):

super().__init__(master=master, cnf=cnf, **kw)

self.name = ""

self.items = []

self.itemEls = []

self._initMenu()

self.bind("", self.showMenu)

self.run()

def showMenu(self, event):

self.menubar.post(event.x_root, event.y_root)

def _initMenu(self):

self.menubar = tk.Menu(self)

# self.menubar.add_separator()

self.menubar.add_command(label='增加', command= self.addItem)

def addItem(self, item = []):

if len(item) == 0:

item = ['', '', '', '', '', '']

self.items.append(item)

_itemElement = Item(self)

_itemElement.setItem(item)

_itemElement.destroyListener = self.itemDestory

self.itemEls.append(_itemElement)

def setItems(self, items):

_len = len(items)

self.items = items

self.itemEls = []

if _len == 0:

self.addItem()

return

for i in range(_len):

_item = items[i]

_itemElement = Item(self)

_itemElement.setItem(_item)

_itemElement.destroyListener = self.itemDestory

self.itemEls.append(_itemElement)

def run(self):

th = threading.Thread(target=self._updateItems ,args=(1,))

# th.setDaemon(True)#守护线程

th.daemon = True

th.start()

def _updateItems(self, code):

while(True):

# print("=========update============")

_codes = []

#拼装code

for i in range(len(self.itemEls)):

_ele = self.itemEls[i]

if len(_ele.item) > 1 and _ele.item[0] != '':

_code = _ele.item[0]

_codes.append(_code)

log.logger.info( "=========update============ %s", (_codes))

if len(_codes) > 0:

try:

_codeStr = ",".join(_codes)

items = httpNet.getStockInfo(_codeStr)

if len(items) == 0:

return

log.logger.info( "=========req============ %s", (items))

for i in range(len(items)):

_item = items[i]

for j in range(len(self.itemEls)):

_ele = self.itemEls[j]

_eleItem = _ele.item

if _item[0] == _eleItem[0]:

_eleitem =_ele.item

_item[4] = _eleitem[4]

_ele.setItem(_item)

self.items[j] = _item

break

except Exception as e:

log.logger.error(e)

# self.setItem(items[0])

time.sleep(2)

pass

def itemDestory(self, item):

for i in range(len(self.items)):

_item = self.items[i]

if item[0] == _item[0]:

self.items.remove(item)

break

# print(self.items)

log.logger.info( 'destory:', self.items )

pass

net.py

import requests as rq

"""

http://hq.sinajs.cn/list=sz002732

0:”大秦铁路”,股票名字;

1:”27.55″,今日开盘价;

2:”27.25″,昨日收盘价;

3:”26.91″,当前价格; """

def getStockInfo(code):

_url = 'http://hq.sinajs.cn/list=%s' % code

resp = rq.get(_url, timeout= 3)

text = resp.text.strip()

lines = text.split(';\n')

items = []

for i in range(len(lines)):

line = lines[i]

line = line.replace('var hq_str_','').replace('"', '')

itemArr = line.split("=")

itemArr2 = itemArr[1].split(",")

code = itemArr[0]

caption = itemArr2[0]

op = float(itemArr2[1])

yp = itemArr2[2]

np = float(itemArr2[3])

yp = float(yp)

rise = format( ((( np - yp) / yp) * 100), '.3f' ) + '%'

item = [code, caption, rise, np, yp, op]

items.append(item)

# print(items)

return items

if __name__ == '__main__':

getStockInfo('sz002732,sz002304,sh110051,sh512170')

item.py

import tkinter as tk

import net as httpNet

import threading

import time

from log import *

log = Logger(level='debug')

class Item(tk.Frame):

# {caption, val, }

# 001 0.5%

def __init__(self, master=None):

super().__init__(master=master)

self.codeVal = tk.StringVar()

self.costVal = tk.DoubleVar()

self.render = False

self.item = []

self.grid()

self.create_widgets()

self.destroyListener = None

# self.run()

def create_widgets(self):

# ,background='gray' ,foreground='red'

self.code = tk.Label(self, textvariable= self.codeVal, justify='center',width=10)

self.code.grid(row=0, column=0)

self.code.bind('', self.codeClick)

self.caption = tk.Label(self, text="Item1", justify='center',width=10)

self.caption.grid(row=0, column=1)

self.rise = tk.Label(self, text="Item1", justify='center',width=8)

self.rise.grid(row=0, column=2)

self.nowprice = tk.Label(self, text="Item1", justify='center',width=8)

self.nowprice.grid(row=0, column=3)

self.costPrice = tk.Label(self, textvariable= self.costVal, justify='center',width=8)

self.costPrice.grid(row=0, column=4)

self.costPrice.bind('', self.costClick)

self.costEdit = tk.Entry(self, textvariable=self.costVal)

self.grow = tk.Label(self, text="Item1", justify='center',width=8)

self.grow.grid(row=0, column=5)

self.deleteBtn = tk.Button(self, text="删除", justify='center',width=8)

self.deleteBtn.grid(row=0, column=10)

self.deleteBtn.bind('', self.deleteClick)

self.codeEdit = tk.Entry(self, textvariable=self.codeVal)

def setItem(self, item):

self.item = item

# code

self.codeVal.set(item[0])

# self.code.config(text= item[0])

#caption

self.caption.config(text= item[1])

#rise

self.rise.config(text= item[2], foreground=self.getTextColor(item[2]))

#price

self.nowprice.config(text= item[3])

#成本

if self.render == False:

self.costVal.set(item[4])

#盈利

v = self.getGrow()

self.grow.config(text= v, foreground=self.getTextColor(v))

self.render = True

# self.costPrice.config(text= item[4])

# self.oprice.config(text= item[5])

def getGrow(self):

n = self.item[3]

cost = self.item[4]

if cost == '' or cost is None: cost = 0

if float(cost) == 0:

return '0%'

v = round( (n - cost) * 100 / cost , 2)

return str(v) + '%'

def getTextColor(self, v):

if type(v) == str:

# log.logger.info( "=========color============ %s", (v))

if v == '': v = '0'

v = float(v.replace('%','').replace('--','0'))

if v > 0:

return 'red'

elif v < 0:

return 'blue'

else:

return 'black'

def deleteClick(self,event):

if self.destroyListener != None:

self.destroyListener(self.item)

self.destroy()

pass

def costClick(self, event):

self.costPrice.grid_forget()

self.costEdit.grid(row=0, column=4)

self.costEdit.bind('', self.costOutEdit)

def costOutEdit(self, evet):

self.costEdit.grid_forget()

_val = self.costVal.get()

self.item[4] = _val

self.costPrice.grid(row=0, column=4)

self.costPrice.bind('', self.costClick)

def codeClick(self, event):

self.code.grid_forget()

self.codeEdit.grid(row=0, column=0, padx=5)

self.codeEdit.bind('', self.outEdit)

def outEdit(self, event):

self.codeEdit.grid_forget()

self.item[0] = self.codeVal.get()

self.code.grid(row=0, column=0, padx=5)

self.code.bind('', self.codeClick)

def run(self):

th = threading.Thread(target=self._updateItem ,args=(1,))

th.setDaemon(True)#守护线程

th.start()

def _updateItem(self, code):

while(True):

if len(self.item) > 1 and self.item[0] != '':

_code = self.item[0]

items = httpNet.getStockInfo(_code)

if len(items) == 1:

print(items)

self.setItem(items[0])

print("=========update============")

time.sleep(2)

pass

fileutil

def writeToFile(file, txt):

f = open(file, "w", encoding='utf-8')

f.writelines(txt)

f.close()

def readFile(file):

f = open(file, "r", encoding='utf-8')

lines = f.readlines()

return "".join(lines)

# while line != "":

# f.readlines()

log.py

import logging

from logging import handlers

class Logger(object):

#日志级别关系映射

level_relations = {

'debug':logging.DEBUG,

'info':logging.INFO,

'warning':logging.WARNING,

'error':logging.ERROR,

'crit':logging.CRITICAL

}

def __init__(self,filename='log/log.log',level='info',when='D',backCount=3,fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):

self.logger = logging.getLogger(filename)

format_str = logging.Formatter(fmt)#设置日志格式

self.logger.setLevel(self.level_relations.get(level))#设置日志级别

sh = logging.StreamHandler()#往屏幕上输出

sh.setFormatter(format_str) #设置屏幕上显示的格式

th = handlers.TimedRotatingFileHandler(filename=filename,when=when,backupCount=backCount,encoding='utf-8')#往文件里写入#指定间隔时间自动生成文件的处理器

#实例化TimedRotatingFileHandler

#interval是时间间隔,backupCount是备份文件的个数,如果超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种:

# S 秒

# M 分

# H 小时、

# D 天、

# W 每星期(interval==0时代表星期一)

# midnight 每天凌晨

th.setFormatter(format_str)#设置文件里写入的格式

self.logger.addHandler(sh) #把对象加到logger里

self.logger.addHandler(th)

if __name__ == '__main__':

# log = Logger('all.log',level='debug')

log = Logger(level='debug')

log.logger.debug('debug')

log.logger.info('info')

log.logger.info([1,2,3])

log.logger.warning('警告')

log.logger.error('报错')

log.logger.critical('严重')

Logger('error.log', level='error').logger.error('error')

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值