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

arrow(c++)改写empyrical系列1---用arrow读取基金净值数据并计算夏普率

用arrow c++版本读取了csv中的基金净值数据,然后计算了夏普率,比较尴尬的是,arrow c++版本计算耗费的时间却比python的empyrical版本耗费时间多。。。
在这里插入图片描述
在这里插入图片描述

arrow新手上路,第一次自己去实现功能,实现的大概率并不是最高效的方式,但是我也踏出了用arrow c++改写backtrader的第一步。

  • 用arrow改写empyrical,就当练手了,目标是做成两个文件:empyrical.h和empyrical.cpp
  • 用arrow和qt改写pyfolio, 实现更美观的界面,做成两个文件:pyfolio.h 和pyfolio.cpp
  • 改写backtrader

c++版本的文件:

my_example.cc

#include <arrow/api.h>
#include <arrow/io/api.h>
#include "arrow/csv/api.h"
#include <arrow/compute/api.h>
#include <iostream>
#include <chrono>
//#include "../empyrical/empyrical.h"arrow::Status RunMain(){auto start_time = std::chrono::high_resolution_clock::now();// 首先,我们需要设置一个可读文件对象,它允许我们将读取器指向磁盘上的正确数据。我们将重复使用这个对象,并将其重新绑定到多个文件中。std::shared_ptr<arrow::io::ReadableFile> infile;// 绑定输入文件到 "test_in.csv"ARROW_ASSIGN_OR_RAISE(infile, arrow::io::ReadableFile::Open("/home/yun/Documents/fund_nav.csv"));// (文档部分:CSV 表格声明)std::shared_ptr<arrow::Table> csv_table;// CSV 读取器有多个对象,用于不同选项。现在,我们将使用默认值。ARROW_ASSIGN_OR_RAISE(auto csv_reader,arrow::csv::TableReader::Make(arrow::io::default_io_context(), infile, arrow::csv::ReadOptions::Defaults(),arrow::csv::ParseOptions::Defaults(), arrow::csv::ConvertOptions::Defaults()));// 读取表格。ARROW_ASSIGN_OR_RAISE(csv_table, csv_reader->Read());// 输出显示Table的元数据信息// std::cout << "Table Metadata:" << std::endl;// std::cout << "Number of columns: " << csv_table->num_columns() << std::endl;// std::cout << "Number of rows: " << csv_table->num_rows() << std::endl;// std::cout << "Schema: " << csv_table->schema()->ToString() << std::endl;// 输出显示Table的数据// for (int i = 0; i < csv_table->num_columns(); ++i) {//   std::shared_ptr<arrow::Array> column = csv_table->column(i);//   std::cout << "Column " << i << ": " << column->ToString() << std::endl;// }// 1. 显示table信息到std::cout的方法// std::shared_ptr<arrow::RecordBatch> record_batch;// arrow::Result<std::shared_ptr<arrow::RecordBatch>> result = csv_table->CombineChunksToBatch(); // 执行某个操作,返回Result// if (result.ok()) {//   record_batch = result.ValueOrDie();//   // 在这里使用 record_batch// } else {//   // 处理错误//   std::cerr << "Error: " << result.status().ToString() << std::endl;// }// //arrow::PrettyPrint(*record_batch, 2, &std::cout);// arrow::Status status = arrow::PrettyPrint(*record_batch, 2, &std::cout);// if (!status.ok()) {//   // 处理错误,例如打印错误信息//   std::cerr << "Error: " << status.ToString() << std::endl;// }// 2. 显示table信息到std::cout的方法// std::cout << csv_table->ToString() << std::endl;// 3. 显示table信息到std::cout的方法// arrow::Status status = arrow::PrettyPrint(*csv_table, 2, &std::cout);// if (!status.ok()) {//   // 处理错误,例如打印错误信息//   std::cerr << "Error: " << status.ToString() << std::endl;// }// 开始计算夏普率// std::cout << "一年的交易日有" << AnnualizationFactors::DAILY << "天" << std::endl;// std::cout << DAILY << std::endl;// 计算收益率arrow::Datum fund_returns;arrow::Datum fund_diff;std::shared_ptr<arrow::ChunkedArray> cum_nav = csv_table->GetColumnByName("复权净值");std::shared_ptr<arrow::ChunkedArray> now_cum_nav = cum_nav->Slice(1,cum_nav->length()-1);std::shared_ptr<arrow::ChunkedArray> pre_cum_nav = cum_nav->Slice(0,cum_nav->length()-1);ARROW_ASSIGN_OR_RAISE(fund_diff, arrow::compute::CallFunction("subtract", {now_cum_nav,pre_cum_nav}));ARROW_ASSIGN_OR_RAISE(fund_returns, arrow::compute::CallFunction("divide", {fund_diff,pre_cum_nav}));// // 获取结果数组// std::cout << "Datum kind: " << fund_returns.ToString()//           << " content type: " << fund_returns.type()->ToString() << std::endl;// // std::cout << fund_returns.scalar_as<arrow::DoubleScalar>().value << std::endl;// std::cout << fund_returns.chunked_array()->ToString() << std::endl;// 计算夏普率arrow::Datum avg_return;arrow::Datum avg_std;arrow::Datum daily_sharpe_ratio;arrow::Datum sharpe_ratio;arrow::Datum sqrt_year;// 创建 Arrow Double 标量double days_of_year_double = 252.0;std::shared_ptr<arrow::Scalar> days_of_year = arrow::MakeScalar(days_of_year_double);ARROW_ASSIGN_OR_RAISE(sqrt_year, arrow::compute::CallFunction("sqrt", {days_of_year}));ARROW_ASSIGN_OR_RAISE(avg_return, arrow::compute::CallFunction("mean", {fund_returns}));arrow::compute::VarianceOptions variance_options;variance_options.ddof = 1;ARROW_ASSIGN_OR_RAISE(avg_std, arrow::compute::CallFunction("stddev", {fund_returns},&variance_options));ARROW_ASSIGN_OR_RAISE(daily_sharpe_ratio, arrow::compute::CallFunction("divide", {avg_return,avg_std}));ARROW_ASSIGN_OR_RAISE(sharpe_ratio, arrow::compute::CallFunction("multiply", {daily_sharpe_ratio,sqrt_year}));std::cout << "计算得到的夏普率为 : " << sharpe_ratio.scalar_as<arrow::DoubleScalar>().value << std::endl;auto end_time = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);std::cout << "c++读取数据,然后计算夏普率一共耗费时间为: " << duration.count()/1000.0 << " ms" << std::endl;return arrow::Status::OK();}// (文档部分: 主函数)
int main() {arrow::Status st = RunMain();if (!st.ok()) {std::cerr << st << std::endl;return 1;}return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)project(MyExample)find_package(Arrow REQUIRED)
find_package(Parquet REQUIRED)
find_package(ArrowDataset REQUIRED)add_executable(my_example my_example.cc)
target_link_libraries(my_example PRIVATE Arrow::arrow_shared Parquet::parquet_shared ArrowDataset::arrow_dataset_shared)

