python:将基金净值数据转换为 midi 文件

开放式基金是没有公布每日交易量的。

/funds/data/660008.csv 文件开头:
date,jz,ljjz
2016-01-04,1.1141,1.1141
2016-01-05,1.1161,1.1161
2016-01-06,1.1350,1.1350

编写 fund2mid.py  如下

# -*- coding: utf-8 -*-
"""
 从 https://fund.eastmoney.com/ 获取基金净值数据并转换为 MIDI文件
 需要先安装依赖:
 pip install midiutil
"""
import sys
import pandas as pd
from midiutil import MIDIFile

if len(sys.argv) ==2:
    fcode = sys.argv[1]
else:
    print('usage: python fund_dc.py fundcode ')
    sys.exit(1)

if len(fcode) !=6:
    print('fund code length: 6')
    sys.exit(2)

f1 = "/funds/data/" + fcode +'.csv'
df = pd.read_csv(f1) # parse_dates=True, index_col=0
#print(len(df))

df = df[ df['date'] > '2024-01-01']
if len(df) <20:
    print(len(df)," < 20")
    sys.exit(2)

# DataFrame 重建索引
df = df.reset_index(drop=True)
print('len(df)=', len(df))

# 提取基金净值序列
prices = df['jz'].astype(float).tolist()

# 数据归一化处理
min_price = min(prices)
max_price = max(prices)
price_range = max_price - min_price
print(f"{fcode}: max={max_price}, min={min_price}, range={price_range}")
print('max/min:', max_price/min_price)

# MIDI参数配置
# C3(MIDI音符范围最小值=48)
min_note = 48
# C5(MIDI音符范围最大值=84)
max_note = 84
if (max_price/min_price) < (84/48):
    max_note = int(50 * max_price/min_price)
if max_note %2 ==1:
    max_note += 1
print(f"max_note={max_note}, min_note={min_note} ")
print('max_note/50=', max_note/50)

track = 0
channel = 0
tempo = 120    # BPM
volume = 80   # 音量(0-127)

# 创建MIDI文件
midi = MIDIFile(1) # 单音轨
midi.addTrackName(track, 0, f"fund {fcode}")
midi.addTempo(track, 0, tempo)

# 生成音符序列
time_counter = 0  # 时间指针(单位:拍)
for price in prices:
    if price_range < 0.001:  # 处理价格无波动的情况
        pitch = (max_note + min_note) // 2
    else:
        normalized = (price - min_price) / price_range
        pitch = min_note + int(normalized * (max_note - min_note))
    
    # 添加音符(每个音符持续1拍,间隔1拍)
    midi.addNote(track, channel, pitch, time_counter, 1, volume)
    time_counter += 1

# 保存MIDI文件
output_file =f"melo_{fcode}.mid"
with open(output_file, 'wb') as f:
    midi.writeFile(f)
print(f" 生成:{output_file}")

以 农银沪深300指数A (660008) 为示例
运行 python fund2mid.py 660008 
 生成:melo_660008.mid

运行 python play_mid.py melo_660008.mid

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值