KTL 用C++14写公式的K线工具 - 0.9.3版
K,K线,Candle蜡烛图。
T,技术分析,工具平台
L,公式Language语言使用c++14,Lite小巧简易。
项目仓库:https://github.com/bbqz007/KTL
国内仓库:https://gitee.com/bbqz007/KTL
当前0.9.3。修正代码编辑器不能调整窗口大小的问题。
新功能以patch.cpprest.7z方式提供,包含源代码。需要手动解压。
关键字:pplx, cpprest, sina finance, baidu gushitong.
新功能如下:
这个版本,加入pplx,cpprest编程模块。使用者可以在本工具使用pplx更简单地写异步代码, 使用cpprest更方便地写异步http,包括http请求数据还有http服务提供数据。
cpprest使用boost178,包含最小的asio头文件依赖。
然后提供应用工具,请求新浪财经数据,使用百度股市通opendata的api请求数据。
先来简单介绍pplx。是一个简化的PPL,相似地为java或javascript的Promise。用于简单方便地写异步应用。
将一个完整流程逻辑,拆分成一段一段的contination。第个contination借助pplx;:task投放到线程池。你可以wait()在当前控制的线程手动同步,或者then()让它在线程池事件循环异步等待结果。
auto task = create_task([]{
return 1;
})
.then([](int){
return 1.;
})
.then([](double){
return std::string("end");
});
这里面安排了三个task,它们构成一个简单的filter-pipeline,前者的输出结果作为后者的输入参数。并且三个task在线程池自动完成分派。
下面是map-reduce形式
std::vector<task<int> > maps = {
create_task([]{
return 1;
}),
create_task([]{
return 12;
}),
create_task([]{
return 13;
}),
create_task([]{
return 14;
}),
};
auto reduce = when_all(maps.begin(), maps.end())
.then([=](auto){
int sum = 0;
for_each(maps.begin(), maps.end(),
[&](auto& task){
sum += task.get();
});
return sum;
});
reduce.get();
产生4个map任务并发, 然后reduce所有结果,一共5个task在线程池自动完成。
为了有更好的控制,这里有一个可等待事件,task_completion_event。我们可以用它作为一个事件源,借助一个task用它作为参数就可以进行同步或异步等待了,类似于future。
我们可以将这个future用作输入源,让安排好异步任务链等待输入才开始执行。
task_completion_event<int> future;
task<int> start(future);
auto pipeline = start.then([](int i){
return i;
})
.then([](int i){
return i;
})
.then([](double){
return std::string("end");
}); start.set(0);
pipeline.wait();
或者利用这个future,让pplx线程池外的线程也参与到pplx异步任务链。让pplx异步任务等待外部线程的结果。
再次指出,then()异步等待,并不阻塞任何线程,它是由线程池的事件循环完成异步等待的。
本工具提供的pplx,其底层基于asio。所有可以用asio的timer进行async_wait。结合task_completion_event,可以实现delay。
pplx::task<void> delay_post(std::chrono::milliseconds delay) {
boost::asio::io_service& io_service = pplx::threadpool::shared_instance().io_service();
pplx::task_completion_event<void> tce;
auto timer = std::make_shared<boost::asio::steady_timer>(io_service);
timer->expires_after(delay);
timer->async_wait([tce, timer](const boost::system::error_code& ec) mutable {
if (!ec) {
tce.set();
} else {
tce.set_exception(std::make_exception_ptr(std::runtime_error("Timer error: " + ec.message())));
}
});
return pplx::create_task(tce);
}了
了解更多pplx,我写了另一篇《浅析pplx库的设计与实现。》
再来介绍cpprest。
cpprest就是cpp实现的rest开发库。线程模型使用pplx,http使用asio的实现。全程支持异步。
对于http client。主要两步,异步等待response,然后异步读取content。当http_client接收读取出status跟header fields后,response完成等待,然后就可以对streambuf进行异步读取content数据。
对于http server。借助于pplx异步模型,灵活性大。一个request不再由一个线程从开头处理到结束。而是把处理逻辑拆分成异步片段。在线程池进行异步任务链处理。这样就可以将http请求实现成poll。
下面就用BlackJack例子说明。
客户端状态机如下:

0,准备开局,接受投注。
>0, 开局中。
1, 需要轮询,等待下一步。
2, 进行处理环节,可以操作。
0, 结束,得出结果。
开始时,大家都在状态0,并进行投注,服务器原子等待所有人都投注后才能开局。
服务器会阻塞所有投注请求,直到人齐数了,才会开局并发出response。
服务器不会将线程阻塞来等待其它投注进来,而是将request作为异步上下文缓存起来。当人数齐后,进行开局逻辑处理,并发出response通知开局信息,包含状态切换。
收到1的玩家,必须调用接口refresh阻塞轮询。收到2的玩家进入服务状态,进行牌局交互操作。结束后,服务器通知其切换状态1进入轮询等待。并选出一下玩家通知它的轮询切换状态2。
服务器通过缓存起全部轮询请求,以确保一桌人数同时在线。
全部玩家相继完成服务环节后,服务器向每人的轮询请求发出结果。并知会状态切换0。


