Commit 5574f3ce authored by 吕先亚's avatar 吕先亚

可以指定任意天数的预测

parent c8796a2a
......@@ -2,7 +2,7 @@ import json
from typing import List
import numpy as np
from py_jftech import autowired, parse_date, prev_workday, format_date
from py_jftech import autowired, parse_date, prev_workday, format_date, get_config
from ai.config import LABEL_RANGE, LABEL_TAG
from ai.dao import robo_predict
......@@ -16,10 +16,10 @@ from api import DataSync
# 截止日期
max_date = None
toForecast = False # False means test, True means forecast
syncData = False # 开启会同步数据库指数及基金数据
uploadData = False # 开启会上传预测结果
doReport = True # 开启会生成Excel报告
toForecast = get_config('robo-executor.to-forecast')
doReport = get_config('robo-executor.export')
numForecastDays = get_config('robo-executor.num-forecast-days') # business days, 21 business days means one month
# JIFU_SPX_OPEPS_CURRQ_TTM
# JIFU_SPX_OPEPS_YMAE1
# JIFU_SPX_OPEPS_YMAE2
......@@ -39,6 +39,8 @@ fund = [156]
@autowired
def sync(syncs: List[DataSync] = None):
sync_data = get_config('robo-executor.sync-data')
if sync_data:
for s in syncs:
# if isinstance(s, (IndexSync, EcoSync)):
s.do_sync()
......@@ -52,29 +54,29 @@ def report_prediction(label, predict_item, indexDict: dict):
# 上传预测结果
key = [k for k, v in indexDict.items() if v == predict_item][0]
index_info = get_base_info(key)[0]
uploadData = get_config('robo-executor.upload-data')
if uploadData:
if len(LABEL_RANGE) > 2:
data = {"rbd_id": key, "date": forecastDay, "predict": prediction}
data = {"rbd_id": key, "date": forecastDay, "predict": prediction, "remark": {"period": numForecastDays}}
robo_predict.insert(data)
else:
from ai.noticer import upload_predict
upload_predict(index_info['ticker'], forecastDay, predictionStr)
send(content)
# send(content)
return prediction
def judgement(id, type, predict):
from datetime import datetime
predict_term = 21
start = parse_date(max_date) if max_date else prev_workday(datetime.today())
navs = []
if type == 'INDEX':
navs = get_index_list(index_ids=id, min_date=start, limit=predict_term + 1)
navs = get_index_list(index_ids=id, min_date=start, limit=numForecastDays + 1)
navs = [nav['rid_close'] for nav in navs]
elif type == 'FUND':
navs = get_fund_list(fund_ids=id, min_date=start, limit=predict_term + 1)
navs = get_fund_list(fund_ids=id, min_date=start, limit=numForecastDays + 1)
navs = [nav['rfn_nav_cal'] for nav in navs]
if len(navs) == predict_term + 1:
if len(navs) == numForecastDays + 1:
upper = True if navs[-1] >= navs[0] else False
result = {}
for k, v, in predict.items():
......@@ -95,13 +97,11 @@ def judgement(id, type, predict):
########################################
if __name__ == '__main__':
if syncData:
sync()
# define some parameters
win1W = 5 # 1 week
win1M = 21 # 1 Month
win1Q = 63 # 1 Quarter
numForecastDays = 21 # business days, 21 business days means one month
theThreshold = 0.0
ids = set(PREDICT_LIST) | set(eco) | set(index) | set(fund)
infos = get_base_info(ids)
......@@ -155,7 +155,7 @@ if __name__ == '__main__':
else:
report_prediction(ensemble_model.predict(scaledX_forecast), indexDict[pid], indexDict)
if doReport:
if len(LABEL_RANGE) > 2:
if len(LABEL_RANGE) > 2 and toForecast:
from ai.reporter import do_reporter2
do_reporter2()
......
import json
from abc import ABC
from datetime import datetime
from lightgbm import LGBMClassifier
from py_jftech import get_config
from sklearn import svm
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
......@@ -41,9 +43,11 @@ class ModelTrainer(ABC):
if doReport:
if strMethod == "Ensemble Model":
datas = []
numForecastDays = get_config('robo-executor.num-forecast-days')
for predict, date in zip(y_pred, date_index):
datas.append(
{'predict': predict, 'date': date, 'rbd_id': self._pid, 'create_time': datetime.now()})
{'predict': predict, 'date': date, 'rbd_id': self._pid,
"remark": json.dumps({"period": numForecastDays}), 'create_time': datetime.now()})
reporter.do_reporter2(records=datas, excel_name='Backtest_Report_chu.xlsx')
# cm_display = ConfusionMatrixDisplay(confusion_matrix=result0, display_labels=labels)
......
......@@ -42,18 +42,20 @@ def do_reporter2(records=None, excel_name=None):
if not records:
records = robo_predict.get_list()
for item in records:
predict_term = json.loads(item['remark'])['period']
result, rtn, real = is_right(item['rbd_id'], info.get(item['rbd_id'])['type'], item['date'],
item['predict'])
item['predict'], predict_term)
labels = list(LABEL_RANGE.keys())[::-1]
data = {
'Forcast On Date': item['date'],
'Ticker': info.get(item['rbd_id'])['ticker'].replace(' Index', '').replace(' Equity', ''),
'In 21 business days': LABEL_TAG.get(item['predict']),
'Forecast Business Days After': predict_term,
'Forecast Label': LABEL_TAG.get(item['predict']),
'real outcome label': LABEL_TAG.get(real),
'random variable label': LABEL_TAG.get(random.randint(labels[0], labels[-1])),
'Ticker Name': json.loads(info.get(item['rbd_id'])['datas'])['chineseName'],
'Run On Time': item['create_time'].replace(minute=0, second=0),
'return in 21 business days': rtn,
'return on Forecast Label': rtn,
'result': result
}
datas.append(data)
......@@ -66,7 +68,9 @@ def do_reporter2(records=None, excel_name=None):
pf['RMSE'] = RMSE
pf['RefRMSE'] = RefRMSE
pf['RevisedReferenceRMSE'] = RevisedReferenceRMSE
pf.to_excel(excel_name if excel_name else "Forcast_Report_chu.xlsx", index=False)
excel_name = excel_name if excel_name else "Forcast_Report_chu.xlsx"
with pd.ExcelWriter(excel_name, mode='a', if_sheet_exists='replace') as writer:
pf.to_excel(writer, sheet_name=f'{predict_term} business days', index=False)
def map_to_label(ret):
......@@ -82,9 +86,11 @@ def get_RMSE(datas):
@return:
"""
datas = [data for data in datas if data.get('real outcome label') is not None]
if not datas:
return 0
tags = {v: k for k, v in LABEL_TAG.items()}
return (sum(
[(tags.get(data['real outcome label']) - tags.get(data['In 21 business days'])) ** 2 for data in datas]) / len(
[(tags.get(data['real outcome label']) - tags.get(data['Forecast Label'])) ** 2 for data in datas]) / len(
datas)) ** 0.5
......@@ -95,6 +101,8 @@ def get_RefRMSE(datas):
@return:
"""
datas = [data for data in datas if data.get('real outcome label') is not None]
if not datas:
return 0
tags = {v: k for k, v in LABEL_TAG.items()}
return (sum(
[(tags.get(data['real outcome label']) - tags.get(data['random variable label'])) ** 2 for data in
......@@ -131,8 +139,7 @@ def get_RevisedReferenceRMSE(datas):
return revised_ref_rmse
def is_right(id, type, start, predict):
predict_term = 21
def is_right(id, type, start, predict, predict_term):
navs = []
if type == 'INDEX':
navs = get_index_list(index_ids=id, min_date=start, limit=predict_term + 1)
......
py-jftech:
logger:
version: 1
formatters:
brief:
format: "%(asctime)s - %(levelname)s - %(message)s"
simple:
format: "%(asctime)s - %(filename)s - %(levelname)s - %(message)s"
handlers:
console:
class: logging.StreamHandler
formatter: simple
level: DEBUG
stream: ext://sys.stdout
file:
class: logging.handlers.TimedRotatingFileHandler
level: INFO
formatter: brief
filename: ${LOG_FILE:logs/info.log}
interval: 1
backupCount: 30
encoding: utf8
when: D
# loggers:
# basic.sync:
# level: DEBUG
# handlers: [console]
# propagate: no
root:
level: ${LOG_LEVEL:INFO}
handlers: ${LOG_HANDLERS:[ console ]}
database:
host: ${MYSQL_HOST:106.14.56.221}
port: ${MYSQL_PORT:3306}
user: ${MYSQL_USER:ai_user}
password: ${MYSQL_PWD:ai.predict*2025}
dbname: ${MYSQL_DBNAME:ai_predict}
injectable:
names:
backtest: robo_executor.BacktestExecutor
datum: basic.datum.DefaultDatum
hold-report: portfolios.holder.DivHoldReportor
mpt: portfolios.builder.PoemARCPortfoliosBuilder
dividend-holder: portfolios.holder.InvTrustPortfoliosHolder
navs-sync: basic.sync.FundNavSync
email:
server: smtphz.qiye.163.com
user: jft-ra@thizgroup.com
password: 5dbb#30ec6d3
mulit-process:
max-workers: ${MAX_PROCESS:4}
basic: # 基础信息模块
sync:
start-date: 2018-08-26 # 同步数据开始日期
datum: # 资料模块
change:
date: ${DATUM_CHANGE_DATE}
file: ${DATUM_CHANGE_FILE}
excludes: # 排除的资料彭博ticker
# backtest:
# - 'TEMUSGI LX Equity'
real:
- 'FGFSACU LX Equity'
- 'TEMUSGI LX Equity'
navs: # 净值模块
exrate: # 汇率,如果不开启,整个这块注释掉
- from: EUR # 需要转换的货币类型
ticker: EURUSD BGN Curncy # 汇率值的彭博ticker
robo-executor: # 执行器相关
to-forecast: off # False means test, True means forecast
sync-data: ${SYNC_DATA:off} # 开启会同步数据库指数及基金数据
upload-data: off # 开启会上传预测结果
export: ${EXPORT_ENABLE:on} # 是否开启报告
num-forecast-days: 21 # business days, 21 business days means one month
use: ${ROBO_EXECUTOR:backtest} # 执行哪个执行器,优先取系统环境变量ROBO_EXECUTOR的值,默认backtest
backtest: # 回测执行器相关
start-date: 2018-11-26 # 回测起始日期
end-date: 2019-01-13 # 回测截止日期
sealing-period: 10 #调仓封闭期
start-step: ${BACKTEST_START_STEP:1} # 回测从哪一步开始执行 1:计算资产池;2:计算最优投组:3:计算再平衡信号以及持仓投组
end-step: ${BACKTEST_END_STEP:3} # 回测从哪一步执行完成后结束执行 1:计算资产池;2:计算最优投组:3:计算再平衡信号以及持仓投组
clean-up: off
real: # 实盘执行器
export: ${EXPORT_ENABLE:off} # 是否开启报告
start-date: 2023-05-08 # 实盘开始时间
include-date: []
This diff is collapsed.
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