在同一个文件夹下,运行

cmake -B build
cmake --build build
./build/my_example

python 运行代码如下:

import pandas as pd 
import empyrical as ep
import time 
a = time.perf_counter()
data = pd.read_csv("/home/yun/Documents/fund_nav.csv")
returns = data['复权净值'].pct_change().dropna()
sharpe_ratio = ep.sharpe_ratio(returns)
print("计算得到的sharpe_ratio : ", sharpe_ratio)
b = time.perf_counter()
print(f"python读取数据,然后计算夏普率一共耗费时间为: {(b-a)*1000.0} ms")

相关文章:

arrow(c++)改写empyrical系列1---用arrow读取基金净值数据并计算夏普率

用arrow c版本读取了csv中的基金净值数据&#xff0c;然后计算了夏普率&#xff0c;比较尴尬的是&#xff0c;arrow c版本计算耗费的时间却比python的empyrical版本耗费时间多。。。 arrow新手上路&#xff0c;第一次自己去实现功能&#xff0c;实现的大概率并不是最高效的方…...

Mathematica强制将函数的自变量由符号转为数值

问题 使用Mathematcia完成函数优化&#xff08;FindMaximum&#xff09;十分方便。但是如果优化的目标函数非常复杂&#xff0c;里面嵌套了若干NSolve函数&#xff0c;那么FindMaximum可能会计算非常长时间&#xff0c;甚至无法得到正确结果。 原因在于&#xff0c;Mathemtic…...

