Python量化交易平台开发教程系列2-类CTP交易API的Python封装设计

CTP-API开发系列之十:v6.7.0-Python版封装(Windows/Linux) 本次分享将采用Swig工具(Swig是一种软件开发工具,可将用 C 和 C++ 编写的程序与各种高级编程语言连接起来),将C++语言版本的 CTP-API 封装成 Python版本,Windows/Linux系统下分别进行封装。 阅读详情
AI摘要

本文详细介绍如何将原生C++交易API封装成Python可用的形式,包括设计思路、工作流程及具体的实现细节。

原创文章,转载请注明出处:用Python的交易员

(本篇教程包含的内容太多也太复杂,有不少读者反应看不懂,因为本身也不是使用vn.py必须掌握的知识,这篇教程暂时处于半完成状态,等多收集些读者的建议后会再做一个比较大的修订)

为什么要封装API

直接原因就是C++的API没法直接在Python里用,不过这个回答有点太简单,这里我们稍微做一些拓展解释:

  1. C++ API中很多函数的调用参数是ApiStruct.h(参见上一篇)中定义的结构体,而在Python中我们既无法直接创建这些结构体(主动函数),也无法提取结构体中包含的数据(回调函数)。

  2. Python虚拟机是基于C语言实现的,所有的Python对象,哪怕只是一个整数或者字符串,在C的环境中都是一个PyObject对象(好吧,我知道C里没有对象,只有结构体,但估计90%的读者都不在乎这个区别)。用户如果在Python中直接传递一个参数到C++环境里,C++是无法识别的(Python:买入1手股指, C++:你要买入多少?)。

  3. Python只能加载封装为PyObject对象的模块,因此原生C++的API在Python中连加载都加载不了。

封装后API的工作流程

主动函数

  1. 用户在Python程序中调用封装API的主动函数,并直接传入Python变量(PyObject对象)作为参数。

  2. 封装API将Python变量转换成C++变量。

  3. 封装API调用原生API的主动函数,并传入C++变量作为参数。

回调函数

  1. 交易柜台通过原生API的C++回调函数推送数据信息,传入参数为C++变量

  2. 封装API将C++变量转换为Python变量

  3. 封装API调用封装后的回调函数向用户的Python程序中推送数据,传入参数为Python变量

名词定义

  • 封装API:指的是经过封装后,可以直接在Python中使用的API

  • 原生API:指的是由软件公司提供,在C++中使用的API

  • Python变量:包含Python中的数字、字符串、对象等等

  • C++变量:包含C++中的内置数据类型和结构体等

从Python的角度看原生API的一些问题

上一篇教程后读者应该对C++ API的结构和使用方法有了基础的了解,这篇教程主要介绍的是对原生的C++ API进行Python封装时的设计和思路,这些构成了vn.py开源项目中vn.lts(华宝证券LTS柜台API封装)的基础。首先让我们来从Python的角度看看原生API的一些问题:

  1. 原生的API中每个功能分为了两个类:分别是包含回调函数的Spi类和主动函数的Api类,这种设计能让用户更好的分清不同的功能。但是从面向对象的角度,把两个类封装到一起更为方便,实际使用中绝大部分C++的用户也会将接口整合到一个类里面(可以参见网上很多CTP开发的示例代码),因此Python的API中,我们也会将Spi和Api两个类的功能封装到一个类中。

  2. 原生的API中回调函数被触发后必须快速返回,否则会导致其他数据的推送被阻塞,阻塞时间长了还有可能导致API发生崩溃,因此回调函数中不适合包含耗时较长的计算逻辑。例如某个TICK行情推送后,如果用户在回调函数中写了一些比较复杂的计算(循环计算等等),耗时超过3秒(这个数字只是笔者的一个经验),则在这个3秒中,其他的行情推送用户是收不到的(被阻塞了),且很可能3秒后会出现API崩溃(程序死掉)。这里的解决方案是使用生产者-消费者模型,在API中包含一个缓冲队列,当回调函数收到新的数据信息时只是简单存入缓冲队列中并立即返回,而数据信息的处理和向Python中的推送则由另一个工作线程来执行。

  3. API的函数中使用了大量的结构体用于数据传送,这在C++而言是非常自然的设计,但是对Python封装会造成不小的麻烦,所有的结构体都要封装成对应的Python类,工作量太大也非常容易出错。这点我们可以利用Python相对于C++更为高级的数据结构来解决,Python中的dict字典本质是一个哈希表,但是同一个字典内键和值的类型允许不同,这个特性使得字典可以非常方便的用来代替C++的结构体。

