当前位置: 首页 > news >正文

nodejs:midi-writer-js 将基金净值数据转换为 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

这是一个将开放式基金数据转换为 MIDI音乐的 js 程序示例。该程序将基金净值映射为 MIDI音符的音高

mkdir test-midi
cd test-midi
npm init -y 
cnpm install csv-parser -S
cnpm install midi-writer-js -S

编写 fund2midi.js  如下

// fund2midi.js
const fs = require('fs');
const csv = require('csv-parser');
const MidiWriter = require('midi-writer-js');// 参数验证
const args = process.argv.slice(2);
if (args.length !== 1 || args[0].length !== 6) {console.log('用法: node fund2midi.js <6位基金代码>');process.exit(1);
}const fcode = args[0];
const csvFile = `/funds/data/${fcode}.csv`;
const outputFile = `melo_${fcode}.mid`;// 读取并处理CSV数据
async function processData() {const results = [];return new Promise((resolve, reject) => {fs.createReadStream(csvFile).pipe(csv()).on('data', (data) => {if (data.date > '2024-01-01') {results.push({date: data.date,jz: parseFloat(data.jz)});}}).on('end', () => {if (results.length < 20) {console.log(`${results.length} < 20`);process.exit(2);}resolve(results);}).on('error', reject);});
}// 生成MIDI文件
function generateMIDI(prices) {const track = new MidiWriter.Track();track.setTempo(120);// 数据归一化const minPrice = Math.min(...prices);const maxPrice = Math.max(...prices);const priceRange = maxPrice - minPrice;// 计算音符范围let minNote = 48; // C3let maxNote = 84; // C5if ((maxPrice / minPrice) < (84 / 48)) {maxNote = Math.round(50 * (maxPrice / minPrice));}if (maxNote % 2 === 1) maxNote++;prices.forEach(price => {const pitch = (priceRange < 0.001)? Math.round((maxNote + minNote) / 2): minNote + Math.round(((price - minPrice) / priceRange) * (maxNote - minNote));const note = new MidiWriter.NoteEvent({pitch: [pitch],duration: '4',velocity: 63   // 音量: 63% *127 = 80});track.addEvent(note);});// 直接在构造函数中传入轨道数组const writer = new MidiWriter.Writer([track]);return writer;
}// 主流程
(async () => {try {const data = await processData();const prices = data.map(d => d.jz);console.log(`基金代码: ${fcode}`);console.log(`数据量: ${prices.length}`);console.log(`最大值: ${Math.max(...prices)}`);console.log(`最小值: ${Math.min(...prices)}`);const midi = generateMIDI(prices);fs.writeFileSync(outputFile, midi.buildFile(), 'binary');console.log(`生成成功: ${outputFile}`);} catch (err) {console.error('发生错误:', err.message);process.exit(1);}
})();

运行 node fund2midi.js 660008 
生成 melo_660008.mid

运行 python play_mid.py melo_660008.mid 

运行 python mido_msg.py melo_660008.mid 查看 midi文件内容


http://www.mrgr.cn/news/96704.html

相关文章:

  • 如何本地部署RWKV-Runner尝鲜CPU版
  • 动态规划入门:从记忆化搜索到递推
  • TypeError: __init__() got an unexpected keyword argument ‘device_type‘
  • 深度学习--softmax回归
  • 高效内存位操作:如何用C++实现数据块交换的性能飞跃?
  • Time spent invoking a CUDA kernel
  • 蓝桥杯准备(前缀和差分)
  • Android 中集成 Google 应用内评分
  • 洛谷题单2-P1424 小鱼的航程(改进版)-python-流程图重构
  • thinkcmf搭建
  • 游戏引擎学习第198天
  • 大模型高质量rag构建:A Cheat Sheet and Some Recipes For Building Advanced RAG
  • 配置防火墙和SELinux(1)
  • 【Yolov8部署】 VS2019 + opencv + onnxruntime 环境下部署目标检测模型
  • mysql 八股
  • C语言常用的字符串函数
  • 06-02-自考数据结构(20331)- 查找技术-动态查找知识点
  • 蓝桥杯 刷题对应的题解
  • Java基础 3.31
  • 【Feign】⭐️使用 openFeign 时传递 MultipartFile 类型的参数参考