前言
续接上篇,上篇完成了一个收集基金净值的功能模块,本篇再次基础上进行包装,产出一个可用的基金助手。
实现
在获取到基金的昨日收盘净值、当天实时净值估算等数据后,据此就可以计算出我们所关心的数据了。 分两种情况,有持仓和未持仓(关注)基金。
有持仓的则根据自己的持仓情况配置(持仓成本价+持仓成本金额或持仓成本价+持仓份额),然后就可以查看当天盈亏、涨跌幅以及估算等基金数据了。
没有持仓的可以按持仓数为0配置,也可以直接配置到列表,如此可以持续关注表现。
为支持配置,设计配置项如下:
{
"data_update_timespan": 300,
"myfunds": [
{
"code": "006229",
"price": 2.1514,
"amount": 0.00,
"cost": 18620
},
{
"code": "012414",
"price": 0.00,
"amount": 0.00,
"cost": 0
}
],
"monitors": ["005669", "000689", "001933"]
}
其中:
data_update_timespan:刷新基金数据的时间间隔,单位为秒;myfunds:我的持仓基金数据code:基金代码price:持仓成本价amount:持仓份额cost:持仓金额
monitors:关注的基金列表
设计创建一个子线程定时去更新基金数据,主线程支持update刷新基金数据,并支持命令行指令。
为了显示美观,支持红绿色,引入prettytable表格显示数据,引入colorama支持红绿色,红涨绿跌。
基金代码前的*表示持仓基金,且最后一行为持仓数据汇总。
助手代码
# coding : utf-8
import threading
import time
import sys
import json
import os
import datetime
import fund_info
import colorama
from prettytable import PrettyTable
def get_fund_info(fund):
"""
获取基金信息
:param fund: 基金配置
:return: 基金对象
"""
try:
code = fund['code']
if 'cost' in fund and float(fund['cost']) >= 0.01:
info = fund_info.FundInfo.get_info_with_cost(code, fund['price'], fund['cost'])
else:
info = fund_info.FundInfo.get_info_with_amount(code, fund['price'], fund['amount'])
return info
except Exception as e:
print('获取基金异常', Exception, e)
return None
def bk_update_info(config, run_flag=False, wait=1):
"""
定时刷新基金详情信息
:param wait:
:param config:
:param run_flag:
:return:
"""
funds = config['myfunds']
wait = config['data_update_timespan']
tab = PrettyTable()
tab.field_names = ['序号', '基金代码', '基金名称', '日涨跌幅', '今日盈亏', '净值估算', '基金净值', '总盈亏估算', '收益率估算',
'持仓市值', '持仓盈亏', '总收益率', '持仓成本', '持仓金额', '持仓份额', '更新时间']
colorama.init(autoreset=True)
while True:
# 更新信息
infos = []
for fc in funds:
fund = get_fund_info(fc)
if fund is None:
continue
infos.append(fund.info)
# 添加汇总信息
if len(infos) > 0:
total = {}
for k, v in infos[-1].items():
total[k] = '-'
total['基金代码'] = '*'*6
total['基金名称'] = '汇总'
total['今日盈亏'] = 0.0
total['持仓盈亏'] = 0.0
total['持仓市值'] = 0.0
total['持仓金额'] = 0.0
total['持仓金额'] = 0.0
total['总盈亏估算'] = 0.0
total['持仓成本'] = '-'
total['日涨跌幅'] = '0.00'
total['更新时间'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
for info in infos:
total['今日盈亏'] += float(info['今日盈亏'])
total['持仓盈亏'] += float(info['持仓盈亏'])
total['总盈亏估算'] += float(info['总盈亏估算'])
total['持仓市值'] += float(info['持仓市值'])
total['持仓金额'] += float(info['持仓金额'])
if abs(total['持仓盈亏']) > 0.00001:
total['总收益率'] = '{0:.4f}'.format(100 * total['持仓盈亏'] / total['持仓金额'])
total['收益率估算'] = '{0:.4f}'.format(total['总盈亏估算'] * 100 / total['持仓金额'])
infos.append(total)
# 组装显示信息
i = 0
tab.clear_rows()
for info in infos:
i += 1
row = [str(i)]
# 我的基金
if float(info['持仓市值']) > 0.00001:
info['基金代码'] = '*' + info['基金代码']
# 字段处理
for field in tab.field_names[1:]:
if field in info:
row.append(info[field])
else:
row.append('-')
# 设置基金红绿颜色
if float(info['日涨跌幅']) > 0.0 or float(info['今日盈亏']) > 0.0:
row[0] = colorama.Fore.RED + row[0]
elif float(info['日涨跌幅']) < 0.0 or float(info['今日盈亏']) < 0.0:
row[0] = colorama.Fore.GREEN + row[0]
row[-1] += colorama.Fore.RESET + colorama.Back.RESET + colorama.Style.RESET_ALL
tab.add_row(row)
# 显示信息
os.system('cls')
print(tab, end='\n>')
if not run_flag:
break
time.sleep(wait)
if __name__ == '__main__':
# 基金配置
config = {
"data_update_timespan": 300,
"myfunds": [
{
"code": "006229",
"price": 2.4514,
"amount": 0.00,
"cost": 250000
},
{
"code": "012414",
"price": 0.00,
"amount": 0.00,
"cost": 0
}
]
}
argv = sys.argv
if len(argv) > 1:
with open(argv[1]) as fd:
config = json.load(fd)
run_flag = True
# 配置特殊处理
funds = config['myfunds']
if 'monitors' in config and len(config['monitors']) > 0:
for fund in config['monitors']:
funds.append({'code': fund, 'price': 0.0, 'amount': 0.0, 'cost': 0.0})
# 获取数据线程
wait = config['data_update_timespan']
bk = threading.Thread(target=bk_update_info, args=(config, run_flag, wait))
bk.start()
time.sleep(1)
while True:
option = input('>')
if option == 'update':
bk_update_info(config)
elif option == 'quit':
run_flag = False
else:
try:
os.system(option)
except Exception as e:
print('异常', Exception, e)
效果
+------+----------+--------------------------+----------+------------+----------+----------+------------+------------+-------------+------------+----------+----------+----------+----------+------------------+
| 序号 | 基金代码 | 基金名称 | 日涨跌幅 | 今日盈亏 | 净值估算 | 基金净值 | 总盈亏估算 | 收益率估算 | 持仓市值 | 持仓盈亏 | 总收益率 | 持仓成本 | 持仓金额 | 持仓份额 | 更新时间 |
+------+----------+--------------------------+----------+------------+----------+----------+------------+------------+-------------+------------+----------+----------+----------+----------+------------------+
| 1 | *006229 | 中欧医疗创新股票C | -1.21 | -1887.3772 | 2.2302 | 2.2576 | 73621.4878 | 92.0269 | 155508.8611 | 75508.8650 | 94.3861 | 1.1614 | 80000.00 | 68882.38 | 2021-12-24 15:00 |
| 2 | 012414 | 招商中证白酒指数(LOF)C | 0.52 | 0.0000 | 1.4162 | 1.4088 | 0.0000 | - | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.00 | 0.00 | 2021-12-24 15:00 |
| 3 | 005669 | 前海开源公用事业股票 | -1.64 | 0.0000 | 3.6775 | 3.7387 | 0.0000 | - | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.00 | 0.00 | 2021-12-24 15:00 |
| 4 | 000689 | 前海开源新经济混合A | -3.52 | 0.0000 | 3.4593 | 3.5854 | 0.0000 | - | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.00 | 0.00 | 2021-12-24 15:00 |
| 5 | 001933 | 华商新兴活力混合 | -3.41 | 0.0000 | 2.8679 | 2.9690 | 0.0000 | - | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.00 | 0.00 | 2021-12-24 15:00 |
| 6 | 001822 | 华商智能生活灵活配置混合 | -3.62 | 0.0000 | 2.9944 | 3.1070 | 0.0000 | - | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.00 | 0.00 | 2021-12-24 15:00 |
| 7 | 001704 | 国投瑞银进宝灵活配置混合 | -4.13 | 0.0000 | 4.2885 | 4.4732 | 0.0000 | - | 0.0000 | 0.0000 | 0.0000 | 0.0000 | 0.00 | 0.00 | 2021-12-24 15:00 |
| 8 | ******* | 汇总 | 0.00 | -1887.3772 | - | - | 73621.4878 | 92.0269 | 155508.8611 | 75508.865 | 94.3861 | - | 80000.0 | - | 2021-12-24 15:38 |
+------+----------+--------------------------+----------+------------+----------+----------+------------+------------+-------------+------------+----------+----------+----------+----------+------------------+