BlackJack例子的实现就是利用pplx的异步优势。
本工具提供的BlackJack例子完全使用cpprest的BlackJack例程,逻辑没有任何修改。原例程应用于控制台标准输入输出,为了让其应用在界面,我只是将标准输入替换成QTextStream再指向pipe,标准输出替换成stringstream。
这样一来,原例程就可以原原本本地作为台后部分运行,界面作为前台部分运行。前后台之间用两条流进行数据交互。
要将cpprest线程池的数据更新到ui线程,我们需要将数据投递到ui线程执行。在win32界面我们可以PostMessage到线程队列,虽然qt没有线程队列,但是基于qt事件循环的线程,每个qt对象都可充当线程队列角色,我说的是signal队列。为方便,我们只需要借用任意一个qt对象的signal就可以了,不必新写一个qt对象只为了定义一个signal。在此,我就借用QFutureWatcher的signal finished(),用作投递方法。

struct MyQFutureWatcher : public QFutureWatcher<int>
{
~MyQFutureWatcher()
{
OutputDebugStringA("~MyQFutureWatcher");
}
QMutex mtx;
QList<std::function<void()> > queue;
MyQFutureWatcher(QObject *parent = nullptr)
: QFutureWatcher(parent)
{
QObject::connect(this, &QFutureWatcher<int>::finished, [=](){
_sched();
});
}
void sched(std::function<void()>& functor)
{
mtx.lock();
queue.push_back(functor);
mtx.unlock();
/// Z#20241210, bug, Q_EMIT dispatch in caller's thread
//Q_EMIT finished(); // to sched
QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
}
private:
void _sched()
{
QList<std::function<void()> > coll;
mtx.lock();
coll = std::move(queue);
mtx.unlock();
while (!coll.empty())
{
coll.front()();
coll.pop_front();
}
}
};
MyUIExecutor
于是有界面例程:

编写服务器也简单方便,虚函数handle_XXX对应于http请求方法的入口,只要override这些虚函数,再根据uri进行不同服务接口处理。
然后就是本工具的新增的主要功能。
通过两个例子,介绍如何使用cpprest写代码,请求新浪财经的数据,使用百度股市通的opendata接口请求数据。
对于新浪财务数据,就是页面的表格。我们可以用QTextEdit转换成MarkDown。

下面就是百度的opendata数据接口,它们在webpack://finance-pc/src/api/路径下api_prefix.js跟detail.js,有详细的注释说明。数据涵盖多个市场,A股,港股,美股,货币,有色金属等。

本功能使用了两个接口,第一个是码表搜索。第二个是基本行情。所有接口皆用JSON承载数据。
本功能帮助大家调试分析这些接口的数据。每次请求结果会在下方树型表缓冲。右键树型节点打开不同功能。根节点预览并转换格式保存文件。对于JSON的对象节点,右键打开属性路径搜索。叶子节点则是复制值。

除了上面两个固定网站的接口应用例子,还可以使用通用请求。

现就用通用请求跟BlackJack例子一同测试一下。

本功能的源代码, 已经完整展示了如何使用cpprest调用opendata接口,如何使用cpprest写界面交互。使用者可以根据需要修改裁剪扩展,满足自己需要的功能。 使用cpprest从其它股票相关网站获取数据也是十分方便。有cpprest借助pplx加承,不必费心多线程跟io并发,轻轻松松写异步http请求。

