Commit 22435898 authored by jichao's avatar jichao

回测报告增加基金池

parent 4516bd33
......@@ -18,6 +18,19 @@ def insert(asset_id, type: DateType, date):
'''
@read
def get_list(asset_ids=None, max_date=None, min_date=None):
sqls = []
if max_date:
sqls.append(f"rap_date <= '{format_date(max_date)}'")
if min_date:
sqls.append(f"rap_date >= '{format_date(min_date)}'")
return f'''
select {','.join([f"`{x[0]}` as `{x[1]}`" for x in __COLUMNS__.items()])} from asset_risk_dates
{where(*sqls, ard_asset_id=asset_ids)} order by ard_asset_id, ard_date
'''
@read(one=True)
def get_last_one(fund_id, date=None, type: DateType = None):
kwargs = {
......
from datetime import datetime as dt
from typing import List
import pandas as pd
from py_jftech import get_config, component, autowired, to_tuple
from api import Navs, Datum, DatumType
from api import Navs, Datum, DatumType, RoboReportor
from basic.dao import robo_exrate as re, robo_fund_navs as rfn, robo_index_datas as rid, robo_eco_datas as red
......@@ -84,3 +87,35 @@ class DefaultNavs(Navs):
return red.get_last_one(eco_id=datum_id, max_date=max_date, by_release_date=by_release_date)
else:
return red.get_last(eco_id=datum_id, max_date=max_date, count=count, by_release_date=by_release_date)
@component(bean_name='navs-report')
class NavsReportor(RoboReportor):
@autowired
def __init__(self, datum: Datum = None, navs: Navs = None):
self._datum = datum;
self._navs = navs
self._config = get_config('reports.navs')
@property
def report_name(self) -> str:
return "基金净值"
@property
def tickers(self):
return self._config['tickers'] if 'tickers' in self._config else None
@property
def type(self):
return DatumType[self._config['type']]
def load_report(self, max_date=dt.today(), min_date=None) -> List[dict]:
asset_ids = {x['id']: x for x in self._datum.get_datums(ticker=self.tickers, type=self.type)}
if self.type == DatumType.FUND:
result = pd.DataFrame(self._navs.get_fund_navs(fund_ids=tuple(asset_ids.keys()), max_date=max_date, min_date=min_date))
result = result.pivot_table(index='nav_date', columns='fund_id', values='nav_cal')
result.rename(columns={x[0]: x[1]['bloombergTicker'] for x in asset_ids.items()}, inplace=True)
result.reset_index(inplace=True)
return result.to_dict('records')
return []
import logging
import unittest
from py_jftech import autowired, parse_date
import pandas as pd
from py_jftech import autowired, parse_date, to_str
from api import Navs, Datum, PortfoliosRisk, DataSync
from api import Navs, Datum, PortfoliosRisk, DataSync, RoboReportor
logger = logging.getLogger(__name__)
class BasicTest(unittest.TestCase):
logger = logging.getLogger(__name__)
@autowired
def test_index_close(self, navs: Navs = None):
closes = navs.get_index_close(ticker='SPX Index', min_date=parse_date('2022-11-01'), datum_ids=67)
self.logger.info(closes)
logger.info(closes)
@autowired
def test_get_high_risk_datums(self, datum: Datum = None):
datums = datum.get_high_risk_datums(PortfoliosRisk.FT9)
self.logger.info(datums)
logger.info(datums)
@autowired(names={'sync': 'index-sync'})
def test_index_sync(self, sync: DataSync = None):
......@@ -31,6 +33,11 @@ class BasicTest(unittest.TestCase):
def test_navs_sync(self, sync: DataSync = None):
sync.do_sync()
@autowired(names={'report': 'navs-report'})
def test_export_navs(self, report: RoboReportor = None):
result = report.load_report()
logger.info(to_str(result))
if __name__ == '__main__':
unittest.main()
......@@ -157,6 +157,14 @@ rebalance: # 再平衡模块
high-low-buy: # 高低买入相关
threshold: [ 0.5, 0.8 ] # [ 低买入阀值,高买入阀值 ]
reports: # 报告模块相关
navs:
type: FUND
tickers:
- TEMTECI LX Equity
- TEPLX US Equity
- FRDPX US Equity
- FKRCX US Equity
- FTNRACU LX Equity
benchmark: # benchmark报告
init-amount: 100 # 初始金额
stock-rate: # stock型基金比例
......@@ -200,7 +208,9 @@ reports: # 报告模块相关
backtest: # 回测导出曹策略
exist-build: on # 如果报告文件存在,是否重新构建文件
save-path: ${EXPORT_PATH:excels} # 导出报告文件存放路径,如果以./或者../开头,则会以执行python文件为根目录,如果以/开头,则为系统绝对路径,否则,以项目目录为根目录
file-name: ${EXPORT_FILENAME:navs}
include-report: # 需要导出的报告类型列表,下面的顺序,也代表了excel中sheet的顺序
# - navs-report # 净值报告
- hold-report # 持仓报告
- signal-report # 信号报告
- asset-pool-report # 基金池报告
......
......@@ -34,12 +34,16 @@ class BacktestExportor(RoboExportor):
def exist_build(self):
return self._config['exist-build']
@property
def file_name(self):
return self._config['file-name'] if 'file-name' in self._config else 'backtest'
def export(self, max_date=dt.today(), min_date=None):
root = self.save_path
os.makedirs(root, exist_ok=True)
filename = f"backtest_{format_date(max_date)}.xlsx"
filename = f"{self.file_name}_{format_date(max_date)}.xlsx"
if min_date:
filename = f"backtest_{format_date(min_date)}_to_{format_date(max_date)}.xlsx"
filename = f"{self.file_name}_{format_date(min_date)}_to_{format_date(max_date)}.xlsx"
file = os.path.join(root, filename)
if os.path.exists(file):
if not self.exist_build:
......
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