【最后203篇系列】005 -QTV200 Online

news2025/1/31 1:06:49

说明

借着春节休假,把这部分完工,然后2025年将正式的把量化研究的成果进行产品化输出。

首先,我会将策略的执行从脚本挪到服务。做法是将策略的逻辑放在微服务里,作为一个接口,而由sniffer来触发策略执行。我想这样策略不会因为任务太多而搞丢或者搞乱。之前QTV100的代码,我已经不知道放在哪了,在运行,但是我都无法去维护。而无数个微服务,哪怕是老版的,我也可以很容易找出来。也就是从"拉"式转为"推"式。

其次,使用数据库来支持策略的断点保存。程序的执行将按时间不断推进,直到最新时间或者指定时间,只需要为程序维持时间轴即可。策略在产生新的变化时,才会发起数据库存储需求。存储分为元数据和数据两部分,以日志的方式存储,这样在回退的时候,可以确保是干净的。

最后,使用mattermost的webhook作为事件消息的载体。当策略产生行动(买/卖),或者是巡检评估产生结论时,通过webhook发送即时消息,同时也将事件消息备份在kafka中。之后,也可考虑基于kafka的消息进行统一信息发送。

内容

1 简单测试一下FastAPI

引入基础模块,定义异步接口,然后进行简单测试。

from fastapi import FastAPI, HTTPException

class Test(BaseModel):
    """
    用于文档:这是一个测试模型,用于演示 FastAPI 的自动文档功能。
    """
    pass 

@app.post('/test/')
async def test(the_test:Test):
    """
    这是一个测试接口。

    - **the_test**: 接收一个 `Test` 模型作为输入。
    - **返回值**: 返回一个包含状态和消息的字典。

    示例:
    - 输入: `{}`
    - 输出: `{"status": true, "msg": "这是一个测试"}`
    """
    webmsg1 = WebMsg1('test')
    webmsg1.status = True 
    webmsg1.msg = '这是一个测试'
    return webmsg1.to_dict()
    

测试

import httpx 

input_dict  ={}
resp = httpx.post('http://localhost:24541/test/', json = input_dict).json()
{'name': 'test', 'status': True, 'msg': '这是一个测试', 'duration': 0, 'data': []}

fastapi自带的自动接口文档还是挺好的

在这里插入图片描述

2 核心接口

主要逻辑如下:

  • 1 元数据对象StrategyTrigger。

    • 包含了策略名(name)和标的名(code),这个用来标志一个唯一的可执行策略
    • 限定了策略的区间,如果不设定终止区间(end_dt),那么代表持续运行(每次取最新时间)
    • 明确了每次的执行最大步长(step)
    • 步长的时间单位(slot_unit)
    • 最新一个(已处理)数据时间(last_dt)
    • 当前开放的订单列表(open_orders):存在这里(redis)的原因是不会很多,而且频繁读取会比较快一些
    • 策略指定的金额(cash)
    • 是否忽略缓存(is_force)
    • 每次买入的比例(buy_cap_pct)
  • 2 元数据载入

    • cache_name: 存放StrategyTrigger元数据的内存变量
    • cache_name_data: 存放历史数据,如capital和close_orders的地方。这些数据之后会被存在mongo中,按照checkpoint(create_time)的方式存放。少量必要的元数据仍然存在次变量中,也是某种形式的redis or mongo。
    • 尝试从redis中恢复数据,如果没有数据,则制造默认的数据格式,在一次迭代执行后保存
  • 3 开始时间

    • 这个时间是用来进行数据端过滤筛选的时间
    • 当数据有last_dt时,说明已经是运行中的某一次迭代,使用这个时间
    • 如果没有last_dt,那么使用 start_dt,这个是策略定义的开始时间
  • 4 构造数据筛选时间段

    • 1 通过确定好的起始时间,转化为utc时间格式(the_utc_dt)
    • 2 最大时间由3个时间点决定:取最小值(stop_dt)
      • 1 策略指定的最大时间
      • 2 当前世界的最新时间
      • 3 步长指定的区间终点
  • 5 发起查询

    • 1 通过时间段、标的来获取对应的数据段(含信号特征)
  • 6 执行回测:遍历每一条时隙记录

    • 1 根据open_orders的数量和当前资金的状况决定是否可以买(is_ok_to_buy)/卖(is_ok_to_sell)
    • 2 买卖事件:在同一时刻,只会发生一种事件。事件触发后,即形成checkpoint,数据必须要保存。
      • 买:当收到买信号时
        • 1 查询资金池,看能买多少。
        • 2 如果能买,那么做一个订单,附加到StrategyTrigger元数据。
      • 卖:当收到卖信号
        • 1 遍历每一个卖单,重新初始化订单对象
        • 2 执行sell,然后将交易(close order)数据附加到trade_orders中
        • 3 清空open_orders列表

