量化必备:Level2实时行情接口和交易报单接口,以及历史数据回测
相同的二级市场,相同的市场数据,为什么自己的账户总是亏的。真正拉开差距的,往往是信息的获取速度和执行效率。 你还在手动盯盘、手动下单的时候,别人已经用程序化交易在毫秒间完成了买卖。
可能他们有更好的策略、更多的资金,或者更丰富的经验。但说实话,这些都不是最核心的原因。
普通投资者接入了实时行情和交易接口,也能搭建自己的量化交易系统。
实时行情接入:为什么Level2行情是量化交易的“刚需”?
很多量化新手一开始都会去抓取基础行情数据,比如Akshare或者一些券商的普通行情接口。但很快就会发现,这些数据远远不够,并发抓取更是灾难。
而且Level2行情根本抓不到,对于高频交易和策略优化来说,Level2行情是必需的数据源。
之前也抓过不少行情源,刷新间隔太大,基本都在3~6s,再刷新拉板都封死了。
Wind 恒生等服务商只对机构合作。只有搞到Level2高速行情,才算是拉平了数据源的差距。用WebSocket接口非常稳定,延迟低,数据全,接入也很简单,没有那么复杂的协议编码。下面是找的一个C++示例,通过WebSocket来接入Level2行情:
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <string>
#include <iostream>
#include <memory>
#include <assert.h>
#include <cstring>
#include "zlib.h"
#define CHUNK 16384
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::client <websocketpp::config::asio_client> client;
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
int DecompressString(const char *in_str, size_t in_len, std::string &out_str);
/**
* 接收处理
*/
void on_message(client *c, websocketpp::connection_hdl hdl, message_ptr msg) {
//文本消息
if (msg->get_opcode()==websocketpp::frame::opcode::text){
std::cout <<"Text响应:"<<msg->get_payload().c_str()<< std::endl;
}
//二进制消息
if (msg->get_opcode()==websocketpp::frame::opcode::binary){
std::string tmp = "";
std::string &out_decompress = tmp;
DecompressString( msg->get_payload().c_str(), msg->get_payload().size(), out_decompress);
std::cout <<"Binary响应:"<<out_decompress<< std::endl;
}
}
/**
* 连接处理
*/
void on_open(client *c, websocketpp::connection_hdl hdl) {
//发送订阅指令
c->send(hdl, "add=lv1_600519,lv2_600519", websocketpp::frame::opcode::text);
std::cout << "连接成功" << std::endl;
}
int main(int argc, char *argv[]) {
//服务地址。 注意:C++版本的地址 问号前需加斜杠
std::string wsUrl = "ws://<服务器地址>/?token=<jvQuant token>";
client c;
//连接相关
try {
//debug日志开关
// c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::all);
c.init_asio();
// 注册处理函数
c.set_message_handler(bind(&on_message, &c, ::_1, ::_2));
c.set_open_handler(bind(&on_open, &c, _1));
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(wsUrl, ec);
if (ec) {
std::cout << "连接失败: " << ec.message() << std::endl;
return 0;
}
c.connect(con);
c.run();
} catch (websocketpp::exception const &e) {
std::cout << e.what() << std::endl;
}
}
/**
*解压缩方法
*/
int DecompressString(const char *in_str, size_t in_len, std::string &out_str) {
if (!in_str)
return Z_DATA_ERROR;
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, -MAX_WBITS);
if (ret != Z_OK)
return ret;
std::shared_ptr <z_stream> sp_strm(&strm, [](z_stream *strm) {
(void) inflateEnd(strm);
});
const char *end = in_str + in_len;
size_t pos_index = 0;
size_t distance = 0;
int flush = 0;
do {
distance = end - in_str;
strm.avail_in = (distance >= CHUNK) ? CHUNK : distance;
strm.next_in = (Bytef *) in_str;
in_str += strm.avail_in;
flush = (in_str == end) ? Z_FINISH : Z_NO_FLUSH;
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR)
break;
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
return ret;
}
have = CHUNK - strm.avail_out;
out_str.append((const char *) out, have);
} while (strm.avail_out == 0);
} while (flush != Z_FINISH);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
copy下来运行就可以实时获取到Level2行情数据,包括买卖盘口、逐笔成交等细节信息。
Python版的Demo请参考:Python 示例 · 开发文档
交易接口:如何实现自动下单?
有了行情数据,接下来就是如何自动下单了。很多量化新手在这一步卡住,因为市面上的交易接口要么不稳定,要么接入复杂。我用的这家服务商提供的交易接口非常简单易用,支持港股、美股和A股的自动下单。
下面是一个简单的交易委托示例:
# 交易委托示例
# 报单模版
http://<柜台地址>/<type>?&token=<token>&ticket=<交易凭证>&code=<证券代码>&name=<证券名称>&price=<委托价格>&volume=<委托数量>
简单的请求,就可以实现自动买入、卖出操作。接口返回的order_id用来跟踪订单状态。
如何快速查询历史数据和生成选股策略?
除了实时行情和交易接口,研究交易策略还需要大量的历史数据进行回测和分析。
K线级别的历史数据很好弄到,各大财经网站都有数据,更细粒度的历史行情就不好弄了。
有些券商提供分时回放功能,这家服务商也有类似功能,历史指数行情也有回放,可以用市场大盘来协同回测股票。
数据库服务还有了智能语义查询功能,类似于智能选股,比写筛选逻辑更简单,校验过,数据都很靠谱。
比如,你想查询沪深主板上非ST股票,且市盈率大于60的股票,用语义化语句这样写:
查询沪深主板上非ST股票,市盈率大于60 query=沪深主板,非ST,市盈率大于60
数据库还支持多条件组合查询、模糊查询等功能,非常适合需要复杂数据筛选的场景。官方的查询语句示例:
字段精确条件
查询沪深主板上非ST股票,要求市盈率、行业,并且昨日最高涨幅大于4%,前2日最低涨幅小于8%:
示例:query=沪深主板,非ST,市盈率,行业,昨日最高涨幅大于4,前2日最低涨幅小于8
字段模糊条件
查询包含“集合竞价抢筹”或“30日均线向上”等模糊条件的股票:
示例:query=集合竞价抢筹,30日均线向上,macd底背离
多个指定日期条件查询(历史数据支持最近3年)
查询在2015年9月13日跌停,且在2015年9月14日涨停的股票(示例中的日期应替换为实际查询的日期):
示例:query=2015-09-13跌停,2015-09-14涨停
多个条件组合查询
查询主板上市盈率大于60的股票,或者属于华为概念且市盈率小于50的股票:
示例:主板,市盈率大于60,或者(华为概念并且市盈率小于50))
实时行情和交易接口以及数据库的更多细节可以参考 官方文档
其实,量化交易的核心在于信息的速度和执行的效率。手动盯盘、手动下单,已经比别人慢了很多。用程序接入实时行情、交易接口和金融数据库,大幅提升交易效率和策略稳定性,剩下的,你只需要研究和检验策略执行效果即可,其他的交给时间。
原文链接:https://zhuanlan.zhihu.com/p/29605505797
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/FuckTheWindows/article/details/146196431
浙公网安备 33010602011771号