用于EagleEye3.0 规则集漏报和误报测试的示例项目,项目收集于github和gitee
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

171 lines
4.3 KiB

3 months ago
"""
General utility functions.
"""
import json
from pathlib import Path
from typing import Callable
from .constant import Exchange
def extract_full_symbol(full_symbol: str):
"""
:return: (symbol, exchange)
"""
tmp = full_symbol.split(' ')
if len(tmp) < 4:
return "unknwonsymbol", Exchange.SHFE
symbol = tmp[2] + tmp[3]
exchange_str = tmp[0]
ex = Exchange(exchange_str)
if ex in [Exchange.SHFE, Exchange.DCE, Exchange.INE]:
symbol = symbol.lower()
return symbol, ex
# from ctp symbol to full symbol
def generate_full_symbol(exchange: Exchange, symbol: str, type: str = 'F'):
product = ''
contractno = ''
fullsym = symbol
if symbol:
if type == 'F' or type == 'O':
for count, word in enumerate(symbol):
if word.isdigit():
break
product = symbol[:count]
contractno = symbol[count:]
fullsym = exchange.value + ' ' + type + ' '\
+ product.upper() + ' ' + contractno
elif type == 'S':
combo = symbol.split(' ', 1)[1]
symbol1 = combo.split('&')[0]
symbol2 = combo.split('&')[1]
for count, word in enumerate(symbol1):
if word.isdigit():
break
product = symbol1[:count]
contractno = symbol1[count:]
for count, word in enumerate(symbol2):
if word.isdigit():
break
product += ('&' + symbol2[:count])
contractno += ('&' + symbol2[count:])
fullsym = exchange.value + ' ' + type + ' '\
+ product.upper() + ' ' + contractno
return fullsym
def extract_vt_symbol(vt_symbol: str):
"""
:return: (symbol, exchange)
"""
symbol, exchange_str = vt_symbol.split('.')
return symbol, Exchange(exchange_str)
def generate_vt_symbol(symbol: str, exchange: Exchange):
return f'{symbol}.{exchange.value}'
def _get_trader_dir(temp_name: str):
"""
Get path where trader is running in.
"""
cwd = Path.cwd()
temp_path = cwd.joinpath(temp_name)
# If .StarQuant folder exists in current working directory,
# then use it as trader running path.
if temp_path.exists():
return cwd, temp_path
# Otherwise use home path of system.
home_path = Path.home()
temp_path = home_path.joinpath(temp_name)
# Create .StarQuant folder under home path if not exist.
if not temp_path.exists():
temp_path.mkdir()
return home_path, temp_path
TRADER_DIR, TEMP_DIR = _get_trader_dir(".StarQuant")
def get_file_path(filename: str):
"""
Get path for temp file with filename.
"""
return TEMP_DIR.joinpath(filename)
def get_folder_path(folder_name: str):
"""
Get path for temp folder with folder name.
"""
folder_path = TEMP_DIR.joinpath(folder_name)
if not folder_path.exists():
folder_path.mkdir()
return folder_path
def get_icon_path(filepath: str, ico_name: str):
"""
Get path for icon file with ico name.
"""
ui_path = Path(filepath).parent
icon_path = ui_path.joinpath("ico", ico_name)
return str(icon_path)
def load_json(filename: str):
"""
Load data from json file in temp path.
"""
filepath = get_file_path(filename)
if filepath.exists():
with open(filepath, mode='r') as f:
data = json.load(f)
return data
else:
save_json(filename, {})
return {}
def save_json(filename: str, data: dict):
"""
Save data into json file in temp path.
"""
filepath = get_file_path(filename)
with open(filepath, mode='w+') as f:
json.dump(data, f, indent=4)
def round_to_pricetick(price: float, pricetick: float):
"""
Round price to price tick value.
"""
rounded = round(price / pricetick, 0) * pricetick
return rounded
def round_to(value: float, target: float):
"""
Round price to price tick value.
"""
rounded = int(round(value / target)) * target
return rounded
def virtual(func: Callable):
"""
mark a function as "virtual", which means that this function can be override.
any base class should use this or @abstractmethod to decorate all functions
that can be (re)implemented by subclasses.
"""
return func