明确了以上的问题后,我们就可以开始着手设计Python API的结构了。

Python API的结构设计

这里使用行情API作为示例。

...表示省略的代码。

//API的继承实现
class MdApi : public CSecurityFtdcMdSpi
{
private:
    CSecurityFtdcMdApi* api;            //API对象
    thread *task_thread;                //工作线程指针(向python中推送数据)
    ConcurrentQueue<Task> task_queue;   //任务队列

public:
    MdApi()
    {
        function0<void> f = boost::bind(&MdApi::processTask, this);
        thread t(f);
        this->task_thread = &t;
    };

    ~MdApi()
    {
    };

    ...

    //登录请求响应
    virtual void OnRspUserLogin(CSecurityFtdcRspUserLoginField *pRspUserLogin, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast);

    ...

    //数据任务处理函数(在工作线程中运行)
    void processTask();

    ...

    //处理登陆请求响应
    void processRspUserLogin(Task task);

    ...

    //该回调函数在Python中继承
    virtual void onRspUserLogin(dict data, dict error, int id, bool last) {};

    ...

    //请求登陆的主动函数
    int reqUserLogin(dict req, int nRequestID);

    ...
};

(以上代码截取自vnltsmd.h文件)

注意原生API的函数名开头都是大写字母,为了便于分辨以及符合Python的PEP8编码规则,作者的函数都以小写字母开头。上面的代码中采用的示例是用户登陆UserLogin这个功能。

封装中的类和函数命名规则

  • 封装后的Python API的类取名为MdApi,注意这个不是原生API中的CSecurityFtdcMdApi。

  • 原生API中以On开头的回调函数(如OnRspUserLogin)对应的Python API的回调函数直接改为以on开头(如onRspUserLogin)。

  • 原生API中的主动函数(如ReqUserLogin)对应的封装后API中的主动函数改为首字母小写(如reqUserLogin)。

MdApi的成员变量

  • api:原生API中的CSecurityFtdcMdApi对象,用于实现主动函数的调用。

  • task_thread:一个boost线程指针,用于实现任务线程的工作。

  • task_queue:一个线程安全的任务队列。

工作步骤(后面会有具体函数的实现细节)

  1. 用户在Python中调用reqUserLogin函数,传入参数为包含登陆信息(用户名、密码)的字典req以及本次请求号nRequestID,该函数自动将字典中的信息提取并创建原生API使用的结构体后,调用原生API的主动函数ReqUserLogin来进行登录。

  2. 登录成功后,原生API会调用OnRspUserLogin的回调函数返回登录信息(注意这里On是大写),在回调函数里,只是简单的把结构体数据保存到一个任务对象Task中,并推送到任务队列里。

  3. 工作线程中运行的函数是processTask,该函数负责检查任务队列中是否有新的任务,如果有则调用对应的process函数进行处理,如果没有则阻塞等待。

  4. processTask函数检查到任务队列中OnRspUserLogin推送的一个任务后,调用processRspUserLogin函数进行处理。该函数首先从结构体中提取数据并转换为Python字典,然后调用onRspUserLogin函数(这里的on是小写)推送到Python环境中,onRspUserLogin函数由用户在Python中继承实现。

Python API的函数实现

仍然使用之前的示例进行函数实现的讲解,包括MdApi的构造、析构函数,主动函数(reqUserLogin等),原生API回调函数(OnRspUserLogin等)和任务处理函数(processTask和processRspUserLogin等)。

构造、析构函数

MdApi()
{
    function0<void> f = boost::bind(&MdApi::processTask, this);
    thread t(f);
    this->task_thread = &t;
};

~MdApi()
{
};

(以上代码截取自vnltsmd.h文件)

构造函数中仅包含了创建一个工作函数为processTask的工作线程,并将该线程的指针绑定到task_thread上。

析构函数为空,用户在退出前应当主动调用安全退出函数(参见源代码中的exit)。

主动函数

