Commit d88c92ae authored by jichao's avatar jichao

导出模块完毕

parent 3dc3238f
...@@ -584,6 +584,7 @@ class RoboReportor(ABC): ...@@ -584,6 +584,7 @@ class RoboReportor(ABC):
''' '''
投组报告器 投组报告器
''' '''
@property @property
@abstractmethod @abstractmethod
def report_name(self) -> str: def report_name(self) -> str:
......
...@@ -28,7 +28,7 @@ class DefaultDatum(Datum): ...@@ -28,7 +28,7 @@ class DefaultDatum(Datum):
datum_ids = to_tuple(datum_ids) datum_ids = to_tuple(datum_ids)
if ticker: if ticker:
datums = rbd.get_base_datums(type=type, ticker=ticker) datums = rbd.get_base_datums(type=type, ticker=ticker)
datum_ids = tuple(set(list(datum_ids or []) | {x['id'] for x in datums})) datum_ids = tuple(set(datum_ids or []) | {x['id'] for x in datums})
result = rbd.get_base_datums(type=type, crncy=crncy, risk=risk, datum_ids=datum_ids) result = rbd.get_base_datums(type=type, crncy=crncy, risk=risk, datum_ids=datum_ids)
result = [{**json.loads(x['datas']), 'id': x['id']} for x in result] result = [{**json.loads(x['datas']), 'id': x['id']} for x in result]
return [self.format_datum(x) for x in result if DatumType(x['type']) is not DatumType.FUND or x['bloombergTicker'] not in self.excludes] return [self.format_datum(x) for x in result if DatumType(x['type']) is not DatumType.FUND or x['bloombergTicker'] not in self.excludes]
...@@ -43,4 +43,3 @@ class DefaultDatum(Datum): ...@@ -43,4 +43,3 @@ class DefaultDatum(Datum):
if risk is PortfoliosRisk.FT9: if risk is PortfoliosRisk.FT9:
return risk3 + self.get_datums(type=DatumType.FUND, risk=(4, 5)) return risk3 + self.get_datums(type=DatumType.FUND, risk=(4, 5))
return None return None
...@@ -40,7 +40,7 @@ class DefaultNavs(Navs): ...@@ -40,7 +40,7 @@ class DefaultNavs(Navs):
datum_ids = to_tuple(datum_ids) datum_ids = to_tuple(datum_ids)
if ticker: if ticker:
datums = self._datum.get_datums(type=DatumType.INDEX, ticker=ticker) datums = self._datum.get_datums(type=DatumType.INDEX, ticker=ticker)
datum_ids = tuple(set(list(datum_ids or []) + [x['id'] for x in datums])) datum_ids = tuple(set(datum_ids or []) | {x['id'] for x in datums})
results = rid.get_list(index_ids=datum_ids, min_date=min_date, max_date=max_date) results = rid.get_list(index_ids=datum_ids, min_date=min_date, max_date=max_date)
return [{'index_id': x['index_id'], 'date': x['date'], 'close': x['close']} for x in results] return [{'index_id': x['index_id'], 'date': x['date'], 'close': x['close']} for x in results]
...@@ -84,5 +84,3 @@ class DefaultNavs(Navs): ...@@ -84,5 +84,3 @@ class DefaultNavs(Navs):
return red.get_last_one(eco_id=datum_id, max_date=max_date, by_release_date=by_release_date) return red.get_last_one(eco_id=datum_id, max_date=max_date, by_release_date=by_release_date)
else: else:
return red.get_last(eco_id=datum_id, max_date=max_date, count=count, by_release_date=by_release_date) return red.get_last(eco_id=datum_id, max_date=max_date, count=count, by_release_date=by_release_date)
import logging import logging
from datetime import datetime as dt
from urllib.parse import quote
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from datetime import datetime as dt
from typing import List from typing import List
from urllib.parse import quote
import requests import requests
from py_jftech import parse_date, format_date, is_workday, component, autowired, get_config, filter_weekend, next_workday from py_jftech import format_date, is_workday, component, autowired, get_config, filter_weekend, next_workday
from api import DatumType, DataSync, Datum from api import DatumType, DataSync, Datum
from basic.dao import robo_base_datum as rbd, robo_index_datas as rid, robo_eco_datas as red, robo_fund_navs as rfn from basic.dao import robo_index_datas as rid, robo_eco_datas as red, robo_fund_navs as rfn
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
......
...@@ -21,11 +21,11 @@ py-jftech: ...@@ -21,11 +21,11 @@ py-jftech:
backupCount: 30 backupCount: 30
encoding: utf8 encoding: utf8
when: D when: D
loggers: # loggers:
basic.sync: # basic.sync:
level: DEBUG # level: DEBUG
handlers: [console] # handlers: [console]
propagate: no # propagate: no
root: root:
level: ${LOG_LEVEL:INFO} level: ${LOG_LEVEL:INFO}
handlers: ${LOG_HANDLERS:[ console ]} handlers: ${LOG_HANDLERS:[ console ]}
......
import json
from datetime import datetime as dt from datetime import datetime as dt
from typing import List, Dict from typing import List, Dict
import json
import pandas as pd
import numpy as np
from py_jftech import component, autowired, get_config, workday_range, next_workday, to_tuple from py_jftech import component, autowired, get_config, workday_range, next_workday, to_tuple
from api import RebalanceRuler, PortfoliosRisk, RebalanceSignal, SignalType, PortfoliosType, PortfoliosHolder, RoboReportor, Datum, DatumType from api import RebalanceRuler, PortfoliosRisk, RebalanceSignal, SignalType, PortfoliosType, PortfoliosHolder, RoboReportor, Datum, DatumType
...@@ -44,7 +42,8 @@ class LevelRebalanceRuler(RebalanceRuler): ...@@ -44,7 +42,8 @@ class LevelRebalanceRuler(RebalanceRuler):
builder = [x for x in self._signals if x.signal_type is SignalType.INIT][0] builder = [x for x in self._signals if x.signal_type is SignalType.INIT][0]
return builder.get_signal(day, risk) return builder.get_signal(day, risk)
long_signals = [x for x in self._signals if x.signal_type.p_type is not PortfoliosType.NORMAL and x.signal_type.level < SignalType(last_re['type']).level] long_signals = [x for x in self._signals if
x.signal_type.p_type is not PortfoliosType.NORMAL and x.signal_type.level < SignalType(last_re['type']).level]
for long_signal in sorted(long_signals, key=lambda x: x.signal_type.level): for long_signal in sorted(long_signals, key=lambda x: x.signal_type.level):
workdays = workday_range(next_workday(last_re['date']), day) workdays = workday_range(next_workday(last_re['date']), day)
if len(workdays) <= self._hold.interval_days: if len(workdays) <= self._hold.interval_days:
......
...@@ -51,5 +51,3 @@ class BacktestExportor(RoboExportor): ...@@ -51,5 +51,3 @@ class BacktestExportor(RoboExportor):
if not datas.empty: if not datas.empty:
datas.to_excel(writer, sheet_name=reportor.report_name, index=False) datas.to_excel(writer, sheet_name=reportor.report_name, index=False)
return file return file
import logging import logging
import os
import sys import sys
import time from concurrent.futures import wait
from datetime import datetime as dt from datetime import datetime as dt
from enum import Enum, unique from enum import Enum, unique
from concurrent.futures import wait
from typing import List from typing import List
import pandas as pd import pandas as pd
from py_jftech import ( from py_jftech import (
component, autowired, get_config, filter_weekend, asynchronized, component, autowired, get_config, filter_weekend, asynchronized,
workday_range, format_date, prev_workday, parse_date, transaction workday_range, format_date, prev_workday, parse_date
) )
from api import ( from api import (
RoboExecutor, AssetRisk, Datum, AssetPool, PortfoliosBuilder, DatumType, RoboExecutor, AssetRisk, Datum, AssetPool, PortfoliosBuilder, DatumType, RoboExportor,
PortfoliosRisk, PortfoliosHolder, PortfoliosType, RebalanceRuler, DataSync PortfoliosRisk, PortfoliosHolder, PortfoliosType, RebalanceRuler, DataSync
) )
...@@ -34,9 +34,9 @@ class BacktestStep(Enum): ...@@ -34,9 +34,9 @@ class BacktestStep(Enum):
@component(bean_name='backtest') @component(bean_name='backtest')
class BacktestExecutor(RoboExecutor): class BacktestExecutor(RoboExecutor):
@autowired @autowired(names={'export': 'backtest-export'})
def __init__(self, risk: AssetRisk = None, datum: Datum = None, pool: AssetPool = None, syncs: List[DataSync] = None, def __init__(self, risk: AssetRisk = None, datum: Datum = None, pool: AssetPool = None, syncs: List[DataSync] = None,
builder: PortfoliosBuilder = None, hold: PortfoliosHolder = None, rule: RebalanceRuler = None): builder: PortfoliosBuilder = None, hold: PortfoliosHolder = None, rule: RebalanceRuler = None, export: RoboExportor = None):
self._risk = risk self._risk = risk
self._datum = datum self._datum = datum
self._pool = pool self._pool = pool
...@@ -44,6 +44,7 @@ class BacktestExecutor(RoboExecutor): ...@@ -44,6 +44,7 @@ class BacktestExecutor(RoboExecutor):
self._hold = hold self._hold = hold
self._rule = rule self._rule = rule
self._syncs = syncs self._syncs = syncs
self._export = export
self._config = get_config(__name__)['backtest'] self._config = get_config(__name__)['backtest']
@property @property
...@@ -112,6 +113,10 @@ class BacktestExecutor(RoboExecutor): ...@@ -112,6 +113,10 @@ class BacktestExecutor(RoboExecutor):
now = dt.now() now = dt.now()
wait([self.async_build_hold(x) for x in PortfoliosRisk]) wait([self.async_build_hold(x) for x in PortfoliosRisk])
logger.info(f"build hold portfolios success, use[{(dt.now() - now).seconds}s]") logger.info(f"build hold portfolios success, use[{(dt.now() - now).seconds}s]")
logger.info("start to export report".center(50, '-'))
now = dt.now()
file = self._export.export(max_date=self.end_date)
logger.info(f"report file[{os.path.basename(file)}] exported successfully. use[{(dt.now() - now).seconds}s].")
@asynchronized(isolate=True) @asynchronized(isolate=True)
def async_build_risk_date(self, asset_id): def async_build_risk_date(self, asset_id):
...@@ -130,7 +135,7 @@ class BacktestExecutor(RoboExecutor): ...@@ -130,7 +135,7 @@ class BacktestExecutor(RoboExecutor):
class RealExecutor(RoboExecutor): class RealExecutor(RoboExecutor):
@autowired @autowired
def __init__(self, builder: PortfoliosBuilder = None, hold: PortfoliosHolder = None, syncs: List[DataSync] = None,): def __init__(self, builder: PortfoliosBuilder = None, hold: PortfoliosHolder = None, syncs: List[DataSync] = None, ):
self._builder = builder self._builder = builder
self._hold = hold self._hold = hold
self._syncs = syncs self._syncs = syncs
......
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