还有一点注意, cpprest默认使用unicode,qt字符串底层也是使用unicode。其它json11,pugihtml需要utf8。
本篇结束。
KTL 用C++14写公式的K线工具 - 0.9.3版的更多相关文章
- KTL 一个支持C++14编辑公式的K线技术工具平台 - 第四版,稳定支持Qt5编程,zqt5语法升级,MA函数提升性能1000%,更多公式算法的内置优化实现。
K,K线,Candle蜡烛图. T,技术分析,工具平台 L,公式Language语言使用c++14,Lite小巧简易. 项目仓库:https://github.com/bbqz007/KTL 国内仓库 ...
- KTL 一个支持C++14编辑公式的K线技术工具平台 - 第五版,支持sqlite3,全新sqlite3zz语法超简单使用sqlite3; 添加方差等统计函数。
K,K线,Candle蜡烛图. T,技术分析,工具平台 L,公式Language语言使用c++14,Lite小巧简易. 项目仓库:https://github.com/bbqz007/KTL 国内仓库 ...
- KTL 一个支持C++14编辑公式的K线技术工具平台 - 第六版,支持OpenGL,3D上帝视角俯视K线概貌。
K,K线,Candle蜡烛图. T,技术分析,工具平台 L,公式Language语言使用c++14,Lite小巧简易. 项目仓库:https://github.com/bbqz007/KTL 国内仓库 ...
- KTL 一个支持C++14编辑公式的K线技术工具平台 - 第七版,体验GPGPU。
K,K线,Candle蜡烛图. T,技术分析,工具平台 L,公式Language语言使用c++14,Lite小巧简易. 项目仓库:https://github.com/bbqz007/KTL 国内仓库 ...
- Python交互K线工具 K线核心功能+指标切换
Python交互K线工具 K线核心功能+指标切换 aiqtt团队量化研究,用vn.py回测和研究策略.基于vnpy开源代码,刚开始接触pyqt,开发界面还是很痛苦,找了很多案例参考,但并不能完全满足我 ...
- 小白学Python(14)——pyecharts 绘制K线图 Kline/Candlestick
Kline-基本示例 from pyecharts import options as opts from pyecharts.charts import Kline data = [ [2320.2 ...
- 个人整理方幂和公式(∑i^k 公式)
有个Oier小学妹问了我一个Σi^k,i<=1e8 ,k<=1e6的问题,我认为这个用伯努利数列可能可以解决他的问题,所以整理了以下文章,给学弟学习学习~~~本人水平有限,也只能帮到这里了 ...
- 基于MATLAB的手写公式识别(转折)
2021-03-29 21:11:00 很难说自己是不是上当受骗了,老师明明说利用MATLAB进行手写体(记得是手写体,再不济印刷体)的识别是轻而易举的. 平时我也十分喜欢MATLAB这一操作系统,认 ...
- 基于MATLAB的手写公式识别(6)
基于MATLAB的手写公式识别 2021-03-29 10:24:51 走通了程序,可以识别"心脑血管这几个字",还有很多不懂的地方. 2021-03-29 12:20:01 tw ...
- 基于MATLAB的手写公式识别(2)
基于MATLAB的手写公式识别 图像的预处理(除去噪声.得到后续定位分割所需的信息.) 预处理其本质就是去除不需要的噪声信息,得到后续定位分割所需要的图像信息.图像信息在采集的过程中由于天气环境的影响 ...
随机推荐
- JNI和HAL 的区别
JNI (Java Native Interface) 和 HAL (Hardware Abstraction Layer) 在 Android 系统中都扮演着与本地代码交互的重要角色,但它们的功能和 ...
- Nuxt.js 应用中的 page:transition:finish 钩子详解
title: Nuxt.js 应用中的 page:transition:finish 钩子详解 date: 2024/10/10 updated: 2024/10/10 author: cmdrago ...
- 宝塔部署java后端项目
1. 安装插件 宝塔面板找到软件商店然后搜索 Java java项目管理安装 安装后点击设置准备安装 tomcat 2. 添加项目
- 65.说下vue3的使用感想(说些vue3对比vue3的方便之处)
vue3 使用了组合式API,setup 替换了选项式api ,不需要在多个api里面写代码了,而且使用了setup的语法糖,可以更加方便写代码 : vue3使用proxy替代了Object.defi ...
- 云原生周刊:K8s 的 YAML 技巧 | 2023.12.4
开源项目推荐 Helmfile Helmfile 是用于部署 Helm Chart 的声明性规范.其功能有: 保留图表值文件的目录并维护版本控制中的更改. 将 CI/CD 应用于配置更改. 定期同步以 ...
- PHP的json浮点精度难题
前言 之前开发的接口需要用到json加签,有一次对接JAVA时,签名怎么都过不了,仔细对比了字符串,发现是PHP进行json_encode时,会将浮点型所有无意义的0给去掉(echo和var_dump ...
- 【小 w 的代数】(提供一种 n^2 log 的解法)
前言: 卖点 记录 CTH 的发言 CTH:你这真是 n^3 的 CTH:我也不知道你线段树优化个啥,\(n^3 \log n\) CTH:你优化到哪了啊 CTH:······你从赛时打这个题到现在 ...
- redis的CPA三进二原则
CAP C:consistency,数据在多个副本中能保持一致的状态. A:Availability,整个系统在任何时刻都能提供可用的服务,通常达到99.99%四个九可以称为高可用 P:Partiti ...
- CSS动画(波光粼粼登录页面)
1.整体效果 https://mmbiz.qpic.cn/sz_mmbiz_gif/EGZdlrTDJa4AbemkU3vLRIDzTIgPHSjicia97wfvMVAhqZL4lsGbQQCbsV ...
- PBI自定义视觉对象环境配置
开发文档地址:https://docs.microsoft.com/zh-cn/power-bi/service-custom-visuals-getting-started-with-develop ...