交易接入
jvQuant OpenAPI直达券商,提供多种登录及交易方式。支持股票、可转债、ETF基金交易操作。
您只需输入对应券商的资金账号密码,即可调用jvQuant OpenAPI进行交易。
*个人账户仅支持东方财富登录,机构账户无限制。
分配服务器
为实现更好的用户体验,jvQuant会根据您所在的地区分配合适的服务器。
注意:
每次分配的服务器地址会发生变化,连接服务前,请务必调用该接口获取最新的服务器地址。
分配服务器地址:
http://jvQuant.com/query/server?market=ab&type=trade&token=<token>
Copy
接口参数:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | market | string | 市场标志,沪深为ab |
2 | type | string | 接口类别,交易类别为trade |
3 | token | string | jvQuant token |
接口返回:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | code | string | 请求状态码 |
2 | server | string | 分配服务器地址及端口号 |
返回示例:
{
"code": "0",
"server": "xx.xx.x.xx:xxxx"
}
Copy
登录柜台
输入交易账户及密码,通过柜台验证后返回授权交易凭证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].usable_vol | string | 可用数量 |
5.5 | hold_list[x].day_earn | string | 当日盈亏 |
5.6 | 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
交易在线测试
WEBSOCKET行情接入
欢迎使用jvQuant行情服务,请按照下面的步骤完成行情接入。
分配服务器
为实现更好的用户体验,jvQuant会根据您所在的地区分配合适的服务器。
注意:
每次分配的服务器地址会发生变化,连接服务前,请务必调用该接口获取最新的服务器地址。
获取服务器:
http://jvQuant.com/query/server?market=ab&type=websocket&token=<token>
Copy
接口参数:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | market | string | 市场标志,沪深为ab |
2 | type | string | 接口类别,行情类别为websocket |
3 | token | string | jvQuant token |
接口返回:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | code | string | 请求状态码 |
2 | server | string | 分配服务器地址及端口号 |
返回示例:
{
"code": "0",
"server": "xx.xx.x.xx:xxxx/xxx"
}
Copy
CODE规范
jvQuant支持沪深主板、科创板、创业板,股票以及可转债、ETF基金行情,提供level1和level2数据推送。
订阅代码由行情标志
和证券代码
组成,用分隔符"_
"连接。
如:
lv1_600519,代表贵州茅台level1行情
lv1_512170,代表医疗ETF level1行情
lv2_127063,代表贵轮转债level2行情
# | 行情标志 | 类型 | 描述 |
---|---|---|---|
1 | lv1 | string | level1行情 |
2 | lv2 | string | level2行情 |
连接登录
使用分配的服务器地址,通过websokcet协议连接服务器。
websocket接口地址:
ws://xx.xx.x.xx:xxxx/xxx?token=<token>
Copy
订阅行情
创建websocket连接后,您可以输入以下指令进行行情订阅:
# | 指令 | 参数 | 描述 |
---|---|---|---|
1 | add | string | 增加订阅code |
2 | del | string | 删除订阅code |
3 | all | string | 覆盖全部code |
4 | list | string | 查看全部订阅code |
指令后接code参数,用分隔符"=
"连接,多个code用分隔符",
"分隔。
例:
add=lv1_600519,lv2_127063
,表示增加订阅lv1_600519,lv2_127063行情。
del=lv1_600519,lv2_127063
,表示删除订阅lv1_600519,lv2_127063行情。
all=lv1_600519
,表示覆盖全部订阅code。
all=
,后接参数为空,表示删除全部订阅code。
list
,无需参数,表示查看全部订阅code。
解析行情
为提高数据传输速率,行情推送采用二进制方式传输,请在接收端解压缩为字符串。
level1
level1行情推送数据以换行符"\n
"为分隔,每一行以lv1_xxxxxx=为开头,代表该类别code对应的行情。
lv1每笔交易数据字段以",
"为分隔符,定义如下:
推送时间,
证券名称,
最新价格,
涨幅,
成交量,
成交额,
买五档[挂单数量,挂单价格],
卖五档[挂单数量,挂单价格]
leve1推送数据包格式如下:
lv1_证券代码1=推送时间
,
证券名称,
最新价格,
涨幅,
成交量,
成交额,
买五档[挂单数量,挂单价格],
卖五档[挂单数量,挂单价格]...lv1_证券代码2=推送时间
,
证券名称,
最新价格,
涨幅,
成交量,
成交额,
买五档[挂单数量,挂单价格],
卖五档[挂单数量,挂单价格]...
level2
level2行情推送数据以换行符"\n
"为分隔,每一行以lv2_xxxxxx=为开头,代表该类别code对应的行情。
同一时刻会存在多笔交易,以"|
"为分隔符。
lv2每笔交易数据字段以",
"为分隔符,定义如下:
成交时间(毫秒),
成交编号,
成交价格,
成交数量/(股)
推送数据包格式如下:
lv2_证券代码1=成交时间1,成交编号1,成交价格1,成交数量1|成交编号2,成交时间2,成交价格2,成交数量2...
lv2_证券代码2=成交时间1,成交编号1,成交价格1,成交数量1|成交编号2,成交时间2,成交价格2,成交数量2...
行情在线测试
历史行情
jvQuant提供2008创立至今的历史股票行情数据,包含沪深主板、科创板、创业板,股票日内行情。
下载地址
http://jvquant.com/query/history?&token=<token>&year=<数据年份>.zip
Copy
例:下载2021年沪深主板、科创板、创业板全部股票(约6000只)日内行情,数据包大小约1.1G,链接为:
http://jvquant.com/query/history?&token=<token>&year=2021.zip
Copy
在线数据库服务
自定义泛查
jvQuant基于自然语言处理技术,支持多模态自然语言处理,精准拆分查询条件,联表超1600G数据可查。
利用多模态的能力,可以轻松实现程序编码较为复杂的策略选股功能
例如,做波段低吸,关注近日有过异动的股票,query示例如下:
query=融券余额小于100万,近一周上过龙虎榜大于2次,昨日低开,昨日大单买入,集合竞价换手率>0.1
早盘09:25筛选集合竞价抢筹,实时买一量较多的票,query示例如下:
query=集合竞价量比大于5,买一量大于1000手
支持API调用,实时行情融合多张数据表,智能联合条件,语义化查询即可解决建库和程序编写的难题。
SQL API参数:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | acc | string | 账户名 |
2 | token | string | jvQuant token |
3 | mode | string | 查询模式,语义查询模式mode为sql |
4 | query | string | 查询语句,多个条件逗号分隔 |
5 | page | int | 查询页表,限定每次查询不超过100条数据 |
语义泛查支持多种查询模式举例:
#数据字段值查询
query=股票代码,股票名称,涨幅,市盈率,行业,量比,买一量,主力流入,昨日开盘涨幅,昨日开盘成交额
#字段精确条件:
query=沪深主板,非ST,市盈率,行业,昨日最高涨幅大于4,前2日最低涨幅小于8
#字段模糊条件:
query=集合竞价抢筹,30日均线向上,macd底背离
#多个指定日期条件查询(历史数据支持最近3年):
query=2015-09-13跌停,2015-09-14涨停
#多个条件组合查询:
主板,市盈率大于60,或者(华为概念并且市盈率小于50)
相较于自主建库,jvQuant在线数据库拥有更广数据,提供更灵活的查询方式,无需熟悉SQL语句,无需自建服务器。
保存查询语句即可实时生成筛选策略
更多条件和组合请前往在线测试。
K线获取
K线可用于形态趋势分析或收益回测。自主线下建库可降低网络查询耗时。
接口参数:
# | 参数名 | 类型 | 描述 |
---|---|---|---|
1 | acc | string | 账户名 |
2 | token | string | jvQuant token |
3 | mode | string | 查询模式,K线查询模式mode为kline |
4 | cate | string | 指定品种,stock/bond/etf/index,缺省默认为stock |
5 | code | string | 查询代码,支持股票/债券/ETF基金/指数等 |
6 | type | string | K线类型,支持日线(day),周线(week),月线(month),缺省默认为day |
7 | fq | string | 复权类型,支持前复权/后复权/不复权,缺省默认为前复权 |
8 | limit | int | 限定查询K线长度,最长支持30年倒查,按需查询可加快查询速度 |
计费标准
行情
行情订阅采用按天计费方式,一个自然天内只计费一次。
行情报价如下:
# | 行情类别 | 单价 | 描述 |
---|---|---|---|
1 | leve1 | 2分 | 订阅level1行情 单价 |
2 | leve2 | 2毛 | 订阅level2行情 单价 |
交易
交易API采用按量计费方式,个人账户单次报单最高限额100万,机构账户按合同规则计费。
交易接口报价如下:
# | 类别 | 单价 | 描述 |
---|---|---|---|
1 | 查询持仓信息 | 2分 | 查询持仓 单价 |
2 | 查询交易信息 | 2分 | 查询交易 单价 |
3 | 委托买入 | 2毛 | 买入报单 单价 |
4 | 委托卖出 | 2毛 | 卖出报单 单价 |
5 | 撤销委托 | 2毛 | 撤销委托 单价 |
6 | 登录柜台 | 5毛 | 登录柜台 单价 |
历史数据
历史数据采用按次计费方式,按年份划分压缩包,下载一次数据包单价为20元
历史数据报价如下:
# | 年份 | 单价 | 描述 |
---|---|---|---|
1 | 2008~至今 | 20元/年 | 每一年数据价格 |
在线数据库服务
数据库服务采用按次计费方式,每个自然日刷新计费周期。
数据库服务报价如下:
# | 类别 | 单价 | 描述 |
---|---|---|---|
1 | 自定义查询 | 1分 | 每100次计费一次 |
2 | K线获取 | 1分 | 每100次计费一次 |
积分明细
为保护您的隐私安全,jvQuant不会记录您的调用明细,只提供当日调用聚合统计。
请留意您的调用记录,避免产生对账偏差。
行情
行情账单出账期为5s,按行情类别进行聚合统计。
日内新增订阅code产生一次计费操作,请前往账户主页关注订阅统计。
交易
交易账单出账期为1min,按交易接口类别进行聚合统计。
新增API调用产生一次计费操作,请前往账户主页关注调用统计。
行情接入示例
PYTHON
#!python3
# -*- coding:utf-8 -*-
import time
import websocket
import zlib
# 发送订阅
def on_open(ws):
ws.send("all=lv2_600519,lv1_000001")
# 接收推送
def on_message(ws, message, type, flag):
# 命令返回文本消息
if type == websocket.ABNF.OPCODE_TEXT:
print(time.strftime('%H:%M:%S', time.localtime(time.time())), "Text响应:", message)
# 行情推送压缩二进制消息,在此解压缩
if type == websocket.ABNF.OPCODE_BINARY:
rb = zlib.decompress(message, -zlib.MAX_WBITS)
print(time.strftime('%H:%M:%S', time.localtime(time.time())), "Binary响应:", rb.decode("utf-8"))
def on_error(ws, error):
print(error)
def on_close(ws, code, msg):
print(time.strftime('%H:%M:%S', time.localtime(time.time())), "连接已断开")
wsUrl = "ws://<服务器地址>?token=<jvQuant token>"
ws = websocket.WebSocketApp(wsUrl,
on_open=on_open,
on_data=on_message,
on_error=on_error,
on_close=on_close)
ws.run_forever()
Copy
GOLANG
package main
import (
"bytes"
"compress/flate"
"github.com/gorilla/websocket"
"log"
"time"
)
func main() {
//连接地址
wsUrl := "ws://<服务器地址>?token=<jvQuant token>"
conn, _, err := websocket.DefaultDialer.Dial(wsUrl, nil)
if err != nil {
log.Fatalln("连接错误:", err)
}
//接收协程
go func() {
receive(conn)
}()
//发送订阅
cmd := "all=lv2_600519,lv1_000001"
err = conn.WriteMessage(websocket.TextMessage, []byte(cmd))
if err != nil {
log.Fatalln("发送指令错误:", err)
}
log.Println("发送指令成功,等待接收")
for {
time.Sleep(time.Second)
}
}
func receive(conn *websocket.Conn) {
for {
//阻塞接收
messageType, rb, err := conn.ReadMessage()
if err != nil {
log.Fatalln("接收错误:", err)
return
}
//文本消息
if messageType == websocket.TextMessage {
log.Println("Text响应:", string(rb))
}
//二进制消息
if messageType == websocket.BinaryMessage {
unZipByte := DeCompress(rb)
log.Println("Binary推送:", string(unZipByte))
}
}
}
//解压方法
func DeCompress(b []byte) []byte {
var buffer bytes.Buffer
buffer.Write([]byte(b))
reader := flate.NewReader(&buffer)
var result bytes.Buffer
result.ReadFrom(reader)
reader.Close()
return result.Bytes()
}
Copy
PHP
<?php
//需安装swoole扩展
use Swoole\Coroutine\Http\Client;
use function Swoole\Coroutine\run;
run(function () {
//服务器地址
$host = '<服务器地址>';
//服务器端口
$port = <服务器端口>;
//连接
$conn = new Client($host, $port);
$conn->upgrade("/?token=<jvQuant token>");
//发送订阅
$conn->push("add=lv2_600519,lv1_000001");
//开启接收协程
go("receive", $conn);
});
function receive($client)
{
while (true) {
$data = $client->recv();
$time = date("H:i:s");
//解压
@$zipStr = gzinflate($data->data);
if ($zipStr) {
echo "{$time} Binary推送:{$zipStr}\n";
} else {
echo "{$time} Text响应:{$data->data}\n";
}
}
}