Python技术迷

用 Python 快速追踪基金的收益情况!

那天晚上十一点多,我在客厅沙发上刷手机,看着基金 App 上一堆红红绿绿的曲线,心里就一个感觉:乱。 单只基金涨跌能看到,但我每个月定投、又在不同平台买,整个组合到底赚了多少、哪只拖后腿,完全没有全局观。

后来我干脆想,那不如用 Python 自己搞一套最简单的“收益仪表盘”,每天一跑,一目了然。今天就把这个东西摊开跟你聊聊,顺便把代码也贴出来,你照着改一下就能用。

我当时是直接在电脑上建了个 fund_positions.csv,放在项目目录里,大概这样:

code,name,shares,cost_price
161725,白酒指数,1000,1.23
501018,新能源车,800,1.80
001500,消费精选,1500,0.95
  • code:基金代码
  • name:你自己方便看的名字
  • shares:当前持有份额
  • cost_price:你的平均持仓成本(可以自己在 App 里看个大概填上)

先别纠结“多笔买入成本怎么精确计算”这种问题,等脚本跑起来你再慢慢抠,这样不容易半途而废。

我一般习惯先写一个特别土但能跑的版本,完全不管优不优雅。比如我们先不连任何接口,假装“当前净值”帮你手动填在代码里,先把计算打通。

import pandas as pd

# 1. 读持仓表
df = pd.read_csv("fund_positions.csv")

# 2. 暂时手动写当前净值(后面再换成接口)
current_nav_map = {
"161725": 1.45,
"501018": 1.60,
"001500": 1.10
}

# 3. 把当前净值映射到 DataFrame 里
df["current_nav"] = df["code"].map(current_nav_map)

# 4. 计算每只基金的数据
df["cost_amount"] = df["shares"] * df["cost_price"]      # 成本金额
df["current_amount"] = df["shares"] * df["current_nav"]  # 当前市值
df["profit"] = df["current_amount"] - df["cost_amount"]  # 浮动盈亏
df["profit_rate"] = df["profit"] / df["cost_amount"]     # 收益率

# 5. 打印看看效果
pd.set_option("display.float_format", lambda x: f"{x:,.2f}")
print(df[["code", "name", "cost_amount", "current_amount", "profit", "profit_rate"]])

# 6. 汇总一下整体
total_cost = df["cost_amount"].sum()
total_value = df["current_amount"].sum()
total_profit = total_value - total_cost
total_rate = total_profit / total_cost

print("\n===== 组合汇总 =====")
print(f"总成本: {total_cost:,.2f}")
print(f"总市值: {total_value:,.2f}")
print(f"总盈亏: {total_profit:,.2f}")
print(f"整体收益率: {total_rate:.2%}")

这个版本虽然“假装”当前净值,但是你一跑,就能立刻看到类似这样的输出(数值我随便举个例子):

    code   name    cost_amount  current_amount    profit  profit_rate
0  161725  白酒指数      1,230.00        1,450.00    220.00        17.89%
1  501018  新能源车      1,440.00        1,280.00   -160.00       -11.11%
2  001500  消费精选      1,425.00        1,650.00    225.00        15.79%

===== 组合汇总 =====
总成本: 4,095.00
总市值: 4,380.00
总盈亏: 285.00
整体收益率: 6.96%

这一步的意义是:把“算收益”这件事拆成了几个很清楚的字段,逻辑完全透明。

上面那种手动填净值的方式,只适合你先验证公式。真正使用肯定得自动拉数据,不然你天天手抄净值会崩溃。

数据来源有很多种:

  1. 你自己每天从平台导出 CSV(有些 App 支持导出交易/持仓明细)
  2. 用第三方库(比如某些基金/股票接口库)
  3. 直接调公开 API(有的基金网站会有 http 接口)

这里我不深入哪家平台接口,用一个“占位函数”的方式写给你,你只要把那一小段替换掉就行,其他逻辑不用动。

比如我们先写一个这样的函数:

import requests

defget_fund_nav(code: str) -> float:
"""
    通过基金代码获取最新净值。
    这里写的是伪代码,你根据自己选的接口改一下就行。
    """

