vnpy_ctp源码下载后转变为python可用的处理过程

news2024/11/29 12:55:02

目录

写在前面 

下载源码并解压

创建python项目

环境

过程

编译vnpy_ctp源码

验证可用性


写在前面 

window系统中必须安装有Visual Studio ,后面源码安装时需要进行C++编译

下载源码并解压

GitHub - vnpy/vnpy_ctp: VeighNa框架的CTP交易接口

下载zip压缩包

解压

要在python中能执行,要有.pyd文件,解压后的文件夹内没有.pyd文件

创建python项目

新建一个python项目,项目在一个新的虚拟环境中执行。

环境

操作系统:window10 64位

开发工具:pycharm

python版本:python3.8.10

过程

编译vnpy_ctp源码

打开项目下方的terminal面板

cd 到解压后setup.py 所在文件夹  

执行 python setup.py build 

大概2到3分钟,编译完毕,在setup.py所在文件夹下多出一个build文件夹

在build下找到与操作系统和python版本对应的文件夹,以本文为例,操作系统是64位,那文件夹名称中就会有amd64,python版本3.8,文件夹名称中就会包含3.8,所以本文的文件夹名为lib.win-amd64-3.8

我们需要的是 build>lib.win-amd64-3.8>vnpy_ctp文件夹下的api文件夹,我们把api文件夹复制到项目目录下

验证可用性

创建Md调用的类和Td调用的类

import datetime,sys,os,time,pytz
from api import (
    TdApi,
    MdApi
)
class CtpMdApi(MdApi):
    def __init__(self)->None:
        super().__init__()

        self.reqid:int = 0
        self.connect_status: bool = False
        self.login_status: bool = False
        self.subscribed: set = set()

        self.userid: str = ""
        self.password: str = ""
        self.brokerid: str = ""

        self.current_date: str = datetime.date.today().strftime('%Y%m%d')
        pass
    def connect(self, address: str, userid: str, password: str, brokerid: str)->None:
        self.userid = userid
        self.password = password
        self.brokerid = brokerid

        if not self.connect_status:
            con_body_path = CTP_MD_CON_DIR
            con_body_path = con_body_path.replace('/','\\')
            self.createFtdcMdApi(con_body_path)
            self.registerFront(address)
            self.init()

            self.connect_status = True
            pass
        pass

    def login(self)->None:
        ctp_req: dict = {
            'UserID':self.userid,
            'Password':self.password,
            'BrokerID':self.brokerid
        }
        self.reqid += 1
        self.reqUserLogin(ctp_req,self.reqid)
        pass
    def subscribe(self,req:dict):
        if self.login_status:
            self.subscribeMarketData(req['symbol'])
        self.subscribed.add(req['symbol'])
        pass
    def close(self)->None:
        if self.connect_status:
            self.exit()
        pass
    def update_date(self)->None:
        self.current_date = datetime.date.today().strftime('%Y%m%d')
        pass
    def onFrontConnected(self)->None:
        self.login()
        pass
    def onFrontDisconnected(self,reason:int)->None:
        self.login_status = False
        pass
    def onRspUserLogin(self,data:dict,error:dict,reqid:int,last:bool)->None:
        if not error['ErrorID']:
            self.login_status = True
            for symbol in self.subscribed:
                self.subscribeMarketData(symbol)
            pass
        else:
            print(f"行情服务器登录失败。{error['ErrorID']}.{error['ErrorMsg']}")
        pass
    def onRspError(self, error: dict, reqid: int, last: bool)->None:
        print('行情接口报错。', error['ErrorID'], error['ErrorMsg'])
        pass
    def onRspSubMarketData(self, data: dict, error: dict, reqid: int, last: bool):
        if not error or not error['ErrorID']:
            return
        print('行情订阅失败。',error['ErrorID'],error['ErrorMsg'])
        pass
    def onRtnDepthMarketData(self,data:dict)->None:
        if not data['UpdateTime']:
            return
        print('tick返回',data['InstrumentID'],data['LastPrice'])
        pass
    pass