3 效果

随机挑了21只ETF实验,每笔按固定金额买入,总共发生466次交易。
效果还是比我预期的要好很多,近10年来只有2018和2023年亏损了,其他年份都明显大幅胜出,整体盈亏比肯定在2以上了。
在这里插入图片描述
资金占用上,看起来也还算好,理论上最高是420k,实际峰值大约360k。如果按天进行滑动,还是可以进一步利用(对冲交易)。
在这里插入图片描述

更有意思的是,2024.10 ~2024.12的持仓量是降低的。现在看来,这是比较明智的。
在这里插入图片描述

总体上,这比我预期的要好,而且是在合理的范围之内。我会用来作为基准策略。

4 技术点

为了简便起见,尽量采用了少量的工具。

  • 1 Mongo[1]: 用于存储原始的数据
  • 2 Influxdb: 用于存储生成的特征(这个还是为了将来考虑,否则可以只使用Mongo)
  • 3 FastAPI: 用来进行策略的回测与持续执行
  • 4 Mongo[2]:用于策略执行状态缓存、交易订单持久化存储。 交易单在之后应该转到clickhouse,可以更快的进行分析。
  • 5 Webhook+Mattermost: 交易事件的消息通知
  • 6 Prefect 、APScheduler: 用于周期性执行程序,包括爬取、特征生成和持续交易。

这样数据链条是完整的:1 数据- 2 特征-3 策略-4 回测- 5 消息,而且由于低频,所以手工操作完全没压力。

还有一些后续需要做的:

  • 1 前端可视化。计划使用Dash来做表格,简单点的话可能先和Gradio或者Streamlit结合,快速上线;或者晚些可以整合到Flask的蓝图框架下。这部分的功能在于快速的进行交易操作,KPI观察和分析。
  • 2 数据流监控。主要通过Kafka方式收集各流程数据,辅以大模型解释和质量抽检。确保:及时性(数据链条在周期内的活动)、完整性(必要字段是否齐全)、正确性(逻辑判断、多数据源交叉检验)。
  • 3 架构功能监控。考虑使用ELK方式,确保程序逻辑性错误得以实时发现、资源会产生预警(不过我一般都是给到非常充裕的硬件资源)比肝功能采集错误样本供快速调试。
  • 4 异步定时任务调度系统。基于Celery协程的方式,来完成数据的获取和流转。所有非高计算负载的都会走这种方式。
  • 5 分布式计算系统。基于Ray和Dask,来完成大量的分布式计算。现在的计算摊在脚本中零星计算,后续要考虑非常大的空间计算。

5 部署

采用docker镜像方式部署。

6 下一次迭代

假期还有一段时间,我应该可以做的更完善一些。

业务角度

现在的基准策略标的是之前根据规模随机挑的,我需要根据业务的对冲性,调整结构,使之表现更加稳定。

例如:国债类ETF、银行类ETF、原油类ETF、黄金类ETF,总体上应该使得整体策略结构更加稳定。

