Commit 3cbf0a21 authored by wenwen.tang's avatar wenwen.tang 😕

需任意挑选起始日期,设定封闭期参数;

调整配息方法;每个季度后的第一天(正好是调仓日)判断是否更新配息金额(预留)。是,则"标准配息(9%)/前一天的单位净值(rhp_asset_nav)";否,则"延续使用前次的配息金额"
parent 39077d30
......@@ -76,7 +76,9 @@ portfolios: # 投组模块
init-nav: 100 # 初始金额
min-interval-days: 10 # 两次实际调仓最小间隔期,单位交易日
dividend-rate: 0.09 #设定年化配息率
dividend-date: 10 #配息日,每月10号
dividend-drift-rate: 0.1 #超过基准配息率上下10%触发配息率重置
dividend-date: 15 #配息日,每月10号
dividend-adjust-day: [1,4,7,10] #每年的首个季度调整配息
solver: # 解算器相关
tol: 1E-10 # 误差满足条件
navs: # 净值要求
......@@ -168,7 +170,8 @@ robo-executor: # 执行器相关
backtest: # 回测执行器相关
start-date: 2012-10-16 # 回测起始日期
end-date: 2023-03-03 # 回测截止日期
start-step: ${BACKTEST_START_STEP:3} # 回测从哪一步开始执行 1:计算资产池;2:计算最优投组:3:计算再平衡信号以及持仓投组
sealing-period: 10 #调仓封闭期
start-step: ${BACKTEST_START_STEP:1} # 回测从哪一步开始执行 1:计算资产池;2:计算最优投组:3:计算再平衡信号以及持仓投组
end-step: ${BACKTEST_END_STEP:3} # 回测从哪一步执行完成后结束执行 1:计算资产池;2:计算最优投组:3:计算再平衡信号以及持仓投组
clean-up: true
real: # 实盘执行器
......
......@@ -23,6 +23,7 @@ class DividendPortfoliosHolder(PortfoliosHolder):
self._executor = executor
self._builder = builder
self._config = get_config(__name__)
self._last_div = None
def get_portfolio_type(self, day, risk: PortfoliosRisk) -> PortfoliosType:
return PortfoliosType.NORMAL
......@@ -69,15 +70,34 @@ class DividendPortfoliosHolder(PortfoliosHolder):
navs = fund_div_tuple[0]
dividend_acc = last_nav['div_acc']
nav = round(sum([navs[x] * y for x, y in share.items()]), 4) + last_nav['fund_div']
# 每年的首个季度调整配息
if day.month in self._config.get('dividend-adjust-day'):
asset_nav = last_nav['asset_nav']
div_rate = self._last_div * 12 / asset_nav
# 超过基准配息率上下10%触发配息率重置
if abs((self._config['dividend-rate'] - div_rate) / self._config['dividend-rate']) > \
self._config['dividend-drift-rate']:
# 以本月前一天的单位净值进行配息计算
dividend = last_nav['asset_nav'] * self.month_dividend
else:
dividend = self._last_div
nav = nav - dividend
dividend_acc = dividend + dividend_acc
self._last_div = dividend
else:
dividend = last_nav['dividend'] + self._last_div
nav = nav - self._last_div
dividend_acc = self._last_div + dividend_acc
else:
nav = self.init_nav
fund_div_tuple = self.get_navs_and_div(fund_ids=tuple(weight), day=day)
navs = fund_div_tuple[0]
dividend = nav * self.month_dividend
nav = nav - dividend
dividend = nav * self.month_dividend
self._last_div = dividend
nav = nav - dividend
dividend_acc = dividend + dividend_acc
share = {x: nav * w / navs[x] for x, w in weight.items()}
fund_dividend = 0
dividend_acc = dividend + dividend_acc
asset_nav = nav + fund_dividend + dividend
rhp.insert({
'date': day,
......
import logging
import os
import sys
from concurrent.futures import wait
from datetime import datetime as dt
......@@ -9,7 +8,7 @@ from typing import List
import pandas as pd
from py_jftech import (
component, autowired, get_config, filter_weekend, asynchronized,
parse_date
parse_date, workday_range
)
from api import (
......@@ -58,7 +57,14 @@ class BacktestExecutor(RoboExecutor):
lambda x: pd.date_range(start=x, end=x + pd.offsets.MonthEnd(0), freq='B')[0]
)
# 返回第一个工作日列表
return list(df['first_business_day'])
result = list(df['first_business_day'])
delta = workday_range(start_date, result[0])
period = get_config(__name__)['backtest']['sealing-period']
if len(delta) <= period:
result.pop(0)
result.insert(0, start_date)
return result
@property
def start_date(self):
......
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