VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 8
声望: 1

首先感谢tonywang_efun
https://www.vnpy.com/forum/topic/1472-ju-kuan-shu-ju-jddatasdk-ji-cheng-fang-an-qi-chang-da-yi-nian

直接上方案:
1、在site-packages目录下新建文件夹vnpy_jqdata
2、在vnpy_jqdata目录下,新建init.py
3、在vnpy_jqdata目录下,新建jqdata_datafeed.py
代码:
init.py

import importlib_metadata

from .jqdata_datafeed import JqdataDatafeed as Datafeed


try:
    __version__ = importlib_metadata.version("vnpy_jqdata")
except importlib_metadata.PackageNotFoundError:
    __version__ = "dev"

jqdata_datafeed.py代码:

import jqdatasdk as jq
from datetime import timedelta, datetime
import datetime
from typing import List

from vnpy.trader.constant import Exchange, Interval
# from vnpy.trader.mddata.dataapi import MdDataApi
from vnpy.trader.datafeed import BaseDatafeed
from vnpy.trader.object import BarData, HistoryRequest
from vnpy.trader.setting import SETTINGS

from pytz import timezone

CHINA_TZ = timezone("Asia/Shanghai")

INTERVAL_VT2JQ = {
    Interval.MINUTE: '1m',
    Interval.HOUR: '60m',
    Interval.DAILY: '1d',
}

INTERVAL_ADJUSTMENT_MAP_JQ = {
    Interval.MINUTE: timedelta(minutes=1),
    Interval.HOUR: timedelta(hours=1),
    Interval.DAILY: timedelta()  # no need to adjust for daily bar
}


class JqdataDatafeed(BaseDatafeed):
    """聚宽JQData客户端封装类"""

    def __init__(self):
        """"""
        self.username = SETTINGS["jqdata.username"]
        self.password = SETTINGS["jqdata.password"]

        self.inited = False

    def init(self, username="", password=""):
        """"""
        if self.inited:
            return True

        if username and password:
            self.username = username
            self.password = password

        if not self.username or not self.password:
            return False

        try:
            jq.auth(self.username, self.password)
        except Exception as ex:
            print("jq auth fail:" + repr(ex))
            return False

        self.inited = True
        return True

    def to_jq_symbol(self, symbol: str, exchange: Exchange):
        """
        CZCE product of RQData has symbol like "TA1905" while
        vt symbol is "TA905.CZCE" so need to add "1" in symbol.
        """
        if exchange in [Exchange.SSE, Exchange.SZSE]:
            if exchange == Exchange.SSE:
                jq_symbol = f"{symbol}.XSHG"  # 上海证券交易所
            else:
                jq_symbol = f"{symbol}.XSHE"  # 深圳证券交易所
        elif exchange == Exchange.SHFE:
            jq_symbol = f"{symbol}.XSGE"  # 上期所
        elif exchange == Exchange.CFFEX:
            jq_symbol = f"{symbol}.CCFX"  # 中金所
        elif exchange == Exchange.DCE:
            jq_symbol = f"{symbol}.XDCE"  # 大商所
        elif exchange == Exchange.INE:
            jq_symbol = f"{symbol}.XINE"  # 上海国际能源期货交易所
        elif exchange == Exchange.CZCE:
            # 郑商所 的合约代码年份只有三位 需要特殊处理
            for count, word in enumerate(symbol):
                if word.isdigit():
                    break
            # Check for index symbol
            time_str = symbol[count:]
            if time_str in ["88", "888", "99", "8888", "9999"]:
                return f"{symbol}.XZCE"
            # noinspection PyUnboundLocalVariable
            product = symbol[:count]
            year = symbol[count]
            month = symbol[count + 1:]
            if year == "9":
                year = "1" + year
            else:
                year = "2" + year
            jq_symbol = f"{product}{year}{month}.XZCE"

        return jq_symbol.upper()

    def query_bar_history(self, req: HistoryRequest):
        """
        Query history bar data from JQData.
        """
        symbol = req.symbol
        exchange = req.exchange
        interval = req.interval
        start = req.start
        end = req.end

        jq_symbol = self.to_jq_symbol(symbol, exchange)
        # if jq_symbol not in self.symbols:
        #     return None

        jq_interval = INTERVAL_VT2JQ.get(interval)
        if not jq_interval:
            return None

        # For adjust timestamp from bar close point (RQData) to open point (VN Trader)
        # adjustment = INTERVAL_ADJUSTMENT_MAP_JQ.get(interval)
        adjustment = INTERVAL_ADJUSTMENT_MAP_JQ[interval]
        # For querying night trading period data
        end += timedelta(1)

        df = jq.get_price(
            jq_symbol,
            frequency=jq_interval,
            fields=["open", "high", "low", "close", "volume"],
            start_date=start,
            end_date=end,
            skip_paused=True,
        )

        data: List[BarData] = []

        if df is not None:
            for ix, row in df.iterrows():
                bar = BarData(
                    symbol=symbol,
                    exchange=exchange,
                    interval=interval,
                    datetime=row.name.to_pydatetime() - adjustment,
                    open_price=row["open"],
                    high_price=row["high"],
                    low_price=row["low"],
                    close_price=row["close"],
                    volume=row["volume"],
                    gateway_name="JQ"
                )
                data.append(bar)

        return data
Member
avatar
加入于:
帖子: 1
声望: 0

请问 这个只是供回测用的是吧 如果我要模拟盘 接入bar数据 当作行情来使用可以么

Member
avatar
加入于:
帖子: 8
声望: 1

nameless13 wrote:

请问 这个只是供回测用的是吧 如果我要模拟盘 接入bar数据 当作行情来使用可以么

我这里是可以的,你也可以自己试下。

Member
avatar
加入于:
帖子: 14
声望: 0

lxero wrote:

nameless13 wrote:

请问 这个只是供回测用的是吧 如果我要模拟盘 接入bar数据 当作行情来使用可以么

我这里是可以的,你也可以自己试下。

聚宽有实时数据?

Member
avatar
加入于:
帖子: 2
声望: 0

我的vnpy 2.7版本,尝试上述操作之后,启动不了,一直出发异常,请问是不兼容2.7吗?

Member
avatar
加入于:
帖子: 4618
声望: 284

可以贴一下报错信息

Member
avatar
加入于:
帖子: 2
声望: 0

已经解决了

Member
avatar
加入于:
帖子: 5
声望: 0

能再说具体些吗,vt_setting要修改吗

Member
avatar
加入于:
帖子: 101
声望: 9

如果要换成该数据服务,需要更改vt_setting中的datafeed相关字段

Member
加入于:
帖子: 3
声望: 0

yumi wrote:

我的vnpy 2.7版本,尝试上述操作之后,启动不了,一直出发异常,请问是不兼容2.7吗?
问下我按照帖子设置完后,在datafeed那里填jqdata和账号密码等也触发异常,在jqdata填又不会成功下载数据
你是怎么解决的?

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】