# 举个结构示意,url 换成你实际的
    url = f"https://example.com/fund/nav?code={code}"
    resp = requests.get(url, timeout=5)
    resp.raise_for_status()

    data = resp.json()
# 假设返回结构是 {"code": "...", "nav": 1.2345, "date": "2024-01-01"}
return float(data["nav"])

然后把第二步里的 current_nav_map 换掉:

# 2. 根据 code 批量去拿当前净值
deffetch_all_current_nav(df: pd.DataFrame) -> pd.Series:
    navs = {}
for code in df["code"]:
try:
            navs[code] = get_fund_nav(code)
except Exception as e:
            print(f"获取 {code} 净值失败:{e}")
# 可以选择:用成本价顶一下,或者用上一次的净值缓存
            navs[code] = None
return pd.Series(navs)

df["current_nav"] = df["code"].map(fetch_all_current_nav(df))

这样你的主流程还是原来的那套,只是“当前净值”这列换成了自动获取。 你先可以只对一两只基金试,然后再慢慢扩展。

我那个脚本跑顺之后,强迫症就犯了,总觉得只看一行数字不过瘾,想看过去一段时间的走势。 最暴力的方法就是:每天把计算结果存一行到一个历史文件里,比如 fund_history.csv。

先改一下脚本最后部分,加个“落盘”的动作:

from datetime import datetime
import os

defappend_summary_history(total_cost, total_value, total_profit, total_rate):
    today = datetime.now().strftime("%Y-%m-%d")
    row = {
"date": today,
"total_cost": total_cost,
"total_value": total_value,
"total_profit": total_profit,
"total_rate": total_rate,
    }

    history_file = "fund_history.csv"
if os.path.exists(history_file):
        hist_df = pd.read_csv(history_file)
# 同一天多次运行可以选择覆盖或者追加,这里简单粗暴去重
        hist_df = hist_df[hist_df["date"] != today]
        hist_df = pd.concat([hist_df, pd.DataFrame([row])], ignore_index=True)
else:
        hist_df = pd.DataFrame([row])

    hist_df.to_csv(history_file, index=False)
    print("已写入历史记录:", row)

# 在打印汇总之后,加一句:
append_summary_history(total_cost, total_value, total_profit, total_rate)

跑几天之后,你就会有一个 fund_history.csv,类似这样:

date,total_cost,total_value,total_profit,total_rate
2024-01-01,10000,10300,300,0.03
2024-01-02,10000,10250,250,0.025
2024-01-03,10000,10420,420,0.042
...

然后用 matplotlib 画一下收益率曲线(不用搞得多花哨,能看就行):

import pandas as pd
import matplotlib.pyplot as plt

hist_df = pd.read_csv("fund_history.csv", parse_dates=["date"])
hist_df = hist_df.sort_values("date")

plt.figure(figsize=(10, 4))
plt.plot(hist_df["date"], hist_df["total_rate"])
plt.title("组合整体收益率走势")
plt.xlabel("日期")
plt.ylabel("收益率")
plt.grid(True)
plt.tight_layout()
plt.show()

你把这个图一打开,心里大概就有数了:是最近走势差一点,还是长期趋势在往上。

我后来嫌每次还要 python xxx.py 麻烦,就干脆把主流程封进一个 main(),脚本放到某个固定目录,然后用系统自带的定时任务搞一下:

脚本大概这么收个尾:

defmain():
    df = pd.read_csv("fund_positions.csv")

# 这里接上前面那一整套处理逻辑:
# 1)获取 current_nav
# 2)计算 cost_amount / current_amount / profit / profit_rate
# 3)打印单只基金和汇总
# 4)append_summary_history

if __name__ == "__main__":
    main()

  • Windows 可以用“任务计划程序”每天 21:00 跑一次
  • mac / Linux 就用 crontab,一行:
0 21 * * * /usr/bin/python3 /path/to/your/fund_tracker.py >> /path/to/log.txt 2>&1

这样你每天打开 fund_history.csv 或者那张收益曲线图,就知道今天的组合情况了,完全不用再一只只点开 App 盯着看。

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB