From b83599bc54a0485deeee02d78551da6714beeff2 Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Thu, 11 Apr 2019 15:25:54 +0800 Subject: [PATCH 1/3] [Fix]close #1580 --- vnpy/gateway/ctp/ctp_gateway.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vnpy/gateway/ctp/ctp_gateway.py b/vnpy/gateway/ctp/ctp_gateway.py index f1a25811..057e6db8 100644 --- a/vnpy/gateway/ctp/ctp_gateway.py +++ b/vnpy/gateway/ctp/ctp_gateway.py @@ -553,7 +553,7 @@ class CtpTdApi(TdApi): ) # For option only - if data["OptionsType"]: + if contract.product == Product.OPTION: contract.option_underlying = data["UnderlyingInstrID"], contract.option_type = OPTIONTYPE_CTP2VT.get(data["OptionsType"], None), contract.option_strike = data["StrikePrice"], From 1d6506c5f3a57b37e30351c7b7e414351a54c867 Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Thu, 11 Apr 2019 16:54:43 +0800 Subject: [PATCH 2/3] [Del]remove Singleton --- vnpy/trader/engine.py | 4 ++-- vnpy/trader/utility.py | 19 ------------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/vnpy/trader/engine.py b/vnpy/trader/engine.py index af136dab..2d4a98e0 100644 --- a/vnpy/trader/engine.py +++ b/vnpy/trader/engine.py @@ -24,7 +24,7 @@ from .event import ( from .gateway import BaseGateway from .object import CancelRequest, LogData, OrderRequest, SubscribeRequest from .setting import SETTINGS -from .utility import Singleton, get_folder_path +from .utility import get_folder_path class MainEngine: @@ -197,7 +197,7 @@ class BaseEngine(ABC): pass -class LogEngine(BaseEngine, metaclass=Singleton): +class LogEngine(BaseEngine): """ Processes log event and output with logging module. """ diff --git a/vnpy/trader/utility.py b/vnpy/trader/utility.py index 6f023259..1f40aa77 100644 --- a/vnpy/trader/utility.py +++ b/vnpy/trader/utility.py @@ -12,25 +12,6 @@ import talib from .object import BarData, TickData -class Singleton(type): - """ - Singleton metaclass, - - usage: - class A(metaclass=Singleton): - ... - """ - _instances = {} - - def __call__(cls, *args, **kwargs): - """""" - if cls not in cls._instances: - cls._instances[cls] = super(Singleton, cls).__call__( - *args, **kwargs - ) - return cls._instances[cls] - - def _get_trader_dir(temp_name: str): """ Get path where trader is running in. From b3961dbb84cbeb1c75c6dc63f55e1e0b37c811b8 Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Thu, 11 Apr 2019 16:56:19 +0800 Subject: [PATCH 3/3] [Add]history data cache in cta backtesting to improve speed --- vnpy/app/cta_backtester/engine.py | 1 + vnpy/app/cta_strategy/backtesting.py | 71 ++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/vnpy/app/cta_backtester/engine.py b/vnpy/app/cta_backtester/engine.py index adcab59d..4dc80589 100644 --- a/vnpy/app/cta_backtester/engine.py +++ b/vnpy/app/cta_backtester/engine.py @@ -165,6 +165,7 @@ class BacktesterEngine(BaseEngine): self.write_log("已有回测在运行中,请等待完成") return False + self.write_log("-" * 40) self.thread = Thread( target=self.run_backtesting, args=( diff --git a/vnpy/app/cta_strategy/backtesting.py b/vnpy/app/cta_strategy/backtesting.py index 5712f798..c1ba8e67 100644 --- a/vnpy/app/cta_strategy/backtesting.py +++ b/vnpy/app/cta_strategy/backtesting.py @@ -2,6 +2,7 @@ from collections import defaultdict from datetime import date, datetime from typing import Callable from itertools import product +from functools import lru_cache import multiprocessing import numpy as np @@ -197,28 +198,18 @@ class BacktestingEngine: self.output("开始加载历史数据") if self.mode == BacktestingMode.BAR: - s = ( - DbBarData.select() - .where( - (DbBarData.vt_symbol == self.vt_symbol) - & (DbBarData.interval == self.interval) - & (DbBarData.datetime >= self.start) - & (DbBarData.datetime <= self.end) - ) - .order_by(DbBarData.datetime) + self.history_data = load_bar_data( + self.vt_symbol, + self.interval, + self.start, + self.end ) - self.history_data = [db_bar.to_bar() for db_bar in s] else: - s = ( - DbTickData.select() - .where( - (DbTickData.vt_symbol == self.vt_symbol) - & (DbTickData.datetime >= self.start) - & (DbTickData.datetime <= self.end) - ) - .order_by(DbTickData.datetime) + self.history_data = load_tick_data( + self.vt_symbol, + self.start, + self.end ) - self.history_data = [db_tick.to_tick() for db_tick in s] self.output(f"历史数据加载完成,数据量:{len(self.history_data)}") @@ -970,3 +961,45 @@ def optimize( target_value = statistics[target_name] return (str(setting), target_value, statistics) + + +@lru_cache(maxsize=10) +def load_bar_data( + vt_symbol: str, + interval: str, + start: datetime, + end: datetime +): + """""" + s = ( + DbBarData.select() + .where( + (DbBarData.vt_symbol == vt_symbol) + & (DbBarData.interval == interval) + & (DbBarData.datetime >= start) + & (DbBarData.datetime <= end) + ) + .order_by(DbBarData.datetime) + ) + data = [db_bar.to_bar() for db_bar in s] + return data + + +@lru_cache(maxsize=10) +def load_tick_data( + vt_symbol: str, + start: datetime, + end: datetime +): + """""" + s = ( + DbTickData.select() + .where( + (DbTickData.vt_symbol == vt_symbol) + & (DbTickData.datetime >= start) + & (DbTickData.datetime <= end) + ) + .order_by(DbTickData.datetime) + ) + data = [db_tick.db_tick() for db_tick in s] + return data \ No newline at end of file