class CtpTdApi(TdApi):
    def __init__(self)->None:
        super().__init__()
        self.reqid: int = 0
        self.order_ref: int = 0

        self.connect_status: bool = False
        self.login_status: bool = False
        self.auth_status: bool = False
        self.login_failed: bool = False
        self.auth_failed: bool = False
        self.contract_inited: bool = False

        self.userid: str = ""
        self.password: str = ""
        self.brokerid: str = ""
        self.auth_code: str = ""
        self.appid: str = ""

        self.frontid: int = 0
        self.sessionid: int = 0
        pass
    def connect(self,address:str,userid:str,password:str,brokerid:str,auth_code:str,appid:str)->None:
        self.userid = userid
        self.password = password
        self.brokerid = brokerid
        self.auth_code = auth_code
        self.appid = appid

        if not self.connect_status:
            con_body_path = CTP_TD_CON_DIR + self.userid + os.path.sep
            if not os.path.exists(con_body_path):
                os.mkdir(con_body_path)
            con_body_path = con_body_path.replace('/','\\')
            self.createFtdcTraderApi(con_body_path)

            self.subscribePrivateTopic(0)
            self.subscribePublicTopic(0)
            self.registerFront(address)
            self.init()

            self.connect_status = True
            pass
        else:
            self.authenticate()
        pass

    def authenticate(self)->None:
        if self.auth_failed:
            return
        ctp_req: dict = {
            "UserID": self.userid,
            "BrokerID": self.brokerid,
            "AuthCode": self.auth_code,
            "AppID": self.appid
        }

        self.reqid += 1
        self.reqAuthenticate(ctp_req, self.reqid)
        pass
    def login(self)->None:
        if self.login_failed:
            return
        ctp_req: dict = {
            "UserID": self.userid,
            "Password": self.password,
            "BrokerID": self.brokerid,
            "AppID": self.appid
        }

        self.reqid += 1
        self.reqUserLogin(ctp_req, self.reqid)
        pass
    def close(self)->None:
        if self.connect_status:
            self.exit()
        pass
    def onFrontConnected(self)->None:
        if self.auth_code:
            self.authenticate()
        else:
            self.login()
        pass
    def onFrontDisconnected(self,reason:int)->None:
        self.login_status = False
        pass
    def onRspAuthenticate(self, data: dict, error: dict, reqid: int, last: bool)->None:
        if not error['ErrorID']:
            self.auth_status = True
            self.login()
        else:
            self.auth_failed = True
            print('交易服务器验证失败。',error['ErrorID'],error['ErrorMsg'])
        pass
    def onRspUserLogin(self,data: dict, error: dict, reqid: int, last: bool)->None:
        if not error["ErrorID"]:
            self.frontid = data["FrontID"]
            self.sessionid = data["SessionID"]
            self.login_status = True

            # 自动确认结算单
            ctp_req: dict = {
                "BrokerID": self.brokerid,
                "InvestorID": self.userid
            }
            self.reqid += 1
            self.reqSettlementInfoConfirm(ctp_req, self.reqid)
        else:
            self.login_failed = True
            print("交易服务器登录失败", error['ErrorID'], error['ErrorMsg'])
        pass
    def onRspSettlementInfoConfirm(self,data: dict, error: dict, reqid: int, last: bool)->None:
        while True:
            self.reqid += 1
            n: int = self.reqQryInstrument({}, self.reqid)
            if not n:
                break
            else:
                time.sleep(1)
        pass
    def onRspQryInstrument(self, data: dict, error: dict, reqid: int, last: bool) -> None:
        print(data['ProductClass'],data['InstrumentID'],data['ProductID'],reqid,last)
        if last:
            self.contract_inited = True
            print('合约信息查询完毕')
        pass
    pass

执行代码

if __name__ == '__main__':
    investorid = ""
    brokerid=""
    password= ""
    appid= ""
    auth_code= "0000000000000000"
    md_ip= "180.168.146.187:10211"
    trader_ip= "180.168.146.187:10201"

    temp_api = CtpTdApi()
    address = f"tcp://{trader_ip}"
    temp_api.connect(address,investorid,password,brokerid,auth_code,appid)

    import keyboard
    keyboard.wait('esc')
    sys.exit()
    pass

