背景
续接上篇,VSCode的基金插件确实不错,不过盈亏查看用着感觉不对,多次购买同一基金后,基金持仓不会填了,而且我还想要更多的数据项,于是乎,自己倒腾个基金工具。
获取基金信息
获取基金的接口有很多,比如天天基金、腾讯、新浪以及其他证券金融公司网站。
这次我选择天天基金的接口,接口地址为:http://fundgz.1234567.com.cn/js/基金代码.js
接口测试:
GET http://fundgz.1234567.com.cn/js/012414.js HTTP/1.1
测试结果:
HTTP/1.1 200 OK
Last-Modified: Tue, 21 Dec 2021 06:53:19 GMT
Etag: "ed43c7037f6d71:0"
Server: NWS_TCloud_static_msoc2
Date: Tue, 21 Dec 2021 06:54:29 GMT
Expires: Tue, 21 Dec 2021 07:04:29 GMT
Content-Type: application/x-javascript
X-Powered-By: ASP.NET
X-Daa-Tunnel: hop_count=1
Cache-Control: max-age=600
Content-Length: 166
Accept-Ranges: bytes
X-NWS-LOG-UUID: 13644477591170197640
X-Cache-Lookup: Cache Hit
Connection: close
Age: 100
jsonpgz({"fundcode":"012414","name":"招商中证白酒指数(LOF)C","jzrq":"2021-12-20","dwjz":"1.3883","gsz":"1.3767","gszzl":"-0.84","gztime":"2021-12-21 14:50"});
接口返回了基金名称、基金单位净值、基金估值、涨跌幅等信息,因此借此可以封装一个获取基金信息的模块
基金信息获取模块
# coding : utf-8
import requests
import json
import sys
def get_info_fundgz(code, fund):
"""
天天基金获取基金最新信息
:param code: 基金代码
:param fund: 目标基金对象
:return: 无
"""
try:
# 获取信息
url = 'http://fundgz.1234567.com.cn/js/{0}.js'.format(code)
resp = requests.get(url)
if resp.status_code != 200:
return
text = resp.text
# 解析为JSON对象
data = json.loads(text[8:-2])
# 设置信息
info = fund.info
info["基金代码"] = data["fundcode"]
info["基金名称"] = data["name"]
info["日涨跌幅"] = data["gszzl"]
info["净值估算"] = data["gsz"]
info["净值日期"] = data["jzrq"]
info["基金净值"] = data["dwjz"]
info["更新时间"] = data["gztime"]
except:
pass
class FundInfo:
"""
基金信息
"""
def __init__(self, code):
self.code = code
# 基金代码 基金名称 日涨跌幅 净值估算 盈亏估算 更新时间 昨日净值 持仓市值 持仓成本 持仓份额 持仓盈亏
self.info = {}
def set_position_amount(self, price, amount):
"""
设置基金持仓成本价及份额
:param price: 持仓成本价
:param amount: 持仓数量(份额)
:return:
"""
self.info['持仓成本'] = '{0:.4f}'.format(price)
self.info['持仓份额'] = '{0:0.2f}'.format(amount)
self.info['持仓金额'] = '{0:0.2f}'.format(price*amount)
def set_position_cost(self, price, costs):
"""
设置基金持仓成本价及份总成本
:param price: 持仓成本价
:param costs: 持仓金额
:return:
"""
self.info['持仓成本'] = '{0:.4f}'.format(price)
self.info['持仓金额'] = '{0:0.2f}'.format(costs)
self.info['持仓份额'] = '{0:0.2f}'.format(float(self.info['持仓金额'])/float(self.info['持仓成本']))
def fresh(self):
"""
重新获取基金信息,联网
:return:
"""
get_info_fundgz(self.code, self)
try:
if '持仓成本' not in self.info:
self.info['持仓成本'] = '0.0000'
if '持仓份额' not in self.info:
self.info['持仓份额'] = '0.00'
if float(self.info['持仓份额']) > 0.001 and self.info['基金净值'] != self.info['净值估算']:
self.info['今日盈亏'] = '{0:.4f}'.format(float(self.info['持仓份额']) * (float(self.info['净值估算']) - float(self.info['基金净值'])))
else:
self.info['今日盈亏'] = '0.0000'
self.info['持仓市值'] = '{0:.4f}'.format(float(self.info['持仓份额'])*float(self.info['基金净值']))
if self.info['基金净值'] != self.info['持仓成本']:
self.info['持仓盈亏'] = '{0:.4f}'.format(float(self.info['持仓份额']) * (float(self.info['基金净值']) - float(self.info['持仓成本'])))
else:
self.info['持仓盈亏'] = '0.0000'
if float(self.info['持仓份额']) > 0.001:
self.info['总收益率'] = '{0:.4f}'.format(100.0 * (float(self.info['基金净值']) - float(self.info['持仓成本'])) / float(self.info['持仓成本']))
else:
self.info['总收益率'] = '0.0000'
self.info['总盈亏估算'] = '{0:.4f}'.format(float(self.info['今日盈亏']) + float(self.info['持仓盈亏']))
self.info['收益率估算'] = '{0:.4f}'.format(float(self.info['总盈亏估算'])*100/float(self.info['持仓金额']))
except:
pass
@staticmethod
def get_info_with_amount(code, price, amount):
fund = FundInfo(code)
fund.set_position_amount(price, amount)
fund.fresh()
return fund
@staticmethod
def get_info_with_cost(code, price, cost):
fund = FundInfo(code)
fund.set_position_cost(price, cost)
fund.fresh()
return fund
def json_dumps(info):
"""
字典转化为JSON并格式化
:param info:
:return:
"""
return json.dumps(info, ensure_ascii=False, indent=4)
if __name__ == '__main__':
argv = sys.argv
# 测试运行
if len(argv) < 2:
# 持仓成本价+持仓总份额
fund = FundInfo.get_info_with_amount('006229', 0, 0.00)
# 持仓成本价+买入总成本
#fund = FundInfo.get_info_with_cost('006229', 2.4514, 25000)
# 带命令行启动
else:
argv[1] = "FundInfo.get_info_with_cost('006228', 2.4515, 25000)"
fund = eval(argv[1])
result = json_dumps(fund.info)
print(result)
测试执行结果
D:\Study\fund>python fund_info.py
{
"持仓成本": "0.0000",
"持仓份额": "0.00",
"持仓金额": "0.00",
"基金代码": "006229",
"基金名称": "中欧医疗创新股票C",
"日涨跌幅": "1.80",
"净值估算": "2.2735",
"净值日期": "2021-12-20",
"基金净值": "2.2333",
"更新时间": "2021-12-21 14:58",
"今日盈亏": "0.0000",
"持仓市值": "0.0000",
"持仓盈亏": "0.0000",
"总收益率": "0.0000",
"总盈亏估算": "0.0000"
}
收工,下次再包装一下,形成一个可以用的产品...(未完待续)