需要完成的工程任务:

  • 1 将现有的本地定时任务项目进行修改,使之更灵活。(git自动同步,只要修改一个txt就可以改变执行项目)
  • 2 将新增的etf类融入,并完成独立和合并测试。最终明确第一版的投资组合。

非结构化数据源

以事件和情感为中心,获取并提炼时事件和情感价值,后续会使用。

增强策略

在基准策略之上进行简单的分类模型,进行二次增强。其执行区间是在基准策略之内的:标的的基准策略买入,增强策略才实行;基准策略卖出,增强策略也清空。

算法类

可以开始考虑如何使用强化学习对策略进行自动优化,做原理性探索和思考。可以先做一个poc。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2286681.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Midjourney基础-常用修饰词+权重的用法大全

用好修饰词很关键 Midjourney要用除了掌握好提示词的写法,按照上一篇《做Midjourney最好图文教程-提示词公式以及高级参数讲解》画面主体 场景氛围 主体行为 构图方式 艺术风格 图像质量。 要画出有质感的内容我们必须要掌握好“修饰词”,这些修饰…

Deepseek的RL算法GRPO解读

在本文中,我们将深入探讨Deepseek采用的策略优化方法GRPO,并顺带介绍一些强化学习(Reinforcement Learning, RL)的基础知识,包括PPO等关键概念。 策略函数(policy) 在强化学习中, a…

神经网络和深度学习

应用 类型 为什么近几年飞速发展 数据增长,算力增长,算法革新 逻辑回归 向量化 浅层神经网络(Shallow neural network) 单条训练数据前向传播计算表达式 batch训练数据前向传播计算表达式 反向传播计算表达式 参数随机初始化 不能全部设为0 原因是同一…

python学opencv|读取图像(四十八)使用cv2.bitwise_xor()函数实现图像按位异或运算

【0】基础定义 按位与运算:两个等长度二进制数上下对齐,全1取1,其余取0。 按位或运算:两个等长度二进制数上下对齐,有1取1,其余取0。 按位取反运算:一个二进制数,0变1,1变0。 按…

关联传播和 Python 和 Scikit-learn 实现

文章目录 一、说明二、什么是 Affinity Propagation。2.1 先说Affinity 传播的工作原理2.2 更多细节2.3 传播两种类型的消息2.4 计算责任和可用性的分数2.4.1 责任2.4.2 可用性分解2.4.3 更新分数:集群是如何形成的2.4.4 估计集群本身的数量。 三、亲和力传播的一些…

【etcd】二进制安装etcd

由于生产服务器不能使用yum 安装 etcd ,或者 安装的etcd 版本比较老,这里介绍一个使用二进制安装的方式。 根据安装文档编写一个下载脚本即可 : 指定 etcd 的版本 提供了两个下载地址 一个 Google 一个 Github, 不过都需要外网 注释掉删除保…

企业知识管理平台助力企业创新与竞争力提升的有效策略探讨

内容概要 在当今快速发展的商业环境中,企业知识管理平台的构建显得至关重要。它不仅为企业的知识资源提供了一个整合与分享的空间,还为企业的创新与竞争力提升提供了策略支持。本文将深入探讨企业知识管理平台的关键要素,包括知识获取、存储…

Java多线程——线程安全性