能登录td服务器,并正常查询合约,可用 

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

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

相关文章

基于YOLOV8+移动窗口切片(完整版)+OnnxRuntime+KMeans+Zbar+传统图像处理算法的大图片小目标光伏产线条码检测研究

文章目录 前言1 项目背景2 训练YOLOV8的一维码检测模型3 读取测试图片3.1 调整首窗口位置4 创建滑动窗口,窗口大小为(640,640),移动距离为160,对不足(640,640)的窗口进行填充5 创建Onnxruntime推理引擎并测试5.1推理测试5.2获得ONNX模型输入层(输出层)和数据维度5.3 …

C++20 Text formatting

C20 Text formatting 格式化字符串&#xff0c; 和 python 类似。 std::formatter - cppreference.com string — Common string operations — Python 3.12.0 documentation 新格式库位于 <format> 头文件中。格式库基于 Python3 中的 str.format() 方法建模。格式…

划分VOC数据集,以及转换为划分后的COCO数据集格式

1.VOC数据集 LabelImg是一款广泛应用于图像标注的开源工具&#xff0c;主要用于构建目标检测模型所需的数据集。Visual Object Classes&#xff08;VOC&#xff09;数据集作为一种常见的目标检测数据集&#xff0c;通过labelimg工具在图像中标注边界框和类别标签&#xff0c;为…

MySQL单表过大、主从模式、同步模式优化原理

文章目录 MYSQL单表数据达2000万性能严重下降?前言InnoDB索引数据结构B树 Sharding Sphere分库分表Sharding-JDBCSharding-JDBC的相关概念说明逻辑表广播表绑定表 Sharding-JDBC中的分片策略自动分片算法取模分片算法哈希取模分片算法分片容量范围标准分片算法行表达式分片算法…

第1章 现代通信网概述

文章目录 1.1 通信网的定义1.2 通信网的分类1.3 通信网的结构1.4 通信网的质量要求 1.1 通信网的定义 1.1.1 通信系统 1.1.2 通信网的定义 通信网是由一定数量的节点 (包括终端节点、交换节点) 和连接这些节点的传输链路有机地组织在一起&#xff0c;以实现两个或多个规…

JWFD开源工作流-随机函数发生器最新进展

使用WIN7 32位&#xff0c;JDK1.8平台&#xff0c;跑语法分析&#xff0c;实测结果如上图&#xff0c;比JDK1.6的每个函数计算速度快了不止100倍&#xff0c;升级为JDK1.8是正确的选择&#xff0c;这个模块是典型的变形函数计算单元&#xff0c;可以解决很多需要动态变形物理模…

阿里云竞争加剧,腾讯云双十一服务器优惠力度爆表!

腾讯云对于新客户和老客户都有相互照顾的优惠力度。特别是在今年的双十一活动中&#xff0c;腾讯云推出了一系列的优惠活动。首先&#xff0c;轻量服务器和云服务器产品的首购活动中&#xff0c;三年的云服务器仅需540元&#xff0c;这是一个非常低廉的价格。其次&#xff0c;香…

linux下俺安Anaconda

