import pandas as pd from framework import filter_weekend, config, dict_remove, get_config from datas import navs from dateutil.relativedelta import relativedelta from empyrical import sortino_ratio optimize_config = get_config(__name__) sortino_config = [{**x, 'name': [f"sortino_{y[1]}_{y[0]}" for y in x.items() if y[0] != 'weight'][0]} for x in optimize_config['sortino_weight']] \ if 'sortino_weight' in optimize_config else [] def find_optimize(fund_ids, day): if not sortino_config: raise NameError(f"find optimize, but not found sortino config.") start = filter_weekend(sorted([day - relativedelta(days=1, **dict_remove(x, ('weight', 'name'))) for x in sortino_config])[0]) fund_navs = pd.DataFrame(navs.get_navs(fund_id=tuple(fund_ids), min_date=start, max_date=day)) fund_navs.sort_values('nav_date', inplace=True) fund_navs = fund_navs.pivot_table(index='nav_date', columns='fund_id', values='nav_cal') fund_navs.fillna(method='ffill', inplace=True) day_income = round(fund_navs.pct_change(), 4) sortino = pd.DataFrame() for item in sortino_config: delta_kwargs = item.copy() del delta_kwargs['weight'], delta_kwargs['name'] ratio = dict(sortino_ratio(day_income.truncate(before=(day - relativedelta(**delta_kwargs))))) sortino = pd.concat([sortino, pd.DataFrame([ratio], index=[item['name']])]) sortino = sortino.T sortino['score'] = sortino.apply(lambda r: sum([x['weight'] * r[x['name']] for x in sortino_config]), axis=1) sortino.sort_values('score', ascending=False, inplace=True) return day_income.columns[sortino.index[0]] def get_optimize_fund_pool(day): pass if __name__ == '__main__': from datetime import date get_optimize_fund_pool(date.today())