线程安全性 当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的 public class A {public void test(){//....} }无状态对象是线程安全的,其不包含任何域,也不包含任何对其他类中域的引用&#…

Windows安装Miniconda和PySide6以及配置PyCharm

目录 1. 选择Miniconda 2. 下载Miniconda 3. 安装Miniconda 4. 在base环境下创建pyside6环境 5. 安装pyside6环境 6. 配置PyCharm环境 7. 运行第一个程序效果 1. 选择Miniconda 选择Miniconda而没有选择Anaconda,是因为它是一个更小的Anaconda发行版&#x…

C++传送锚点的内存寻址:内存管理

文章目录 1.C/C内存分布回顾2.C内存管理2.1 内存申请2.2 operator new与operator delete函数2.3 定位new表达式 3.关于内存管理的常见知识点3.1 malloc/free和new/delete的区别3.2 内存泄漏 希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力! 继C语…

循序渐进kubernetes-RBAC(Role-Based Access Control)

文章目录 概要Kubernetes API了解 Kubernetes 中的 RBACRoles and Role Bindings:ClusterRoles and ClusterRoleBindings检查访问权限:外部用户结论 概要 Kubernetes 是容器化应用的强大引擎,但仅仅关注部署和扩展远远不够,集群的安全同样至…

《从因果关系的角度学习失真不变表示以用于图像恢复》学习笔记

paper:2303.06859 GitHub:lixinustc/Causal-IR-DIL: Distortion invariant feature learning for image restoration from a causality perspective 2023 CVPR 目录 摘要 1、介绍 1.1 图像修复任务 1.2 失真不变表示学习 1.3 因果效应估计的挑战…

亚博microros小车-原生ubuntu支持系列:16 机器人状态估计

本来想测试下gmapping建图,但是底层依赖了yahboomcar_bringup做底层的数据处理,所以先把依赖的工程导入。 程序启动后,会订阅imu和odom数据,过滤掉一部分的imu数据后,然后与odom数据进行融合,最后输出一个…

Greenplum临时表未清除导致库龄过高处理

1.问题 Greenplum集群segment后台日志报错 2.回收库龄 master上执行 vacuumdb -F -d cxy vacuumdb -F -d template1 vacuumdb -F -d rptdb 3.回收完成后检查 仍然发现segment还是有库龄报警警告信息发出 4.检查 4.1 在master上检查库年龄 SELECT datname, datfrozen…

【Unity3D】实现横版2D游戏角色二段跳、蹬墙跳、扶墙下滑

目录 一、二段跳、蹬墙跳 二、扶墙下滑 一、二段跳、蹬墙跳 GitHub - prime31/CharacterController2D 下载工程后直接打开demo场景:DemoScene(Unity 2019.4.0f1项目环境) Player物体上的CharacterController2D,Mask添加Wall层…

mybatis(134/134)完结

一级缓存(默认情况下开启)同一个sqlsession中执行相同的查询语句走一级缓存 二级缓存 :同一个sqlsessionfactory,sqlsession关闭了才会将一级缓存提交到二级缓存中 外部编写的缓存 PageHelper插件:方便进行分页&#x…

PaddleSeg 从配置文件和模型 URL 自动化运行预测任务

git clone https://github.com/PaddlePaddle/PaddleSeg.git# 在ipynb里面运行 cd PaddleSegimport sys sys.path.append(/home/aistudio/work/PaddleSeg)import os# 配置文件夹路径 folder_path "/home/aistudio/work/PaddleSeg/configs"# 遍历文件夹,寻…

BLE透传方案,IoT短距无线通信的“中坚力量”

在物联网(IoT)短距无线通信生态系统中,低功耗蓝牙(BLE)数据透传是一种无需任何网络或基础设施即可完成双向通信的技术。其主要通过简单操作串口的方式进行无线数据传输,最高能满足2Mbps的数据传输速率&…

苍穹外卖—订单模块

该模块分为地址表的增删改查、用户下单、订单支付三个部分。 第一部分地址表的增删改查无非就是对于单表的增删改查,较基础,因此直接导入代码。 地址表 一个用户可以有多个地址,同时有一个地址为默认地址。用户还可为地址添加例如&q…

openeuler 22.03 lts sp4 使用 cri-o 和 静态 pod 的方式部署 k8s-v1.32.0 高可用集群

前情提要 整篇文章会非常的长…可以选择性阅读,另外,这篇文章是自己学习使用的,用于生产,还请三思和斟酌 静态 pod 的部署方式和二进制部署的方式是差不多的,区别在于 master 组件的管理方式是 kubectl 还是 systemctl有 kubeadm 工具,为什么还要用静态 pod 的方式部署?…