int MdApi::reqUserLogin(dict req, int nRequestID)
{
    //创建原生API函数调用需要的结构体
    CSecurityFtdcReqUserLoginField myreq = CSecurityFtdcReqUserLoginField();
    //初始化这个结构体的内存
    memset(&myreq, 0, sizeof(myreq));
    //提取字典中的内容并复制到结构体中
    getChar(req, "MacAddress", myreq.MacAddress);
    getChar(req, "UserProductInfo", myreq.UserProductInfo);
    getChar(req, "UserID", myreq.UserID);
    getChar(req, "AuthCode", myreq.AuthCode);
    getChar(req, "TradingDay", myreq.TradingDay);
    getChar(req, "InterfaceProductInfo", myreq.InterfaceProductInfo);
    getChar(req, "BrokerID", myreq.BrokerID);
    getChar(req, "ClientIPAddress", myreq.ClientIPAddress);
    getChar(req, "OneTimePassword", myreq.OneTimePassword);
    getChar(req, "ProtocolInfo", myreq.ProtocolInfo);
    getChar(req, "Password", myreq.Password);
    //将结构体的指针和代表请求编号的整数作为参数调用原生API的函数
    int i = this->api->ReqUserLogin(&myreq, nRequestID);
    //返回原生API函数的调用结果
    return i;
};

(以上代码截取自vnltsmd.cpp文件)

原生API中的请求登录函数为ReqUserLogin,传入的参数一共包含两个:一个CSecurityFtdcReqUserLoginField 结构体的指针,一个代表请求编号的整数。

封装后的API函数为reqUserLogin,传入参数同样为两个:一个Python字典对象、一个整数。reqUserLogin函数会从Python字典对象中根据键值依次提取结构体中对应的数据。如结构体中有一个成员叫做BrokerID,则使用getChar函数从字典对象中提取"BrokerID"键对应的值。

getChar函数的实现如下: :::c++ //d为Python字典对象 //key为d中想要提取的数据的键名 //value为最终需要这个数据的结构体成员的指针 void getChar(dict d, string key, char *value) { //首先检查字典中是否存在key这个键 if (d.has_key(key)) { //提取key这个键对应的值,即Python对象o object o = d[key];

        //生成从o中提取std::string类的提取器
        extract<string> x(o);

        //检查提取器是否能提取出数据
        if (x.check())
        {
            //执行解包器,提取string对象s
            string s = x();

            //从s中获取字符串指针buffer
            const char *buffer = s.c_str();

            //将字符串指针指向的字符串数组复制到结构体成员的指针上
            //对字符串指针赋值必须使用strcpy_s, vs2013使用strcpy编译通不过
            //+1应该是因为C++字符串的结尾符号?不是特别确定,不加这个1会出错
            strcpy_s(value, strlen(buffer) + 1, buffer);
        }
    }
};

(以上代码截取自vnltsmd.cpp文件)

由于原生API中用到的底层数据类型主要包括四种:char字符、char[]字符串数组、int整数、double浮点数,可以对应的Python中的数据类型为:string、int、float。因此设计了三个函数getChar、getInt、getDouble来从Python对象中提取所需的C++数据,getInt、getDouble请参见源代码。

原生API的回调函数

void MdApi::OnRspUserLogin(CSecurityFtdcRspUserLoginField *pRspUserLogin, CSecurityFtdcRspInfoField *pRspInfo, int nRequestID, bool bIsLast)
{
    Task task = Task();
    task.task_name = ONRSPUSERLOGIN;
    task.task_data = *pRspUserLogin;
    if (pRspInfo)
    {
        task.task_error = *pRspInfo;
    }
    else
    {
        CSecurityFtdcRspInfoField empty_error = CSecurityFtdcRspInfoField();
        memset(&empty_error, 0, sizeof(empty_error));
        task.task_error = empty_error;
    }
    task.task_id = nRequestID;
    task.task_last = bIsLast;
    this->task_queue.push(task);
};

(以上代码截取自vnltsmd.cpp文件)

当登录成功后,原生API中的回调函数OnRspUserLogin会被自动调用,通知用户登录相关的信息,传入参数包括四个,分别为CSecurityFtdcRspUserLoginField结构体指针(用户本次登录的相关信息)pRspUserLogin,CSecurityFtdcRspInfoField结构体指针(登录是否存在错误的相关信息)pRspInfo,整数(登陆请求编号)nRequestID和布尔值(是否为该请求的最后一次通知)bIsLast。

在回调函数中,我们通过创建一个Task对象来保存这些信息,并推入task_queue中,等待工作线程的提取处理。其中,由于pRspInfo可能存在空指针的情况,所以需要进行判断,若指针为空,则在Task对象上绑定一个内容为空的CSecurityFtdcRspInfoField结构体(这步等于一个异常情况的处理)。ONRSPUSERLOGIN是一个整数常量(在头文件中定义),用于标识该Task对象包含的是哪个回调函数返回的信息。

Task对象的定义如下: :::c++ //任务结构体 struct Task { int task_name; //回调函数名称对应的常量 any task_data; //数据结构体 any task_error; //错误结构体 int task_id; //请求id bool task_last; //是否为最后返回 };

(以上代码截取自vnltsmd.h文件)

其中any是boost库中的any类,作用是定义一个可以存放任意类型数据的变量(有点类似于Python里的变量),但是当用户尝试从该变量中获取原本的数据时,需要知道原本数据的类型。原生API中不同回调函数返回的参数类型是不同的,因此为了提高代码的简洁性选择使用boost.any这个泛型类。

任务处理函数

首先是负责从任务队列中提取任务,并根据任务名称的不同使用对应的函数进行处理的processTask函数:

///-------------------------------------------------------------------------------------
///工作线程从队列中取出数据,转化为python对象后,进行推送
///-------------------------------------------------------------------------------------
void MdApi::processTask()
{
    while (1)
    {
        Task task = this->task_queue.wait_and_pop();

        switch (task.task_name)
        {
            ...

            case ONRSPUSERLOGIN:
            {
                this->processRspUserLogin(task);
                break;
            }

            ...
        };
    }
};

(以上代码截取自vnltsmd.cpp文件)

使用while (1)的方式让processTask处于无限循环中不断运行,从task_queue队列中提取任务对象task后,使用swtich根据任务的回调函数名称task_name,调用对应的函数处理该任务。上面的例子中,当程序检查task_name是ONRSPUSERLOGIN这个常量值后,就会调用processRspUserLogin函数进行处理,其代码如下:

void MdApi::processRspUserLogin(Task task)
{
    CSecurityFtdcRspUserLoginField task_data = any_cast<CSecurityFtdcRspUserLoginField>(task.task_data);
    dict data;
    data["MaxOrderRef"] = task_data.MaxOrderRef;
    data["UserID"] = task_data.UserID;
    data["TradingDay"] = task_data.TradingDay;
    data["SessionID"] = task_data.SessionID;
    data["SystemName"] = task_data.SystemName;
    data["FrontID"] = task_data.FrontID;
    data["BrokerID"] = task_data.BrokerID;
    data["LoginTime"] = task_data.LoginTime;

    CSecurityFtdcRspInfoField task_error = any_cast<CSecurityFtdcRspInfoField>(task.task_error);
    dict error;
    error["ErrorMsg"] = task_error.ErrorMsg;
    error["ErrorID"] = task_error.ErrorID;

    this->onRspUserLogin(data, error, task.task_id, task.task_last);
};

(以上代码截取自vnltsmd.cpp文件)

any_cast函数由boost.any库提供,作用之前提到的从any变量中提取出用户需要的数据类型来。dict类由boost.python库提供,使用dict可以直接创建Python环境中的字典,同时当我们使用d[key] = value这种语句进行赋值时,dict中的key和value均会自动转换为对应的Python对象。当我们将返回的业务信息CSecurityFtdcRspUserLoginField结构体和错误信息结构体CSecurityFtdcRspInfoField分别转换为data和error这两个Python字典后,我们就可以通过onRspUserLogin回调函数推送到Python环境中了。

总结

之前几段示例代码展示的是用户登陆这个简单业务操作,包括了从用户在Python中调用主动函数到柜台通过回调函数返回信息再推送到Python中的全过程。文章主要是对源代码中的注释起到一个更为细致的解释作用。同样这篇内容对于想用vn.py做量化平台开发的用户而言不是必须掌握的东西,放在这里主要是考虑教程的完整性,看不懂的就先跳过吧。

下一章是vn.py平台中API部分的编译方法,github上项目里的.pyd文件可能由于你的操作系统或者编译器和作者本人的不同没法直接使用,必须自行编译,整个教程会包含一步步的截图和说明,包教包会(还不会的可以到github上提问 :p )。

CTP_将C++封装为Python可调用接口 使用pybind11和setuptools的方式封装CTP接口为python可调用 阅读详情

相关推荐

跨品种套利 - 期货

