VeighNa量化社区
你的开源社区量化交易平台 | vn.py | vnpy
Member
avatar
加入于:
帖子: 4
声望: 0

如果用图形界面的的datarecorder,在手动输入合约的情况下是可以进行录制的,但是在no_ui下无法订阅期货合约,增加了输出数据接受日志发现只能接收到期权的数据
代码参考的是enter link description here
顺便问一下,no_ui下如果可以接受数据,存到数据库的速度是否会比图形界面要快
比较小白,真的是解决不了了,先谢谢大佬的解答
description

Member
avatar
加入于:
帖子: 5576
声望: 336

等合约查询成功日志输出之后再去订阅吧

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

现在就是合约查询也查询不到期货合约,输出的合约列表里面只有期权和套利组合

Member
avatar
加入于:
帖子: 5576
声望: 336

是等合约查询成功日志输出之后去查的吗

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

对的,就是等查询成功才开始print合约列表的

Member
avatar
加入于:
帖子: 5576
声望: 336

get_all_contracts里面也没有吗
是实盘还是simnow

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

1.get_all_contracts里面有所有的合约
2.是实盘
完整代码如下

code text here
import sys
import multiprocessing
import re
import pandas as pd
from copy import copy
from enum import Enum
from time import sleep
from datetime import datetime, time
from logging import INFO

from vnpy.event import EventEngine
from vnpy.trader.setting import SETTINGS
from vnpy.trader.engine import MainEngine
from vnpy.trader.utility import load_json, extract_vt_symbol
from vnpy.trader.constant import Exchange
from vnpy.trader.object import BarData, TickData

from vnpy_ctp import CtpGateway
from vnpy_ctastrategy.base import EVENT_CTA_LOG
from vnpy_datarecorder.engine import RecorderEngine

EXCHANGE_LIST = [
    Exchange.SHFE,
    Exchange.DCE,
    Exchange.CZCE,
    Exchange.CFFEX,
    Exchange.INE,
]

SETTINGS["log.active"] = True
SETTINGS["log.level"] = INFO
SETTINGS["log.console"] = True
CTP_SETTING = load_json("connect_ctp.json")


def is_futures(vt_symbol: str) -> bool:
    """
    是否是期货
    """
    match = re.match(r"^[a-zA-Z]{1,3}\d{2,4}.[A-Z]+$", vt_symbol)
    return bool(match)


class RecordMode(Enum):
    BAR = "bar"
    TICK = "tick"


class WholeMarketRecorder(RecorderEngine):
    def __init__(self, main_engine, event_engine, record_modes=[RecordMode.BAR]):
        super().__init__(main_engine, event_engine)
        self.record_modes = record_modes
        self.main_engine.write_log("WholeMarketRecorder初始化")
        # 非交易时间
        self.drop_start = time(3, 15)
        self.drop_end = time(8, 45)

        # 大连、上海、郑州交易所,小节休息
        self.rest_start = time(10, 15)
        self.rest_end = time(10, 30)

    def is_trading(self, vt_symbol, current_time) -> bool:
        """
        交易时间,过滤校验Tick
        """
        symbol, exchange = extract_vt_symbol(vt_symbol)

        if current_time >= self.drop_start and current_time < self.drop_end:
            return False
        if exchange in [Exchange.DCE, Exchange.SHFE, Exchange.CZCE]:
            if current_time >= self.rest_start and current_time < self.rest_end:
                return False
        return True

    def record_tick(self, tick: TickData):
        """
        抛弃非交易时间校验数据
        """
        tick_time = tick.datetime.time()
        if not self.is_trading(tick.vt_symbol, tick_time):
            self.main_engine.write_log(f"非交易时间Tick数据丢弃: {tick}")
            return
        self.main_engine.write_log(f"记录Tick数据: {tick}")
        task = ("tick", [copy(tick)])
        self.queue.put(task)

    def record_bar(self, bar: BarData):
        """
        抛弃非交易时间校验数据
        """
        bar_time = bar.datetime.time()
        if not self.is_trading(bar.vt_symbol, bar_time):
            self.main_engine.write_log(f"非交易时间Bar数据丢弃: {bar}")
            return
        self.main_engine.write_log(f"记录Bar数据: {bar}")
        task = ("bar", [copy(bar)])
        self.queue.put(task)

    def load_setting(self):
        # 不读取原数据记录设置
        pass

    def process_contract_event(self, event):
        """
        设置记录所有期货合约
        """
        contract = event.data

        vt_symbol = contract.vt_symbol

        # self.main_engine.write_log(f"处理合约事件: {contract}")

        # 不录制期权
        if is_futures(vt_symbol):
            self.main_engine.write_log(f"订阅期货合约: {vt_symbol}")
            if RecordMode.BAR in self.record_modes:
                self.add_bar_recording(vt_symbol)
            if RecordMode.TICK in self.record_modes:
                self.add_tick_recording(vt_symbol)
            self.subscribe(contract)
        else:
            self.main_engine.write_log(f"忽略非期货合约: {vt_symbol}")


def run_child():
    """
    Running in the child process.
    """
    SETTINGS["log.file"] = True

    event_engine = EventEngine()
    main_engine = MainEngine(event_engine)
    main_engine.add_gateway(CtpGateway)
    main_engine.write_log("主引擎创建成功")

    # 记录引擎
    log_engine = main_engine.get_engine("log")
    event_engine.register(EVENT_CTA_LOG, log_engine.process_log_event)
    main_engine.write_log("注册日志事件监听")

    main_engine.connect(CTP_SETTING, "CTP")
    main_engine.write_log("连接CTP接口")
    sleep(10)
    # allcontractsinfo = main_engine.get_all_contracts()
    # df = pd.DataFrame(allcontractsinfo)
    # df.to_csv('C:/Users/Administrator/Desktop/1/123.csv')

    whole_market_recorder = WholeMarketRecorder(main_engine, event_engine)
    main_engine.write_log("WholeMarketRecorder创建成功")

    while True:
        sleep(1)


def run_parent():
    """
    Running in the parent process.
    """
    print("启动CTA策略守护父进程")

    # Chinese futures market trading period (day/night)
    MORNING_START = time(8, 45)
    MORNING_END = time(11, 45)

    AFTERNOON_START = time(13, 15)
    AFTERNOON_END = time(15, 15)

    NIGHT_START = time(20, 45)
    NIGHT_END = time(2, 45)

    child_process = None

    while True:
        current_time = datetime.now().time()
        trading = False

        # Check whether in trading period
        if (
                (current_time >= MORNING_START and current_time <= MORNING_END)
                or (current_time >= AFTERNOON_START and current_time <= AFTERNOON_END)
                or (current_time >= NIGHT_START)
                or (current_time <= NIGHT_END)
        ):
            trading = True

        # Start child process in trading period
        if trading and child_process is None:
            print("启动数据录制子进程")
            child_process = multiprocessing.Process(target=run_child)
            child_process.start()
            print("数据录制子进程启动成功")

        # 非记录时间则退出数据录制子进程
        if not trading and child_process is not None:
            print("关闭数据录制子进程")
            child_process.terminate()
            child_process.join()
            child_process = None
            print("数据录制子进程关闭成功")
        sys.stdout.flush()
        sleep(5)


if __name__ == "__main__":
    run_parent()
© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

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