Commit 466c7595 authored by stephen.wang's avatar stephen.wang

Merge remote-tracking branch 'origin/dev-dividend' into dev-dividend

parents f6fff7b4 69854f30
import logging
import sys
from abc import ABC, abstractmethod
from datetime import datetime as dt
......@@ -6,6 +7,8 @@ from typing import List
from py_jftech import get_config, parse_date
logger = logging.getLogger(__name__)
@unique
class BacktestStep(Enum):
......
......@@ -42,7 +42,7 @@ class SortinoAssetOptimize(AssetOptimize, ABC):
pass
@abstractmethod
def get_groups(self):
def get_groups(self, day=None):
'''
:return: 返回待处理的id数组
'''
......@@ -122,7 +122,7 @@ class FundDividendSortinoAssetOptimize(SortinoAssetOptimize):
min_dates = self.nav_min_dates
max_incept_date = sorted([(day - relativedelta(**x)) for x in self.delta_kwargs])[0]
max_incept_date = max_incept_date if is_workday(max_incept_date) else next_workday(max_incept_date)
for fund_group in self.get_groups():
for fund_group in self.get_groups(day):
fund_group = [x for x in fund_group if min_dates[x] <= max_incept_date]
if len(fund_group) > self.optimize_count:
pool.extend(self.find_optimize(tuple(fund_group), day)[0])
......@@ -132,8 +132,16 @@ class FundDividendSortinoAssetOptimize(SortinoAssetOptimize):
last_one = rop.get_last_one(day=day, type=AssetPoolType.OPTIMIZE)
return json.loads(last_one['asset_ids'])
def get_filtered_funds(self):
def get_filtered_funds(self, day):
funds = self._datum.get_datums(type=DatumType.FUND)
if get_config('portfolios.checker.month-fund-filter'):
# 如果有按月剔除
filters = get_config('portfolios.checker.month-fund-filter')
excludes = filters.get(day.month)
if excludes:
for f in funds[:]:
if f['bloombergTicker'] in excludes:
funds.remove(f)
if self.asset_filter:
filters = list(self.asset_filter.keys())[0]
funds_in = []
......@@ -143,8 +151,8 @@ class FundDividendSortinoAssetOptimize(SortinoAssetOptimize):
return funds_in
return funds
def get_groups(self):
funds = pd.DataFrame(self.get_filtered_funds())
def get_groups(self, day=None):
funds = pd.DataFrame(self.get_filtered_funds(day))
result = []
if self.asset_include:
include = list(self.asset_include.keys())[0]
......
......@@ -34,7 +34,7 @@ py-jftech:
port: ${MYSQL_PORT:3306}
user: ${MYSQL_USER:root}
password: ${MYSQL_PWD:changeit}
dbname: ${MYSQL_DBNAME:mdiv_prr3} # mdiv_prr3
dbname: ${MYSQL_DBNAME:j_robo} # mdiv_prr3
injectable:
names:
backtest: robo_executor.BacktestExecutor
......@@ -115,7 +115,7 @@ portfolios: # 投组模块
checker: #投组检测模块
switch: on #是否开启检查
custom-type-priority: [3,2,1,4] # 检测优先级
month-fund-filter: {2:['TEMSCFA LX Equity'],12:['TEMHYAD LX Equity','TEMFIAI LX Equity']} # 根据月份删除某几档基金
reports: # 报告模块相关
navs:
type: FUND
......@@ -245,7 +245,7 @@ robo-executor: # 执行器相关
sealing-period: 10 #调仓封闭期
start-step: ${BACKTEST_START_STEP:1} # 回测从哪一步开始执行 1:计算资产池;2:计算最优投组:3:计算再平衡信号以及持仓投组
end-step: ${BACKTEST_END_STEP:3} # 回测从哪一步执行完成后结束执行 1:计算资产池;2:计算最优投组:3:计算再平衡信号以及持仓投组
clean-up: off
clean-up: on
real: # 实盘执行器
export: ${EXPORT_ENABLE:off} # 是否开启报告
start-date: 2023-05-08 # 实盘开始时间
......
......@@ -29,10 +29,16 @@ class DefaultPortfoliosChecker(PortfoliosChecker):
# step1: 检查原始投组的customType。检查顺序用列表呈现,依序进行
priority = self._config.get('custom-type-priority')
for p in priority:
# 找出对应优先级序列的基金列表
keys = [key for key in portfolios.keys() if customType[key] == p]
# 若存在匹配值则执行后跳出循环
if len(keys) > 0:
ids = [fund['id'] for fund in funds if fund['companyType'] != list(companies)[0]]
# 选取非同公司的、风险等级小于等于原基金的 基金
min_risk = min(fund['risk'] for fund in funds if str(fund['id']) in keys)
ids = [fund['id'] for fund in funds if fund['companyType'] != list(companies)[0] and
fund['risk'] <= min_risk]
if len(ids) == 0:
continue
best = self.find_highest_score(ids, day)
# 若刚好有一个匹配,直接替换
if len(keys) == 1:
......@@ -42,7 +48,7 @@ class DefaultPortfoliosChecker(PortfoliosChecker):
else:
# 算分,把分低的替换掉
scores = self.do_score(keys, day)
weight_scores = {key: scores[key]*portfolios[key] for key in keys}
weight_scores = {key: scores[key] * portfolios[key] for key in keys}
lowest = min(scores, key=lambda k: weight_scores[k])
portfolios[best] = portfolios[lowest]
# 删除原始键
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment