[调整CTA基础组件]

This commit is contained in:
msincenselee 2020-03-09 21:52:29 +08:00
parent 4ffbd50496
commit 000ccfef81
18 changed files with 148 additions and 150 deletions

View File

@ -1,18 +1,13 @@
from pathlib import Path
from vnpy.trader.app import BaseApp
from vnpy.trader.constant import Direction,Offset,Status,Color
from vnpy.trader.object import TickData, BarData, TradeData, OrderData
from vnpy.trader.utility import BarGenerator, ArrayManager
from .cta_position import CtaPosition
from .cta_line_bar import CtaLineBar, CtaMinuteBar, CtaHourBar, CtaDayBar, CtaWeekBar
from .base import APP_NAME, StopOrder, CtaComponent
from .cta_policy import CtaPolicy
from .cta_grid_trade import CtaGrid, CtaGridTrade
from .base import APP_NAME, StopOrder
from .engine import CtaEngine
from .template import CtaTemplate, CtaSignal, TargetPosTemplate, CtaProTemplate, CtaProFutureTemplate
from .template_spread import CtaSpreadTemplate
class CtaStrategyProApp(BaseApp):
""""""

View File

@ -370,7 +370,7 @@ class BackTestingEngine(object):
holding = self.holdings.get(k, None)
if not holding:
symbol, exchange = extract_vt_symbol(vt_symbol)
if self.contract_type== 'future':
if self.contract_type == 'future':
product = Product.FUTURES
elif self.contract_type == 'stock':
product = Product.EQUITY
@ -1901,7 +1901,7 @@ class BackTestingEngine(object):
self.daily_max_drawdown_rate = drawdown_rate
self.max_drawdown_rate_time = data['date']
msg = u'{}: net={}, capital={} max={} margin={} commission={} pos: {}'\
msg = u'{}: net={}, capital={} max={} margin={} commission={} pos: {}' \
.format(data['date'],
data['net'], c, m,
today_holding_profit,
@ -1916,11 +1916,13 @@ class BackTestingEngine(object):
# 今仓 =》 昨仓
for holding in self.holdings.values():
if holding.long_td > 0:
self.write_log(f'{holding.vt_symbol} 多单今仓{holding.long_td},昨仓:{holding.long_yd}=> 昨仓:{holding.long_pos}')
self.write_log(
f'{holding.vt_symbol} 多单今仓{holding.long_td},昨仓:{holding.long_yd}=> 昨仓:{holding.long_pos}')
holding.long_td = 0
holding.long_yd = holding.long_pos
if holding.short_td > 0:
self.write_log(f'{holding.vt_symbol} 空单今仓{holding.short_td},昨仓:{holding.short_yd}=> 昨仓:{holding.short_pos}')
self.write_log(
f'{holding.vt_symbol} 空单今仓{holding.short_td},昨仓:{holding.short_yd}=> 昨仓:{holding.short_pos}')
holding.short_td = 0
holding.short_yd = holding.short_pos

View File

@ -1,12 +1,10 @@
"""
Defines constants and objects used in CtaStrategyPro App.
"""
import sys
from abc import ABC
from dataclasses import dataclass, field
from enum import Enum
from datetime import timedelta
from logging import INFO, ERROR
from vnpy.trader.constant import Direction, Offset, Interval
APP_NAME = "CtaStrategyPro"
@ -29,46 +27,6 @@ class BacktestingMode(Enum):
TICK = 2
class Area(Enum):
""" Kline area """
LONG_A = 'LONG_A'
LONG_B = 'LONG_B'
LONG_C = 'LONG_C'
LONG_D = 'LONG_D'
LONG_E = 'LONG_E'
SHORT_A = 'SHORT_A'
SHORT_B = 'SHORT_B'
SHORT_C = 'SHORT_C'
SHORT_D = 'SHORT_D'
SHORT_E = 'SHORT_E'
# 各类商品所在市场underly_symbol: price_tick
# 上期所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~2:30
NIGHT_MARKET_SQ1 = {'AU': 0.05, 'AG': 1, 'SC': 0.1}
# 上期所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~1:00
NIGHT_MARKET_SQ2 = {'CU': 10, 'PB': 5, 'AL': 5, 'ZN': 5, 'WR': 1, 'NI': 10}
# 上期所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~23:00
NIGHT_MARKET_SQ3 = {'RU': 5, 'RB': 1, 'HC': 1, 'SP': 2, 'FU': 1, 'BU': 2, 'NR': 5, 'C': 1, 'CS': 1}
# 郑商所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~23:00
NIGHT_MARKET_ZZ = {'TA': 2, 'JR': 1, 'OI': 0, 'RO': 1, 'PM': 1, 'WH': 1, 'CF': 5, 'SR': 0, 'FG': 1,
'MA': 1, 'RS': 1, 'RM': 1, 'RI': 1, 'ZC': 0.2}
# 大商所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~23:00
NIGHT_MARKET_DL = {'V': 5, 'L': 5, 'BB': 0.05, 'I': 0.5, 'FB': 0.05, 'C': 1, 'PP': 1, 'A': 1, 'B': 1, 'M': 1, 'Y': 2,
'P': 2,
'JM': 0.5, 'J': 0.5, 'EG': 1}
# 中金日盘9:15 ~11:30, 13:00~15:15
MARKET_ZJ = {'IC': 0.2, 'IF': 0.2, 'IH': 0.2, 'T': 0.005, 'TF': 0.005, 'TS': 0.005}
# 只有日盘得合约
MARKET_DAY_ONLY = {'IC': 0.2, 'IF': 0.2, 'IH': 0.2, 'T': 0.005, 'TF': 0.005, 'TS': 0.005,
'JD': 1, 'BB': 0.05, 'CS': 1, 'FB': 0.05, 'L': 5, 'V': 5,
'JR': 1, 'LR': 1, 'PM': 1, 'RI': 1, 'RS': 1, 'SM': 2, 'WH': 1, 'AP': 1, 'CJ': 1, 'UR': 1}
# 夜盘23:00收盘的合约
NIGHT_MARKET_23 = {**NIGHT_MARKET_DL, **NIGHT_MARKET_ZZ, **NIGHT_MARKET_SQ3}
@dataclass
class StopOrder:
vt_symbol: str
@ -93,28 +51,3 @@ INTERVAL_DELTA_MAP = {
Interval.HOUR: timedelta(hours=1),
Interval.DAILY: timedelta(days=1),
}
class CtaComponent(ABC):
""" CTA策略基础组件"""
def __init__(self, strategy=None, **kwargs):
"""
构造
:param strategy:
"""
self.strategy = strategy
def write_log(self, content: str):
"""记录日志"""
if self.strategy:
self.strategy.write_log(msg=content, level=INFO)
else:
print(content)
def write_error(self, content: str, level: int = ERROR):
"""记录错误日志"""
if self.strategy:
self.strategy.write_log(msg=content, level=level)
else:
print(content, file=sys.stderr)

View File

@ -60,11 +60,10 @@ from .base import (
StopOrder,
StopOrderStatus,
STOPORDER_PREFIX,
MARKET_DAY_ONLY
)
from .template import CtaTemplate
from .cta_position import CtaPosition
from vnpy.component.base import MARKET_DAY_ONLY
from vnpy.component.cta_position import CtaPosition
STOP_STATUS_MAP = {
Status.SUBMITTING: StopOrderStatus.WAITING,

View File

@ -12,7 +12,7 @@ import os
import gc
import pandas as pd
import traceback
import random
import bz2
import pickle
@ -21,15 +21,12 @@ from time import sleep
from vnpy.trader.object import (
TickData,
BarData,
RenkoBarData,
)
from vnpy.trader.constant import (
Exchange,
)
from vnpy.trader.utility import (
get_trading_date,
extract_vt_symbol,
get_underlying_symbol,
import_module_by_str
@ -46,6 +43,7 @@ VN_EXCHANGE_TICKFOLDER_MAP = {
Exchange.INE.value: 'SQ'
}
class SpreadTestingEngine(BackTestingEngine):
"""
CTA套利组合回测引擎, 使用回测引擎作为父类
@ -231,7 +229,6 @@ class SpreadTestingEngine(BackTestingEngine):
tick_date.strftime('%Y%m%d'),
'{}{}_{}.csv'.format(underly_symbol.upper(), symbol[-2:], tick_date.strftime('%Y%m%d'))))
ticks = []
if not os.path.isfile(file_path):
self.write_log(u'{0}文件不存在'.format(file_path))

View File

@ -16,8 +16,8 @@ from vnpy.trader.object import BarData, TickData, OrderData, TradeData
from vnpy.trader.utility import virtual, append_data, extract_vt_symbol, get_underlying_symbol
from .base import StopOrder, EngineType
from .cta_grid_trade import CtaGrid, CtaGridTrade, LOCK_GRID
from .cta_position import CtaPosition
from vnpy.component.cta_grid_trade import CtaGrid, CtaGridTrade, LOCK_GRID
from vnpy.component.cta_position import CtaPosition
class CtaTemplate(ABC):

View File

@ -815,7 +815,7 @@ class CtaSpreadTemplate(CtaTemplate):
# 开空委托单
if order_info['direction'] == Direction.SHORT:
short_price = self.cta_engine.get_price(order_vt_symbol) \
- self.cta_engine.get_price_tick(order_vt_symbol)
- self.cta_engine.get_price_tick(order_vt_symbol) # noqa
self.write_log(u'重新提交{}开空委托,开空价{}v:{}'
.format(order_vt_symbol, short_price, order_volume))
@ -834,7 +834,7 @@ class CtaSpreadTemplate(CtaTemplate):
else:
buy_price = self.cta_engine.get_price(order_vt_symbol) \
+ self.cta_engine.get_price_tick(order_vt_symbol)
+ self.cta_engine.get_price_tick(order_vt_symbol) # noqa
self.write_log(u'重新提交{}开多委托,开多价{}v:{}'
.format(order_vt_symbol, buy_price, order_volume))
vt_orderids = self.buy(price=buy_price,
@ -869,8 +869,9 @@ class CtaSpreadTemplate(CtaTemplate):
# 属于平空委托单
else:
cover_price = self.cta_engine.get_price(order_vt_symbol) \
+ self.cta_engine.get_price_tick(order_vt_symbol)
self.write_log(u'重新提交{}平空委托,委托价{}v:{}'.format(order_vt_symbol, cover_price, order_volume))
+ self.cta_engine.get_price_tick(order_vt_symbol) # noqa
self.write_log(u'重新提交{}平空委托,委托价{}v:{}'
.format(order_vt_symbol, cover_price, order_volume))
vt_orderids = self.cover(price=cover_price,
volume=order_volume,
vt_symbol=order_vt_symbol,

View File

72
vnpy/component/base.py Normal file
View File

@ -0,0 +1,72 @@
"""
定义appc常使用的基础组件
"""
import sys
from abc import ABC
from enum import Enum
from logging import INFO, ERROR
class Area(Enum):
""" Kline area """
LONG_A = 'LONG_A'
LONG_B = 'LONG_B'
LONG_C = 'LONG_C'
LONG_D = 'LONG_D'
LONG_E = 'LONG_E'
SHORT_A = 'SHORT_A'
SHORT_B = 'SHORT_B'
SHORT_C = 'SHORT_C'
SHORT_D = 'SHORT_D'
SHORT_E = 'SHORT_E'
# 各类商品所在市场underly_symbol: price_tick
# 上期所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~2:30
NIGHT_MARKET_SQ1 = {'AU': 0.05, 'AG': 1, 'SC': 0.1}
# 上期所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~1:00
NIGHT_MARKET_SQ2 = {'CU': 10, 'PB': 5, 'AL': 5, 'ZN': 5, 'WR': 1, 'NI': 10}
# 上期所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~23:00
NIGHT_MARKET_SQ3 = {'RU': 5, 'RB': 1, 'HC': 1, 'SP': 2, 'FU': 1, 'BU': 2, 'NR': 5, 'C': 1, 'CS': 1}
# 郑商所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~23:00
NIGHT_MARKET_ZZ = {'TA': 2, 'JR': 1, 'OI': 0, 'RO': 1, 'PM': 1, 'WH': 1, 'CF': 5, 'SR': 0, 'FG': 1,
'MA': 1, 'RS': 1, 'RM': 1, 'RI': 1, 'ZC': 0.2}
# 大商所夜盘9:00~10:15, 10:30~11:30, 13:30~15:00, 21:00 ~23:00
NIGHT_MARKET_DL = {'V': 5, 'L': 5, 'BB': 0.05, 'I': 0.5, 'FB': 0.05, 'C': 1, 'PP': 1, 'A': 1, 'B': 1, 'M': 1, 'Y': 2,
'P': 2,
'JM': 0.5, 'J': 0.5, 'EG': 1}
# 中金日盘9:15 ~11:30, 13:00~15:15
MARKET_ZJ = {'IC': 0.2, 'IF': 0.2, 'IH': 0.2, 'T': 0.005, 'TF': 0.005, 'TS': 0.005}
# 只有日盘得合约
MARKET_DAY_ONLY = {'IC': 0.2, 'IF': 0.2, 'IH': 0.2, 'T': 0.005, 'TF': 0.005, 'TS': 0.005,
'JD': 1, 'BB': 0.05, 'CS': 1, 'FB': 0.05, 'L': 5, 'V': 5,
'JR': 1, 'LR': 1, 'PM': 1, 'RI': 1, 'RS': 1, 'SM': 2, 'WH': 1, 'AP': 1, 'CJ': 1, 'UR': 1}
# 夜盘23:00收盘的合约
NIGHT_MARKET_23 = {**NIGHT_MARKET_DL, **NIGHT_MARKET_ZZ, **NIGHT_MARKET_SQ3}
class CtaComponent(ABC):
""" CTA策略基础组件"""
def __init__(self, strategy=None, **kwargs):
"""
构造
:param strategy:
"""
self.strategy = strategy
def write_log(self, content: str):
"""记录日志"""
if self.strategy:
self.strategy.write_log(msg=content, level=INFO)
else:
print(content)
def write_error(self, content: str, level: int = ERROR):
"""记录错误日志"""
if self.strategy:
self.strategy.write_log(msg=content, level=level)
else:
print(content, file=sys.stderr)

View File

@ -10,7 +10,7 @@ import traceback
from collections import OrderedDict
from datetime import datetime
from vnpy.trader.utility import get_folder_path
from vnpy.app.cta_strategy_pro.base import Direction, CtaComponent
from vnpy.component.base import Direction, CtaComponent
"""
网格交易用于套利单

View File

@ -16,17 +16,16 @@ import csv
from collections import OrderedDict
from datetime import datetime, timedelta
from pykalman import KalmanFilter
from vnpy.app.cta_strategy_pro.base import (
from vnpy.component.base import (
Direction,
Area,
MARKET_DAY_ONLY,
NIGHT_MARKET_23,
NIGHT_MARKET_SQ2,
MARKET_ZJ)
from vnpy.app.cta_strategy_pro.cta_period import CtaPeriod, Period
from vnpy.component.cta_period import CtaPeriod, Period
from vnpy.trader.object import BarData, TickData
from vnpy.trader.constant import Interval, Color
from vnpy.trader.utility import round_to, get_trading_date, get_underlying_symbol

View File

@ -4,7 +4,7 @@ import os
import json
from datetime import datetime
from collections import OrderedDict
from vnpy.app.cta_strategy_pro.base import CtaComponent
from vnpy.component.base import CtaComponent
from vnpy.trader.utility import get_folder_path
TNS_STATUS_OBSERVATE = 'observate'

View File

@ -1,8 +1,7 @@
# encoding: UTF-8
import sys
from vnpy.app.cta_strategy_pro.base import Direction, CtaComponent
from vnpy.component.base import Direction, CtaComponent
class CtaPosition(CtaComponent):

View File

@ -17,7 +17,7 @@ os.environ["VNPY_TESTING"] = "1"
from vnpy.trader.constant import Interval, Exchange
from vnpy.data.tdx.tdx_common import FakeStrategy
from vnpy.data.tdx.tdx_future_data import TdxFutureData
from vnpy.app.cta_strategy_pro.cta_line_bar import CtaLineBar
from vnpy.component.cta_line_bar import CtaLineBar
from vnpy.trader.object import TickData
from vnpy.trader.utility import get_trading_date

View File

@ -18,7 +18,7 @@ os.environ["VNPY_TESTING"] = "1"
from vnpy.trader.constant import Interval, Exchange
from vnpy.trader.object import BarData
from vnpy.app.cta_strategy_pro.cta_line_bar import (
from vnpy.component.cta_line_bar import (
CtaLineBar,
CtaMinuteBar,
CtaHourBar,

View File

@ -118,6 +118,7 @@ class RenkoBarData(BarData):
low_time = None # 最后一次进入低位区域的时间
high_time = None # 最后一次进入高位区域的时间
@dataclass
class OrderData(BaseData):
"""

View File

@ -246,7 +246,7 @@ def get_icon_path(filepath: str, ico_name: str):
return str(icon_path)
def load_json(filename: str, auto_save : bool = True):
def load_json(filename: str, auto_save: bool = True):
"""
Load data from json file in temp path.
"""