1. 原理 什么是套利? 套利是指在买入或卖出一种金融资产的同时卖出或买入另一种相关的金融资产从中利用价差获得套利的过程。 什么是跨品种套利? 当两个合约有很强的相关性时,可能存在相似的变动关系,两种合约之间的价差会维持在一定的水平上。当市场出现变化时,两种合约之间的价差会偏离均衡水平。此时,可以买入其中一份合约同时卖出其中一份合约,当价差恢复到正常水平时平仓,获取收益。 以大商所玉米和淀粉为例,合约分别为DCE.c1801和DCE.cs1801。二者之间相关性为0.7333,价差处于相对稳定合理

小壁虎的春天 1782

python从0到1:期货量化交易系统(CTP实战,高频及合成K线数据

独一无二的期货实战课程,助你从零到精通!无论你是否了解期货交易,我们都将从零开始,带领你逐步入门,并最终掌握基于CTP接口的期货交易系统开发。我们注重细节,用简单易懂的语言一句一句地解释代码,让你轻松理解Python语言开发的技巧。课程中,我们将教授创建多线程CTP交易系统的方法,特别强调策略系统与行情系统的分离,确保策略系统能够及时、准确地运行。更棒的是,我们所教授的CTP交易系统支持实盘交易,并且可根据你的个性化需求进行修改和功能定制。这意味着你可以根据不同的策略进行灵活应对。除此之外,在课程中我们还会介绍如何利用神经网络进行量化交易。这将是你在期货交易道路上的一大优势。最后,我们提供配套社群和全程答疑服务。你将加入一个活跃的社群,与其他学员共同学习并互相支持。同时,你还可以随时向我们提问,我们将全程为你解答疑惑。现在就加入我们的期货实战课程,成为一名真正的期货交易大师! 

三大主流交易接口实战指南:XTP、CTP与数字货币API接入解析

本文深入解析了量化交易中三大主流交易接口:XTP、CTP与数字货币API的实战接入。文章对比了各自在A股、期货及数字货币市场的应用场景、核心优势与开发要点,并提供了详细的代码示例与避坑指南,旨在帮助开发者根据策略需求选择最合适的接口,顺利完成实盘交易系统的搭建。

docker7nomad的博客 1420

Python - 期货CTP常见问题解答

Python - 期货CTP常见问题解答

weixin_49634344的博客 7143

Python-CTPAPI:Python CTP API

一,简介 此CTP Python API在Windows上由Python3.X系列互不兼容,所以分别编译了Python3.7和Python3.8的版本,在Windows上使用时请安装相应的Python版本,linux上无此问题。该API是用swig方法在官方C ++ API上编译得到的,完全开放的,有兴趣自己编译的读者Windows64版可以参考笔者博客,Linux版只需要参考笔者其他博客,更改下makefile即可。此方法编译得到的API在数据结构,参数名,函数名及用法上与C ++版API完全一致,十分容易上手。 Github上是否不方便下,请到gitee上下载扫码进入QQ群群文件中下载。编译维护不易,欢迎星级,叉鼓励。 二,文件清单 . |-- 6.3.19_API接口说明_20200511.chm //官方文档,也可至http://www.sfit.com.cn/下载(加了日期便于区别版本) |-- demo //相关demo,见下面章节详述 | |-- calculate_volume_delta.py | |-- candle_demo.py | |-- md_

ctpwrapper:上海期货交易所CTP接口 Shanghai Future CTP Interface CTP Python API Wrapper

CTP期货API Python包装器 版本:v6.5.1 P1(v6.5.1 20200908) 平台:Linux 64位,Windows 64位 Python需求:x86-64 特别支持PyPy3-3.6 Linux 64bit 灵感来自Lovelylain 安装 在安装ctpwrapper软件包之前,需要确保已安装cython软件包。 >>>pip install cython --upgrade >>>pip install ctpwrapper --upgrade 捐赠[逐步] :warning: :warning: 注意 :warning: :warning: 有时引用市场期货数据,但API流中没有交易数据,最好在调用Init()方法后添加time.sleep(2) func调用,这可能有助于解决无数据响应的问题。 演示版 样本代码样本 文献资料 CTP文档可以在文档中找到 接触 如果您对ctpwrapper A

【量化】Python量化交易平台vnpy开发-汇总笔记

文章目录0.引言1.类CTP交易API的工作原理2.类CTP交易API的Python封装设计3.vn.py项目中API封装的编译4.事件驱动引擎原理和使用5.底层接口对接6.中层引擎设计7.顶层GUI界面开发(1)8.顶层GUI界面开发(2) 文章专栏:https://zhuanlan.zhihu.com/vn-py 开源代码:https://github.com/vnpy/vnpy [5年前的文...

GreatXiang888的博客 3643

基于Python的CTP交易接口.zip

python

Python量化交易平台开发教程系列1-类CTP交易API的工作原理

转自:https://zhuanlan.zhihu.com/p/20031646?columnSlug=vn-py 用python的交易员  · 2 年前 转载请注明出处:用Python的交易员 类CTP交易API简介 国内程序化交易技术的爆发式发展几乎就是起源于上期技术公司基于CTP柜台推出了交易API,使得用户可以随意开发自己的交易软件直接连接到交易柜台上进行交易,同时CT

gavinking0110的博客 5339

AS5600磁编码器IIC通信与角度读取实战指南

本文提供了AS5600磁编码器通过IIC通信协议实现高精度角度读取的完整实战指南。详细解析了硬件连接要点、IIC通信时序、Arduino与STM32平台驱动代码,并分享了多圈测量、噪声滤波等进阶应用与避坑技巧,帮助开发者快速将这款非接触式角度传感器集成到电机控制、旋钮等项目中。

weixin_29172201的博客 243

【NVIDIA Jetson Orin系列 - 安装NVIDIA SDK Manager】

NVIDIA Jetson Orin - 安装NVIDIA SDK Manager

dally2的博客 2695

期货量化交易入门系列二——CTP和CTP API的概念

摘要: CTP(Comprehensive Transaction Platform)是上海期货交易所自主研发的核心期货/期权交易系统,提供交易、行情、风控等功能。CTP API是其编程接口,分为交易接口和行情接口,支持自动化交易与数据获取,具有低延迟、异步通信等技术特点。开发者需通过C++或封装语言接入,流程包括登录认证、行情订阅和交易指令处理。CTP API适用于高频交易、量化策略等场景,优势在于低延迟和稳定性,但开发复杂度较高。与其它API相比,CTP专攻境内市场且生态丰富。学习资源包括官方文档和开源

mdd2012的专栏 4739

《C语言小游戏之贪吃蛇程序代码》

//为广大编程游戏爱好者提供一个参考的游戏源代码#include&lt;stdio.h&gt;#include&lt;conio.h&gt;#include&lt;windows.h&gt;#include&lt;time.h&gt;#define framex 5#define framey 5#define wide 20#define high 20int i,j,a[2];//将光标移动到...

qq_42052821的博客 2万+

CTP收集行情数据封装接口方法集合

基于C++/CLI开发和封装CTP接口供C#托管代码进行调用 https://blog.youkuaiyun.com/u011439313/article/details/81175342 Python量化交易平台开发教程系列1-类CTP交易API的工作原理 https://blog.youkuaiyun.com/Trader_Python/article/details/52856760 CTP入门: https://...

weixin_40975356的博客 2116

目标检测YOLO实战应用案例100讲-基于数据融合的SAR图像中海上目标检测与跟踪(中)

本文使用的数据集为欧空局(European Space Agency, ESA)提供的Sentinal-1 数据集,Sentinel-1是欧洲“哥白尼计划”的SAR卫星机群,主要是用于陆地和海 洋服务的极地轨道全天候昼夜雷达成像任务[ 34]。Sentinel-1A于2014年4月3日发 射升空,Sentinel-1B于2016年4月25日发射升空,每颗卫星都携带C波段SAR, 共同提供地球表面的全天候、昼夜图像。

qq_36130719的博客 361

《YOLO26/YOLO11/YOLOv8改进与系统实战》,改进与系统实战专栏目录和介绍

YOLOv8 是目前比较火和比较成熟的深度学习框架,是2023年1月发布的,由 Ultralytics 团队开发。Ultralytics自YOLOv5 开始一直积极维护和更新 YOLO 框架,因此 YOLOv8 也享有持续的维护与升级支持。因此我写下《手把手教你YOLOv8实战》专栏,专门为那些对计算机视觉、深度学习、以及目标检测技术感兴趣的读者设计。通过本专栏,你将深入理解 YOLOv8 的核心原理与实际应用,从0 开始学习并掌握如何使用 YOLOv8 完成各类目标检测任务,帮助你快速上手并掌握 YOLO

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 1万+

Python量化交易利器:pyctp让CTP开发变得简单高效

在金融交易领域,CTP(Comprehensive Transaction Platform)作为中国期货市场的主流交易接口,其重要性不言而喻。然而,对于Python开发者而言,直接使用CTP API往往面临诸多挑战。pyctp项目应运而生,为Python开发者提供了一个简洁、易用的CTP封装解决方案。 ## 什么是pyctp? pyctp是一个专为Python开发者设计的CTP API封装库

gitblog_00486的博客 975

一条 POST 创建整棵业务对象树,SAP Gateway Deep Create 的运行机制与 ABAP 实现

SAPUI5 的 OData V2 Model 支持 Deep Create,可以为一个新建的 transient parent context 创建 Navigation Property 下的 subentity,并把这些子实体的数据合并进 Root Entity 对应的 OData 请求 Payload。销售组织是否合法,客户是否允许下单,物料是否存在,销售区域是否匹配,计量单位是否正确,项目类别如何确定,定价是否成功,合作伙伴如何派生,交货工厂如何确定,这些都可能在一次创建过程中被触发。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 149

[转载]Python量化交易平台开发教程系列1-类CTP交易API的工作原理

原文出处:http://vnpy.org/2015/03/05/20150305_Python%E9%87%8F%E5%8C%96%E4%BA%A4%E6%98%93%E5%B9%B3%E5%8F%B0%E5%BC%80%E5%8F%91%E6%95%99%E7%A8%8B%E7%B3%BB%E5%88%971-%E7%B1%BBCTP%E4%BA%A4%E6%98%93API%E7%9...

dijiesa4351的博客 988

深度解析大众点评反爬机制:构建高可用店铺评论采集系统(2026最新实战)

在中文互联网数据采集领域,大众点评(现归属美团)始终占据着特殊地位。其丰富的UGC(用户生成内容)包含了超过2亿条真实店铺评论、数百万家商户的详细POI信息以及用户行为数据,对商业分析、口碑监测、本地生活趋势研究具有不可替代的价值。然而,大众点评的安全团队投入了顶级资源构建反爬系统——从请求签名、行为验证到设备指纹,其防御强度甚至超过多数电商平台。本文将完整呈现一套2026年依然有效的技术方案,包括破解核心参数_token、动态代理池维护、无头浏览器指纹伪装等,最终产出一个生产级采集框架。目录。

2201_76125261的博客 815

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

python量化交易:基础知识_基于Python的开源量化交易平台开发框架vnpy-转自github

基于Python的开源量化交易平台开发框架 http://www.vnpy.com By Traders, For Traders. vn.py是一套基于Python的开源量化交易系统开发框架,自2015年1月正式发布以来,在开源社区5年持续不断的贡献下一步步成长为全功能量化交易平台,目前国内外金融机构用户已经超过300家,包括:私募基金、证券自营和资管、期货资管和子公司、高校研究机构...

santirenpc的博客 7191

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

python量化交易平台开发教程系列_Python量化交易平台开发教程系列0-引言

原创文章,转载请注明出处:用Python的交易员为什么用Python来开发量化交易平台目前本人所在的公司一共有三款平台,分别基于C++, C#和Python。其中C#和Python平台都是由交易员开发;C++平台则是由专职IT团队作为一个通用平台开发,内部组件进行了封装(交易员不可见),对外提供行情、交易的API用于策略开发(除了C++ 外也包括C#和Python可用的API)。理论上这款C++平...

weixin_39695490的博客 288

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Python量化交易终极指南:利用CTP接口构建专业级金融系统

在当今高速发展的金融市场中,Python量化交易已成为机构投资者和个人交易者的重要工具。本文深入解析如何通过pyctp库高效接入CTP接口,构建稳定可靠的自动化交易系统。 ## 为什么选择Python进行量化交易开发? ### 传统交易系统开发的痛点 传统金融交易系统开发面临诸多挑战:复杂的底层接口、跨平台兼容性问题、繁琐的配置流程,这些都严重影响了开发效率和系统稳定性。特别是对于中小型投资

gitblog_00560的博客 987

python-期货CTP接口封装

使用cython对CTP接口完成封装:低延时,基于Cython释放GIL;支持多路行情源;无需主事件引擎,实现去中心化。忠实于CTP官方特性:充分利用CTP的异步、多线程特性

syealfalfa的博客 4708
上一篇: Python量化交易平台开发教程系列1-类CTP交易API的工作原理
下一篇: Python量化交易平台开发教程系列3-vn.py项目中API封装的编译
Trader_Python
博客等级 码龄11年 392粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值