文章目录 一、linux下安装anaconda1 下载anaconda的安装包2 安装anaconda3设置环境变量4完成安装以及检测是否安装成功 二、linux下配置并运行![在这里插入图片描述](https://img-blog.csdnimg.cn/30a818b7a0b24d81aceef93e2d365b7e.png)1、一般情况下&#xff0c;anaconda中默…

标本传送设备物联网应用案例|蓝蜂物联网一体化方案

标本传送设备物联网应用案例 标本传输系统被大量应用到现代医院场景中&#xff0c;系统各个设备的运行情况直接影响到整个医院系统的正常稳定&#xff0c;所以对于标本传输系统的实时监控和及时运维是维持医院稳定和规避风险的重中之重。 针对标本传输系统应用过程中的数据统…

HTML5学习系列之简单使用1

HTML5学习系列之简单使用1 前言基础显示学习定义网页标题定义网页元信息定义网页元信息定义文档结构div元素di和classtitlerole注释 总结 前言 下班加班期间的简单学习。 基础显示学习 定义网页标题 <html lang"en"> <head> <title>从今天开始努…

WPS的JS宏基础(二)

数据的输入和输出 InputBox(‘请输入内容’) //输入框 alert(‘a’) //简单消息框 MsgBox(‘b’) //进阶消息框 Debug.Print(‘c’) //立即窗口 Console.log(‘d’) //立即窗口 编写规则与注释 1.严格遵循大小写规范 2.每条语句之间用分号分隔 3.复合语句块&#xff08;块中…

Ionic组件 ion-list ion-list-header

1 ion-list 列表由多行项目组成&#xff0c;这些项目可以包含 text, buttons, toggles, icons, thumbnails等。列表通常包含具有类似数据内容的项目&#xff0c;如 images and text。 列表支持多种交互&#xff0c;包括滑动项目以显示选项、拖动以重新排列列表中的项目以及删除…

无线充,大功率小家电,智能家居,无人机快速充电等产品供电 LDR6328S芯片TYUPE-C PD诱骗电压 USB-C解决PD电源取电问题

LDR6328S 是乐得瑞科技有限公司开发的一款兼容 USB PD、QC 和 AFC 协议的 Sink 控制器。 LDR6328S 从支持 USB PD、QC 和 AFC 协议的适配器取电&#xff0c;然后供电给设备。比如可以配置适配器输 出需要的功率&#xff0c;给无线充电器设备供电。LDR6328S 也兼容传统 USB 电源…

【算法与数据结构】40、LeetCode组合总和 II

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;【算法与数据结构】39、LeetCode组合总和的基础之上&#xff0c;这道题变成了candidates中有重复元素&…

Bytebase 2.11.0 - 支持 OceanBase Oracle 模式

&#x1f680; 新功能 支持 OceanBase Oracle 模式。支持设置 MySQL 在线变更参数。新增项目数据库查看者的角色。 &#x1f384; 改进 支持在项目中直接选择所有用户并为之添加角色。 调整了项目页面的布局。在 SQL 编辑器中通过悬浮面板展示表和列的详情。 &#x1faa6; …

弹性布局display:flex

弹性布局display:flex 一、弹性布局的特点二、容器的属性1、justify-content1.1 justify-content: center 居中1.2 justify-content: flex-start&#xff08;默认值&#xff09;&#xff1a;左对齐1.3 justify-content: flex-end 右对齐1.4 justify-content:space-between 两端…

第四季度净利润扭亏为盈,迪士尼的流媒体终于成功了?

对于一直关注迪士尼的投资者来说&#xff0c;眼下最关心的问题只有一个——迪士尼转行流媒体成功了吗&#xff1f; 而对于这一问题答案&#xff0c;或许可以从迪士尼最新发布的财报中找到。11月9日&#xff0c;华特迪士尼公布了截至2023年9月30日的第四季度和全年收益。其中&a…

大厂面试题-什么是聚集索引和非聚集索引

1.简单来说&#xff0c;聚集索引就是基于主键创建的索引&#xff0c;除了主键索引以外的其他索引&#xff0c;称为非聚集索引&#xff0c;也叫做二级索引。 2.由于在InnoDB引擎里面&#xff0c;一张表的数据对应的物理文件本身就是按照B树来组织的一种索引结构&#xff0c;而聚…

图论10-哈密尔顿回路和哈密尔顿路径+状态压缩+记忆化搜索

文章目录 1 哈密尔顿回路2 哈密尔顿回路算法实现2.1 常规回溯算法2.2 引入变量记录剩余未访问的节点数量 3 哈密尔顿路径问题4 状态压缩4.1 查看第i位是否为14.2 设置第i位是为1或者04.3 小结4.4 状态压缩在哈密尔顿问题中的应用 5 记忆化搜索5.1 记忆化搜索与递推区别5.2 记忆…

洛谷 Equalize the Remainders

洛谷没提供中文题面&#xff0c;这里大致翻译一下&#xff1a; 可以进行的操作&#xff1a;任选一个数加一。 一共有n个整数&#xff0c;还有一个约数m&#xff0c;n个数都对m进行求余&#xff0c;累计余数的数量&#xff0c;要求每个余数都有n/m个。 对于样例1的输入&#xff…