Merge pull request #109 from vnpy/dev

Dev
This commit is contained in:
noranhe
2025-06-17 09:26:24 +08:00
committed by GitHub
16 changed files with 1910 additions and 47 deletions

View File

@@ -17,7 +17,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install ruff mypy uv
uv pip install ta-lib==0.6.3 --index=https://pypi.vnpy.com --system
uv pip install ta-lib==0.6.4 --index=https://pypi.vnpy.com --system
uv pip install -e .[alpha,dev] --system
- name: Lint with ruff
run: |

View File

@@ -3127,14 +3127,14 @@
" dt = datetime.strptime(i, \"%Y%m%d\")\n",
" if dt > end_datetime:\n",
" continue\n",
" \n",
"\n",
" xt_symbols = xtdata.get_stock_list_in_sector(xt_index_symbol, i)\n",
" \n",
"\n",
" vt_symbols: list = []\n",
" for xt_symbol in xt_symbols:\n",
" vt_symbol = xt_symbol.replace(\"SH\", \"SSE\").replace(\"SZ\", \"SZSE\")\n",
" vt_symbols.append(vt_symbol)\n",
" \n",
"\n",
" index_components[dt.strftime(\"%Y-%m-%d\")] = vt_symbols\n",
"\n",
"# 保存到数据中心\n",

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@ IF NOT %pypi_index%"" == "" SET pypi_index=--index-url %pypi_index%
%python% -m pip install --upgrade pip wheel %pypi_index%
::Install prebuild wheel
%python% -m pip install --extra-index-url https://pypi.vnpy.com ta_lib==0.6.3
%python% -m pip install --extra-index-url https://pypi.vnpy.com ta_lib==0.6.4
:: Install VeighNa
%python% -m pip install .

View File

@@ -14,18 +14,18 @@ $python -m pip install --upgrade pip wheel --index $pypi_index
function install-ta-lib()
{
# install numpy first
$python -m pip install numpy==1.23.1 --index $pypi_index
$python -m pip install numpy==2.2.3 --index $pypi_index
pushd /tmp
wget https://pip.vnpy.com/colletion/ta-lib-0.6.3-src.tar.gz
tar -xf ta-lib-0.6.3-src.tar.gz
cd ta-lib
wget https://pip.vnpy.com/colletion/ta-lib-0.6.4-src.tar.gz
tar -xf ta-lib-0.6.4-src.tar.gz
cd ta-lib-0.6.4
./configure --prefix=/usr/local
make -j1
make install
popd
$python -m pip install ta-lib==0.6.3 --index $pypi_index
$python -m pip install ta-lib==0.6.4 --index $pypi_index
}
function ta-lib-exists()
{

View File

@@ -22,8 +22,8 @@ function ta-lib-exists()
ta-lib-exists || install-ta-lib
# install ta-lib
$python -m pip install numpy==1.23.1 --index $pypi_index
$python -m pip install ta-lib==0.6.3 --index $pypi_index
$python -m pip install numpy==2.2.3 --index $pypi_index
$python -m pip install ta-lib==0.6.4 --index $pypi_index
# Install VeighNa
$python -m pip install . --index $pypi_index

View File

@@ -24,12 +24,12 @@ classifiers = [
requires-python = ">=3.10"
dependencies = [
"tzlocal>=5.3.1",
"PySide6>=6.9.0",
"PySide6==6.8.2.1",
"pyqtgraph>=0.13.7",
"qdarkstyle>=3.2.3",
"numpy>=2.2.3",
"pandas>=2.2.3",
"ta-lib>=0.6.3",
"ta-lib>=0.6.4",
"deap>=1.4.2",
"pyzmq>=26.3.0",
"plotly>=6.0.0",

View File

@@ -7,7 +7,7 @@ from multiprocessing.context import BaseContext
import polars as pl
import pandas as pd
from tqdm import tqdm # type: ignore
from tqdm import tqdm
from alphalens.utils import get_clean_factor_and_forward_returns # type: ignore
from alphalens.tears import create_full_tear_sheet # type: ignore
@@ -120,9 +120,9 @@ class AlphaDataset:
# Merge result data factor features
logger.info("开始合并结果数据因子特征")
for name, result in tqdm(self.feature_results.items()):
result = result.rename({"data": name})
self.result_df = self.result_df.join(result, on=["datetime", "vt_symbol"], how="inner")
for name, feature_result in tqdm(self.feature_results.items()):
feature_result = feature_result.rename({"data": name})
self.result_df = self.result_df.join(feature_result, on=["datetime", "vt_symbol"], how="inner")
# Generate raw data
raw_df = self.result_df.fill_null(float("nan"))

View File

@@ -127,7 +127,6 @@ class MlpModel(AlphaModel):
mode="min",
factor=0.5,
patience=10,
verbose=True,
threshold=0.0001,
threshold_mode="rel",
cooldown=0,

View File

@@ -8,7 +8,7 @@ import numpy as np
import polars as pl
import plotly.graph_objects as go # type: ignore
from plotly.subplots import make_subplots # type: ignore
from tqdm import tqdm # type: ignore
from tqdm import tqdm
from vnpy.trader.constant import Direction, Offset, Interval, Status
from vnpy.trader.object import OrderData, TradeData, BarData

View File

@@ -68,6 +68,7 @@ class OrderType(Enum):
FAK = "FAK"
FOK = "FOK"
RFQ = _("询价")
ETF = "ETF"
class OptionType(Enum):

View File

@@ -598,6 +598,7 @@ class EmailEngine(BaseEngine):
with smtplib.SMTP_SSL(server, port) as smtp:
smtp.login(username, password)
smtp.send_message(msg)
smtp.close()
except Exception:
log_msg: str = _("邮件发送失败: {}").format(traceback.format_exc())
self.main_engine.write_log(log_msg, "EMAIL")

View File

@@ -28,6 +28,10 @@ format: str = (
)
# Add default gateway
logger.configure(extra={"gateway_name": "Logger"})
# Log level
level: int = SETTINGS["log.level"]

View File

@@ -8,7 +8,7 @@ from multiprocessing.context import BaseContext
from multiprocessing.managers import DictProxy
from _collections_abc import dict_keys, dict_values, Iterable
from tqdm import tqdm # type: ignore
from tqdm import tqdm
from deap import creator, base, tools, algorithms # type: ignore
from .locale import _
@@ -134,18 +134,23 @@ def run_ga_optimization(
optimization_setting: OptimizationSetting,
key_func: KEY_FUNC,
max_workers: int | None = None,
population_size: int = 100,
ngen_size: int = 30,
output: OUTPUT_FUNC = print
pop_size: int = 100, # population size: number of individuals in each generation
ngen: int = 30, # number of generations: number of generations to evolve
mu: int | None = None, # mu: number of individuals to select for the next generation
lambda_: int | None = None, # lambda: number of children to produce at each generation
cxpb: float = 0.95, # crossover probability: probability that an offspring is produced by crossover
mutpb: float | None = None, # mutation probability: probability that an offspring is produced by mutation
indpb: float = 1.0, # independent probability: probability for each gene to be mutated
output: OUTPUT_FUNC = print,
) -> list[tuple]:
"""Run genetic algorithm optimization"""
# Define functions for generate parameter randomly
buf: list[dict] = optimization_setting.generate_settings()
settings: list[list[tuple]] = [list(d.items()) for d in buf]
settings: list[dict] = optimization_setting.generate_settings()
parameter_tuples: list[list[tuple]] = [list(d.items()) for d in settings]
def generate_parameter() -> list:
""""""
return choice(settings)
return choice(parameter_tuples)
def mutate_individual(individual: list, indpb: float) -> tuple:
""""""
@@ -167,7 +172,7 @@ def run_ga_optimization(
toolbox.register("individual", tools.initIterate, creator.Individual, generate_parameter)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", mutate_individual, indpb=1)
toolbox.register("mutate", mutate_individual, indpb=indpb)
toolbox.register("select", tools.selNSGA2)
toolbox.register("map", pool.map)
toolbox.register(
@@ -178,15 +183,17 @@ def run_ga_optimization(
key_func
)
total_size: int = len(settings)
pop_size: int = population_size # number of individuals in each generation
lambda_: int = pop_size # number of children to produce at each generation
mu: int = int(pop_size * 0.8) # number of individuals to select for the next generation
# Set default values for DEAP parameters if not specified
if mu is None:
mu = int(pop_size * 0.8)
cxpb: float = 0.95 # probability that an offspring is produced by crossover
mutpb: float = 1 - cxpb # probability that an offspring is produced by mutation
ngen: int = ngen_size # number of generation
if lambda_ is None:
lambda_ = pop_size
if mutpb is None:
mutpb = 1.0 - cxpb
total_size: int = len(parameter_tuples)
pop: list = toolbox.population(pop_size)
# Run ga optimization
@@ -197,6 +204,7 @@ def run_ga_optimization(
output(_("迭代次数:{}").format(ngen))
output(_("交叉概率:{:.0%}").format(cxpb))
output(_("突变概率:{:.0%}").format(mutpb))
output(_("个体突变概率:{:.0%}").format(indpb))
start: float = perf_counter()

View File

@@ -49,7 +49,7 @@ def create_qapp(app_name: str = "VeighNa Trader") -> QtWidgets.QApplication:
exc_traceback: types.TracebackType | None
) -> None:
"""Show exception detail with QMessageBox."""
logger.opt(exception=(exc_type, exc_value, exc_traceback)).error("Main thread exception")
logger.opt(exception=(exc_type, exc_value, exc_traceback)).critical("Main thread exception")
sys.__excepthook__(exc_type, exc_value, exc_traceback)
msg: str = "".join(traceback.format_exception(exc_type, exc_value, exc_traceback))
@@ -60,7 +60,7 @@ def create_qapp(app_name: str = "VeighNa Trader") -> QtWidgets.QApplication:
def threading_excepthook(args: threading.ExceptHookArgs) -> None:
"""Show exception detail from background threads with QMessageBox."""
if args.exc_value and args.exc_traceback:
logger.opt(exception=(args.exc_type, args.exc_value, args.exc_traceback)).error("Background thread exception")
logger.opt(exception=(args.exc_type, args.exc_value, args.exc_traceback)).critical("Background thread exception")
sys.__excepthook__(args.exc_type, args.exc_value, args.exc_traceback)
msg: str = "".join(traceback.format_exception(args.exc_type, args.exc_value, args.exc_traceback))

View File

@@ -632,7 +632,7 @@ class ArrayManager:
"""
APO.
"""
result_array: np.ndarray = talib.APO(self.close, fast_period, slow_period, talib.MA_Type(matype))
result_array: np.ndarray = talib.APO(self.close, fast_period, slow_period, matype) # type: ignore
if array:
return result_array
@@ -671,7 +671,7 @@ class ArrayManager:
"""
PPO.
"""
result_array: np.ndarray = talib.PPO(self.close, fast_period, slow_period, talib.MA_Type(matype))
result_array: np.ndarray = talib.PPO(self.close, fast_period, slow_period, matype) # type: ignore
if array:
return result_array
@@ -1087,9 +1087,9 @@ class ArrayManager:
self.close,
fastk_period,
slowk_period,
talib.MA_Type(slowk_matype),
slowk_matype, # type: ignore
slowd_period,
talib.MA_Type(slowd_matype)
slowd_matype # type: ignore
)
if array:
return k, d