什么叫程序化交易?
既然是程序化交易,少不了"程序"。简单的计算机编程还是容易的,相比excel也差不多。
其次,要能搞到数据,数据是程序的输入源。
再才是策略,构建策略,验证策略,应用策略到实盘中。
总结起来,做程序化交易,你需要接入行情数据,需要交易接口,这两者必不可少。
人脑VS电脑。
人脑对海量数据的学习效率是比不过计算机的。
如果没有计算机的辅助,人眼每天翻3000只股,脑海里也形成不了对市场的认识,甚至很可能因为自己的偏好和既有认知导致得出错误的认识。
获取股票的历史数据,可以从一般的财经网站抓取,一般k线是开放的。
但是作为日内交易,用k线回归数据粒度还是太粗,无法得知某一日内的交易明细,比如开盘后走势,午盘后走势等等。所以如果你做量化,一定要注意从现在开始积累数据,每一分数据都是不可重复获得的。
我每天都会分两个机器接收level1和level2的数据推送,一是注入策略做交易,二来保存文件入库,这也是价值最大化利用。
每天全市场5000多只票,全实盘压缩保存下来,几百兆每天,这都是市场的印记,未来回归时我就有了别人没有的数据,这也是你跟别人的策略结论拉开差别的原因。
所以,做回归回测,历史数据的质量很重要,最好是level2,事无具细,统统记录在案,留着后面由你决定模型回测的粒度。
可以参考下:
level2和level1行情实盘交易差异_FuckTheWindows的博客-CSDN博客
websocket level2行情推送接口 行情实盘记录 历史数据包_FuckTheWindows的博客-CSDN博客
为什么要使用level2行情?
Level-2产品是由上海证券交易所推出的实时行情信息服务,提供在证券交易所上市交易的证券产品的实时交易数据。
相比level1基础行情3秒一次切片推送,level2为实时推送。经FPGA高速分发,每一笔成交延迟可控制在毫秒内。
为什么使用websocket协议推送行情信息?
为保证推送的实时性,任何level2级别交易推送都不可能通过简单的http方式达成,必须依赖长链接的行全双工通信的协议。
WebSocket是一种在单个TCP连接上进行全双工通信的协议。相比普通tcp/udp协议,在保证消息实时性的前提下,websocket提供了更通用的封装。
在交易所交易成交流的场景下,相比http轮询的请求方式,websocket具有更高的吞吐量和更低的延迟。
在接入方式上,常用的编程语言如Python/Golang/PHP/NodeJs都集成有相应的websocket模块,C/C++/JAVA也有相应的代码包可用,可以极大的降低level2行情解析成本。
交易接入
接口参数:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | market | string | 市场标志,沪深为ab |
2 | type | string | 接口类别,交易类别为trade |
3 | token | string | jvQuant token |
接口返回:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | code | string | 请求状态码 |
2 | server | string | 分配服务器地址及端口号 |
登录柜台
输入交易账户及密码,通过柜台验证后返回授权交易凭证ticket。
请妥善保管好交易凭证,在ticket有效期内,您可以免登录进行后续的交易操作。
接口地址:
http://xx.xx.x.xx:xxxx/login?&token=<token>&acc=<资金账号>&pass=<密码>
Copy
接口参数:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | token | string | jvQuant token |
2 | acc | string | 12位资金账号 |
3 | pass | string | 资金交易密码 |
接口返回:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | code | string | 请求状态码 |
2 | ticket | string | 登录凭证 |
2 | expire | int | ticket有效时间(秒) |
返回示例:
{ "code": "0", "ticket": "xxxx", "expire": xxx }
Copy
查询持仓信息
接口地址:
http://xx.xx.x.xx:xxxx/check_hold?&token=<token>&ticket=<交易凭证>
Copy
接口参数:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | token | string | jvQuant token |
2 | ticket | string | 交易凭证ticket |
接口返回:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | message | string | 错误信息 |
2 | total | string | 账户总资产 |
2 | usable | string | 账户可用资金 |
3 | day_earn | string | 账户当日盈亏 |
4 | hold_earn | string | 账户持仓盈亏 |
5 | hold_list | array | 账户持仓明细 |
5.1 | hold_list[x].code | string | 账户持仓证券列表 |
5.2 | hold_list[x].name | string | 持仓证券名 |
5.3 | hold_list[x].hold_vol | string | 持仓数量 |
5.4 | hold_list[x].hold_vol | string | 持仓数量 |
5.5 | hold_list[x].usable_vol | string | 可用数量 |
5.6 | hold_list[x].usable_vol | string | 可用数量 |
5.7 | hold_list[x].day_earn | string | 当日盈亏 |
5.8 | hold_list[x].hold_earn | string | 持仓盈亏 |
返回示例:
{ "code": "0", "message": "", "total": "501527.77", "usable": "422977.27", "day_earn": "16325.27", "hold_earn": "18273.22", "hold_list": [ { "code": "128079", "name": "英联转债", "hold_vol": "0", "usable_vol": "0", "hold_earn": "12242.69", "day_earn": "12242.32" }, { "code": "111013", "name": "新港转债", "hold_vol": "0", "usable_vol": "0", "hold_earn": "-560.93", "day_earn": "-560.96" } ] }
Copy
查询交易信息
接口地址:
http://xx.xx.x.xx:xxxx/check_order?&token=<token>&ticket=<交易凭证>
Copy
接口参数:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | token | string | jvQuant token |
2 | ticket | string | 交易凭证ticket |
接口返回:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | message | string | 错误信息 |
2 | list | array | 交易明细列表 |
2.1 | list[x].order_id | string | 委托编号 |
2.2 | list[x].order_id | day | 委托日期 |
2.3 | list[x].time | string | 委托时间 |
2.4 | list[x].code | string | 委托证券代码 |
2.5 | list[x].name | string | 委托证券名 |
2.6 | list[x].type | string | 委托类型 |
2.7 | list[x].status | string | 委托状态 |
2.8 | list[x].order_price | string | 委托价格 |
2.9 | list[x].order_volume | string | 委托数量 |
2.10 | list[x].deal_price | string | 成交价格 |
2.11 | list[x].deal_volume | string | 成交数量 |
返回示例:
{ "code": "0", "message": "", "list": [ { "order_id": "1334564", "day": "20180402", "time": "142423", "code": "110074", "name": "精达转债", "type": "证券卖出", "status": "已成", "order_price": "151.885", "order_volume": "8000", "deal_price": "151.927", "deal_volume": "8000" } ] }
Copy
委托报单
接口地址:
http://xx.xx.x.xx:xxxx/<trade>?&token=<token>&ticket=<交易凭证>&code=<证券代码>&name=<证券名称>&price=<委托价格>&volume=<委托数量>
Copy
接口参数:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | trade | string | 买入(buy)或卖出(sale) |
2 | token | string | jvQuant token |
3 | ticket | string | 交易凭证ticket |
4 | code | string | 证券代码 |
5 | name | string | 证券名称 |
6 | price | float | 委托价格 |
7 | volume | int | 委托数量 |
接口返回:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | message | string | 错误信息 |
2 | order_id | string | 委托编号 |
返回示例:
{ "code": "0", "message": "", "order_id":"4362316" }
Copy
撤销报单
接口地址:
http://xx.xx.x.xx:xxxx/cancel?&token=<token>&ticket=<交易凭证>&order_id=<委托编号>
Copy
接口参数:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | token | string | jvQuant token |
2 | ticket | string | 交易凭证ticket |
3 | order_id | string | 委托编号 |
接口返回:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | code | string | 返回状态码 |
2 | message | string | 错误信息 |
返回示例:
{ "code": "0", "message": "", "order_id":"4362316" }
Copy