【wps】记录

1、ppt背景图片上的字体怎样消除&#xff1f; 打开PPT要删除文字的PPT后&#xff0c;依次点击视图→母版视图→幻灯片母版。 在幻灯片母版的左侧&#xff0c;选择版式页面&#xff0c;在母版的右侧选择要删除的文字&#xff0c;删除即可 点击“关闭母版视图”即可退出幻灯片…...

扩散模型学习

第一章 1.1 的原理 给定一批训练数据X&#xff0c;假设其服从某种复杂的真实 分布p(x)&#xff0c;则给定的训练数据可视为从该分布中采样的观测样本x。 生成模型就是估计训练数据的真实分布&#xff0c;使得估计的分布q(x)和真实分布p(x)差距尽可能能的小。 使得所有训练…...

解决方法:从客户端(---<A href=“http://l...“)中检测到有潜在危险的 Request.Form 值。

从客户端(-----<A href"http://l...")中检测到有潜在危险的 Request.Form 值。 解决方法&#xff1a;应该是不同的.net Framework版本对代码的校验不同&#xff0c;造成在高版本操作系统&#xff08;即高.net Framework版本校验&#xff09;不兼容&#xff0c;可…...

Linux shell编程学习笔记14:编写和运行第一个shell脚本hello world!

* 20231020 写这篇博文断断续续花了好几天&#xff0c;为了说明不同shell在执行同一脚本文件时的差别&#xff0c;我分别在csdn提供线上Linux环境 &#xff08;使用的shell是zsh&#xff09;和自己的电脑上&#xff08;使用的shell是bash&#xff09;做测试。功夫不负有心人&am…...

隐式类型转换

什么是隐式类型转换&#xff0c;多参数的造函数隐式类型转换&#xff0c;和单参数的构造函数隐式类型转换有什么区别 C中有三种主要的隐式类型转换&#xff1a; 1:多参数的构造函数隐式类型转换 2:单参数的构造函数隐式类型转换 3:成员函数隐式类型转换。…...

单例模式:饿汉式、懒汉式

一、单例模式 定义&#xff1a;一个类中的对象只能有一个&#xff0c;它在内存中只会创建一次对象的设计模式。 用法&#xff1a;在程序中如果多次用到同一个类中的方法进行操作时&#xff0c;在使用时就会创建多个对象。为了防止频繁创建对象造成内存资源浪费&#xff0c;就可…...

“人间烟火”背后,长沙招商引资再出圈

连续多年&#xff0c;长沙荣膺全国最具幸福感城市。同时&#xff0c;长沙也被誉为“中部崛起的引擎城市”。长沙不仅有网红城市的人间烟火气&#xff0c;更以创新的精神&#xff0c;优质的营商环境&#xff0c;高效的政府服务&#xff0c;丰富的人才资源和深厚的产业基础&#…...

操作系统【OS】中断和异常

异常&#xff08;内中断&#xff09; 中断&#xff08;外中断&#xff09; 基本概念 由CPU执行指令内部产生的事件内中断都是不可屏蔽中断&#xff0c;一旦出现&#xff0c;就要立即处理。 由来自CPU外部的设备发出的中断请求&#xff08;常用于输入输出&#xff09;典型的由…...

[AutoSAR系列] 1.1 AutoSar 发展历史

AUTOSAR,全称为Automotive Open System Architecture,即汽车开放系统架构。 AutoSar 是一项开源的汽车软件标准,旨在提高汽车电子系统的互操作性和可重用性。AutoSar 成员通常是汽车制造商、电子元件制造商、软件供应商和工具供应商等公司,他们在共同开发和推进 AutoSar 标…...

【vscode编辑器插件】前端 php unity自用插件分享

文章目录 一篇一句前言前端vuegitphpunity后端其他待续完结 一篇一句 “思考是最困难的工作&#xff0c;这也许是为什么很少有人这样做。” - 亨利福特&#xff08;Henry Ford&#xff09; 前言 无论是什么语言&#xff0c;我都会选择使用vscode进行开发&#xff0c;我愿称v…...

【企业级SpringBoot单体项目模板 】—— 项目代码管理

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;SpringBoot项目模版、企业级、模版、代码管理☀️每日 一言&#xff1a;生命力顽强的种子&#xff0c;从不对瘠土唱诅咒的歌。 文章目录 一、第一种&#xff1a;先创建仓库1.1 创建仓库1.2 clone…...

Python读取Excel文件中指定的列数并生成CSV文件

0x00 安装Pandas和OpenPyXL pip install pandaspip install openpyxl0x01 Encoding import os import pandas as pd import openpyxl from openpyxl import load_workbook import csvdef write_dict_to_csv(dict_data, fileName):df pd.DataFrame.from_dict(dict_data)# 将D…...

MySQl有哪些索引(种类)?索引特点?为什么要使用索引?

普通索引&#xff1a;仅加速查询唯一索引&#xff1a;加速查询 列值唯一&#xff08;可以有null&#xff09;主键索引&#xff1a;加速查询 列值唯一&#xff08;不可以有null&#xff09; 表中只有一个组合索引&#xff1a;多列值组成一个索引&#xff0c;专门用于组合搜索&…...

49数码论坛系统设计与实现

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…...

蓝桥杯每日一题2023.10.19

题目描述 完全二叉树的权值 - 蓝桥云课 (lanqiao.cn) 题目分析 我们以每一个节点的坐标来将这一深度的权值之和相加从而算出权值和 要清楚每一个深度的其实节点和末尾节点&#xff0c;使用双指针将这个深度节点的权值和计算出来&#xff0c;记录所 需要的深度即可 #includ…...

NIO IN:技术蔚来的首次「大阅兵」

宝山&#xff0c;上海第一钢铁厂旧址。 上周&#xff0c;蔚来在这里点亮金色炉台&#xff0c;2500 立方米高炉&#xff0c;浓重的工业气质与古典凝重的光影交织&#xff0c;蔚来 NIO IN 用科技的进步呼应那个火红的年代。 这是蔚来第一次开科技发布会&#xff0c;为了全方位展…...

Android推送问题排查

针对MobPush智能推送服务在使用过程中可能出现的问题&#xff0c;本文为各位开发者们带来了针对MobPush安卓端推送问题的解决办法。 TCP在线推送排查 排查TCP在线收不到推送时&#xff0c;我们先通过客户端的RegistrationId接口获取设备的唯一标识 示例&#xff1a; MobPush…...

轻量级导出 Excel 标准格式

一般业务系统中都有导出到 Excel 功能&#xff0c;其实质就是把数据库里面一条条记录转换到 Excel 文件上。Java 常用的第三方类库有 Apache POI 和阿里巴巴开源的 EasyExcel 等。另外也有通过 Web 模板技术渲染 Excel 文件导出&#xff0c;这实质是 MVC 模式的延伸&#xff0c…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...