import json from datetime import datetime as dt from typing import List from urllib.parse import urlencode import pandas as pd import requests from py_jftech import component, filter_weekend, next_workday, get_config, format_date from api import RoboReportor from reports.dao import robo_benckmark as rb config = get_config(__name__) @component(bean_name='benckmark-report') class BenchmarkAlligamReportor(RoboReportor): @property def report_name(self) -> str: return 'BENCHMARK_ALLIGAM' @property def module_name(self) -> str: return 'divrobo' @property def risk(self): return 'alligam' @property def base_params(self): return { 'subjectKeys': 879, 'size': 200, 'sourceType': 'BLOOMBERG' } def sync_benchmark(self, start_date=None): params = { **self.base_params, 'page': 0 } if start_date: params['startDate'] = format_date(start_date) while True: response = requests.get(f'http://jdcprod.thiztech.com/api/datas/asset-value?{urlencode(params)}').json() if not response['success']: raise Exception(f'''request jdc alligam failed: {response['status']}''') rb.batch_insert([{ 'date': dt.fromtimestamp(x['date'] / 1000), 'module': self.module_name, 'risk': self.risk, 'nav': x['calibrateValue'], 'remarks': json.dumps({ 'av': x['originValue'], 'div': x['dividend'] if 'dividend' in x else 0 }, ensure_ascii=False) } for x in response['body']['content']]) if response['body']['last']: break else: params = {**params, 'page': params['page'] + 1} def load_report(self, max_date=dt.today(), min_date=None) -> List[dict]: max_date = filter_weekend(max_date) min_date = filter_weekend(min_date) if min_date else None last = rb.get_last_one(module=self.module_name, risk=self.risk, max_date=max_date) if not last or last['date'] < max_date: self.sync_benchmark(start_date=next_workday(last['date']) if last else None) result = pd.DataFrame(rb.get_list(max_date=max_date, min_date=min_date)) result['av'] = result['remarks'].apply(lambda x: json.loads(x)['av']) result['div'] = result['remarks'].apply(lambda x: json.loads(x)['div']) result['acc'] = result.apply(lambda row: result[result['date'] <= row['date']]['div'].sum() + row['av'], axis=1) result = result[['date', 'av', 'div', 'acc', 'nav']] result.rename(columns={'nav': f'{self.risk}_nav', 'av': f'{self.risk}_av', 'div': f'{self.risk}_div', 'acc': f'{self.risk}_acc'}, inplace=True) return result.to_dict('records')