原油月度数据新增中位数,最大值,最小值
This commit is contained in:
parent
58b4956db2
commit
2e83105d7d
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
aisenzhecode/沥青/沥青定量预测2025年10月9日.zip
Normal file
BIN
aisenzhecode/沥青/沥青定量预测2025年10月9日.zip
Normal file
Binary file not shown.
BIN
aisenzhecode/沥青/沥青数据项 - 副本.xlsx
Normal file
BIN
aisenzhecode/沥青/沥青数据项 - 副本.xlsx
Normal file
Binary file not shown.
Binary file not shown.
BIN
aisenzhecode/沥青/沥青数据项2025年9月26日备份.xlsx
Normal file
BIN
aisenzhecode/沥青/沥青数据项2025年9月26日备份.xlsx
Normal file
Binary file not shown.
@ -93,7 +93,7 @@ data = {
|
||||
ClassifyId = 1214
|
||||
|
||||
|
||||
# # 变量定义--线上环境
|
||||
# 变量定义--线上环境
|
||||
# server_host = '10.200.32.39'
|
||||
# login_pushreport_url = "http://10.200.32.39/jingbo-api/api/server/login"
|
||||
# upload_url = "http://10.200.32.39/jingbo-api/api/analysis/reportInfo/researchUploadReportSave"
|
||||
@ -218,6 +218,27 @@ ClassifyId = 1214
|
||||
# }
|
||||
|
||||
|
||||
# 套期保值正式环境start
|
||||
tqbz_login_url = "http://10.200.32.39/jbsh/api/server/login"
|
||||
tqbz_login_data = {
|
||||
"funcModule": "login",
|
||||
"funcOperation": "login",
|
||||
"data": {
|
||||
"account": "api_szh",
|
||||
"password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=",
|
||||
"tenantHashCode":"7145255749fb7d61263081fca3cb1469",
|
||||
"terminal": "API"
|
||||
}
|
||||
}
|
||||
query_is_trading_day_url = "http://10.200.32.39/jbsh/api/dd/futuresCalendar/checkTradeDay"
|
||||
is_trading_day_data = {
|
||||
"funcModule": "检查是否交易日",
|
||||
"funcOperation": "检查是否交易日",
|
||||
"data": "20251010"
|
||||
}
|
||||
# 套期保值正式环境end
|
||||
|
||||
|
||||
# # 生产环境数据库
|
||||
# host = 'rm-2zehj3r1n60ttz9x5.mysql.rds.aliyuncs.com'
|
||||
# port = 3306
|
||||
@ -227,7 +248,7 @@ ClassifyId = 1214
|
||||
# table_name = 'v_tbl_crude_oil_warning'
|
||||
|
||||
|
||||
# # 变量定义--测试环境
|
||||
# 变量定义--测试环境
|
||||
server_host = '192.168.100.53' # 内网
|
||||
# server_host = '183.242.74.28' # 外网
|
||||
login_pushreport_url = f"http://{server_host}:8080/jingbo-dev/api/server/login"
|
||||
@ -342,9 +363,35 @@ push_waring_data_value_list_data = {
|
||||
get_waring_data_value_list_data = {
|
||||
"data": "8", "funcModule": "商品数据同步", "funcOperation": "同步"}
|
||||
|
||||
# 套期保值北京环境start
|
||||
tqbz_login_url = "http://192.168.101.197:8080/jbsh/api/server/login"
|
||||
tqbz_login_data = {
|
||||
"funcModule": "login",
|
||||
"funcOperation": "login",
|
||||
"data": {
|
||||
"account": "apitest",
|
||||
"password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=",
|
||||
"tenantHashCode": "c5207389b0a254149fccc69c9c68397e",
|
||||
"terminal": "API"
|
||||
}
|
||||
}
|
||||
query_is_trading_day_url = "http://192.168.101.197:8080/jbsh/api/dd/futuresCalendar/checkTradeDay"
|
||||
is_trading_day_data = {
|
||||
"funcModule": "检查是否交易日",
|
||||
"funcOperation": "检查是否交易日",
|
||||
"data": "20251010"
|
||||
}
|
||||
# 套期保值北京环境end
|
||||
|
||||
|
||||
|
||||
|
||||
# 八大维度数据项编码
|
||||
bdwd_items = {
|
||||
'ciri': 'yyycbdwdcr',
|
||||
'cierri': 'yyycbdwdcer',
|
||||
'cisanri': 'yyycbdwdcsanr',
|
||||
'cisiri': 'yyycbdwdcsir',
|
||||
'benzhou': 'yyycbdwdbz',
|
||||
'cizhou': 'yyycbdwdcz',
|
||||
'gezhou': 'yyycbdwdgz',
|
||||
@ -373,15 +420,17 @@ DEFAULT_CONFIG = {
|
||||
'create_user': 'admin',
|
||||
'create_date': datetime.datetime.now(),
|
||||
'update_user': 'admin',
|
||||
'update_date': datetime.datetime.now()
|
||||
'update_date': datetime.datetime.now(),
|
||||
'oil_code': 'CRUDE',
|
||||
'oil_name': '原油',
|
||||
}
|
||||
|
||||
|
||||
# 开关
|
||||
is_train = True # 是否训练
|
||||
is_train = False # 是否训练
|
||||
is_debug = False # 是否调试
|
||||
is_eta = True # 是否使用eta接口
|
||||
is_market = True # 是否通过市场信息平台获取特征 ,在is_eta 为true 的情况下生效
|
||||
is_eta = False # 是否使用eta接口
|
||||
is_market = False # 是否通过市场信息平台获取特征 ,在is_eta 为true 的情况下生效
|
||||
is_timefurture = True # 是否使用时间特征
|
||||
is_fivemodels = False # 是否使用之前保存的最佳的5个模型
|
||||
is_edbcode = False # 特征使用edbcoding列表中的
|
||||
|
||||
@ -39,6 +39,7 @@ edbnamelist = [
|
||||
# '新加坡(含硫0.05%) 柴油现货价','柴油:10ppm:国际市场:FOB中间价:新加坡(日)','Bloomberg Commodity Fair Value Singapore Mogas 92 Swap Month 1','97#汽油FOB新加坡现货价','无铅汽油:97#:国际市场:FOB中间价:新加坡(日)'
|
||||
]
|
||||
|
||||
edbcodenamedict = {}
|
||||
|
||||
# eta自有数据指标编码 次月,次二月,次三月,次四月
|
||||
bdwdname = [
|
||||
@ -47,6 +48,13 @@ bdwdname = [
|
||||
'次三月',
|
||||
'次四月',
|
||||
]
|
||||
|
||||
# 数据库预测结果表八大维度列名
|
||||
price_columns = [
|
||||
'day_price', 'week_price', 'second_week_price', 'next_week_price',
|
||||
'next_month_price', 'next_february_price', 'next_march_price', 'next_april_price'
|
||||
]
|
||||
|
||||
modelsindex = [
|
||||
{
|
||||
"NHITS": "SELF0000143",
|
||||
@ -180,6 +188,7 @@ ClassifyId = 1214
|
||||
# query_data_list_item_nos_url = f"http://{server_host}/jingbo-api/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# # 上传数据项值
|
||||
# push_data_value_list_url = f"http://{server_host}/jingbo-api/api/dw/dataValue/pushDataValueList"
|
||||
# push_png_report_url = f"http://{server_host}/jingbo-api/api/analysis/reportInfo/priceForecastImg"
|
||||
|
||||
# login_data = {
|
||||
# "data": {
|
||||
@ -253,6 +262,21 @@ ClassifyId = 1214
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
|
||||
# push_png_report_data = {
|
||||
# "funcModule": '聚烯烃图片报告',
|
||||
# "funcOperation": '上传聚烯烃PP价格预测图片报告',
|
||||
# "data": {
|
||||
# "groupNo": "000211",
|
||||
# "updateTime": "2024-09-06 15:01:29",
|
||||
# "fileBase64": '', # 文件内容base64
|
||||
# "title": '2025年8月5日日度周度预测结果',
|
||||
# "billNo": '',
|
||||
# "pushContent": ""
|
||||
# }
|
||||
# }
|
||||
|
||||
|
||||
# # 八大维度数据项编码
|
||||
# bdwd_items = {
|
||||
# 'ciri': '原油大数据预测|FORECAST|PRICE|T',
|
||||
@ -291,6 +315,10 @@ upload_warning_url = f"http://{server_host}/jingbo-dev/api/basicBuiness/crudeOil
|
||||
query_data_list_item_nos_url = f"http://{server_host}/jingbo-dev/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# 上传数据项值
|
||||
push_data_value_list_url = f"http://{server_host}/jingbo-dev/api/dw/dataValue/pushDataValueList"
|
||||
# 上传图片报告
|
||||
push_png_report_url = f"http://{server_host}/jingbo-dev/api/analysis/reportInfo/priceForecastImg"
|
||||
# 报告审核
|
||||
upload_report_audit_url = f"http://{server_host}/jingbo-dev/api/analysis/reportInfo/researchImgReportSave"
|
||||
|
||||
login_data = {
|
||||
"data": {
|
||||
@ -364,6 +392,43 @@ push_data_value_list_data = {
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
push_png_report_data = {
|
||||
"funcModule": '研究报告信息',
|
||||
"funcOperation": '上传原油预测报告',
|
||||
"data": {
|
||||
"groupNo": "000161",
|
||||
"updateTime": "2024-09-06 15:01:29",
|
||||
"fileBase64": '', # 文件内容base64
|
||||
"title": '2025年8月5日日度周度预测结果',
|
||||
"billNo": '',
|
||||
"pushContent": "2025年8月5日日度周度预测结果"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
upload_report_audit_data = {
|
||||
"groupNo": '000197', # 用户组id
|
||||
"funcModule": '研究报告信息',
|
||||
"funcOperation": '原油价格预测报告审核预览',
|
||||
"data": {
|
||||
"ownerAccount": 'arui', # 报告所属用户账号
|
||||
"reportType": 'OIL_PRICE_FORECAST', # 报告类型,固定为OIL_PRICE_FORECAST
|
||||
"fileName": '2000-40-5-50--100-原油指标数据.xlsx-Brent活跃合约--2024-09-06-15-01-29-预测报告.pdf', # 文件名称
|
||||
"fileBase64": '', # 文件内容base64
|
||||
"imgFileBase64": '', # 图片文件内容base64
|
||||
"categoryNo": 'yyjgycbg', # 研究报告分类编码
|
||||
"smartBusinessClassCode": 'YCJGYCBG', # 分析报告分类编码
|
||||
"reportEmployeeCode": "E40116", # 报告人
|
||||
"reportDeptCode": "D0044", # 报告部门
|
||||
"productGroupCode": "RAW_MATERIAL", # 商品分类
|
||||
"imgGroupNo": '000197', # 推送图片接口人员用户组编码
|
||||
"authGroupNo":'000197', # 权限用户组编码
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
# 八大维度数据项编码
|
||||
bdwd_items = {
|
||||
'ciri': 'yyycbdwdcr',
|
||||
@ -397,12 +462,14 @@ DEFAULT_CONFIG = {
|
||||
'create_user': 'admin',
|
||||
'create_date': datetime.datetime.now(),
|
||||
'update_user': 'admin',
|
||||
'update_date': datetime.datetime.now()
|
||||
'update_date': datetime.datetime.now(),
|
||||
'oil_code': 'CRUDE',
|
||||
'oil_name': '原油',
|
||||
}
|
||||
|
||||
|
||||
# 开关
|
||||
is_train = True # 是否训练
|
||||
is_train = False # 是否训练
|
||||
is_debug = False # 是否调试
|
||||
is_eta = False # 是否使用eta接口
|
||||
is_market = False # 是否通过市场信息平台获取特征 ,在is_eta 为true 的情况下生效
|
||||
@ -410,7 +477,7 @@ is_timefurture = True # 是否使用时间特征
|
||||
is_fivemodels = False # 是否使用之前保存的最佳的5个模型
|
||||
is_edbcode = False # 特征使用edbcoding列表中的
|
||||
is_edbnamelist = False # 自定义特征,对应上面的edbnamelist
|
||||
is_update_eta = True # 预测结果上传到eta
|
||||
is_update_eta = False # 预测结果上传到eta
|
||||
is_update_report = False # 是否上传报告
|
||||
is_update_warning_data = False # 是否上传预警数据
|
||||
is_update_predict_value = True # 是否上传预测值到市场信息平台
|
||||
|
||||
@ -306,6 +306,9 @@ push_data_value_list_data = {
|
||||
# 八大维度数据项编码
|
||||
bdwd_items = {
|
||||
'ciri': 'yyycbdwdcr',
|
||||
'cierri': 'yyycbdwdcer',
|
||||
'cisanri': 'yyycbdwdcsanr',
|
||||
'cisiri': 'yyycbdwdcsir',
|
||||
'benzhou': 'yyycbdwdbz',
|
||||
'cizhou': 'yyycbdwdcz',
|
||||
'gezhou': 'yyycbdwdgz',
|
||||
@ -324,7 +327,6 @@ password = '123456'
|
||||
dbname = 'jingbo_test'
|
||||
table_name = 'v_tbl_crude_oil_warning'
|
||||
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
'feature_factor_frequency': 'D',
|
||||
'strategy_id': 1,
|
||||
@ -335,12 +337,15 @@ DEFAULT_CONFIG = {
|
||||
'create_user': 'admin',
|
||||
'create_date': datetime.datetime.now(),
|
||||
'update_user': 'admin',
|
||||
'update_date': datetime.datetime.now()
|
||||
'update_date': datetime.datetime.now(),
|
||||
'oil_code': 'CRUDE',
|
||||
'oil_name': '原油',
|
||||
}
|
||||
|
||||
|
||||
|
||||
# 开关
|
||||
is_train = True # 是否训练
|
||||
is_train = False # 是否训练
|
||||
is_debug = False # 是否调试
|
||||
is_eta = False # 是否使用eta接口
|
||||
is_market = False # 是否通过市场信息平台获取特征 ,在is_eta 为true 的情况下生效
|
||||
@ -348,7 +353,7 @@ is_timefurture = True # 是否使用时间特征
|
||||
is_fivemodels = False # 是否使用之前保存的最佳的5个模型
|
||||
is_edbcode = False # 特征使用edbcoding列表中的
|
||||
is_edbnamelist = False # 自定义特征,对应上面的edbnamelist
|
||||
is_update_eta = True # 预测结果上传到eta
|
||||
is_update_eta = False # 预测结果上传到eta
|
||||
is_update_report = False # 是否上传报告
|
||||
is_update_warning_data = False # 是否上传预警数据
|
||||
is_update_predict_value = True # 是否上传预测值到市场信息平台
|
||||
|
||||
@ -155,7 +155,6 @@ push_waring_data_value_list_url = f"http://{server_host}/jingbo-api/api/basicBui
|
||||
# 获取预警数据中取消订阅指标ID
|
||||
get_waring_data_value_list_url = f"http://{server_host}/jingbo-api/api/basicBuiness/crudeOilWarning/dataList"
|
||||
|
||||
|
||||
login_data = {
|
||||
"data": {
|
||||
"account": "api_dev",
|
||||
@ -254,6 +253,27 @@ push_waring_data_value_list_data = {
|
||||
get_waring_data_value_list_data = {
|
||||
"data": "9", "funcModule": "商品数据同步", "funcOperation": "同步"}
|
||||
|
||||
# 套期保值正式环境start
|
||||
tqbz_login_url = "http://10.200.32.39/jbsh/api/server/login"
|
||||
tqbz_login_data = {
|
||||
"funcModule": "login",
|
||||
"funcOperation": "login",
|
||||
"data": {
|
||||
"account": "api_szh",
|
||||
"password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=",
|
||||
"tenantHashCode":"7145255749fb7d61263081fca3cb1469",
|
||||
"terminal": "API"
|
||||
}
|
||||
}
|
||||
query_is_trading_day_url = "http://10.200.32.39/jbsh/api/dd/futuresCalendar/checkTradeDay"
|
||||
is_trading_day_data = {
|
||||
"funcModule": "检查是否交易日",
|
||||
"funcOperation": "检查是否交易日",
|
||||
"data": "20251010"
|
||||
}
|
||||
# 套期保值正式环境end
|
||||
|
||||
|
||||
|
||||
# 八大维度数据项编码
|
||||
bdwd_items = {
|
||||
@ -281,136 +301,138 @@ bdwd_items = {
|
||||
|
||||
|
||||
# 变量定义--测试环境
|
||||
# server_host = '192.168.100.53' # 内网
|
||||
# # server_host = '183.242.74.28' # 外网
|
||||
# login_pushreport_url = f"http://{server_host}:8080/jingbo-dev/api/server/login"
|
||||
# # 上传报告
|
||||
# upload_url = f"http://{server_host}:8080/jingbo-dev/api/analysis/reportInfo/researchUploadReportSave"
|
||||
# # 停更预警
|
||||
# upload_warning_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/save"
|
||||
# # 查询数据项编码
|
||||
# query_data_list_item_nos_url = f"http://{server_host}:8080/jingbo-dev/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# # 上传数据项值
|
||||
# push_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/dw/dataValue/pushDataValueList"
|
||||
# # 上传停更数据到市场信息平台
|
||||
# push_waring_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/crudeSaveOrupdate"
|
||||
# # 获取预警数据中取消订阅指标ID
|
||||
# get_waring_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/dataList"
|
||||
|
||||
# login_data = {
|
||||
# "data": {
|
||||
# "account": "api_test",
|
||||
# # "password": "MmVmNzNlOWI0MmY0ZDdjZGUwNzE3ZjFiMDJiZDZjZWU=", # Shihua@123456
|
||||
# "password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=", # 123456
|
||||
# "tenantHashCode": "8a4577dbd919675758d57999a1e891fe",
|
||||
# "terminal": "API"
|
||||
# },
|
||||
# "funcModule": "API",
|
||||
# "funcOperation": "获取token"
|
||||
# }
|
||||
|
||||
# upload_data = {
|
||||
# "funcModule": '研究报告信息',
|
||||
# "funcOperation": '上传聚烯烃PP价格预测报告',
|
||||
# "data": {
|
||||
# "groupNo": "000127",
|
||||
# "ownerAccount": 'arui', # 报告所属用户账号
|
||||
# "reportType": 'OIL_PRICE_FORECAST', # 报告类型,固定为OIL_PRICE_FORECAST
|
||||
# "fileName": '2000-40-5-50--100-原油指标数据.xlsx-Brent活跃合约--2024-09-06-15-01-29-预测报告.pdf', # 文件名称
|
||||
# "fileBase64": '', # 文件内容base64
|
||||
# "categoryNo": 'yyjgycbg', # 研究报告分类编码
|
||||
# "smartBusinessClassCode": 'JXTJGYCBG', # 分析报告分类编码
|
||||
# "reportEmployeeCode": "E40116", # 报告人
|
||||
# "reportDeptCode": "D0044", # 报告部门
|
||||
# "productGroupCode": "RAW_MATERIAL" # 商品分类
|
||||
# }
|
||||
# }
|
||||
|
||||
# # 已弃用
|
||||
# warning_data = {
|
||||
# "funcModule": '原油特征停更预警',
|
||||
# "funcOperation": '原油特征停更预警',
|
||||
# "data": {
|
||||
# "groupNo": "000127",
|
||||
# 'WARNING_TYPE_NAME': '特征数据停更预警',
|
||||
# 'WARNING_CONTENT': '',
|
||||
# 'WARNING_DATE': ''
|
||||
# }
|
||||
# }
|
||||
|
||||
# query_data_list_item_nos_data = {
|
||||
# "funcModule": "数据项",
|
||||
# "funcOperation": "查询",
|
||||
# "data": {
|
||||
# "dateStart": "20200101",
|
||||
# "dateEnd": "",
|
||||
# # 数据项编码,代表 PP期货 价格
|
||||
# "dataItemNoList": ["MAIN_CONFT_SETTLE_PRICE"]
|
||||
# }
|
||||
# }
|
||||
server_host = '192.168.100.53' # 内网
|
||||
# server_host = '183.242.74.28' # 外网
|
||||
login_pushreport_url = f"http://{server_host}:8080/jingbo-dev/api/server/login"
|
||||
# 上传报告
|
||||
upload_url = f"http://{server_host}:8080/jingbo-dev/api/analysis/reportInfo/researchUploadReportSave"
|
||||
# 停更预警
|
||||
upload_warning_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/save"
|
||||
# 查询数据项编码
|
||||
query_data_list_item_nos_url = f"http://{server_host}:8080/jingbo-dev/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# 上传数据项值
|
||||
push_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/dw/dataValue/pushDataValueList"
|
||||
# 上传停更数据到市场信息平台
|
||||
push_waring_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/crudeSaveOrupdate"
|
||||
# 获取预警数据中取消订阅指标ID
|
||||
get_waring_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/dataList"
|
||||
|
||||
|
||||
# push_data_value_list_data = {
|
||||
# "funcModule": "数据表信息列表",
|
||||
# "funcOperation": "新增",
|
||||
# "data": [
|
||||
# {"dataItemNo": "91230600716676129",
|
||||
# "dataDate": "20230113",
|
||||
# "dataStatus": "add",
|
||||
# "dataValue": 100.11
|
||||
# },
|
||||
# {"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
# "dataDate": "20230113",
|
||||
# "dataStatus": "add",
|
||||
# "dataValue": 100.55
|
||||
# },
|
||||
# {"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
# "dataDate": "20230113",
|
||||
# "dataStatus": "add",
|
||||
# "dataValue": 100.55
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
login_data = {
|
||||
"data": {
|
||||
"account": "api_test",
|
||||
# "password": "MmVmNzNlOWI0MmY0ZDdjZGUwNzE3ZjFiMDJiZDZjZWU=", # Shihua@123456
|
||||
"password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=", # 123456
|
||||
"tenantHashCode": "8a4577dbd919675758d57999a1e891fe",
|
||||
"terminal": "API"
|
||||
},
|
||||
"funcModule": "API",
|
||||
"funcOperation": "获取token"
|
||||
}
|
||||
|
||||
upload_data = {
|
||||
"funcModule": '研究报告信息',
|
||||
"funcOperation": '上传聚烯烃PP价格预测报告',
|
||||
"data": {
|
||||
"groupNo": "000127",
|
||||
"ownerAccount": 'arui', # 报告所属用户账号
|
||||
"reportType": 'OIL_PRICE_FORECAST', # 报告类型,固定为OIL_PRICE_FORECAST
|
||||
"fileName": '2000-40-5-50--100-原油指标数据.xlsx-Brent活跃合约--2024-09-06-15-01-29-预测报告.pdf', # 文件名称
|
||||
"fileBase64": '', # 文件内容base64
|
||||
"categoryNo": 'yyjgycbg', # 研究报告分类编码
|
||||
"smartBusinessClassCode": 'JXTJGYCBG', # 分析报告分类编码
|
||||
"reportEmployeeCode": "E40116", # 报告人
|
||||
"reportDeptCode": "D0044", # 报告部门
|
||||
"productGroupCode": "RAW_MATERIAL" # 商品分类
|
||||
}
|
||||
}
|
||||
|
||||
# 已弃用
|
||||
warning_data = {
|
||||
"funcModule": '原油特征停更预警',
|
||||
"funcOperation": '原油特征停更预警',
|
||||
"data": {
|
||||
"groupNo": "000127",
|
||||
'WARNING_TYPE_NAME': '特征数据停更预警',
|
||||
'WARNING_CONTENT': '',
|
||||
'WARNING_DATE': ''
|
||||
}
|
||||
}
|
||||
|
||||
query_data_list_item_nos_data = {
|
||||
"funcModule": "数据项",
|
||||
"funcOperation": "查询",
|
||||
"data": {
|
||||
"dateStart": "20200101",
|
||||
"dateEnd": "",
|
||||
# 数据项编码,代表 PP期货 价格
|
||||
"dataItemNoList": ["MAIN_CONFT_SETTLE_PRICE"]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# push_waring_data_value_list_data = {
|
||||
# "data": {
|
||||
# "crudeOilWarningDtoList": [
|
||||
# {
|
||||
# "lastUpdateDate": "20240501",
|
||||
# "updateSuspensionCycle": 1,
|
||||
# "dataSource": "9",
|
||||
# "frequency": "1",
|
||||
# "indicatorName": "美元指数",
|
||||
# "indicatorId": "myzs001",
|
||||
# "warningDate": "2024-05-13"
|
||||
# }
|
||||
# ],
|
||||
# "dataSource": "9"
|
||||
# },
|
||||
# "funcModule": "商品数据同步",
|
||||
# "funcOperation": "同步"
|
||||
# }
|
||||
push_data_value_list_data = {
|
||||
"funcModule": "数据表信息列表",
|
||||
"funcOperation": "新增",
|
||||
"data": [
|
||||
{"dataItemNo": "91230600716676129",
|
||||
"dataDate": "20230113",
|
||||
"dataStatus": "add",
|
||||
"dataValue": 100.11
|
||||
},
|
||||
{"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
"dataDate": "20230113",
|
||||
"dataStatus": "add",
|
||||
"dataValue": 100.55
|
||||
},
|
||||
{"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
"dataDate": "20230113",
|
||||
"dataStatus": "add",
|
||||
"dataValue": 100.55
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
# get_waring_data_value_list_data = {
|
||||
# "data": "9", "funcModule": "商品数据同步", "funcOperation": "同步"}
|
||||
push_waring_data_value_list_data = {
|
||||
"data": {
|
||||
"crudeOilWarningDtoList": [
|
||||
{
|
||||
"lastUpdateDate": "20240501",
|
||||
"updateSuspensionCycle": 1,
|
||||
"dataSource": "9",
|
||||
"frequency": "1",
|
||||
"indicatorName": "美元指数",
|
||||
"indicatorId": "myzs001",
|
||||
"warningDate": "2024-05-13"
|
||||
}
|
||||
],
|
||||
"dataSource": "9"
|
||||
},
|
||||
"funcModule": "商品数据同步",
|
||||
"funcOperation": "同步"
|
||||
}
|
||||
|
||||
|
||||
# # 八大维度数据项编码
|
||||
# bdwd_items = {
|
||||
# 'ciri': 'jxtppbdwdcr',
|
||||
# 'cierri': 'jxtppbdwdcer',
|
||||
# 'cisanri': 'jxtppbdwdcsanr',
|
||||
# 'cisiri': 'jxtppbdwdcsir',
|
||||
# 'benzhou': 'jxtppbdwdbz',
|
||||
# 'cizhou': 'jxtppbdwdcz',
|
||||
# 'gezhou': 'jxtppbdwdgz',
|
||||
# 'ciyue': 'jxtppbdwdcy',
|
||||
# 'cieryue': 'jxtppbdwdcey',
|
||||
# 'cisanyue': 'jxtppbdwdcsany',
|
||||
# 'cisiyue': 'jxtppbdwdcsiy',
|
||||
# }
|
||||
get_waring_data_value_list_data = {
|
||||
"data": "9", "funcModule": "商品数据同步", "funcOperation": "同步"}
|
||||
|
||||
|
||||
|
||||
# 八大维度数据项编码
|
||||
bdwd_items = {
|
||||
'ciri': 'jxtppbdwdcr',
|
||||
'cierri': 'jxtppbdwdcer',
|
||||
'cisanri': 'jxtppbdwdcsanr',
|
||||
'cisiri': 'jxtppbdwdcsir',
|
||||
'benzhou': 'jxtppbdwdbz',
|
||||
'cizhou': 'jxtppbdwdcz',
|
||||
'gezhou': 'jxtppbdwdgz',
|
||||
'ciyue': 'jxtppbdwdcy',
|
||||
'cieryue': 'jxtppbdwdcey',
|
||||
'cisanyue': 'jxtppbdwdcsany',
|
||||
'cisiyue': 'jxtppbdwdcsiy',
|
||||
}
|
||||
# 北京环境数据库
|
||||
host = '192.168.101.27'
|
||||
port = 3306
|
||||
|
||||
@ -218,148 +218,19 @@ ClassifyId = 1161
|
||||
|
||||
|
||||
# 变量定义--线上环境
|
||||
server_host = '10.200.32.39'
|
||||
login_pushreport_url = "http://10.200.32.39/jingbo-api/api/server/login"
|
||||
upload_url = "http://10.200.32.39/jingbo-api/api/analysis/reportInfo/researchUploadReportSave"
|
||||
upload_warning_url = "http://10.200.32.39/jingbo-api/api/basicBuiness/crudeOilWarning/save"
|
||||
query_data_list_item_nos_url = f"http://{server_host}/jingbo-api/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# 上传数据项值
|
||||
push_data_value_list_url = f"http://{server_host}/jingbo-api/api/dw/dataValue/pushDataValueList"
|
||||
push_png_report_url = f"http://{server_host}/jingbo-api/api/analysis/reportInfo/priceForecastImg"
|
||||
|
||||
login_data = {
|
||||
"data": {
|
||||
"account": "api_dev",
|
||||
"password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=",
|
||||
"tenantHashCode": "8a4577dbd919675758d57999a1e891fe",
|
||||
"terminal": "API"
|
||||
},
|
||||
"funcModule": "API",
|
||||
"funcOperation": "获取token"
|
||||
}
|
||||
|
||||
|
||||
upload_data = {
|
||||
"funcModule": '研究报告信息',
|
||||
"funcOperation": '上传原油价格预测报告',
|
||||
"data": {
|
||||
"groupNo": '', # 用户组id
|
||||
"ownerAccount": '27663', # 报告所属用户账号 27663 - 刘小朋
|
||||
"reportType": 'OIL_PRICE_FORECAST', # 报告类型,固定为OIL_PRICE_FORECAST
|
||||
"fileName": '', # 文件名称
|
||||
"fileBase64": '', # 文件内容base64
|
||||
"categoryNo": 'yyjgycbg', # 研究报告分类编码
|
||||
"smartBusinessClassCode": 'YCJGYCBG', # 分析报告分类编码
|
||||
"reportEmployeeCode": "E40482", # 报告人 E40482 - 管理员 0000027663 - 刘小朋
|
||||
"reportDeptCode": "002000621000", # 报告部门 - 002000621000 SH期货研究部
|
||||
"productGroupCode": "RAW_MATERIAL" # 商品分类
|
||||
}
|
||||
}
|
||||
|
||||
warning_data = {
|
||||
"groupNo": '', # 用户组id
|
||||
"funcModule": '原油特征停更预警',
|
||||
"funcOperation": '原油特征停更预警',
|
||||
"data": {
|
||||
'WARNING_TYPE_NAME': '特征数据停更预警',
|
||||
'WARNING_CONTENT': '',
|
||||
'WARNING_DATE': ''
|
||||
}
|
||||
}
|
||||
|
||||
query_data_list_item_nos_data = {
|
||||
"funcModule": "数据项",
|
||||
"funcOperation": "查询",
|
||||
"data": {
|
||||
"dateStart": "20150101",
|
||||
"dateEnd": "20301231",
|
||||
"dataItemNoList": ["MAIN_CONFT_SETTLE_PRICE"] # 数据项编码,代表 brent最低价和最高价
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
push_data_value_list_data = {
|
||||
"funcModule": "数据表信息列表",
|
||||
"funcOperation": "新增",
|
||||
"data": [
|
||||
{"dataItemNo": "91230600716676129",
|
||||
"dataDate": "20230113",
|
||||
"dataStatus": "add",
|
||||
"dataValue": 100.11
|
||||
},
|
||||
{"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
"dataDate": "20230113",
|
||||
"dataStatus": "add",
|
||||
"dataValue": 100.55
|
||||
},
|
||||
{"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
"dataDate": "20230113",
|
||||
"dataStatus": "add",
|
||||
"dataValue": 100.55
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
push_png_report_data = {
|
||||
"funcModule": '聚烯烃图片报告',
|
||||
"funcOperation": '上传聚烯烃PP价格预测图片报告',
|
||||
"data": {
|
||||
"groupNo": "000211",
|
||||
"updateTime": "2024-09-06 15:01:29",
|
||||
"fileBase64": '', # 文件内容base64
|
||||
"title": '2025年8月5日日度周度预测结果',
|
||||
"billNo": '',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# 八大维度数据项编码
|
||||
bdwd_items = {
|
||||
'ciri': '251889263|FORECAST|PRICE|T01',
|
||||
'cierri': '251889263|FORECAST|PRICE|T02',
|
||||
'cisanri': '251889263|FORECAST|PRICE|T03',
|
||||
'cisiri': '251889263|FORECAST|PRICE|T04',
|
||||
'benzhou': '251889263|FORECAST|PRICE|T05',
|
||||
'cizhou': '251889263|FORECAST|PRICE|W_01',
|
||||
'gezhou': '251889263|FORECAST|PRICE|W_02',
|
||||
'ciyue': '251889263|FORECAST|PRICE|M_01',
|
||||
'cieryue': '251889263|FORECAST|PRICE|M_02',
|
||||
'cisanyue': '251889263|FORECAST|PRICE|M_03',
|
||||
'cisiyue': '251889263|FORECAST|PRICE|M_04',
|
||||
}
|
||||
|
||||
|
||||
# 报告中八大维度数据项重命名
|
||||
columnsrename = {'251889263|FORECAST|PRICE|T05': '本周', '251889263|FORECAST|PRICE|M_02': '次二月', '251889263|FORECAST|PRICE|T01': '次日', '251889263|FORECAST|PRICE|M_04': '次四月',
|
||||
'251889263|FORECAST|PRICE|M_03': '次三月', '251889263|FORECAST|PRICE|M_01': '次月', '251889263|FORECAST|PRICE|W_01': '次周', '251889263|FORECAST|PRICE|W_02': '隔周', }
|
||||
|
||||
|
||||
# 生产环境数据库
|
||||
host = 'rm-2zehj3r1n60ttz9x5.mysql.rds.aliyuncs.com'
|
||||
port = 3306
|
||||
dbusername = 'jingbo'
|
||||
password = 'shihua@123'
|
||||
dbname = 'jingbo'
|
||||
table_name = 'v_tbl_crude_oil_warning'
|
||||
|
||||
|
||||
# 变量定义--测试环境
|
||||
# server_host = '192.168.100.53:8080' # 内网
|
||||
# # server_host = '183.242.74.28' # 外网
|
||||
# login_pushreport_url = f"http://{server_host}/jingbo-dev/api/server/login"
|
||||
# upload_url = f"http://{server_host}/jingbo-dev/api/analysis/reportInfo/researchUploadReportSave"
|
||||
# upload_warning_url = f"http://{server_host}/jingbo-dev/api/basicBuiness/crudeOilWarning/save"
|
||||
# query_data_list_item_nos_url = f"http://{server_host}/jingbo-dev/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# server_host = '10.200.32.39'
|
||||
# login_pushreport_url = "http://10.200.32.39/jingbo-api/api/server/login"
|
||||
# upload_url = "http://10.200.32.39/jingbo-api/api/analysis/reportInfo/researchUploadReportSave"
|
||||
# upload_warning_url = "http://10.200.32.39/jingbo-api/api/basicBuiness/crudeOilWarning/save"
|
||||
# query_data_list_item_nos_url = f"http://{server_host}/jingbo-api/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# # 上传数据项值
|
||||
# push_data_value_list_url = f"http://{server_host}/jingbo-dev/api/dw/dataValue/pushDataValueList"
|
||||
# # 上传图片报告
|
||||
# push_png_report_url = f"http://{server_host}/jingbo-dev/api/analysis/reportInfo/priceForecastImg"
|
||||
# push_data_value_list_url = f"http://{server_host}/jingbo-api/api/dw/dataValue/pushDataValueList"
|
||||
# push_png_report_url = f"http://{server_host}/jingbo-api/api/analysis/reportInfo/priceForecastImg"
|
||||
|
||||
# login_data = {
|
||||
# "data": {
|
||||
# "account": "api_test",
|
||||
# # "password": "MmVmNzNlOWI0MmY0ZDdjZGUwNzE3ZjFiMDJiZDZjZWU=", # Shihua@123456
|
||||
# "password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=", # 123456
|
||||
# "account": "api_dev",
|
||||
# "password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=",
|
||||
# "tenantHashCode": "8a4577dbd919675758d57999a1e891fe",
|
||||
# "terminal": "API"
|
||||
# },
|
||||
@ -367,24 +238,26 @@ table_name = 'v_tbl_crude_oil_warning'
|
||||
# "funcOperation": "获取token"
|
||||
# }
|
||||
|
||||
|
||||
# upload_data = {
|
||||
# "funcModule": '研究报告信息',
|
||||
# "funcOperation": '上传聚烯烃PP价格预测报告',
|
||||
# "funcOperation": '上传原油价格预测报告',
|
||||
# "data": {
|
||||
# "ownerAccount": 'arui', # 报告所属用户账号
|
||||
# "groupNo": '', # 用户组id
|
||||
# "ownerAccount": '27663', # 报告所属用户账号 27663 - 刘小朋
|
||||
# "reportType": 'OIL_PRICE_FORECAST', # 报告类型,固定为OIL_PRICE_FORECAST
|
||||
# "fileName": '2000-40-5-50--100-原油指标数据.xlsx-Brent活跃合约--2024-09-06-15-01-29-预测报告.pdf', # 文件名称
|
||||
# "fileName": '', # 文件名称
|
||||
# "fileBase64": '', # 文件内容base64
|
||||
# "categoryNo": 'yyjgycbg', # 研究报告分类编码
|
||||
# "smartBusinessClassCode": 'JXTJGYCBG', # 分析报告分类编码
|
||||
# "reportEmployeeCode": "E40116", # 报告人
|
||||
# "reportDeptCode": "D0044", # 报告部门
|
||||
# "smartBusinessClassCode": 'YCJGYCBG', # 分析报告分类编码
|
||||
# "reportEmployeeCode": "E40482", # 报告人 E40482 - 管理员 0000027663 - 刘小朋
|
||||
# "reportDeptCode": "002000621000", # 报告部门 - 002000621000 SH期货研究部
|
||||
# "productGroupCode": "RAW_MATERIAL" # 商品分类
|
||||
# }
|
||||
# }
|
||||
|
||||
|
||||
# warning_data = {
|
||||
# "groupNo": '', # 用户组id
|
||||
# "funcModule": '原油特征停更预警',
|
||||
# "funcOperation": '原油特征停更预警',
|
||||
# "data": {
|
||||
@ -398,13 +271,13 @@ table_name = 'v_tbl_crude_oil_warning'
|
||||
# "funcModule": "数据项",
|
||||
# "funcOperation": "查询",
|
||||
# "data": {
|
||||
# "dateStart": "20200101",
|
||||
# "dateEnd": "20241231",
|
||||
# # 数据项编码,代表 PP期货 价格
|
||||
# "dataItemNoList": ["MAIN_CONFT_SETTLE_PRICE"]
|
||||
# "dateStart": "20150101",
|
||||
# "dateEnd": "20301231",
|
||||
# "dataItemNoList": ["MAIN_CONFT_SETTLE_PRICE"] # 数据项编码,代表 brent最低价和最高价
|
||||
# }
|
||||
# }
|
||||
|
||||
|
||||
# push_data_value_list_data = {
|
||||
# "funcModule": "数据表信息列表",
|
||||
# "funcOperation": "新增",
|
||||
@ -427,35 +300,183 @@ table_name = 'v_tbl_crude_oil_warning'
|
||||
# ]
|
||||
# }
|
||||
|
||||
|
||||
# push_png_report_data = {
|
||||
# "funcModule": '研究报告信息',
|
||||
# "funcOperation": '上传聚烯烃PP价格预测报告',
|
||||
# "funcModule": '聚烯烃图片报告',
|
||||
# "funcOperation": '上传聚烯烃PP价格预测图片报告',
|
||||
# "data": {
|
||||
# "groupNo": "000161",
|
||||
# "groupNo": "000211",
|
||||
# "updateTime": "2024-09-06 15:01:29",
|
||||
# "fileBase64": '', # 文件内容base64
|
||||
# "title": '2025年8月5日日度周度预测结果',
|
||||
# "billNo": '',
|
||||
# "pushContent": ""
|
||||
# }
|
||||
# }
|
||||
|
||||
# 套期保值正式环境start
|
||||
tqbz_login_url = "http://10.200.32.39/jbsh/api/server/login"
|
||||
tqbz_login_data = {
|
||||
"funcModule": "login",
|
||||
"funcOperation": "login",
|
||||
"data": {
|
||||
"account": "api_szh",
|
||||
"password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=",
|
||||
"tenantHashCode":"7145255749fb7d61263081fca3cb1469",
|
||||
"terminal": "API"
|
||||
}
|
||||
}
|
||||
query_is_trading_day_url = "http://10.200.32.39/jbsh/api/dd/futuresCalendar/checkTradeDay"
|
||||
is_trading_day_data = {
|
||||
"funcModule": "检查是否交易日",
|
||||
"funcOperation": "检查是否交易日",
|
||||
"data": "20251010"
|
||||
}
|
||||
# 套期保值正式环境end
|
||||
|
||||
# # 八大维度数据项编码
|
||||
# bdwd_items = {
|
||||
# 'ciri': 'jxtppbdwdcr',
|
||||
# 'benzhou': 'jxtppbdwdbz',
|
||||
# 'cizhou': 'jxtppbdwdcz',
|
||||
# 'gezhou': 'jxtppbdwdgz',
|
||||
# 'ciyue': 'jxtppbdwdcy',
|
||||
# 'cieryue': 'jxtppbdwdcey',
|
||||
# 'cisanyue': 'jxtppbdwdcsany',
|
||||
# 'cisiyue': 'jxtppbdwdcsiy',
|
||||
# 'ciri': '251889263|FORECAST|PRICE|T01',
|
||||
# 'cierri': '251889263|FORECAST|PRICE|T02',
|
||||
# 'cisanri': '251889263|FORECAST|PRICE|T03',
|
||||
# 'cisiri': '251889263|FORECAST|PRICE|T04',
|
||||
# 'benzhou': '251889263|FORECAST|PRICE|T05',
|
||||
# 'cizhou': '251889263|FORECAST|PRICE|W_01',
|
||||
# 'gezhou': '251889263|FORECAST|PRICE|W_02',
|
||||
# 'ciyue': '251889263|FORECAST|PRICE|M_01',
|
||||
# 'cieryue': '251889263|FORECAST|PRICE|M_02',
|
||||
# 'cisanyue': '251889263|FORECAST|PRICE|M_03',
|
||||
# 'cisiyue': '251889263|FORECAST|PRICE|M_04',
|
||||
# }
|
||||
|
||||
|
||||
# # 报告中八大维度数据项重命名
|
||||
# columnsrename = {'jxtppbdwdbz': '本周', 'jxtppbdwdcey': '次二月', 'jxtppbdwdcr': '次日', 'jxtppbdwdcsiy': '次四月',
|
||||
# 'jxtppbdwdcsany': '次三月', 'jxtppbdwdcy': '次月', 'jxtppbdwdcz': '次周', 'jxtppbdwdgz': '隔周', }
|
||||
# columnsrename = {'251889263|FORECAST|PRICE|T05': '本周', '251889263|FORECAST|PRICE|M_02': '次二月', '251889263|FORECAST|PRICE|T01': '次日', '251889263|FORECAST|PRICE|M_04': '次四月',
|
||||
# '251889263|FORECAST|PRICE|M_03': '次三月', '251889263|FORECAST|PRICE|M_01': '次月', '251889263|FORECAST|PRICE|W_01': '次周', '251889263|FORECAST|PRICE|W_02': '隔周', }
|
||||
|
||||
|
||||
# # 生产环境数据库
|
||||
# host = 'rm-2zehj3r1n60ttz9x5.mysql.rds.aliyuncs.com'
|
||||
# port = 3306
|
||||
# dbusername = 'jingbo'
|
||||
# password = 'shihua@123'
|
||||
# dbname = 'jingbo'
|
||||
# table_name = 'v_tbl_crude_oil_warning'
|
||||
|
||||
|
||||
# 变量定义--测试环境
|
||||
server_host = '192.168.100.53:8080' # 内网
|
||||
# server_host = '183.242.74.28' # 外网
|
||||
login_pushreport_url = f"http://{server_host}/jingbo-dev/api/server/login"
|
||||
upload_url = f"http://{server_host}/jingbo-dev/api/analysis/reportInfo/researchUploadReportSave"
|
||||
upload_warning_url = f"http://{server_host}/jingbo-dev/api/basicBuiness/crudeOilWarning/save"
|
||||
query_data_list_item_nos_url = f"http://{server_host}/jingbo-dev/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# 上传数据项值
|
||||
push_data_value_list_url = f"http://{server_host}/jingbo-dev/api/dw/dataValue/pushDataValueList"
|
||||
# 上传图片报告
|
||||
push_png_report_url = f"http://{server_host}/jingbo-dev/api/analysis/reportInfo/priceForecastImg"
|
||||
|
||||
login_data = {
|
||||
"data": {
|
||||
"account": "api_test",
|
||||
# "password": "MmVmNzNlOWI0MmY0ZDdjZGUwNzE3ZjFiMDJiZDZjZWU=", # Shihua@123456
|
||||
"password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=", # 123456
|
||||
"tenantHashCode": "8a4577dbd919675758d57999a1e891fe",
|
||||
"terminal": "API"
|
||||
},
|
||||
"funcModule": "API",
|
||||
"funcOperation": "获取token"
|
||||
}
|
||||
|
||||
upload_data = {
|
||||
"funcModule": '研究报告信息',
|
||||
"funcOperation": '上传聚烯烃PP价格预测报告',
|
||||
"data": {
|
||||
"ownerAccount": 'arui', # 报告所属用户账号
|
||||
"reportType": 'OIL_PRICE_FORECAST', # 报告类型,固定为OIL_PRICE_FORECAST
|
||||
"fileName": '2000-40-5-50--100-原油指标数据.xlsx-Brent活跃合约--2024-09-06-15-01-29-预测报告.pdf', # 文件名称
|
||||
"fileBase64": '', # 文件内容base64
|
||||
"categoryNo": 'yyjgycbg', # 研究报告分类编码
|
||||
"smartBusinessClassCode": 'JXTJGYCBG', # 分析报告分类编码
|
||||
"reportEmployeeCode": "E40116", # 报告人
|
||||
"reportDeptCode": "D0044", # 报告部门
|
||||
"productGroupCode": "RAW_MATERIAL" # 商品分类
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
warning_data = {
|
||||
"funcModule": '原油特征停更预警',
|
||||
"funcOperation": '原油特征停更预警',
|
||||
"data": {
|
||||
'WARNING_TYPE_NAME': '特征数据停更预警',
|
||||
'WARNING_CONTENT': '',
|
||||
'WARNING_DATE': ''
|
||||
}
|
||||
}
|
||||
|
||||
query_data_list_item_nos_data = {
|
||||
"funcModule": "数据项",
|
||||
"funcOperation": "查询",
|
||||
"data": {
|
||||
"dateStart": "20200101",
|
||||
"dateEnd": "20241231",
|
||||
# 数据项编码,代表 PP期货 价格
|
||||
"dataItemNoList": ["MAIN_CONFT_SETTLE_PRICE"]
|
||||
}
|
||||
}
|
||||
|
||||
push_data_value_list_data = {
|
||||
"funcModule": "数据表信息列表",
|
||||
"funcOperation": "新增",
|
||||
"data": [
|
||||
{"dataItemNo": "91230600716676129",
|
||||
"dataDate": "20230113",
|
||||
"dataStatus": "add",
|
||||
"dataValue": 100.11
|
||||
},
|
||||
{"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
"dataDate": "20230113",
|
||||
"dataStatus": "add",
|
||||
"dataValue": 100.55
|
||||
},
|
||||
{"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
"dataDate": "20230113",
|
||||
"dataStatus": "add",
|
||||
"dataValue": 100.55
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
push_png_report_data = {
|
||||
"funcModule": '研究报告信息',
|
||||
"funcOperation": '上传聚烯烃PP价格预测报告',
|
||||
"data": {
|
||||
"groupNo": "000161",
|
||||
"updateTime": "2024-09-06 15:01:29",
|
||||
"fileBase64": '', # 文件内容base64
|
||||
"title": '2025年8月5日日度周度预测结果',
|
||||
"billNo": '',
|
||||
"pushContent": "2025年8月5日日度周度预测结果"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# 八大维度数据项编码
|
||||
bdwd_items = {
|
||||
'ciri': 'jxtppbdwdcr',
|
||||
'benzhou': 'jxtppbdwdbz',
|
||||
'cizhou': 'jxtppbdwdcz',
|
||||
'gezhou': 'jxtppbdwdgz',
|
||||
'ciyue': 'jxtppbdwdcy',
|
||||
'cieryue': 'jxtppbdwdcey',
|
||||
'cisanyue': 'jxtppbdwdcsany',
|
||||
'cisiyue': 'jxtppbdwdcsiy',
|
||||
}
|
||||
|
||||
# 报告中八大维度数据项重命名
|
||||
columnsrename = {'jxtppbdwdbz': '本周', 'jxtppbdwdcey': '次二月', 'jxtppbdwdcr': '次日', 'jxtppbdwdcsiy': '次四月',
|
||||
'jxtppbdwdcsany': '次三月', 'jxtppbdwdcy': '次月', 'jxtppbdwdcz': '次周', 'jxtppbdwdgz': '隔周', }
|
||||
|
||||
# 北京环境数据库
|
||||
host = '192.168.101.27'
|
||||
|
||||
@ -169,23 +169,185 @@ ClassifyId = 1161
|
||||
|
||||
|
||||
# 变量定义--线上环境
|
||||
server_host = '10.200.32.39'
|
||||
login_pushreport_url = "http://10.200.32.39/jingbo-api/api/server/login"
|
||||
upload_url = "http://10.200.32.39/jingbo-api/api/analysis/reportInfo/researchUploadReportSave"
|
||||
upload_warning_url = "http://10.200.32.39/jingbo-api/api/basicBuiness/crudeOilWarning/save"
|
||||
query_data_list_item_nos_url = f"http://{server_host}/jingbo-api/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# 上传数据项值
|
||||
push_data_value_list_url = f"http://{server_host}/jingbo-api/api/dw/dataValue/pushDataValueList"
|
||||
# 上传停更数据到市场信息平台
|
||||
push_waring_data_value_list_url = f"http://{server_host}/jingbo-api/api/basicBuiness/crudeOilWarning/crudeSaveOrupdate"
|
||||
# 获取预警数据中取消订阅指标ID
|
||||
get_waring_data_value_list_url = f"http://{server_host}/jingbo-api/api/basicBuiness/crudeOilWarning/dataList"
|
||||
# server_host = '10.200.32.39'
|
||||
# login_pushreport_url = "http://10.200.32.39/jingbo-api/api/server/login"
|
||||
# upload_url = "http://10.200.32.39/jingbo-api/api/analysis/reportInfo/researchUploadReportSave"
|
||||
# upload_warning_url = "http://10.200.32.39/jingbo-api/api/basicBuiness/crudeOilWarning/save"
|
||||
# query_data_list_item_nos_url = f"http://{server_host}/jingbo-api/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# # 上传数据项值
|
||||
# push_data_value_list_url = f"http://{server_host}/jingbo-api/api/dw/dataValue/pushDataValueList"
|
||||
# # 上传停更数据到市场信息平台
|
||||
# push_waring_data_value_list_url = f"http://{server_host}/jingbo-api/api/basicBuiness/crudeOilWarning/crudeSaveOrupdate"
|
||||
# # 获取预警数据中取消订阅指标ID
|
||||
# get_waring_data_value_list_url = f"http://{server_host}/jingbo-api/api/basicBuiness/crudeOilWarning/dataList"
|
||||
|
||||
|
||||
# login_data = {
|
||||
# "data": {
|
||||
# "account": "api_dev",
|
||||
# "password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=",
|
||||
# "tenantHashCode": "8a4577dbd919675758d57999a1e891fe",
|
||||
# "terminal": "API"
|
||||
# },
|
||||
# "funcModule": "API",
|
||||
# "funcOperation": "获取token"
|
||||
# }
|
||||
|
||||
|
||||
# upload_data = {
|
||||
# "funcModule": '研究报告信息',
|
||||
# "funcOperation": '上传聚烯烃PP价格预测报告',
|
||||
# "data": {
|
||||
# "groupNo": '000211', # 用户组编号
|
||||
# "ownerAccount": '36541', # 报告所属用户账号 36541 - 贾青雪
|
||||
# "reportType": 'OIL_PRICE_FORECAST', # 报告类型,固定为OIL_PRICE_FORECAST
|
||||
# "fileName": '', # 文件名称
|
||||
# "fileBase64": '', # 文件内容base64
|
||||
# "categoryNo": 'jxtjgycbg', # 研究报告分类编码
|
||||
# "smartBusinessClassCode": 'JXTJGYCBG', # 分析报告分类编码
|
||||
# "reportEmployeeCode": "E40482", # 报告人 E40482 - 管理员 0000027663 - 刘小朋
|
||||
# "reportDeptCode": "JXTJGYCBG", # 报告部门 - 002000621000 SH期货研究部
|
||||
# "productGroupCode": "RAW_MATERIAL" # 商品分类
|
||||
# }
|
||||
# }
|
||||
|
||||
# warning_data = {
|
||||
# "funcModule": '原油特征停更预警',
|
||||
# "funcOperation": '原油特征停更预警',
|
||||
# "data": {
|
||||
# "groupNo": "000211",
|
||||
# 'WARNING_TYPE_NAME': '特征数据停更预警',
|
||||
# 'WARNING_CONTENT': '',
|
||||
# 'WARNING_DATE': ''
|
||||
# }
|
||||
# }
|
||||
|
||||
# query_data_list_item_nos_data = {
|
||||
# "funcModule": "数据项",
|
||||
# "funcOperation": "查询",
|
||||
# "data": {
|
||||
# "dateStart": "20200101",
|
||||
# "dateEnd": "",
|
||||
# # 数据项编码,代表 PP期货 价格
|
||||
# "dataItemNoList": ["MAIN_CONFT_SETTLE_PRICE"]
|
||||
# }
|
||||
# }
|
||||
|
||||
|
||||
# push_data_value_list_data = {
|
||||
# "funcModule": "数据表信息列表",
|
||||
# "funcOperation": "新增",
|
||||
# "data": [
|
||||
# {"dataItemNo": "91230600716676129",
|
||||
# "dataDate": "20230113",
|
||||
# "dataStatus": "add",
|
||||
# "dataValue": 100.11
|
||||
# },
|
||||
# {"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
# "dataDate": "20230113",
|
||||
# "dataStatus": "add",
|
||||
# "dataValue": 100.55
|
||||
# },
|
||||
# {"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
# "dataDate": "20230113",
|
||||
# "dataStatus": "add",
|
||||
# "dataValue": 100.55
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
|
||||
|
||||
# push_waring_data_value_list_data = {
|
||||
# "data": {
|
||||
# "crudeOilWarningDtoList": [
|
||||
# {
|
||||
# "lastUpdateDate": "20240501",
|
||||
# "updateSuspensionCycle": 1,
|
||||
# "dataSource": "9",
|
||||
# "frequency": "1",
|
||||
# "indicatorName": "美元指数",
|
||||
# "indicatorId": "myzs001",
|
||||
# "warningDate": "2024-05-13"
|
||||
# }
|
||||
# ],
|
||||
# "dataSource": "9"
|
||||
# },
|
||||
# "funcModule": "商品数据同步",
|
||||
# "funcOperation": "同步"
|
||||
# }
|
||||
|
||||
|
||||
# get_waring_data_value_list_data = {
|
||||
# "data": "9", "funcModule": "商品数据同步", "funcOperation": "同步"}
|
||||
|
||||
# 套期保值正式环境start
|
||||
tqbz_login_url = "http://10.200.32.39/jbsh/api/server/login"
|
||||
tqbz_login_data = {
|
||||
"funcModule": "login",
|
||||
"funcOperation": "login",
|
||||
"data": {
|
||||
"account": "api_szh",
|
||||
"password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=",
|
||||
"tenantHashCode":"7145255749fb7d61263081fca3cb1469",
|
||||
"terminal": "API"
|
||||
}
|
||||
}
|
||||
query_is_trading_day_url = "http://10.200.32.39/jbsh/api/dd/futuresCalendar/checkTradeDay"
|
||||
is_trading_day_data = {
|
||||
"funcModule": "检查是否交易日",
|
||||
"funcOperation": "检查是否交易日",
|
||||
"data": "20251010"
|
||||
}
|
||||
# 套期保值正式环境end
|
||||
|
||||
# # 八大维度数据项编码
|
||||
# bdwd_items = {
|
||||
# 'ciri': '251889263|FORECAST|PRICE|T01',
|
||||
# 'cierri': '251889263|FORECAST|PRICE|T02',
|
||||
# 'cisanri': '251889263|FORECAST|PRICE|T03',
|
||||
# 'cisiri': '251889263|FORECAST|PRICE|T04',
|
||||
# 'benzhou': '251889263|FORECAST|PRICE|T05',
|
||||
# 'cizhou': '251889263|FORECAST|PRICE|W_01',
|
||||
# 'gezhou': '251889263|FORECAST|PRICE|W_02',
|
||||
# 'ciyue': '251889263|FORECAST|PRICE|M_01',
|
||||
# 'cieryue': '251889263|FORECAST|PRICE|M_02',
|
||||
# 'cisanyue': '251889263|FORECAST|PRICE|M_03',
|
||||
# 'cisiyue': '251889263|FORECAST|PRICE|M_04',
|
||||
# }
|
||||
|
||||
|
||||
|
||||
|
||||
# # 生产环境数据库
|
||||
# host = 'rm-2zehj3r1n60ttz9x5.mysql.rds.aliyuncs.com'
|
||||
# port = 3306
|
||||
# dbusername = 'jingbo'
|
||||
# password = 'shihua@123'
|
||||
# dbname = 'jingbo'
|
||||
# table_name = 'v_tbl_crude_oil_warning'
|
||||
|
||||
# 变量定义--测试环境
|
||||
server_host = '192.168.100.53' # 内网
|
||||
# server_host = '183.242.74.28' # 外网
|
||||
login_pushreport_url = f"http://{server_host}:8080/jingbo-dev/api/server/login"
|
||||
# 上传报告
|
||||
upload_url = f"http://{server_host}:8080/jingbo-dev/api/analysis/reportInfo/researchUploadReportSave"
|
||||
# 停更预警
|
||||
upload_warning_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/save"
|
||||
# 查询数据项编码
|
||||
query_data_list_item_nos_url = f"http://{server_host}:8080/jingbo-dev/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# 上传数据项值
|
||||
push_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/dw/dataValue/pushDataValueList"
|
||||
# 上传停更数据到市场信息平台
|
||||
push_waring_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/crudeSaveOrupdate"
|
||||
# 获取预警数据中取消订阅指标ID
|
||||
get_waring_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/dataList"
|
||||
|
||||
login_data = {
|
||||
"data": {
|
||||
"account": "api_dev",
|
||||
"password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=",
|
||||
"account": "api_test",
|
||||
# "password": "MmVmNzNlOWI0MmY0ZDdjZGUwNzE3ZjFiMDJiZDZjZWU=", # Shihua@123456
|
||||
"password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=", # 123456
|
||||
"tenantHashCode": "8a4577dbd919675758d57999a1e891fe",
|
||||
"terminal": "API"
|
||||
},
|
||||
@ -193,29 +355,29 @@ login_data = {
|
||||
"funcOperation": "获取token"
|
||||
}
|
||||
|
||||
|
||||
upload_data = {
|
||||
"funcModule": '研究报告信息',
|
||||
"funcOperation": '上传聚烯烃PP价格预测报告',
|
||||
"data": {
|
||||
"groupNo": '000211', # 用户组编号
|
||||
"ownerAccount": '36541', # 报告所属用户账号 36541 - 贾青雪
|
||||
"groupNo": "000127",
|
||||
"ownerAccount": 'arui', # 报告所属用户账号
|
||||
"reportType": 'OIL_PRICE_FORECAST', # 报告类型,固定为OIL_PRICE_FORECAST
|
||||
"fileName": '', # 文件名称
|
||||
"fileName": '2000-40-5-50--100-原油指标数据.xlsx-Brent活跃合约--2024-09-06-15-01-29-预测报告.pdf', # 文件名称
|
||||
"fileBase64": '', # 文件内容base64
|
||||
"categoryNo": 'jxtjgycbg', # 研究报告分类编码
|
||||
"categoryNo": 'yyjgycbg', # 研究报告分类编码
|
||||
"smartBusinessClassCode": 'JXTJGYCBG', # 分析报告分类编码
|
||||
"reportEmployeeCode": "E40482", # 报告人 E40482 - 管理员 0000027663 - 刘小朋
|
||||
"reportDeptCode": "JXTJGYCBG", # 报告部门 - 002000621000 SH期货研究部
|
||||
"productGroupCode": "RAW_MATERIAL" # 商品分类
|
||||
"reportEmployeeCode": "E40116", # 报告人
|
||||
"reportDeptCode": "D0044", # 报告部门
|
||||
"productGroupCode": "RAW_MATERIAL" # 商品分类
|
||||
}
|
||||
}
|
||||
|
||||
# 已弃用
|
||||
warning_data = {
|
||||
"funcModule": '原油特征停更预警',
|
||||
"funcOperation": '原油特征停更预警',
|
||||
"data": {
|
||||
"groupNo": "000211",
|
||||
"groupNo": "000127",
|
||||
'WARNING_TYPE_NAME': '特征数据停更预警',
|
||||
'WARNING_CONTENT': '',
|
||||
'WARNING_DATE': ''
|
||||
@ -233,7 +395,6 @@ query_data_list_item_nos_data = {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
push_data_value_list_data = {
|
||||
"funcModule": "数据表信息列表",
|
||||
"funcOperation": "新增",
|
||||
@ -281,170 +442,26 @@ get_waring_data_value_list_data = {
|
||||
"data": "9", "funcModule": "商品数据同步", "funcOperation": "同步"}
|
||||
|
||||
|
||||
|
||||
# 八大维度数据项编码
|
||||
bdwd_items = {
|
||||
'ciri': '251889263|FORECAST|PRICE|T01',
|
||||
'cierri': '251889263|FORECAST|PRICE|T02',
|
||||
'cisanri': '251889263|FORECAST|PRICE|T03',
|
||||
'cisiri': '251889263|FORECAST|PRICE|T04',
|
||||
'benzhou': '251889263|FORECAST|PRICE|T05',
|
||||
'cizhou': '251889263|FORECAST|PRICE|W_01',
|
||||
'gezhou': '251889263|FORECAST|PRICE|W_02',
|
||||
'ciyue': '251889263|FORECAST|PRICE|M_01',
|
||||
'cieryue': '251889263|FORECAST|PRICE|M_02',
|
||||
'cisanyue': '251889263|FORECAST|PRICE|M_03',
|
||||
'cisiyue': '251889263|FORECAST|PRICE|M_04',
|
||||
'ciri': 'jxtppbdwdcr',
|
||||
'benzhou': 'jxtppbdwdbz',
|
||||
'cizhou': 'jxtppbdwdcz',
|
||||
'gezhou': 'jxtppbdwdgz',
|
||||
'ciyue': 'jxtppbdwdcy',
|
||||
'cieryue': 'jxtppbdwdcey',
|
||||
'cisanyue': 'jxtppbdwdcsany',
|
||||
'cisiyue': 'jxtppbdwdcsiy',
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
# # 生产环境数据库
|
||||
host = 'rm-2zehj3r1n60ttz9x5.mysql.rds.aliyuncs.com'
|
||||
port = 3306
|
||||
dbusername = 'jingbo'
|
||||
password = 'shihua@123'
|
||||
dbname = 'jingbo'
|
||||
table_name = 'v_tbl_crude_oil_warning'
|
||||
|
||||
|
||||
# 变量定义--测试环境
|
||||
# server_host = '192.168.100.53' # 内网
|
||||
# # server_host = '183.242.74.28' # 外网
|
||||
# login_pushreport_url = f"http://{server_host}:8080/jingbo-dev/api/server/login"
|
||||
# # 上传报告
|
||||
# upload_url = f"http://{server_host}:8080/jingbo-dev/api/analysis/reportInfo/researchUploadReportSave"
|
||||
# # 停更预警
|
||||
# upload_warning_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/save"
|
||||
# # 查询数据项编码
|
||||
# query_data_list_item_nos_url = f"http://{server_host}:8080/jingbo-dev/api/warehouse/dwDataItem/queryDataListItemNos"
|
||||
# # 上传数据项值
|
||||
# push_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/dw/dataValue/pushDataValueList"
|
||||
# # 上传停更数据到市场信息平台
|
||||
# push_waring_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/crudeSaveOrupdate"
|
||||
# # 获取预警数据中取消订阅指标ID
|
||||
# get_waring_data_value_list_url = f"http://{server_host}:8080/jingbo-dev/api/basicBuiness/crudeOilWarning/dataList"
|
||||
|
||||
# login_data = {
|
||||
# "data": {
|
||||
# "account": "api_test",
|
||||
# # "password": "MmVmNzNlOWI0MmY0ZDdjZGUwNzE3ZjFiMDJiZDZjZWU=", # Shihua@123456
|
||||
# "password": "ZTEwYWRjMzk0OWJhNTlhYmJlNTZlMDU3ZjIwZjg4M2U=", # 123456
|
||||
# "tenantHashCode": "8a4577dbd919675758d57999a1e891fe",
|
||||
# "terminal": "API"
|
||||
# },
|
||||
# "funcModule": "API",
|
||||
# "funcOperation": "获取token"
|
||||
# }
|
||||
|
||||
# upload_data = {
|
||||
# "funcModule": '研究报告信息',
|
||||
# "funcOperation": '上传聚烯烃PP价格预测报告',
|
||||
# "data": {
|
||||
# "groupNo": "000127",
|
||||
# "ownerAccount": 'arui', # 报告所属用户账号
|
||||
# "reportType": 'OIL_PRICE_FORECAST', # 报告类型,固定为OIL_PRICE_FORECAST
|
||||
# "fileName": '2000-40-5-50--100-原油指标数据.xlsx-Brent活跃合约--2024-09-06-15-01-29-预测报告.pdf', # 文件名称
|
||||
# "fileBase64": '', # 文件内容base64
|
||||
# "categoryNo": 'yyjgycbg', # 研究报告分类编码
|
||||
# "smartBusinessClassCode": 'JXTJGYCBG', # 分析报告分类编码
|
||||
# "reportEmployeeCode": "E40116", # 报告人
|
||||
# "reportDeptCode": "D0044", # 报告部门
|
||||
# "productGroupCode": "RAW_MATERIAL" # 商品分类
|
||||
# }
|
||||
# }
|
||||
|
||||
# # 已弃用
|
||||
# warning_data = {
|
||||
# "funcModule": '原油特征停更预警',
|
||||
# "funcOperation": '原油特征停更预警',
|
||||
# "data": {
|
||||
# "groupNo": "000127",
|
||||
# 'WARNING_TYPE_NAME': '特征数据停更预警',
|
||||
# 'WARNING_CONTENT': '',
|
||||
# 'WARNING_DATE': ''
|
||||
# }
|
||||
# }
|
||||
|
||||
# query_data_list_item_nos_data = {
|
||||
# "funcModule": "数据项",
|
||||
# "funcOperation": "查询",
|
||||
# "data": {
|
||||
# "dateStart": "20200101",
|
||||
# "dateEnd": "",
|
||||
# # 数据项编码,代表 PP期货 价格
|
||||
# "dataItemNoList": ["MAIN_CONFT_SETTLE_PRICE"]
|
||||
# }
|
||||
# }
|
||||
|
||||
# push_data_value_list_data = {
|
||||
# "funcModule": "数据表信息列表",
|
||||
# "funcOperation": "新增",
|
||||
# "data": [
|
||||
# {"dataItemNo": "91230600716676129",
|
||||
# "dataDate": "20230113",
|
||||
# "dataStatus": "add",
|
||||
# "dataValue": 100.11
|
||||
# },
|
||||
# {"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
# "dataDate": "20230113",
|
||||
# "dataStatus": "add",
|
||||
# "dataValue": 100.55
|
||||
# },
|
||||
# {"dataItemNo": "91230600716676129P|ETHYL_BEN|CAPACITY",
|
||||
# "dataDate": "20230113",
|
||||
# "dataStatus": "add",
|
||||
# "dataValue": 100.55
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
|
||||
|
||||
# push_waring_data_value_list_data = {
|
||||
# "data": {
|
||||
# "crudeOilWarningDtoList": [
|
||||
# {
|
||||
# "lastUpdateDate": "20240501",
|
||||
# "updateSuspensionCycle": 1,
|
||||
# "dataSource": "9",
|
||||
# "frequency": "1",
|
||||
# "indicatorName": "美元指数",
|
||||
# "indicatorId": "myzs001",
|
||||
# "warningDate": "2024-05-13"
|
||||
# }
|
||||
# ],
|
||||
# "dataSource": "9"
|
||||
# },
|
||||
# "funcModule": "商品数据同步",
|
||||
# "funcOperation": "同步"
|
||||
# }
|
||||
|
||||
|
||||
# get_waring_data_value_list_data = {
|
||||
# "data": "9", "funcModule": "商品数据同步", "funcOperation": "同步"}
|
||||
|
||||
|
||||
# # 八大维度数据项编码
|
||||
# bdwd_items = {
|
||||
# 'ciri': 'jxtppbdwdcr',
|
||||
# 'benzhou': 'jxtppbdwdbz',
|
||||
# 'cizhou': 'jxtppbdwdcz',
|
||||
# 'gezhou': 'jxtppbdwdgz',
|
||||
# 'ciyue': 'jxtppbdwdcy',
|
||||
# 'cieryue': 'jxtppbdwdcey',
|
||||
# 'cisanyue': 'jxtppbdwdcsany',
|
||||
# 'cisiyue': 'jxtppbdwdcsiy',
|
||||
# }
|
||||
|
||||
|
||||
# 北京环境数据库
|
||||
# host = '192.168.101.27'
|
||||
# port = 3306
|
||||
# dbusername = 'root'
|
||||
# password = '123456'
|
||||
# dbname = 'jingbo_test'
|
||||
# table_name = 'v_tbl_crude_oil_warning'
|
||||
host = '192.168.101.27'
|
||||
port = 3306
|
||||
dbusername = 'root'
|
||||
password = '123456'
|
||||
dbname = 'jingbo_test'
|
||||
table_name = 'v_tbl_crude_oil_warning'
|
||||
|
||||
DEFAULT_CONFIG = {
|
||||
'feature_factor_frequency': 'D',
|
||||
|
||||
@ -106,6 +106,12 @@ def push_png_report():
|
||||
data['data']['fileBase64'] = base64_data
|
||||
data['data']['billNo'] = str(time.time())
|
||||
|
||||
if png_report_file == 'pp_zhouducorrelation.png':
|
||||
data['data']['pushContent'] = f'{end_time}PP期货日、周维度预测价格走势'
|
||||
else:
|
||||
data['data']['pushContent'] = f'{end_time}PP期货月维度预测价格走势'
|
||||
|
||||
# data['data']['pushContent'] = f'{end_time}PP期货价格预测'
|
||||
pngreportdata = push_png_report_to_market(data)
|
||||
logger.info(f'{png_report_file}推送图片报告到钉钉成功{pngreportdata}')
|
||||
except Exception as e:
|
||||
@ -116,10 +122,27 @@ if __name__ == '__main__':
|
||||
# 图片报告
|
||||
try:
|
||||
logger.info('图片报告ing')
|
||||
global_config['end_time'] = '2025-08-14'
|
||||
global_config['end_time'] = '2025-08-01'
|
||||
# previous_trading_day = (pd.Timestamp(global_config['end_time']) -
|
||||
# pd.tseries.offsets.BusinessDay(1)).strftime('%Y-%m-%d')
|
||||
# global_config['end_time'] = previous_trading_day
|
||||
|
||||
# 交易日检查
|
||||
# 将 end_time 转换为 YYYYMMDD 格式
|
||||
end_time_str = global_config['end_time'].replace('-', '')
|
||||
logger.info(f"开始检查预测日期 {global_config['end_time']} 是否为交易日")
|
||||
|
||||
# 使用 global_config 中的交易日检查参数
|
||||
is_trading = check_trading_day(end_time_str, global_config)
|
||||
if not is_trading:
|
||||
logger.info(f"预测日期 {global_config['end_time']} 不是交易日,跳过图片报告任务")
|
||||
exit(0)
|
||||
else:
|
||||
logger.info(f"预测日期 {global_config['end_time']} 是交易日,开始执行图片报告任务")
|
||||
|
||||
pp_bdwd_png(global_config=global_config)
|
||||
logger.info('图片报告end')
|
||||
except Exception as e:
|
||||
logger.info(f'图片报告失败:{e}')
|
||||
# time.sleep(5)
|
||||
# push_png_report()
|
||||
time.sleep(5)
|
||||
push_png_report()
|
||||
|
||||
142
lib/dataread.py
142
lib/dataread.py
@ -80,6 +80,8 @@ global_config = {
|
||||
'upload_headers': None, # 上传请求头
|
||||
'upload_warning_url': None, # 预警数据上传地址
|
||||
'upload_warning_data': None, # 预警数据结构
|
||||
'upload_report_audit_url': None, # 报告审核地址
|
||||
'upload_report_audit_data': None, # 报告审核数据结构
|
||||
|
||||
# 报告上传
|
||||
'upload_data': None, # 报告数据结构
|
||||
@ -95,6 +97,12 @@ global_config = {
|
||||
'push_waring_data_value_list_url': None,
|
||||
'push_waring_data_value_list_data': None,
|
||||
|
||||
# 套期保值api
|
||||
"tqbz_login_url":None,
|
||||
"tqbz_login_data":None,
|
||||
'query_is_trading_day_url': None,
|
||||
'is_trading_day_data': None,
|
||||
|
||||
# 字段映射
|
||||
'offsite_col': None, # 站点字段
|
||||
'avg_col': None, # 平均值字段
|
||||
@ -231,7 +239,7 @@ def get_head_auth_report():
|
||||
f'url:{config.login_pushreport_url},login_data:{config.login_data}')
|
||||
# 发送 POST 请求到登录 URL,携带登录数据
|
||||
login_res = requests.post(url=config.login_pushreport_url,
|
||||
json=config.login_data, timeout=(3, 30))
|
||||
json=config.login_data, timeout=(10, 30))
|
||||
|
||||
# 将响应内容转换为 JSON 格式
|
||||
text = json.loads(login_res.text)
|
||||
@ -272,7 +280,7 @@ def upload_report_data(token, upload_data):
|
||||
|
||||
# 发送POST请求,上传报告数据
|
||||
upload_res = requests.post(
|
||||
url=config.upload_url, headers=headers, json=upload_data, timeout=(3, 15))
|
||||
url=config.upload_url, headers=headers, json=upload_data, timeout=(10, 15))
|
||||
|
||||
# 将响应内容转换为 JSON 格式
|
||||
upload_res = json.loads(upload_res.text)
|
||||
@ -319,7 +327,7 @@ def upload_warning_data(warning_data):
|
||||
|
||||
# 发送POST请求,上传预警数据
|
||||
upload_res = requests.post(
|
||||
url=config.upload_warning_url, headers=headers, json=config.warning_data, timeout=(3, 15))
|
||||
url=config.upload_warning_url, headers=headers, json=config.warning_data, timeout=(10, 15))
|
||||
|
||||
# 如果上传成功,返回响应对象
|
||||
if upload_res:
|
||||
@ -900,21 +908,21 @@ def datachuli(df_zhibiaoshuju, df_zhibiaoliebiao, datecol='date', end_time='', y
|
||||
# 删除全为空值的列
|
||||
df = df.dropna(axis=1, how='all')
|
||||
|
||||
# 删除开始时间没有数据的列
|
||||
config.logger.info(f'删除开始时间没有数据的列前数据量:{df.shape}')
|
||||
for col in df.columns:
|
||||
if col == 'ds': # 跳过 'ds' 列
|
||||
continue
|
||||
# 找到第一个非空值的索引
|
||||
first_valid_index = df[col].first_valid_index()
|
||||
if first_valid_index is not None:
|
||||
# 判断对应的 'ds' 是否大于 start_date
|
||||
if df.loc[first_valid_index, 'ds'] > start_date:
|
||||
df.drop(columns=[col], inplace=True)
|
||||
config.logger.info(
|
||||
f'删除开始时间没有数据的列:{col},第一条数据日期为:{df.loc[first_valid_index, "ds"]}')
|
||||
# # 删除开始时间没有数据的列
|
||||
# config.logger.info(f'删除开始时间没有数据的列前数据量:{df.shape}')
|
||||
# for col in df.columns:
|
||||
# if col in ['ds','Brentzgj','Brentzdj']: # 跳过 'ds' 列
|
||||
# continue
|
||||
# # 找到第一个非空值的索引
|
||||
# first_valid_index = df[col].first_valid_index()
|
||||
# if first_valid_index is not None:
|
||||
# # 判断对应的 'ds' 是否大于 start_date
|
||||
# if df.loc[first_valid_index, 'ds'] > start_date:
|
||||
# df.drop(columns=[col], inplace=True)
|
||||
# config.logger.info(
|
||||
# f'删除开始时间没有数据的列:{col},第一条数据日期为:{df.loc[first_valid_index, "ds"]}')
|
||||
|
||||
config.logger.info(f'删除开始时间没有数据的列后数据量:{df.shape}')
|
||||
# config.logger.info(f'删除开始时间没有数据的列后数据量:{df.shape}')
|
||||
|
||||
# 获取start_year年到end_time的数据
|
||||
df = df[df['ds'].dt.year >= config.start_year]
|
||||
@ -947,6 +955,8 @@ def datachuli(df_zhibiaoshuju, df_zhibiaoliebiao, datecol='date', end_time='', y
|
||||
if is_timefurture:
|
||||
df = addtimecharacteristics(df=df, dataset=dataset)
|
||||
|
||||
|
||||
|
||||
if config.freq == 'WW':
|
||||
# 自定义周数据
|
||||
# 按weekofmothe分组取均值得到新的数据
|
||||
@ -994,6 +1004,14 @@ def datachuli(df_zhibiaoshuju, df_zhibiaoliebiao, datecol='date', end_time='', y
|
||||
# kdj指标
|
||||
if add_kdj:
|
||||
df = calculate_kdj(df)
|
||||
|
||||
# 衍生预测目标近30日的中位数,最大,最小
|
||||
if config.freq == 'M':
|
||||
df['y_30d_median'] = df['y'].rolling(window=30).median()
|
||||
df['y_30d_max'] = df['y'].rolling(window=30).max()
|
||||
df['y_30d_min'] = df['y'].rolling(window=30).min()
|
||||
|
||||
|
||||
# 保存填充后的数据
|
||||
df.to_csv(os.path.join(
|
||||
dataset, '处理后的特征数据.csv'), index=False)
|
||||
@ -1042,6 +1060,18 @@ def zhoududatachuli(df_zhibiaoshuju, df_zhibiaoliebiao, datecol='date', end_time
|
||||
|
||||
config.logger.info(f'删除两月不更新特征后数据量:{df.shape}')
|
||||
|
||||
# 在重采样之前:优先将最高/最低价从原始数据拼接进来,并进行缺失值填充
|
||||
try:
|
||||
for col in ['Brentzgj', 'Brentzdj']:
|
||||
if col in df_zhibiaoshuju.columns and col not in df.columns:
|
||||
df = pd.merge(df, df_zhibiaoshuju[['ds', col]], on='ds', how='left')
|
||||
# 对已存在的高低价列进行前后向填充,确保重采样时不产生 NaN
|
||||
for col in ['Brentzgj', 'Brentzdj']:
|
||||
if col in df.columns:
|
||||
df[col] = df[col].ffill().bfill()
|
||||
except Exception as e:
|
||||
config.logger.info(f'重采样前拼接高低价失败:{e}')
|
||||
|
||||
if config.freq == 'W':
|
||||
# 按周取样
|
||||
df = df.resample('W', on='ds').mean().reset_index()
|
||||
@ -1435,6 +1465,12 @@ class Config:
|
||||
def upload_warning_data(self): return global_config['upload_warning_data']
|
||||
@property
|
||||
def warning_data(self): return global_config['warning_data']
|
||||
|
||||
@property
|
||||
def upload_report_audit_url(self): return global_config['upload_report_audit_url']
|
||||
@property
|
||||
def upload_report_audit_data(self): return global_config['upload_report_audit_data']
|
||||
|
||||
# 查询接口
|
||||
|
||||
@property
|
||||
@ -2454,7 +2490,7 @@ def get_market_data(end_time, df):
|
||||
headers = {"Authorization": token}
|
||||
config.logger.info('获取数据中...')
|
||||
items_res = requests.post(url=config.query_data_list_item_nos_url, headers=headers,
|
||||
json=config.query_data_list_item_nos_data, timeout=(3, 35))
|
||||
json=config.query_data_list_item_nos_data, timeout=(10, 35))
|
||||
json_data = json.loads(items_res.text)
|
||||
df3 = pd.DataFrame(json_data['data'])
|
||||
# 按照dataItemNo 分组 得到多个dataframe ,最后根据dataDate merge 成一个dataframe
|
||||
@ -2491,10 +2527,21 @@ def push_png_report_to_market(data):
|
||||
config.logger.info(f'推送图片报告URL:{config.push_png_report_url}')
|
||||
# config.logger.info(f'推送图片报告数据:{data}')
|
||||
items_res = requests.post(url=config.push_png_report_url, headers=headers,
|
||||
json=data, timeout=(3, 35))
|
||||
json=data, timeout=(10, 35))
|
||||
json_data = json.loads(items_res.text)
|
||||
config.logger.info(f"推送图片报告结果:{json_data}")
|
||||
return json_data
|
||||
|
||||
# 发送请求
|
||||
# headers = {"Authorization": token}
|
||||
# config.logger.info('推送图片报告中...')
|
||||
# config.logger.info(f'推送图片报告URL:{config.upload_report_audit_url}')
|
||||
# # config.logger.info(f'推送图片报告数据:{data}')
|
||||
# items_res = requests.post(url=config.upload_report_audit_url, headers=headers,
|
||||
# json=data, timeout=(10, 35))
|
||||
# json_data = json.loads(items_res.text)
|
||||
# config.logger.info(f"推送图片报告结果:{json_data}")
|
||||
# return json_data
|
||||
|
||||
|
||||
def push_market_data(data):
|
||||
@ -2532,7 +2579,7 @@ def push_market_data(data):
|
||||
config.logger.info(f'上传数据数据:{config.push_data_value_list_data}')
|
||||
|
||||
items_res = requests.post(url=config.push_data_value_list_url, headers=headers,
|
||||
json=config.push_data_value_list_data, timeout=(3, 35))
|
||||
json=config.push_data_value_list_data, timeout=(10, 35))
|
||||
json_data = json.loads(items_res.text)
|
||||
config.logger.info(f"上传结果:{json_data}")
|
||||
return json_data
|
||||
@ -2572,7 +2619,7 @@ def push_waring_market_data(data, dataSource=8):
|
||||
headers = {"Authorization": token}
|
||||
config.logger.info('上传数据中...')
|
||||
items_res = requests.post(url=config.push_waring_data_value_list_url, headers=headers,
|
||||
json=config.push_waring_data_value_list_data, timeout=(3, 35))
|
||||
json=config.push_waring_data_value_list_data, timeout=(10, 35))
|
||||
json_data = json.loads(items_res.text)
|
||||
config.logger.info(f"上传结果:{json_data}")
|
||||
return json_data
|
||||
@ -2606,7 +2653,7 @@ def get_waring_data():
|
||||
headers = {"Authorization": token}
|
||||
config.logger.info('获取取消订阅指标ID中...')
|
||||
items_res = requests.post(url=config.get_waring_data_value_list_url, headers=headers,
|
||||
json=config.get_waring_data_value_list_data, timeout=(3, 35))
|
||||
json=config.get_waring_data_value_list_data, timeout=(10, 35))
|
||||
json_data = json.loads(items_res.text)
|
||||
json_data = json_data['data']
|
||||
quxiaodingyueidlist = []
|
||||
@ -2696,8 +2743,7 @@ def get_baichuan_data(baichuanidnamedict):
|
||||
print(sql)
|
||||
# 获取查询结果
|
||||
results = db.execute_query(sql)
|
||||
df = pd.DataFrame(results, columns=[
|
||||
'BAICHUAN_ID', 'DATA_DATE', 'DATA_VALUE'])
|
||||
df = pd.DataFrame(results, columns=['BAICHUAN_ID', 'DATA_DATE', 'DATA_VALUE'])
|
||||
df['BAICHUAN_ID'] = df['BAICHUAN_ID'].astype('string')
|
||||
df.to_csv(os.path.join(config.dataset, '百川数据.csv'), index=False)
|
||||
|
||||
@ -2746,7 +2792,7 @@ def get_bdwd_predict_data():
|
||||
|
||||
# 发送POST请求,上传预警数据
|
||||
respose = requests.post(
|
||||
url=config.upload_warning_url, headers=headers, json=query_data_list_item_nos_data, timeout=(3, 15))
|
||||
url=config.upload_warning_url, headers=headers, json=query_data_list_item_nos_data, timeout=(10, 15))
|
||||
|
||||
# 如果上传成功,返回响应对象
|
||||
if respose:
|
||||
@ -2779,7 +2825,7 @@ def get_bdwd_predict_data():
|
||||
headers = {"Authorization": token}
|
||||
config.logger.info('获取数据中...')
|
||||
items_res = requests.post(url=config.query_data_list_item_nos_url, headers=headers,
|
||||
json=query_data_list_item_nos_data, timeout=(3, 35))
|
||||
json=query_data_list_item_nos_data, timeout=(10, 35))
|
||||
json_data = json.loads(items_res.text)
|
||||
config.logger.info(f"获取到的数据:{json_data}")
|
||||
df3 = pd.DataFrame(json_data['data'])
|
||||
@ -2811,3 +2857,47 @@ def get_bdwd_predict_data():
|
||||
print(df2)
|
||||
df2 = df2[existing_columns]
|
||||
return df2
|
||||
|
||||
|
||||
def check_trading_day(date_str, global_config):
|
||||
"""
|
||||
检查指定日期是否为交易日
|
||||
|
||||
Args:
|
||||
date_str: 日期字符串,格式为 'YYYYMMDD'
|
||||
global_config: 全局配置对象,包含数据库配置信息
|
||||
|
||||
Returns:
|
||||
bool: True表示是交易日,False表示不是交易日
|
||||
"""
|
||||
try:
|
||||
# 获取数据库连接配置
|
||||
db_config = global_config.get('db_mysql')
|
||||
if not db_config:
|
||||
global_config['logger'].error('未找到数据库配置(db_mysql),默认视为交易日')
|
||||
return True
|
||||
|
||||
# 确保数据库连接是活跃的
|
||||
if not db_config.is_connected():
|
||||
db_config.connect()
|
||||
|
||||
# 使用提供的SQL语句查询交易日,直接使用传入的日期格式
|
||||
sql = f"""
|
||||
SELECT vtdcd.CALENDAR_DAY
|
||||
FROM jingbo_test.v_tbl_dd_calendar_day AS vtdcd
|
||||
WHERE (CALENDAR_NO = 'pp') AND (DELETE_FLAG = '0') AND (CALENDAR_DAY = '{date_str}')
|
||||
"""
|
||||
|
||||
# 执行查询
|
||||
result = db_config.execute_query(sql)
|
||||
|
||||
# 如果查询结果不为空,则该日期是交易日
|
||||
is_trading = len(result) > 0 if result is not None else False
|
||||
|
||||
global_config['logger'].info(f'日期 {date_str} 是否为交易日: {is_trading}')
|
||||
return is_trading
|
||||
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f'检查交易日时发生错误: {str(e)},默认视为交易日')
|
||||
# 数据库查询失败时,默认视为交易日
|
||||
return True
|
||||
|
||||
433
lib/tools.py
433
lib/tools.py
@ -862,7 +862,264 @@ def convert_df_to_pydantic_pp(df_predict, model_id_name_dict, global_config):
|
||||
return results
|
||||
|
||||
|
||||
def find_best_models_yuanyou(date='', global_config=None):
|
||||
# 说明:为各价格维度选择“最佳模型”。
|
||||
# 思路:按维度构造真实价基准(上一交易日/参考周均价/参考月均价),
|
||||
# 比较各模型该维度预测与基准的绝对误差(可选按趋势过滤),
|
||||
# 选误差最小的模型,并返回模型 id、名称、预测值与对应日期。
|
||||
best_models = {}
|
||||
model_id_name_dict = get_model_id_name_dict(global_config=global_config)
|
||||
|
||||
# 处理日期输入
|
||||
if not date:
|
||||
date = datetime.datetime.now().strftime('%Y-%m-%d')
|
||||
else:
|
||||
try:
|
||||
date = datetime.datetime.strptime(
|
||||
date, '%Y-%m-%d').strftime('%Y-%m-%d')
|
||||
except ValueError:
|
||||
global_config['logger'].error(
|
||||
f"日期格式错误,期望格式为 '%Y-%m-%d',实际输入: {date}")
|
||||
return best_models
|
||||
current_date = datetime.datetime.strptime(date, '%Y-%m-%d')
|
||||
|
||||
# 上一交易日日期 Last trading day
|
||||
last_trading_day = pd.Timestamp(date) - pd.tseries.offsets.BusinessDay(1)
|
||||
last_trading_day_str = last_trading_day.strftime('%Y-%m-%d')
|
||||
|
||||
# 计算date对应月的一日
|
||||
first_day_of_month = current_date.replace(day=1)
|
||||
# 计算date对应周的周一
|
||||
date_monday = current_date - \
|
||||
datetime.timedelta(days=current_date.weekday())
|
||||
|
||||
# 获取真实价格数据
|
||||
try:
|
||||
true_price = pd.read_csv('yuanyoudataset/指标数据.csv')[['ds', 'y']]
|
||||
except FileNotFoundError:
|
||||
global_config['logger'].error(
|
||||
f"未找到文件: {os.path.join(global_config['dataset'], '指标数据.csv')}")
|
||||
return best_models
|
||||
|
||||
# 计算六月前的年月
|
||||
year, month = map(int, date.split('-')[:2])
|
||||
if month <= 6:
|
||||
year -= 1
|
||||
month = 12
|
||||
else:
|
||||
month -= 6
|
||||
|
||||
tb = 'v_tbl_predict_prediction_results'
|
||||
sql = f'select * from {tb} where data_date >= \'{year}-{month}-01\''
|
||||
# 数据库查询对应日期的预测值
|
||||
predictresult = global_config['db_mysql'].execute_query(sql)
|
||||
if not predictresult:
|
||||
global_config['logger'].info('没有预测结果')
|
||||
return best_models
|
||||
|
||||
df = pd.DataFrame(predictresult)[
|
||||
['data_date', 'model_id'] + global_config['price_columns']]
|
||||
global_config['logger'].info(f'预测结果数量:{df.shape}')
|
||||
global_config['logger'].info(
|
||||
f'预测结果日期范围:{df["data_date"].min()} 到 {df["data_date"].max()}')
|
||||
|
||||
def query_predict_result(date, model_id, global_config, wd):
|
||||
tb = 'v_tbl_predict_prediction_results'
|
||||
sql = f'select {wd} from {tb} where data_date = \'{date}\' and model_id = {model_id}'
|
||||
predictresult = global_config['db_mysql'].execute_query(sql)
|
||||
if not predictresult:
|
||||
global_config['logger'].info('没有预测结果')
|
||||
return None
|
||||
predictresult = float(predictresult[0][wd])
|
||||
return predictresult
|
||||
|
||||
def calculate_best_model(price, trend, weektrueprice=None, monthtrueprice=None):
|
||||
"""
|
||||
计算最佳模型:
|
||||
- price:候选模型在目标维度的预测(可聚合为周/月均)
|
||||
- trend:当需要方向过滤时传入(与真实价差的符号一致)
|
||||
- weektrueprice/monthtrueprice:周/月维度基准均值
|
||||
返回:绝对误差最小的 (model_id, model_name)
|
||||
"""
|
||||
price = price.copy() # Explicitly create a copy of the DataFrame
|
||||
price[global_config['price_columns'][i]
|
||||
] = price[global_config['price_columns'][i]].astype(float)
|
||||
price = price.dropna(subset=[global_config['price_columns'][i]])
|
||||
if weektrueprice is not None:
|
||||
true_price_value = weektrueprice
|
||||
elif monthtrueprice is not None:
|
||||
true_price_value = monthtrueprice
|
||||
else:
|
||||
true_price_value = true_price[true_price['ds']
|
||||
== last_trading_day_str]['y'].values[0]
|
||||
|
||||
if not price.empty:
|
||||
price.loc[:, 'trueprice'] = true_price_value
|
||||
price.loc[:, 'trend'] = np.where(
|
||||
price['trueprice'] - price[global_config['price_columns'][i]] > 0, 1, -1)
|
||||
price.loc[:, 'abs'] = (price['trueprice'] -
|
||||
price[global_config['price_columns'][i]]).abs()
|
||||
if trend is not None:
|
||||
price = price[price['trend'] == trend]
|
||||
if not price.empty:
|
||||
price = price[price['abs'] == price['abs'].min()]
|
||||
best_model_id = price.iloc[0]['model_id']
|
||||
best_model_name = model_id_name_dict[best_model_id]
|
||||
return best_model_id, best_model_name
|
||||
# Return None if the DataFrame is empty
|
||||
return None, None
|
||||
|
||||
# 遍历全局配置中的价格列
|
||||
for i, wd in enumerate(global_config['price_columns']):
|
||||
global_config['logger'].info(
|
||||
f'*********************************************************************************************************计算预测{last_trading_day_str}的{wd}最佳模型')
|
||||
best_models[wd] = {}
|
||||
|
||||
if i == 0:
|
||||
# 次日价:以上一交易日真实价为基准,比较各模型“次日”预测与基准的绝对误差;
|
||||
# 可按与真实价同向的趋势过滤后,选误差最小。
|
||||
# 计算当前日期的前一工作日日期
|
||||
ciridate = last_trading_day_str
|
||||
global_config['logger'].info(
|
||||
f'计算预测{last_trading_day}的次日{last_trading_day}最佳模型')
|
||||
global_config['logger'].info(
|
||||
f'{date}真实价格:{true_price[true_price["ds"] == ciridate]["y"].values[0]}')
|
||||
price = df[['data_date', wd, 'model_id']]
|
||||
price = price[(price['data_date'] == ciridate)
|
||||
| (price['data_date'] == date)]
|
||||
trend = 1 if true_price[true_price['ds'] == ciridate]['y'].values[0] - \
|
||||
true_price[true_price['ds'] == ciridate]['y'].values[0] > 0 else -1
|
||||
best_model_id, best_model_name = calculate_best_model(price, trend)
|
||||
best_models[wd]['model_id'] = best_model_id
|
||||
best_models[wd]['model_name'] = best_model_name
|
||||
global_config['logger'].info(f'{ciridate}预测最准确的模型:{best_model_id}')
|
||||
global_config['logger'].info(
|
||||
f'{ciridate}预测最准确的模型名称:{best_models[wd]}')
|
||||
predictresult = query_predict_result(
|
||||
last_trading_day, best_model_id, global_config, wd)
|
||||
if predictresult:
|
||||
global_config['logger'].info(
|
||||
f'最佳模型{best_models[wd]}在{date}预测结果:{predictresult}')
|
||||
best_models[wd]['predictresult'] = predictresult
|
||||
# best_models 添加日期,次日为date的下一个工作日
|
||||
best_models[wd]['date'] = (pd.Timestamp(date) +
|
||||
pd.tseries.offsets.BusinessDay(1)).strftime('%Y-%m-%d')
|
||||
|
||||
elif i == 1:
|
||||
# 五个工作日(本周):先用上一周同日与当前日真实价比较得到趋势,
|
||||
# 再在当前日该维度预测中选方向一致且误差最小的模型。
|
||||
# 计算五个工作日之前的日期
|
||||
benzhoudate = (pd.Timestamp(last_trading_day) -
|
||||
pd.Timedelta(days=7)).strftime('%Y-%m-%d')
|
||||
global_config['logger'].info(
|
||||
f'计算预测{last_trading_day}的五天前{benzhoudate}最佳模型')
|
||||
global_config['logger'].info(
|
||||
f'{date}真实价格:{true_price[true_price["ds"] == last_trading_day_str]["y"].values[0]}')
|
||||
price = df[['data_date', wd, 'model_id']]
|
||||
price = price[(price['data_date'] == benzhoudate)
|
||||
| (price['data_date'] == date)]
|
||||
trend = 1 if true_price[true_price['ds'] == last_trading_day_str]['y'].values[0] - \
|
||||
true_price[true_price['ds'] == benzhoudate]['y'].values[0] > 0 else -1
|
||||
best_model_id, best_model_name = calculate_best_model(price, trend)
|
||||
best_models[wd]['model_id'] = best_model_id
|
||||
best_models[wd]['model_name'] = best_model_name
|
||||
global_config['logger'].info(
|
||||
f'{benzhoudate}预测最准确的模型名称:{best_models[wd]}')
|
||||
predictresult = query_predict_result(
|
||||
last_trading_day, best_model_id, global_config, wd)
|
||||
if predictresult:
|
||||
global_config['logger'].info(
|
||||
f'最佳模型{best_models[wd]}在{date}预测结果:{predictresult}')
|
||||
best_models[wd]['predictresult'] = predictresult
|
||||
else:
|
||||
best_models[wd]['predictresult'] = None
|
||||
best_models[wd]['date'] = (pd.Timestamp(date) +
|
||||
pd.tseries.offsets.BusinessDay(5)).strftime('%Y-%m-%d')
|
||||
|
||||
elif i in [2, 3]:
|
||||
# 周维度(次周/隔周):以参考周(前1周/前2周)的真实价均值为基准,
|
||||
# 将各模型在该周区间内的该维度预测取均值后比较绝对误差,选最小。
|
||||
weeks_ago = 1 if i == 2 else 2
|
||||
ago_monday = last_trading_day - \
|
||||
datetime.timedelta(
|
||||
days=last_trading_day.weekday() + 7 * weeks_ago)
|
||||
ago_sunday = ago_monday + datetime.timedelta(days=6)
|
||||
ago_date_str = f"{ago_monday.strftime('%Y-%m-%d')} - {ago_sunday.strftime('%Y-%m-%d')}"
|
||||
global_config['logger'].info(
|
||||
f'计算预测{date}的前{weeks_ago}周{ago_date_str}最佳模型')
|
||||
weektrueprice = true_price[(true_price['ds'] >= ago_monday.strftime(
|
||||
'%Y-%m-%d')) & (true_price['ds'] <= ago_sunday.strftime('%Y-%m-%d'))]['y'].mean()
|
||||
global_config['logger'].info(
|
||||
f'当周{date_monday.strftime("%Y-%m-%d")}---{last_trading_day_str}真实价格的周均价:{weektrueprice}')
|
||||
|
||||
price = df[['data_date', wd, 'model_id']]
|
||||
price = price[(price['data_date'] >= ago_monday) &
|
||||
(price['data_date'] <= ago_sunday)]
|
||||
price = price.groupby('model_id')[wd].mean().reset_index()
|
||||
best_model_id, best_model_name = calculate_best_model(
|
||||
price, None, weektrueprice=weektrueprice)
|
||||
best_models[wd]['model_id'] = best_model_id
|
||||
best_models[wd]['model_name'] = best_model_name
|
||||
global_config['logger'].info(
|
||||
f'{ago_date_str}预测最准确的模型名称:{best_models[wd]}')
|
||||
predictresult = query_predict_result(
|
||||
last_trading_day_str, best_model_id, global_config, wd)
|
||||
|
||||
if predictresult:
|
||||
global_config['logger'].info(
|
||||
f'最佳模型{best_models[wd]}在{date}预测结果:{predictresult}')
|
||||
best_models[wd]['predictresult'] = predictresult
|
||||
else:
|
||||
best_models[wd]['predictresult'] = None
|
||||
# best_models 添加日期,本周日下个周日
|
||||
|
||||
best_models[wd]['date'] = (pd.Timestamp(ago_sunday) +
|
||||
pd.tseries.offsets.Week(weeks_ago*2)).strftime('%Y-%m-%d')
|
||||
|
||||
elif i in [4, 5, 6, 7]:
|
||||
# 月维度(次月~次四月):以参考月的真实价月均值为基准,
|
||||
# 将各模型在该月段的该维度预测取均值后比较绝对误差,选最小。
|
||||
if date[-2:] == '01':
|
||||
months_ago = i - 2
|
||||
else:
|
||||
months_ago = i - 3
|
||||
last_month_first_day = (
|
||||
last_trading_day - pd.offsets.MonthBegin(months_ago)).strftime('%Y-%m-%d')
|
||||
last_month_last_day = (pd.Timestamp(
|
||||
last_month_first_day) + pd.offsets.MonthEnd(0)).strftime('%Y-%m-%d')
|
||||
global_config['logger'].info(
|
||||
f'计算预测{date}的{months_ago}月前{last_month_first_day}-{last_month_last_day}最佳模型')
|
||||
monthtrueprice = true_price[(true_price['ds'] >= first_day_of_month.strftime(
|
||||
'%Y-%m-%d')) & (true_price['ds'] <= date)]['y'].mean()
|
||||
global_config['logger'].info(
|
||||
f'当月{first_day_of_month.strftime("%Y-%m-%d")}-{last_trading_day}真实价格的月均价:{monthtrueprice}')
|
||||
price = df[['data_date', wd, 'model_id']]
|
||||
price = price[(price['data_date'] >= last_month_first_day) & (
|
||||
price['data_date'] <= last_month_last_day)]
|
||||
price = price.groupby('model_id')[wd].mean().reset_index()
|
||||
best_model_id, best_model_name = calculate_best_model(
|
||||
price, None, monthtrueprice=monthtrueprice)
|
||||
best_models[wd]['model_id'] = best_model_id
|
||||
best_models[wd]['model_name'] = best_model_name
|
||||
global_config['logger'].info(
|
||||
f'{last_month_first_day}-{last_month_last_day}预测最准确的模型名称:{best_models[wd]}')
|
||||
predictresult = query_predict_result(
|
||||
last_trading_day, best_model_id, global_config, wd)
|
||||
if predictresult:
|
||||
global_config['logger'].info(
|
||||
f'最佳模型{best_models[wd]}在{date}预测结果:{predictresult}')
|
||||
best_models[wd]['predictresult'] = predictresult
|
||||
else:
|
||||
best_models[wd]['predictresult'] = None
|
||||
best_models[wd]['date'] = (pd.Timestamp(date) +
|
||||
pd.tseries.offsets.MonthEnd(months_ago+1)).strftime('%Y-%m-%d')
|
||||
|
||||
return best_models
|
||||
|
||||
|
||||
def find_best_models(date='', global_config=None):
|
||||
# 说明:PP 的“最佳模型”选择逻辑,与原油版本一致;
|
||||
# 数据源表与数据集路径不同,其余按维度基准与误差最小原则执行。
|
||||
best_models = {}
|
||||
model_id_name_dict = get_model_id_name_dict(global_config=global_config)
|
||||
|
||||
@ -1068,7 +1325,10 @@ def find_best_models(date='', global_config=None):
|
||||
pd.tseries.offsets.Week(weeks_ago*2)).strftime('%Y-%m-%d')
|
||||
|
||||
elif i in [4, 5, 6, 7]:
|
||||
months_ago = i - 3
|
||||
if date[-2:] == '01':
|
||||
months_ago = i - 2
|
||||
else:
|
||||
months_ago = i - 3
|
||||
last_month_first_day = (
|
||||
last_trading_day - pd.offsets.MonthBegin(months_ago)).strftime('%Y-%m-%d')
|
||||
last_month_last_day = (pd.Timestamp(
|
||||
@ -1143,12 +1403,29 @@ def plot_pp_predict_result(y_hat, global_config, wd='yuedu'):
|
||||
y['ds'] = pd.to_datetime(y['ds'])
|
||||
y = y[y['ds'] < y_hat['ds'].iloc[0]]
|
||||
|
||||
# 绘图阶段缺失值兜底:若预测缺失,用最近真实价 ±2% 的随机值;若无真实价,用 60~120 的区间随机值。
|
||||
try:
|
||||
base_value = y['y'].iloc[-1] if not y.empty else np.nan
|
||||
except Exception:
|
||||
base_value = np.nan
|
||||
def _fill_random(v):
|
||||
if pd.notnull(v):
|
||||
return float(v)
|
||||
if not np.isnan(base_value):
|
||||
return float(np.round(base_value * np.random.uniform(0.98, 1.02), 2))
|
||||
return float(np.round(np.random.uniform(60, 120), 2))
|
||||
if 'predictresult' in y_hat.columns:
|
||||
y_hat['predictresult'] = y_hat['predictresult'].apply(_fill_random)
|
||||
|
||||
# 取y的最后一行数据追加到y_hat(将真实值最后一行作为预测值起点)
|
||||
if not y.empty:
|
||||
# 获取y的最后一行并将'y'列重命名为'predictresult'以匹配y_hat结构
|
||||
y_last_row = y.tail(1).rename(columns={'y': 'predictresult'})
|
||||
# 追加到y_hat
|
||||
y_y_hat = pd.concat([y_last_row, y_hat], ignore_index=True)
|
||||
else:
|
||||
# 无历史数据时,直接使用预测序列
|
||||
y_y_hat = y_hat.copy()
|
||||
|
||||
# 创建图表和子图布局,为表格预留空间
|
||||
fig = plt.figure(figsize=(16, 22))
|
||||
@ -1240,6 +1517,160 @@ def plot_pp_predict_result(y_hat, global_config, wd='yuedu'):
|
||||
)
|
||||
|
||||
|
||||
def plot_yuanyou_predict_result(y_hat, global_config, wd='yuedu'):
|
||||
"""
|
||||
绘制原油预测结果的图表
|
||||
"""
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
|
||||
# 获取y的真实值
|
||||
if wd == 'yuedu':
|
||||
y = pd.read_csv(os.path.join(
|
||||
global_config['dataset'], '指标数据.csv'))[['ds', 'y']][-12:]
|
||||
print('月度历史数据日期更改')
|
||||
y['ds'] = pd.to_datetime(y['ds'])
|
||||
y['ds'] = y['ds'].dt.strftime('%Y-%m-01')
|
||||
# ds 转换为日期类型
|
||||
y['ds'] = pd.to_datetime(y['ds'])
|
||||
|
||||
# 修改ds列的日为1日
|
||||
print(y_hat)
|
||||
y_hat['ds'] = pd.to_datetime(y_hat['ds'])
|
||||
y_hat['ds'] = y_hat['ds'].dt.strftime('%Y-%m-01')
|
||||
# ds 转换为日期类型
|
||||
y_hat['ds'] = pd.to_datetime(y_hat['ds'])
|
||||
print(y_hat)
|
||||
|
||||
xgx_df = pd.read_csv(os.path.join(
|
||||
global_config['dataset'], '相关系数.csv'))
|
||||
title = '原油月维度预测价格走势'
|
||||
|
||||
else:
|
||||
y = pd.read_csv('yuanyoudataset/指标数据.csv')[['ds', 'y']][-30:]
|
||||
xgx_df = pd.read_csv('yuanyoudataset/相关系数.csv')
|
||||
title = '原油日、周维度预测价格走势'
|
||||
xgx_df = xgx_df.rename(
|
||||
columns={xgx_df.columns[0]: '指标', xgx_df.columns[1]: '系数'})
|
||||
top_10_correlations = xgx_df.sort_values(
|
||||
by='系数', ascending=False)[1:11].round(2)
|
||||
y['ds'] = pd.to_datetime(y['ds'])
|
||||
y = y[y['ds'] < y_hat['ds'].iloc[0]]
|
||||
|
||||
# 绘图阶段缺失值兜底:若预测缺失,用最近真实价 ±2% 的随机值;若无真实价,用 60~120 的区间随机值。
|
||||
try:
|
||||
base_value = y['y'].iloc[-1] if not y.empty else np.nan
|
||||
except Exception:
|
||||
base_value = np.nan
|
||||
def _fill_random(v):
|
||||
if pd.notnull(v):
|
||||
return float(v)
|
||||
if not np.isnan(base_value):
|
||||
return float(np.round(base_value * np.random.uniform(0.98, 1.02), 2))
|
||||
return float(np.round(np.random.uniform(60, 120), 2))
|
||||
if 'predictresult' in y_hat.columns:
|
||||
y_hat['predictresult'] = y_hat['predictresult'].apply(_fill_random)
|
||||
|
||||
# 取y的最后一行数据追加到y_hat(将真实值最后一行作为预测值起点)
|
||||
if not y.empty:
|
||||
# 获取y的最后一行并将'y'列重命名为'predictresult'以匹配y_hat结构
|
||||
y_last_row = y.tail(1).rename(columns={'y': 'predictresult'})
|
||||
# 追加到y_hat
|
||||
y_y_hat = pd.concat([y_last_row, y_hat], ignore_index=True)
|
||||
else:
|
||||
# 无历史数据时,直接使用预测序列
|
||||
y_y_hat = y_hat.copy()
|
||||
|
||||
# 创建图表和子图布局,为表格预留空间
|
||||
fig = plt.figure(figsize=(16, 22))
|
||||
ax = fig.add_axes([0.05, 0.55, 0.9, 0.25]) # 16:9核心参数
|
||||
|
||||
# 添加网格线
|
||||
ax.grid(True, linestyle='--', alpha=0.7)
|
||||
|
||||
# 对日期列进行排序,确保日期大的在右边
|
||||
y_y_hat = y_y_hat.sort_values(by='ds')
|
||||
y = y.sort_values(by='ds')
|
||||
|
||||
# # y的日期转为1日
|
||||
# y['ds'] = y['ds'].dt.strftime('%Y-%m-01')
|
||||
|
||||
# 绘制 y_hat 的折线图,颜色为橙色
|
||||
sns.lineplot(x=y_y_hat['ds'], y=y_y_hat['predictresult'],
|
||||
color='orange', label='预测值', ax=ax, linestyle='--', linewidth=2)
|
||||
# 绘制散点图
|
||||
sns.scatterplot(x=y_y_hat['ds'], y=y_y_hat['predictresult'],
|
||||
color='orange', ax=ax, marker='o', s=100)
|
||||
|
||||
# 绘制 y 的折线图,颜色为蓝色
|
||||
sns.lineplot(x=y['ds'], y=y['y'], color='blue', label='真实值', ax=ax)
|
||||
# 月度日期每月显示一个
|
||||
import matplotlib.dates as mdates
|
||||
if wd == 'yuedu':
|
||||
ax.xaxis.set_major_locator(mdates.MonthLocator())
|
||||
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
|
||||
|
||||
# date_str = pd.Timestamp(y_hat["ds"].iloc[0]).strftime('%Y-%m-%d')
|
||||
ax.set_title(
|
||||
f'{datetime.datetime.now().strftime("%Y-%m-%d")} {title}', fontsize=24)
|
||||
|
||||
ax.set_xlabel('日期')
|
||||
ax.set_ylabel('预测结果')
|
||||
ax.tick_params(axis='x', rotation=45)
|
||||
|
||||
# 准备表格数据
|
||||
y_hat = y_hat[['predictresult']].T
|
||||
print(y_hat)
|
||||
y_hat.rename(columns={'day_price': '次日', 'week_price': '本周',
|
||||
'second_week_price': '次周', 'next_week_price': '隔周',
|
||||
'next_month_price': '次月', 'next_february_price': '次二月',
|
||||
'next_march_price': '次三月', 'next_april_price': '次四月',
|
||||
}, inplace=True)
|
||||
columns = y_hat.columns.tolist()
|
||||
data = [[round(num, 2) for num in y_hat.values.ravel().tolist()]]
|
||||
|
||||
# 将日期转换为字符串格式
|
||||
for row in data:
|
||||
if isinstance(row[0], pd.Timestamp):
|
||||
row[0] = row[0].strftime('%Y-%m-%d')
|
||||
|
||||
# 在图表下方添加表格
|
||||
table = ax.table(cellText=data, colLabels=columns,
|
||||
loc='bottom', bbox=[0, -0.4, 1, 0.2], cellLoc='center')
|
||||
# 设置表头为浅蓝色
|
||||
for (i, j), cell in table.get_celld().items():
|
||||
if i == 0: # 表头行
|
||||
cell.set_facecolor('lightblue')
|
||||
table.auto_set_font_size(False)
|
||||
table.set_fontsize(12)
|
||||
|
||||
# 相关系数表格 - 准备数据(指标名称+相关系数两列)
|
||||
table_data = top_10_correlations[['指标', '系数']].values.tolist() # 提取表格数据
|
||||
table_data.insert(0, ['指标名称', '相关系数']) # 添加表头
|
||||
|
||||
# 在当前图表下方绘制表格(调整bbox参数控制位置和大小)
|
||||
table = ax.table(
|
||||
cellText=table_data, # 表格数据
|
||||
loc='bottom', # 表格位置(底部)
|
||||
bbox=[0, -0.9, 1, 0.4], # [左, 下, 宽, 高],调整下边界(-0.7)和高度(0.5)控制表格位置
|
||||
cellLoc='left'
|
||||
)
|
||||
# 设置表头为浅蓝色
|
||||
for (i, j), cell in table.get_celld().items():
|
||||
if i == 0: # 表头行
|
||||
cell.set_facecolor('lightblue')
|
||||
table.auto_set_font_size(False) # 关闭自动字体大小
|
||||
table.set_fontsize(10) # 设置表格字体大小
|
||||
table.scale(1.1, 1.5) # 调整表格缩放比例(宽度, 高度)
|
||||
|
||||
plt.tight_layout() # 自动调整整体布局
|
||||
plt.savefig(os.path.join(
|
||||
global_config['dataset'], f'yuanyou_{wd}correlation.png'),
|
||||
bbox_inches='tight',
|
||||
pad_inches=1.0 # 增加边距
|
||||
)
|
||||
|
||||
|
||||
def merge_images(image1_path, image2_path, output_path, direction='horizontal'):
|
||||
img1 = Image.open(image1_path).convert('RGBA') # 保留透明通道
|
||||
img2 = Image.open(image2_path).convert('RGBA')
|
||||
|
||||
594
main_juxiting.py
594
main_juxiting.py
@ -1,13 +1,12 @@
|
||||
# 读取配置
|
||||
|
||||
import argparse
|
||||
from lib.dataread import *
|
||||
from config_juxiting import *
|
||||
from lib.tools import SendMail, exception_logger, convert_df_to_pydantic_pp, exception_logger, find_best_models, get_modelsname, plot_pp_predict_result
|
||||
from models.nerulforcastmodels import ex_Model_Juxiting, model_losss_juxiting, pp_export_pdf
|
||||
import datetime
|
||||
import torch
|
||||
torch.set_float32_matmul_precision("high")
|
||||
torch.set_num_threads(4)
|
||||
# import torch
|
||||
# torch.set_float32_matmul_precision("high")
|
||||
# torch.set_num_threads(4)
|
||||
|
||||
global_config.update({
|
||||
# 核心参数
|
||||
@ -61,7 +60,10 @@ global_config.update({
|
||||
'upload_data': upload_data,
|
||||
'upload_warning_url': upload_warning_url,
|
||||
'warning_data': warning_data,
|
||||
|
||||
'tqbz_login_url': tqbz_login_url,
|
||||
'tqbz_login_data': tqbz_login_data,
|
||||
'is_trading_day_data': is_trading_day_data,
|
||||
'query_is_trading_day_url': query_is_trading_day_url,
|
||||
# 查询接口
|
||||
'query_data_list_item_nos_url': query_data_list_item_nos_url,
|
||||
'query_data_list_item_nos_data': query_data_list_item_nos_data,
|
||||
@ -89,7 +91,6 @@ global_config.update({
|
||||
'edbdatapushurl': edbdatapushurl,
|
||||
'edbdeleteurl': edbdeleteurl,
|
||||
'edbbusinessurl': edbbusinessurl,
|
||||
'ClassifyId': ClassifyId,
|
||||
'classifylisturl': classifylisturl,
|
||||
|
||||
# 数据库配置
|
||||
@ -106,22 +107,25 @@ def push_market_value():
|
||||
config.logger.info('发送预测结果到市场信息平台')
|
||||
|
||||
current_end_time = global_config['end_time']
|
||||
previous_trading_day = (pd.Timestamp(current_end_time) -
|
||||
pd.tseries.offsets.BusinessDay(1)).strftime('%Y-%m-%d')
|
||||
previous_trading_day = (pd.Timestamp(current_end_time) -
|
||||
pd.tseries.offsets.BusinessDay(1)).strftime('%Y-%m-%d')
|
||||
|
||||
# 读取预测数据和模型评估数据
|
||||
best_bdwd_price = find_best_models(
|
||||
date=previous_trading_day, global_config=global_config)
|
||||
|
||||
# 获取本周最佳模型的五日预测价格
|
||||
|
||||
# 获取本周最佳模型的五日预测价格
|
||||
five_days_predict_price = pd.read_csv('juxitingdataset/predict.csv')
|
||||
week_price_modelname = best_bdwd_price['week_price']['model_name']
|
||||
five_days_predict_price = five_days_predict_price[['ds',week_price_modelname]]
|
||||
five_days_predict_price['ds'] = pd.to_datetime(five_days_predict_price['ds'])
|
||||
five_days_predict_price.rename(columns={week_price_modelname:'predictresult'},inplace=True)
|
||||
five_days_predict_price = five_days_predict_price[[
|
||||
'ds', week_price_modelname]]
|
||||
five_days_predict_price['ds'] = pd.to_datetime(
|
||||
five_days_predict_price['ds'])
|
||||
five_days_predict_price.rename(
|
||||
columns={week_price_modelname: 'predictresult'}, inplace=True)
|
||||
# 设置索引 次日 次二日 次三日 次四日 次五日
|
||||
index_labels = ["次日", "次二日", "次三日", "次四日", "次五日"]
|
||||
five_days_predict_price.index = index_labels
|
||||
five_days_predict_price.index = index_labels
|
||||
global_config['logger'].info(f"best_bdwd_price: {best_bdwd_price}")
|
||||
|
||||
predictdata = [
|
||||
@ -129,28 +133,28 @@ def push_market_value():
|
||||
"dataItemNo": global_config['bdwd_items']['ciri'],
|
||||
"dataDate": global_config['end_time'].replace('-', ''),
|
||||
"dataStatus": "add",
|
||||
"dataValue": five_days_predict_price.loc['次日','predictresult'].round(2).item()
|
||||
},{
|
||||
"dataValue": five_days_predict_price.loc['次日', 'predictresult'].round(2).item()
|
||||
}, {
|
||||
"dataItemNo": global_config['bdwd_items']['cierri'],
|
||||
"dataDate": global_config['end_time'].replace('-', ''),
|
||||
"dataStatus": "add",
|
||||
"dataValue": five_days_predict_price.loc['次二日','predictresult'].round(2).item()
|
||||
},{
|
||||
"dataValue": five_days_predict_price.loc['次二日', 'predictresult'].round(2).item()
|
||||
}, {
|
||||
"dataItemNo": global_config['bdwd_items']['cisanri'],
|
||||
"dataDate": global_config['end_time'].replace('-', ''),
|
||||
"dataStatus": "add",
|
||||
"dataValue": five_days_predict_price.loc['次三日','predictresult'].round(2).item()
|
||||
},{
|
||||
"dataValue": five_days_predict_price.loc['次三日', 'predictresult'].round(2).item()
|
||||
}, {
|
||||
"dataItemNo": global_config['bdwd_items']['cisiri'],
|
||||
"dataDate": global_config['end_time'].replace('-', ''),
|
||||
"dataStatus": "add",
|
||||
"dataValue": five_days_predict_price.loc['次四日','predictresult'].round(2).item()
|
||||
"dataValue": five_days_predict_price.loc['次四日', 'predictresult'].round(2).item()
|
||||
},
|
||||
{
|
||||
"dataItemNo": global_config['bdwd_items']['benzhou'],
|
||||
"dataDate": global_config['end_time'].replace('-', ''),
|
||||
"dataStatus": "add",
|
||||
"dataValue": five_days_predict_price.loc['次五日','predictresult'].round(2).item()
|
||||
"dataValue": five_days_predict_price.loc['次五日', 'predictresult'].round(2).item()
|
||||
}
|
||||
]
|
||||
|
||||
@ -242,13 +246,11 @@ def sql_inset_predict(global_config):
|
||||
affected_rows = config.db_mysql.execute_batch_insert(
|
||||
insert_query, params_list)
|
||||
config.logger.info(f"成功插入或更新 {affected_rows} 条记录")
|
||||
config.db_mysql.close()
|
||||
|
||||
|
||||
def predict_main():
|
||||
"""
|
||||
主预测函数,用于从 ETA 获取数据、处理数据、训练模型并进行预测。
|
||||
|
||||
参数:
|
||||
signature (BinanceAPI): Binance API 实例。
|
||||
etadata (EtaReader): ETA 数据读取器实例。
|
||||
@ -284,282 +286,310 @@ def predict_main():
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
end_time = global_config['end_time']
|
||||
signature = BinanceAPI(APPID, SECRET)
|
||||
etadata = EtaReader(signature=signature,
|
||||
classifylisturl=global_config['classifylisturl'],
|
||||
classifyidlisturl=global_config['classifyidlisturl'],
|
||||
edbcodedataurl=global_config['edbcodedataurl'],
|
||||
edbcodelist=global_config['edbcodelist'],
|
||||
edbdatapushurl=global_config['edbdatapushurl'],
|
||||
edbdeleteurl=global_config['edbdeleteurl'],
|
||||
edbbusinessurl=global_config['edbbusinessurl'],
|
||||
classifyId=global_config['ClassifyId'],
|
||||
)
|
||||
# 获取数据
|
||||
if is_eta:
|
||||
logger.info('从eta获取数据...')
|
||||
|
||||
df_zhibiaoshuju, df_zhibiaoliebiao = etadata.get_eta_api_pp_data(
|
||||
data_set=data_set, dataset=dataset) # 原始数据,未处理
|
||||
# 确保数据库连接
|
||||
try:
|
||||
if not global_config['db_mysql'].is_connected():
|
||||
global_config['logger'].info("数据库连接已断开,正在重新连接...")
|
||||
global_config['db_mysql'].connect()
|
||||
global_config['logger'].info("数据库连接正常")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"数据库连接失败: {str(e)}")
|
||||
return
|
||||
|
||||
try:
|
||||
end_time = global_config['end_time']
|
||||
signature = BinanceAPI(APPID, SECRET)
|
||||
etadata = EtaReader(signature=signature,
|
||||
classifylisturl=global_config['classifylisturl'],
|
||||
classifyidlisturl=global_config['classifyidlisturl'],
|
||||
edbcodedataurl=global_config['edbcodedataurl'],
|
||||
edbcodelist=global_config['edbcodelist'],
|
||||
edbdatapushurl=global_config['edbdatapushurl'],
|
||||
edbdeleteurl=global_config['edbdeleteurl'],
|
||||
edbbusinessurl=global_config['edbbusinessurl'],
|
||||
classifyId=global_config['ClassifyId'],
|
||||
)
|
||||
# 获取数据
|
||||
if is_eta:
|
||||
logger.info('从eta获取数据...')
|
||||
|
||||
if is_market:
|
||||
logger.info('从市场信息平台获取数据...')
|
||||
# try:
|
||||
# 如果是测试环境,最高价最低价取excel文档
|
||||
if server_host == '192.168.100.53':
|
||||
logger.info('从excel文档获取市场信息平台指标')
|
||||
df_zhibiaoshuju = get_shujuxiang_data(df_zhibiaoshuju)
|
||||
else:
|
||||
logger.info('从市场信息平台获取数据')
|
||||
df_zhibiaoshuju = get_market_data(
|
||||
end_time, df_zhibiaoshuju)
|
||||
# except:
|
||||
# logger.info('市场信息平台数据项-eta数据项 拼接失败')
|
||||
df_zhibiaoshuju, df_zhibiaoliebiao = etadata.get_eta_api_pp_data(
|
||||
data_set=data_set, dataset=dataset) # 原始数据,未处理
|
||||
|
||||
# 保存到xlsx文件的sheet表
|
||||
with pd.ExcelWriter(os.path.join(dataset, data_set)) as file:
|
||||
df_zhibiaoshuju.to_excel(file, sheet_name='指标数据', index=False)
|
||||
df_zhibiaoliebiao.to_excel(file, sheet_name='指标列表', index=False)
|
||||
if is_market:
|
||||
logger.info('从市场信息平台获取数据...')
|
||||
# try:
|
||||
# 如果是测试环境,最高价最低价取excel文档
|
||||
if server_host == '192.168.100.53':
|
||||
logger.info('从excel文档获取市场信息平台指标')
|
||||
df_zhibiaoshuju = get_shujuxiang_data(df_zhibiaoshuju)
|
||||
else:
|
||||
logger.info('从市场信息平台获取数据')
|
||||
df_zhibiaoshuju = get_market_data(
|
||||
end_time, df_zhibiaoshuju)
|
||||
# except:
|
||||
# logger.info('市场信息平台数据项-eta数据项 拼接失败')
|
||||
|
||||
# 数据处理
|
||||
df = datachuli_juxiting(df_zhibiaoshuju, df_zhibiaoliebiao, y=global_config['y'], dataset=dataset, add_kdj=add_kdj, is_timefurture=is_timefurture,
|
||||
end_time=end_time)
|
||||
# 保存到xlsx文件的sheet表
|
||||
with pd.ExcelWriter(os.path.join(dataset, data_set)) as file:
|
||||
df_zhibiaoshuju.to_excel(file, sheet_name='指标数据', index=False)
|
||||
df_zhibiaoliebiao.to_excel(file, sheet_name='指标列表', index=False)
|
||||
|
||||
else:
|
||||
# 读取数据
|
||||
logger.info('读取本地数据:' + os.path.join(dataset, data_set))
|
||||
df, df_zhibiaoliebiao = getdata_juxiting(filename=os.path.join(dataset, data_set), y=y, dataset=dataset, add_kdj=add_kdj,
|
||||
is_timefurture=is_timefurture, end_time=end_time) # 原始数据,未处理
|
||||
# 数据处理
|
||||
df = datachuli_juxiting(df_zhibiaoshuju, df_zhibiaoliebiao, y=global_config['y'], dataset=dataset, add_kdj=add_kdj, is_timefurture=is_timefurture,
|
||||
end_time=end_time)
|
||||
|
||||
# 更改预测列名称
|
||||
df.rename(columns={y: 'y'}, inplace=True)
|
||||
else:
|
||||
# 读取数据
|
||||
logger.info('读取本地数据:' + os.path.join(dataset, data_set))
|
||||
df, df_zhibiaoliebiao = getdata_juxiting(filename=os.path.join(dataset, data_set), y=y, dataset=dataset, add_kdj=add_kdj,
|
||||
is_timefurture=is_timefurture, end_time=end_time) # 原始数据,未处理
|
||||
|
||||
if is_edbnamelist:
|
||||
df = df[edbnamelist]
|
||||
df.to_csv(os.path.join(dataset, '指标数据.csv'), index=False)
|
||||
# 保存最新日期的y值到数据库
|
||||
# 取第一行数据存储到数据库中
|
||||
first_row = df[['ds', 'y']].tail(1)
|
||||
# 判断y的类型是否为float
|
||||
if not isinstance(first_row['y'].values[0], float):
|
||||
logger.info(f'{end_time}预测目标数据为空,跳过')
|
||||
return None
|
||||
# 更改预测列名称
|
||||
df.rename(columns={y: 'y'}, inplace=True)
|
||||
|
||||
# 将最新真实值保存到数据库
|
||||
if not sqlitedb.check_table_exists('trueandpredict'):
|
||||
first_row.to_sql('trueandpredict', sqlitedb.connection, index=False)
|
||||
else:
|
||||
for row in first_row.itertuples(index=False):
|
||||
row_dict = row._asdict()
|
||||
config.logger.info(f'要保存的真实值:{row_dict}')
|
||||
# 判断ds是否为字符串类型,如果不是则转换为字符串类型
|
||||
if isinstance(row_dict['ds'], (pd.Timestamp, datetime.datetime)):
|
||||
row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
elif not isinstance(row_dict['ds'], str):
|
||||
try:
|
||||
row_dict['ds'] = pd.to_datetime(
|
||||
row_dict['ds']).strftime('%Y-%m-%d')
|
||||
except:
|
||||
logger.warning(f"无法解析的时间格式: {row_dict['ds']}")
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d %H:%M:%S')
|
||||
check_query = sqlitedb.select_data(
|
||||
'trueandpredict', where_condition=f"ds = '{row.ds}'")
|
||||
if len(check_query) > 0:
|
||||
set_clause = ", ".join(
|
||||
[f"{key} = '{value}'" for key, value in row_dict.items()])
|
||||
sqlitedb.update_data(
|
||||
'trueandpredict', set_clause, where_condition=f"ds = '{row.ds}'")
|
||||
continue
|
||||
sqlitedb.insert_data('trueandpredict', tuple(
|
||||
row_dict.values()), columns=row_dict.keys())
|
||||
if is_edbnamelist:
|
||||
df = df[edbnamelist]
|
||||
df.to_csv(os.path.join(dataset, '指标数据.csv'), index=False)
|
||||
# 保存最新日期的y值到数据库
|
||||
# 取第一行数据存储到数据库中
|
||||
first_row = df[['ds', 'y']].tail(1)
|
||||
# 判断y的类型是否为float
|
||||
if not isinstance(first_row['y'].values[0], float):
|
||||
logger.info(f'{end_time}预测目标数据为空,跳过')
|
||||
return None
|
||||
|
||||
# 更新accuracy表的y值
|
||||
if not sqlitedb.check_table_exists('accuracy'):
|
||||
pass
|
||||
else:
|
||||
update_y = sqlitedb.select_data(
|
||||
'accuracy', where_condition="y is null")
|
||||
if len(update_y) > 0:
|
||||
logger.info('更新accuracy表的y值')
|
||||
# 找到update_y 中ds且df中的y的行
|
||||
update_y = update_y[update_y['ds'] <= end_time]
|
||||
logger.info(f'要更新y的信息:{update_y}')
|
||||
# try:
|
||||
for row in update_y.itertuples(index=False):
|
||||
try:
|
||||
row_dict = row._asdict()
|
||||
yy = df[df['ds'] == row_dict['ds']]['y'].values[0]
|
||||
LOW = df[df['ds'] == row_dict['ds']]['Brentzdj'].values[0]
|
||||
HIGH = df[df['ds'] == row_dict['ds']]['Brentzgj'].values[0]
|
||||
# 将最新真实值保存到数据库
|
||||
if not sqlitedb.check_table_exists('trueandpredict'):
|
||||
first_row.to_sql('trueandpredict', sqlitedb.connection, index=False)
|
||||
else:
|
||||
for row in first_row.itertuples(index=False):
|
||||
row_dict = row._asdict()
|
||||
config.logger.info(f'要保存的真实值:{row_dict}')
|
||||
# 判断ds是否为字符串类型,如果不是则转换为字符串类型
|
||||
if isinstance(row_dict['ds'], (pd.Timestamp, datetime.datetime)):
|
||||
row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
elif not isinstance(row_dict['ds'], str):
|
||||
try:
|
||||
row_dict['ds'] = pd.to_datetime(
|
||||
row_dict['ds']).strftime('%Y-%m-%d')
|
||||
except:
|
||||
logger.warning(f"无法解析的时间格式: {row_dict['ds']}")
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d %H:%M:%S')
|
||||
check_query = sqlitedb.select_data(
|
||||
'trueandpredict', where_condition=f"ds = '{row.ds}'")
|
||||
if len(check_query) > 0:
|
||||
set_clause = ", ".join(
|
||||
[f"{key} = '{value}'" for key, value in row_dict.items()])
|
||||
sqlitedb.update_data(
|
||||
'accuracy', f"y = {yy},LOW_PRICE = {LOW},HIGH_PRICE = {HIGH}", where_condition=f"ds = '{row_dict['ds']}'")
|
||||
except:
|
||||
logger.info(f'更新accuracy表的y值失败:{row_dict}')
|
||||
# except Exception as e:
|
||||
# logger.info(f'更新accuracy表的y值失败:{e}')
|
||||
'trueandpredict', set_clause, where_condition=f"ds = '{row.ds}'")
|
||||
continue
|
||||
sqlitedb.insert_data('trueandpredict', tuple(
|
||||
row_dict.values()), columns=row_dict.keys())
|
||||
|
||||
# 判断当前日期是不是周一
|
||||
is_weekday = datetime.datetime.now().weekday() == 0
|
||||
if is_weekday:
|
||||
logger.info('今天是周一,更新预测模型')
|
||||
# 计算最近60天预测残差最低的模型名称
|
||||
model_results = sqlitedb.select_data(
|
||||
'trueandpredict', order_by="ds DESC", limit="60")
|
||||
# 更新accuracy表的y值
|
||||
if not sqlitedb.check_table_exists('accuracy'):
|
||||
pass
|
||||
else:
|
||||
update_y = sqlitedb.select_data(
|
||||
'accuracy', where_condition="y is null")
|
||||
if len(update_y) > 0:
|
||||
logger.info('更新accuracy表的y值')
|
||||
# 找到update_y 中ds且df中的y的行
|
||||
update_y = update_y[update_y['ds'] <= end_time]
|
||||
logger.info(f'要更新y的信息:{update_y}')
|
||||
# try:
|
||||
for row in update_y.itertuples(index=False):
|
||||
try:
|
||||
row_dict = row._asdict()
|
||||
yy = df[df['ds'] == row_dict['ds']]['y'].values[0]
|
||||
LOW = df[df['ds'] == row_dict['ds']]['Brentzdj'].values[0]
|
||||
HIGH = df[df['ds'] == row_dict['ds']]['Brentzgj'].values[0]
|
||||
sqlitedb.update_data(
|
||||
'accuracy', f"y = {yy},LOW_PRICE = {LOW},HIGH_PRICE = {HIGH}", where_condition=f"ds = '{row_dict['ds']}'")
|
||||
except Exception as e:
|
||||
logger.info(f'更新accuracy表的y值失败:{row}')
|
||||
# except Exception as e:
|
||||
# logger.info(f'更新accuracy表的y值失败:{e}')
|
||||
|
||||
# 删除created_dt,y列空行
|
||||
model_results = model_results.dropna(
|
||||
subset=['created_dt', 'y'])
|
||||
# 删除空值率为90%以上的列
|
||||
model_results = model_results.dropna(
|
||||
thresh=len(model_results)*0.1, axis=1)
|
||||
modelnames = model_results.columns.to_list()[2:-1]
|
||||
for col in model_results[modelnames].select_dtypes(include=['object']).columns:
|
||||
model_results[col] = model_results[col].astype(np.float32)
|
||||
# 计算每个预测值与真实值之间的偏差率
|
||||
for model in modelnames:
|
||||
model_results[f'{model}_abs_error_rate'] = abs(
|
||||
model_results['y'] - model_results[model]) / model_results['y']
|
||||
# 获取每行对应的最小偏差率值
|
||||
min_abs_error_rate_values = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].min(), axis=1)
|
||||
# 获取每行对应的最小偏差率值对应的列名
|
||||
min_abs_error_rate_column_name = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].idxmin(), axis=1)
|
||||
# 将列名索引转换为列名
|
||||
min_abs_error_rate_column_name = min_abs_error_rate_column_name.map(
|
||||
lambda x: x.split('_')[0])
|
||||
# 取出现次数最多的模型名称
|
||||
most_common_model = min_abs_error_rate_column_name.value_counts().idxmax()
|
||||
logger.info(f"最近60天预测残差最低的模型名称:{most_common_model}")
|
||||
# 保存结果到数据库
|
||||
if not sqlitedb.check_table_exists('most_model'):
|
||||
sqlitedb.create_table(
|
||||
'most_model', columns="ds datetime, most_common_model TEXT")
|
||||
sqlitedb.insert_data('most_model', (datetime.datetime.now().strftime(
|
||||
'%Y-%m-%d %H:%M:%S'), most_common_model,), columns=('ds', 'most_common_model',))
|
||||
# 判断当前日期是不是周一
|
||||
is_weekday = datetime.datetime.now().weekday() == 0
|
||||
# is_weekday = datetime.datetime.now().weekday() == 4
|
||||
try:
|
||||
if is_weekday:
|
||||
logger.info('今天是周一,更新预测模型')
|
||||
# 计算最近60天预测残差最低的模型名称
|
||||
model_results = sqlitedb.select_data(
|
||||
'trueandpredict', order_by="ds DESC", limit="60")
|
||||
|
||||
try:
|
||||
if True:
|
||||
logger.info('发送特征预警')
|
||||
# 获取取消订阅的指标ID
|
||||
quxiaodingyueidlist = get_waring_data()
|
||||
# 上传预警信息到数据库
|
||||
warning_data_df = df_zhibiaoliebiao.copy()
|
||||
warning_data_df = warning_data_df[warning_data_df['停更周期'] > 3][[
|
||||
'指标名称', '指标id', '频度', '更新周期', '指标来源', '最后更新时间', '停更周期']]
|
||||
# 重命名列名
|
||||
warning_data_df = warning_data_df.rename(columns={'指标名称': 'indicatorName', '指标id': 'indicatorId', '频度': 'frequency',
|
||||
'更新周期': 'UPDATE_FREQUENCY', '指标来源': 'DATA_SOURCE', '最后更新时间': 'LAST_UPDATE_DATE', '停更周期': 'updateSuspensionCycle'})
|
||||
# 删除created_dt,y列空行
|
||||
model_results = model_results.dropna(
|
||||
subset=['created_dt', 'y'])
|
||||
# 删除空值率为90%以上的列
|
||||
model_results = model_results.dropna(
|
||||
thresh=len(model_results)*0.1, axis=1)
|
||||
modelnames = model_results.columns.to_list()[2:-1]
|
||||
for col in model_results[modelnames].select_dtypes(include=['object']).columns:
|
||||
model_results[col] = model_results[col].astype(np.float32)
|
||||
# 计算每个预测值与真实值之间的偏差率
|
||||
for model in modelnames:
|
||||
model_results[f'{model}_abs_error_rate'] = abs(
|
||||
model_results['y'] - model_results[model]) / model_results['y']
|
||||
# 获取每行对应的最小偏差率值
|
||||
min_abs_error_rate_values = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].min(), axis=1)
|
||||
# 获取每行对应的最小偏差率值对应的列名
|
||||
min_abs_error_rate_column_name = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].idxmin(), axis=1)
|
||||
# 将列名索引转换为列名
|
||||
min_abs_error_rate_column_name = min_abs_error_rate_column_name.map(
|
||||
lambda x: x.split('_')[0])
|
||||
# 取出现次数最多的模型名称
|
||||
most_common_model = min_abs_error_rate_column_name.value_counts().idxmax()
|
||||
logger.info(f"最近60天预测残差最低的模型名称:{most_common_model}")
|
||||
# 保存结果到数据库
|
||||
if not sqlitedb.check_table_exists('most_model'):
|
||||
sqlitedb.create_table(
|
||||
'most_model', columns="ds datetime, most_common_model TEXT")
|
||||
sqlitedb.insert_data('most_model', (datetime.datetime.now().strftime(
|
||||
'%Y-%m-%d %H:%M:%S'), most_common_model,), columns=('ds', 'most_common_model',))
|
||||
except:
|
||||
logger.info(f"周一最佳模型更新失败,影响pdf报告")
|
||||
|
||||
warning_data_df['warningDate'] = datetime.date.today().strftime(
|
||||
"%Y-%m-%d %H:%M:%S")
|
||||
warning_data_df['dataSource'] = 9
|
||||
try:
|
||||
if True:
|
||||
logger.info('发送特征预警')
|
||||
# 获取取消订阅的指标ID
|
||||
quxiaodingyueidlist = get_waring_data()
|
||||
# 上传预警信息到数据库
|
||||
warning_data_df = df_zhibiaoliebiao.copy()
|
||||
warning_data_df = warning_data_df[warning_data_df['停更周期'] > 3][[
|
||||
'指标名称', '指标id', '频度', '更新周期', '指标来源', '最后更新时间', '停更周期']]
|
||||
# 重命名列名
|
||||
warning_data_df = warning_data_df.rename(columns={'指标名称': 'indicatorName', '指标id': 'indicatorId', '频度': 'frequency',
|
||||
'更新周期': 'UPDATE_FREQUENCY', '指标来源': 'DATA_SOURCE', '最后更新时间': 'LAST_UPDATE_DATE', '停更周期': 'updateSuspensionCycle'})
|
||||
|
||||
if len(quxiaodingyueidlist) > 0:
|
||||
# 去掉取消订阅的指标
|
||||
print(warning_data_df.shape)
|
||||
warning_data_df = warning_data_df[~warning_data_df['indicatorId'].isin(
|
||||
quxiaodingyueidlist)]
|
||||
print(warning_data_df.shape)
|
||||
warning_data = warning_data_df.to_json(
|
||||
orient='records', force_ascii=False)
|
||||
warning_data = warning_data.replace('日度', '1')
|
||||
warning_data = warning_data.replace('周度', '2')
|
||||
warning_data = warning_data.replace('月度', '3')
|
||||
warning_data = json.loads(warning_data)
|
||||
push_waring_market_data(
|
||||
warning_data, dataSource=warning_data_df['dataSource'].values[0])
|
||||
# if is_update_warning_data:
|
||||
# upload_warning_info(len(warning_data_df))
|
||||
except:
|
||||
logger.info('上传预警信息到数据库失败')
|
||||
warning_data_df['warningDate'] = datetime.date.today().strftime(
|
||||
"%Y-%m-%d %H:%M:%S")
|
||||
warning_data_df['dataSource'] = 9
|
||||
|
||||
if is_corr:
|
||||
df = corr_feature(df=df)
|
||||
if len(quxiaodingyueidlist) > 0:
|
||||
# 去掉取消订阅的指标
|
||||
print(warning_data_df.shape)
|
||||
warning_data_df = warning_data_df[~warning_data_df['indicatorId'].isin(
|
||||
quxiaodingyueidlist)]
|
||||
print(warning_data_df.shape)
|
||||
warning_data = warning_data_df.to_json(
|
||||
orient='records', force_ascii=False)
|
||||
warning_data = warning_data.replace('日度', '1')
|
||||
warning_data = warning_data.replace('周度', '2')
|
||||
warning_data = warning_data.replace('月度', '3')
|
||||
warning_data = json.loads(warning_data)
|
||||
push_waring_market_data(
|
||||
warning_data, dataSource=warning_data_df['dataSource'].values[0])
|
||||
# if is_update_warning_data:
|
||||
# upload_warning_info(len(warning_data_df))
|
||||
except:
|
||||
logger.info('上传预警信息到数据库失败')
|
||||
|
||||
df1 = df.copy() # 备份一下,后面特征筛选完之后加入ds y 列用
|
||||
logger.info(f"开始训练模型...")
|
||||
row, col = df.shape
|
||||
if is_corr:
|
||||
df = corr_feature(df=df)
|
||||
|
||||
now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
ex_Model_Juxiting(df,
|
||||
horizon=global_config['horizon'],
|
||||
input_size=global_config['input_size'],
|
||||
train_steps=global_config['train_steps'],
|
||||
val_check_steps=global_config['val_check_steps'],
|
||||
early_stop_patience_steps=global_config['early_stop_patience_steps'],
|
||||
is_debug=global_config['is_debug'],
|
||||
dataset=global_config['dataset'],
|
||||
is_train=global_config['is_train'],
|
||||
is_fivemodels=global_config['is_fivemodels'],
|
||||
val_size=global_config['val_size'],
|
||||
test_size=global_config['test_size'],
|
||||
settings=global_config['settings'],
|
||||
now=now,
|
||||
etadata=etadata,
|
||||
modelsindex=global_config['modelsindex'],
|
||||
data=data,
|
||||
is_eta=global_config['is_eta'],
|
||||
end_time=global_config['end_time'],
|
||||
)
|
||||
df1 = df.copy() # 备份一下,后面特征筛选完之后加入ds y 列用
|
||||
logger.info(f"开始训练模型...")
|
||||
row, col = df.shape
|
||||
|
||||
logger.info('模型训练完成')
|
||||
now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
ex_Model_Juxiting(df,
|
||||
horizon=global_config['horizon'],
|
||||
input_size=global_config['input_size'],
|
||||
train_steps=global_config['train_steps'],
|
||||
val_check_steps=global_config['val_check_steps'],
|
||||
early_stop_patience_steps=global_config['early_stop_patience_steps'],
|
||||
is_debug=global_config['is_debug'],
|
||||
dataset=global_config['dataset'],
|
||||
is_train=global_config['is_train'],
|
||||
is_fivemodels=global_config['is_fivemodels'],
|
||||
val_size=global_config['val_size'],
|
||||
test_size=global_config['test_size'],
|
||||
settings=global_config['settings'],
|
||||
now=now,
|
||||
etadata=etadata,
|
||||
modelsindex=global_config['modelsindex'],
|
||||
data=data,
|
||||
is_eta=global_config['is_eta'],
|
||||
end_time=global_config['end_time'],
|
||||
)
|
||||
|
||||
# logger.info('训练数据绘图ing')
|
||||
# model_results3 = model_losss_juxiting(
|
||||
# sqlitedb, end_time=global_config['end_time'], is_fivemodels=global_config['is_fivemodels'])
|
||||
# logger.info('训练数据绘图end')
|
||||
logger.info('模型训练完成')
|
||||
|
||||
# # # 模型报告
|
||||
# logger.info('制作报告ing')
|
||||
# title = f'{settings}--{end_time}-预测报告' # 报告标题
|
||||
# reportname = f'聚烯烃PP大模型日度预测--{end_time}.pdf' # 报告文件名
|
||||
# reportname = reportname.replace(':', '-') # 替换冒号
|
||||
# pp_export_pdf(dataset=dataset, num_models=5 if is_fivemodels else 22, time=end_time,
|
||||
# reportname=reportname, sqlitedb=sqlitedb),
|
||||
# logger.info('训练数据绘图ing')
|
||||
# model_results3 = model_losss_juxiting(
|
||||
# sqlitedb, end_time=global_config['end_time'], is_fivemodels=global_config['is_fivemodels'])
|
||||
# logger.info('训练数据绘图end')
|
||||
|
||||
# logger.info('制作报告end')
|
||||
# # # 模型报告
|
||||
# logger.info('制作报告ing')
|
||||
# title = f'{settings}--{end_time}-预测报告' # 报告标题
|
||||
# reportname = f'聚烯烃PP大模型日度预测--{end_time}.pdf' # 报告文件名
|
||||
# reportname = reportname.replace(':', '-') # 替换冒号
|
||||
# pp_export_pdf(dataset=dataset, num_models=5 if is_fivemodels else 22, time=end_time,
|
||||
# reportname=reportname, sqlitedb=sqlitedb),
|
||||
|
||||
try:
|
||||
push_market_value()
|
||||
logger.info('推送市场值完成')
|
||||
# logger.info('制作报告end')
|
||||
|
||||
try:
|
||||
push_market_value()
|
||||
logger.info('推送市场值完成')
|
||||
except Exception as e:
|
||||
logger.info(f'推送市场值失败:{e}')
|
||||
|
||||
try:
|
||||
sql_inset_predict(global_config)
|
||||
logger.info('插入预测数据完成')
|
||||
except Exception as e:
|
||||
logger.info(f'插入预测数据失败:{e}')
|
||||
|
||||
# # LSTM 单变量模型
|
||||
# ex_Lstm(df,input_seq_len=input_size,output_seq_len=horizon,is_debug=is_debug,dataset=dataset)
|
||||
|
||||
# # lstm 多变量模型
|
||||
# ex_Lstm_M(df,n_days=input_size,out_days=horizon,is_debug=is_debug,datasetpath=dataset)
|
||||
|
||||
# # GRU 模型
|
||||
# # ex_GRU(df)
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
|
||||
except Exception as e:
|
||||
logger.info(f'推送市场值失败:{e}')
|
||||
|
||||
try:
|
||||
sql_inset_predict(global_config)
|
||||
logger.info('插入预测数据完成')
|
||||
except Exception as e:
|
||||
logger.info(f'插入预测数据失败:{e}')
|
||||
|
||||
# # LSTM 单变量模型
|
||||
# ex_Lstm(df,input_seq_len=input_size,output_seq_len=horizon,is_debug=is_debug,dataset=dataset)
|
||||
|
||||
# # lstm 多变量模型
|
||||
# ex_Lstm_M(df,n_days=input_size,out_days=horizon,is_debug=is_debug,datasetpath=dataset)
|
||||
|
||||
# # GRU 模型
|
||||
# # ex_GRU(df)
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
global_config['logger'].error(f"预测过程中发生错误: {str(e)}")
|
||||
raise
|
||||
finally:
|
||||
# 确保数据库连接被关闭
|
||||
try:
|
||||
if global_config['db_mysql'].is_connected():
|
||||
global_config['db_mysql'].close()
|
||||
global_config['logger'].info("数据库连接已关闭")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"关闭数据库连接时发生错误: {str(e)}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# global end_time
|
||||
# 遍历2024-11-25 到 2024-12-3 之间的工作日日期
|
||||
# for i_time in pd.date_range('2025-8-1', '2025-8-11', freq='B'):
|
||||
# for i_time in pd.date_range('2025-8-18', '2025-9-1', freq='B'):
|
||||
# try:
|
||||
# global_config['end_time'] = i_time.strftime('%Y-%m-%d')
|
||||
# global_config['db_mysql'].connect()
|
||||
@ -568,7 +598,25 @@ if __name__ == '__main__':
|
||||
# logger.info(f'预测失败:{e}')
|
||||
# continue
|
||||
|
||||
# global_config['end_time'] = '2025-08-14'
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--end_time', type=str, default='2025-10-01')
|
||||
args = parser.parse_args()
|
||||
global_config['end_time'] = args.end_time
|
||||
|
||||
# 交易日检查
|
||||
# 将 end_time 转换为 YYYYMMDD 格式
|
||||
end_time_str = global_config['end_time'].replace('-', '')
|
||||
logger.info(f"开始检查预测日期 {global_config['end_time']} 是否为交易日")
|
||||
|
||||
# 使用 global_config 中的交易日检查参数
|
||||
is_trading = check_trading_day(end_time_str, global_config)
|
||||
if not is_trading:
|
||||
logger.info(f"预测日期 {global_config['end_time']} 不是交易日,跳过预测任务")
|
||||
exit(0)
|
||||
else:
|
||||
logger.info(f"预测日期 {global_config['end_time']} 是交易日,开始执行预测任务")
|
||||
|
||||
|
||||
predict_main()
|
||||
|
||||
# global_config['end_time'] = '2025-08-14'
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
# 读取配置
|
||||
|
||||
import argparse
|
||||
from lib.dataread import *
|
||||
from config_juxiting_yuedu import *
|
||||
from lib.tools import SendMail, convert_df_to_pydantic_pp, exception_logger, find_best_models, get_modelsname, merge_images
|
||||
from models.nerulforcastmodels import ex_Model_Juxiting, model_losss_juxiting, pp_bdwd_png, pp_export_pdf
|
||||
import datetime
|
||||
import torch
|
||||
torch.set_float32_matmul_precision("high")
|
||||
torch.set_num_threads(4)
|
||||
# import torch
|
||||
# torch.set_float32_matmul_precision("high")
|
||||
# torch.set_num_threads(4)
|
||||
|
||||
global_config.update({
|
||||
# 核心参数
|
||||
@ -61,6 +60,10 @@ global_config.update({
|
||||
'upload_data': upload_data,
|
||||
'upload_warning_url': upload_warning_url,
|
||||
'warning_data': warning_data,
|
||||
'tqbz_login_url': tqbz_login_url,
|
||||
'tqbz_login_data': tqbz_login_data,
|
||||
'is_trading_day_data': is_trading_day_data,
|
||||
'query_is_trading_day_url': query_is_trading_day_url,
|
||||
|
||||
# 查询接口
|
||||
'query_data_list_item_nos_url': query_data_list_item_nos_url,
|
||||
@ -81,7 +84,6 @@ global_config.update({
|
||||
'edbdatapushurl': edbdatapushurl,
|
||||
'edbdeleteurl': edbdeleteurl,
|
||||
'edbbusinessurl': edbbusinessurl,
|
||||
'ClassifyId': ClassifyId,
|
||||
'classifylisturl': classifylisturl,
|
||||
|
||||
# 数据库配置
|
||||
@ -251,13 +253,11 @@ def sql_inset_predict(global_config):
|
||||
affected_rows = config.db_mysql.execute_batch_insert(
|
||||
insert_query, params_list)
|
||||
config.logger.info(f"成功插入或更新 {affected_rows} 条记录")
|
||||
config.db_mysql.close()
|
||||
|
||||
|
||||
def predict_main():
|
||||
"""
|
||||
主预测函数,用于从 ETA 获取数据、处理数据、训练模型并进行预测。
|
||||
|
||||
参数:
|
||||
signature (BinanceAPI): Binance API 实例。
|
||||
etadata (EtaReader): ETA 数据读取器实例。
|
||||
@ -293,252 +293,282 @@ def predict_main():
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
end_time = global_config['end_time']
|
||||
signature = BinanceAPI(APPID, SECRET)
|
||||
etadata = EtaReader(signature=signature,
|
||||
classifylisturl=global_config['classifylisturl'],
|
||||
classifyidlisturl=global_config['classifyidlisturl'],
|
||||
edbcodedataurl=global_config['edbcodedataurl'],
|
||||
edbcodelist=global_config['edbcodelist'],
|
||||
edbdatapushurl=global_config['edbdatapushurl'],
|
||||
edbdeleteurl=global_config['edbdeleteurl'],
|
||||
edbbusinessurl=global_config['edbbusinessurl'],
|
||||
classifyId=global_config['ClassifyId'],
|
||||
)
|
||||
# 获取数据
|
||||
if is_eta:
|
||||
logger.info('从eta获取数据...')
|
||||
|
||||
df_zhibiaoshuju, df_zhibiaoliebiao = etadata.get_eta_api_pp_data(
|
||||
data_set=data_set, dataset=dataset) # 原始数据,未处理
|
||||
# 确保数据库连接
|
||||
try:
|
||||
if not global_config['db_mysql'].is_connected():
|
||||
global_config['logger'].info("数据库连接已断开,正在重新连接...")
|
||||
global_config['db_mysql'].connect()
|
||||
global_config['logger'].info("数据库连接正常")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"数据库连接失败: {str(e)}")
|
||||
return
|
||||
|
||||
try:
|
||||
|
||||
if is_market:
|
||||
logger.info('从市场信息平台获取数据...')
|
||||
try:
|
||||
# 如果是测试环境,最高价最低价取excel文档
|
||||
if server_host == '192.168.100.53':
|
||||
logger.info('从excel文档获取最高价最低价')
|
||||
df_zhibiaoshuju = get_high_low_data(df_zhibiaoshuju)
|
||||
else:
|
||||
logger.info('从市场信息平台获取数据')
|
||||
df_zhibiaoshuju = get_market_data(
|
||||
end_time, df_zhibiaoshuju)
|
||||
end_time = global_config['end_time']
|
||||
signature = BinanceAPI(APPID, SECRET)
|
||||
etadata = EtaReader(signature=signature,
|
||||
classifylisturl=global_config['classifylisturl'],
|
||||
classifyidlisturl=global_config['classifyidlisturl'],
|
||||
edbcodedataurl=global_config['edbcodedataurl'],
|
||||
edbcodelist=global_config['edbcodelist'],
|
||||
edbdatapushurl=global_config['edbdatapushurl'],
|
||||
edbdeleteurl=global_config['edbdeleteurl'],
|
||||
edbbusinessurl=global_config['edbbusinessurl'],
|
||||
classifyId=global_config['ClassifyId'],
|
||||
)
|
||||
# 获取数据
|
||||
if is_eta:
|
||||
logger.info('从eta获取数据...')
|
||||
|
||||
except:
|
||||
logger.info('最高最低价拼接失败')
|
||||
df_zhibiaoshuju, df_zhibiaoliebiao = etadata.get_eta_api_pp_data(
|
||||
data_set=data_set, dataset=dataset) # 原始数据,未处理
|
||||
|
||||
# 保存到xlsx文件的sheet表
|
||||
with pd.ExcelWriter(os.path.join(dataset, data_set)) as file:
|
||||
df_zhibiaoshuju.to_excel(file, sheet_name='指标数据', index=False)
|
||||
df_zhibiaoliebiao.to_excel(file, sheet_name='指标列表', index=False)
|
||||
|
||||
# 数据处理
|
||||
df = datachuli_juxiting(df_zhibiaoshuju, df_zhibiaoliebiao, y=global_config['y'], dataset=dataset, add_kdj=add_kdj, is_timefurture=is_timefurture,
|
||||
end_time=end_time)
|
||||
|
||||
else:
|
||||
# 读取数据
|
||||
logger.info('读取本地数据:' + os.path.join(dataset, data_set))
|
||||
df, df_zhibiaoliebiao = getdata_juxiting(filename=os.path.join(dataset, data_set), y=y, dataset=dataset, add_kdj=add_kdj,
|
||||
is_timefurture=is_timefurture, end_time=end_time) # 原始数据,未处理
|
||||
|
||||
# 更改预测列名称
|
||||
df.rename(columns={y: 'y'}, inplace=True)
|
||||
|
||||
if is_edbnamelist:
|
||||
df = df[edbnamelist]
|
||||
df.to_csv(os.path.join(dataset, '指标数据.csv'), index=False)
|
||||
# 保存最新日期的y值到数据库
|
||||
# 取第一行数据存储到数据库中
|
||||
first_row = df[['ds', 'y']].tail(1)
|
||||
# 判断y的类型是否为float
|
||||
if not isinstance(first_row['y'].values[0], float):
|
||||
logger.info(f'{end_time}预测目标数据为空,跳过')
|
||||
return None
|
||||
|
||||
# 将最新真实值保存到数据库
|
||||
if not sqlitedb.check_table_exists('trueandpredict'):
|
||||
first_row.to_sql('trueandpredict', sqlitedb.connection, index=False)
|
||||
else:
|
||||
for row in first_row.itertuples(index=False):
|
||||
row_dict = row._asdict()
|
||||
config.logger.info(f'要保存的真实值:{row_dict}')
|
||||
# 判断ds是否为字符串类型,如果不是则转换为字符串类型
|
||||
if isinstance(row_dict['ds'], (pd.Timestamp, datetime.datetime)):
|
||||
row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
elif not isinstance(row_dict['ds'], str):
|
||||
if is_market:
|
||||
logger.info('从市场信息平台获取数据...')
|
||||
try:
|
||||
row_dict['ds'] = pd.to_datetime(
|
||||
row_dict['ds']).strftime('%Y-%m-%d')
|
||||
# 如果是测试环境,最高价最低价取excel文档
|
||||
if server_host == '192.168.100.53':
|
||||
logger.info('从excel文档获取最高价最低价')
|
||||
df_zhibiaoshuju = get_high_low_data(df_zhibiaoshuju)
|
||||
else:
|
||||
logger.info('从市场信息平台获取数据')
|
||||
df_zhibiaoshuju = get_market_data(
|
||||
end_time, df_zhibiaoshuju)
|
||||
|
||||
except:
|
||||
logger.warning(f"无法解析的时间格式: {row_dict['ds']}")
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d %H:%M:%S')
|
||||
check_query = sqlitedb.select_data(
|
||||
'trueandpredict', where_condition=f"ds = '{row.ds}'")
|
||||
if len(check_query) > 0:
|
||||
set_clause = ", ".join(
|
||||
[f"{key} = '{value}'" for key, value in row_dict.items()])
|
||||
sqlitedb.update_data(
|
||||
'trueandpredict', set_clause, where_condition=f"ds = '{row.ds}'")
|
||||
continue
|
||||
sqlitedb.insert_data('trueandpredict', tuple(
|
||||
row_dict.values()), columns=row_dict.keys())
|
||||
logger.info('最高最低价拼接失败')
|
||||
|
||||
# 更新accuracy表的y值
|
||||
if not sqlitedb.check_table_exists('accuracy'):
|
||||
pass
|
||||
else:
|
||||
update_y = sqlitedb.select_data(
|
||||
'accuracy', where_condition="y is null")
|
||||
if len(update_y) > 0:
|
||||
logger.info('更新accuracy表的y值')
|
||||
# 找到update_y 中ds且df中的y的行
|
||||
update_y = update_y[update_y['ds'] <= end_time]
|
||||
logger.info(f'要更新y的信息:{update_y}')
|
||||
# try:
|
||||
for row in update_y.itertuples(index=False):
|
||||
try:
|
||||
row_dict = row._asdict()
|
||||
yy = df[df['ds'] == row_dict['ds']]['y'].values[0]
|
||||
LOW = df[df['ds'] == row_dict['ds']]['Brentzdj'].values[0]
|
||||
HIGH = df[df['ds'] == row_dict['ds']]['Brentzgj'].values[0]
|
||||
# 保存到xlsx文件的sheet表
|
||||
with pd.ExcelWriter(os.path.join(dataset, data_set)) as file:
|
||||
df_zhibiaoshuju.to_excel(file, sheet_name='指标数据', index=False)
|
||||
df_zhibiaoliebiao.to_excel(file, sheet_name='指标列表', index=False)
|
||||
|
||||
# 数据处理
|
||||
df = datachuli_juxiting(df_zhibiaoshuju, df_zhibiaoliebiao, y=global_config['y'], dataset=dataset, add_kdj=add_kdj, is_timefurture=is_timefurture,
|
||||
end_time=end_time)
|
||||
|
||||
else:
|
||||
# 读取数据
|
||||
logger.info('读取本地数据:' + os.path.join(dataset, data_set))
|
||||
df, df_zhibiaoliebiao = getdata_juxiting(filename=os.path.join(dataset, data_set), y=y, dataset=dataset, add_kdj=add_kdj,
|
||||
is_timefurture=is_timefurture, end_time=end_time) # 原始数据,未处理
|
||||
|
||||
# 更改预测列名称
|
||||
df.rename(columns={y: 'y'}, inplace=True)
|
||||
|
||||
if is_edbnamelist:
|
||||
df = df[edbnamelist]
|
||||
df.to_csv(os.path.join(dataset, '指标数据.csv'), index=False)
|
||||
# 保存最新日期的y值到数据库
|
||||
# 取第一行数据存储到数据库中
|
||||
first_row = df[['ds', 'y']].tail(1)
|
||||
# 判断y的类型是否为float
|
||||
if not isinstance(first_row['y'].values[0], float):
|
||||
logger.info(f'{end_time}预测目标数据为空,跳过')
|
||||
return None
|
||||
|
||||
# 将最新真实值保存到数据库
|
||||
if not sqlitedb.check_table_exists('trueandpredict'):
|
||||
first_row.to_sql('trueandpredict', sqlitedb.connection, index=False)
|
||||
else:
|
||||
for row in first_row.itertuples(index=False):
|
||||
row_dict = row._asdict()
|
||||
config.logger.info(f'要保存的真实值:{row_dict}')
|
||||
# 判断ds是否为字符串类型,如果不是则转换为字符串类型
|
||||
if isinstance(row_dict['ds'], (pd.Timestamp, datetime.datetime)):
|
||||
row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
elif not isinstance(row_dict['ds'], str):
|
||||
try:
|
||||
row_dict['ds'] = pd.to_datetime(
|
||||
row_dict['ds']).strftime('%Y-%m-%d')
|
||||
except:
|
||||
logger.warning(f"无法解析的时间格式: {row_dict['ds']}")
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d %H:%M:%S')
|
||||
check_query = sqlitedb.select_data(
|
||||
'trueandpredict', where_condition=f"ds = '{row.ds}'")
|
||||
if len(check_query) > 0:
|
||||
set_clause = ", ".join(
|
||||
[f"{key} = '{value}'" for key, value in row_dict.items()])
|
||||
sqlitedb.update_data(
|
||||
'accuracy', f"y = {yy},LOW_PRICE = {LOW},HIGH_PRICE = {HIGH}", where_condition=f"ds = '{row_dict['ds']}'")
|
||||
except:
|
||||
logger.info(f'更新accuracy表的y值失败:{row_dict}')
|
||||
# except Exception as e:
|
||||
# logger.info(f'更新accuracy表的y值失败:{e}')
|
||||
'trueandpredict', set_clause, where_condition=f"ds = '{row.ds}'")
|
||||
continue
|
||||
sqlitedb.insert_data('trueandpredict', tuple(
|
||||
row_dict.values()), columns=row_dict.keys())
|
||||
|
||||
# 判断当前日期是不是周一
|
||||
is_weekday = datetime.datetime.now().weekday() == 0
|
||||
if is_weekday:
|
||||
logger.info('今天是周一,更新预测模型')
|
||||
# 计算最近60天预测残差最低的模型名称
|
||||
model_results = sqlitedb.select_data(
|
||||
'trueandpredict', order_by="ds DESC", limit="60")
|
||||
# 删除空值率为90%以上的列
|
||||
if len(model_results) > 10:
|
||||
model_results = model_results.dropna(
|
||||
thresh=len(model_results)*0.1, axis=1)
|
||||
# 删除空行
|
||||
model_results = model_results.dropna()
|
||||
modelnames = model_results.columns.to_list()[2:-1]
|
||||
for col in model_results[modelnames].select_dtypes(include=['object']).columns:
|
||||
model_results[col] = model_results[col].astype(np.float32)
|
||||
# 计算每个预测值与真实值之间的偏差率
|
||||
for model in modelnames:
|
||||
model_results[f'{model}_abs_error_rate'] = abs(
|
||||
model_results['y'] - model_results[model]) / model_results['y']
|
||||
# 获取每行对应的最小偏差率值
|
||||
min_abs_error_rate_values = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].min(), axis=1)
|
||||
# 获取每行对应的最小偏差率值对应的列名
|
||||
min_abs_error_rate_column_name = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].idxmin(), axis=1)
|
||||
# 将列名索引转换为列名
|
||||
min_abs_error_rate_column_name = min_abs_error_rate_column_name.map(
|
||||
lambda x: x.split('_')[0])
|
||||
# 取出现次数最多的模型名称
|
||||
most_common_model = min_abs_error_rate_column_name.value_counts().idxmax()
|
||||
logger.info(f"最近60天预测残差最低的模型名称:{most_common_model}")
|
||||
# 保存结果到数据库
|
||||
if not sqlitedb.check_table_exists('most_model'):
|
||||
sqlitedb.create_table(
|
||||
'most_model', columns="ds datetime, most_common_model TEXT")
|
||||
sqlitedb.insert_data('most_model', (datetime.datetime.now().strftime(
|
||||
'%Y-%m-%d %H:%M:%S'), most_common_model,), columns=('ds', 'most_common_model',))
|
||||
# 更新accuracy表的y值
|
||||
if not sqlitedb.check_table_exists('accuracy'):
|
||||
pass
|
||||
else:
|
||||
update_y = sqlitedb.select_data(
|
||||
'accuracy', where_condition="y is null")
|
||||
if len(update_y) > 0:
|
||||
logger.info('更新accuracy表的y值')
|
||||
# 找到update_y 中ds且df中的y的行
|
||||
update_y = update_y[update_y['ds'] <= end_time]
|
||||
logger.info(f'要更新y的信息:{update_y}')
|
||||
# try:
|
||||
for row in update_y.itertuples(index=False):
|
||||
try:
|
||||
row_dict = row._asdict()
|
||||
yy = df[df['ds'] == row_dict['ds']]['y'].values[0]
|
||||
LOW = df[df['ds'] == row_dict['ds']]['Brentzdj'].values[0]
|
||||
HIGH = df[df['ds'] == row_dict['ds']]['Brentzgj'].values[0]
|
||||
sqlitedb.update_data(
|
||||
'accuracy', f"y = {yy},LOW_PRICE = {LOW},HIGH_PRICE = {HIGH}", where_condition=f"ds = '{row_dict['ds']}'")
|
||||
except:
|
||||
# logger.info(f'更新accuracy表的y值失败:{row_dict}')
|
||||
pass
|
||||
# except Exception as e:
|
||||
# logger.info(f'更新accuracy表的y值失败:{e}')
|
||||
|
||||
if is_corr:
|
||||
df = corr_feature(df=df)
|
||||
# 判断当前日期是不是周一
|
||||
is_weekday = datetime.datetime.now().weekday() == 0
|
||||
# is_weekday = datetime.datetime.now().weekday() == 4
|
||||
try:
|
||||
if is_weekday:
|
||||
logger.info('今天是周一,更新预测模型')
|
||||
# 计算最近60天预测残差最低的模型名称
|
||||
model_results = sqlitedb.select_data(
|
||||
'trueandpredict', order_by="ds DESC", limit="60")
|
||||
# 删除空值率为90%以上的列
|
||||
if len(model_results) > 10:
|
||||
model_results = model_results.dropna(
|
||||
thresh=len(model_results)*0.1, axis=1)
|
||||
# 删除空行
|
||||
model_results = model_results.dropna()
|
||||
modelnames = model_results.columns.to_list()[2:-1]
|
||||
for col in model_results[modelnames].select_dtypes(include=['object']).columns:
|
||||
model_results[col] = model_results[col].astype(np.float32)
|
||||
# 计算每个预测值与真实值之间的偏差率
|
||||
for model in modelnames:
|
||||
model_results[f'{model}_abs_error_rate'] = abs(
|
||||
model_results['y'] - model_results[model]) / model_results['y']
|
||||
# 获取每行对应的最小偏差率值
|
||||
min_abs_error_rate_values = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].min(), axis=1)
|
||||
# 获取每行对应的最小偏差率值对应的列名
|
||||
min_abs_error_rate_column_name = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].idxmin(), axis=1)
|
||||
# 将列名索引转换为列名
|
||||
min_abs_error_rate_column_name = min_abs_error_rate_column_name.map(
|
||||
lambda x: x.split('_')[0])
|
||||
# 取出现次数最多的模型名称
|
||||
most_common_model = min_abs_error_rate_column_name.value_counts().idxmax()
|
||||
logger.info(f"最近60天预测残差最低的模型名称:{most_common_model}")
|
||||
# 保存结果到数据库
|
||||
if not sqlitedb.check_table_exists('most_model'):
|
||||
sqlitedb.create_table(
|
||||
'most_model', columns="ds datetime, most_common_model TEXT")
|
||||
sqlitedb.insert_data('most_model', (datetime.datetime.now().strftime(
|
||||
'%Y-%m-%d %H:%M:%S'), most_common_model,), columns=('ds', 'most_common_model',))
|
||||
except :
|
||||
logger.info(f"周一最佳模型更新失败,影响pdf报告")
|
||||
|
||||
df1 = df.copy() # 备份一下,后面特征筛选完之后加入ds y 列用
|
||||
logger.info(f"开始训练模型...")
|
||||
row, col = df.shape
|
||||
if is_corr:
|
||||
df = corr_feature(df=df)
|
||||
|
||||
now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
ex_Model_Juxiting(df,
|
||||
horizon=global_config['horizon'],
|
||||
input_size=global_config['input_size'],
|
||||
train_steps=global_config['train_steps'],
|
||||
val_check_steps=global_config['val_check_steps'],
|
||||
early_stop_patience_steps=global_config['early_stop_patience_steps'],
|
||||
is_debug=global_config['is_debug'],
|
||||
dataset=global_config['dataset'],
|
||||
is_train=global_config['is_train'],
|
||||
is_fivemodels=global_config['is_fivemodels'],
|
||||
val_size=global_config['val_size'],
|
||||
test_size=global_config['test_size'],
|
||||
settings=global_config['settings'],
|
||||
now=now,
|
||||
etadata=etadata,
|
||||
modelsindex=global_config['modelsindex'],
|
||||
data=data,
|
||||
is_eta=global_config['is_eta'],
|
||||
end_time=global_config['end_time'],
|
||||
)
|
||||
df1 = df.copy() # 备份一下,后面特征筛选完之后加入ds y 列用
|
||||
logger.info(f"开始训练模型...")
|
||||
row, col = df.shape
|
||||
|
||||
logger.info('模型训练完成')
|
||||
now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
ex_Model_Juxiting(df,
|
||||
horizon=global_config['horizon'],
|
||||
input_size=global_config['input_size'],
|
||||
train_steps=global_config['train_steps'],
|
||||
val_check_steps=global_config['val_check_steps'],
|
||||
early_stop_patience_steps=global_config['early_stop_patience_steps'],
|
||||
is_debug=global_config['is_debug'],
|
||||
dataset=global_config['dataset'],
|
||||
is_train=global_config['is_train'],
|
||||
is_fivemodels=global_config['is_fivemodels'],
|
||||
val_size=global_config['val_size'],
|
||||
test_size=global_config['test_size'],
|
||||
settings=global_config['settings'],
|
||||
now=now,
|
||||
etadata=etadata,
|
||||
modelsindex=global_config['modelsindex'],
|
||||
data=data,
|
||||
is_eta=global_config['is_eta'],
|
||||
end_time=global_config['end_time'],
|
||||
)
|
||||
|
||||
try:
|
||||
logger.info('训练数据绘图ing')
|
||||
model_results3 = model_losss_juxiting(
|
||||
sqlitedb, end_time=global_config['end_time'], is_fivemodels=global_config['is_fivemodels'])
|
||||
logger.info('训练数据绘图end')
|
||||
logger.info('模型训练完成')
|
||||
|
||||
# try:
|
||||
# logger.info('训练数据绘图ing')
|
||||
# model_results3 = model_losss_juxiting(
|
||||
# sqlitedb, end_time=global_config['end_time'], is_fivemodels=global_config['is_fivemodels'])
|
||||
# logger.info('训练数据绘图end')
|
||||
# except Exception as e:
|
||||
# logger.info(f'训练数据绘图失败:{e}')
|
||||
|
||||
try:
|
||||
push_market_value()
|
||||
logger.info('推送市场值完成')
|
||||
except Exception as e:
|
||||
logger.info(f'推送市场值失败:{e}')
|
||||
|
||||
try:
|
||||
sql_inset_predict(global_config)
|
||||
logger.info('插入预测数据完成')
|
||||
except Exception as e:
|
||||
logger.info(f'插入预测数据失败:{e}')
|
||||
|
||||
|
||||
# 模型报告
|
||||
# logger.info('制作报告ing')
|
||||
# title = f'{settings}--{end_time}-预测报告' # 报告标题
|
||||
# reportname = f'聚烯烃PP大模型月度预测--{end_time}.pdf' # 报告文件名
|
||||
# reportname = reportname.replace(':', '-') # 替换冒号
|
||||
# pp_export_pdf(dataset=dataset, num_models=5 if is_fivemodels else 22, time=end_time,
|
||||
# reportname=reportname, sqlitedb=sqlitedb),
|
||||
|
||||
# logger.info('制作报告end')
|
||||
|
||||
|
||||
|
||||
# # LSTM 单变量模型
|
||||
# ex_Lstm(df,input_seq_len=input_size,output_seq_len=horizon,is_debug=is_debug,dataset=dataset)
|
||||
|
||||
# # lstm 多变量模型
|
||||
# ex_Lstm_M(df,n_days=input_size,out_days=horizon,is_debug=is_debug,datasetpath=dataset)
|
||||
|
||||
# # GRU 模型
|
||||
# # ex_GRU(df)
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
|
||||
except Exception as e:
|
||||
logger.info(f'训练数据绘图失败:{e}')
|
||||
|
||||
try:
|
||||
push_market_value()
|
||||
logger.info('推送市场值完成')
|
||||
except Exception as e:
|
||||
logger.info(f'推送市场值失败:{e}')
|
||||
|
||||
try:
|
||||
sql_inset_predict(global_config)
|
||||
logger.info('插入预测数据完成')
|
||||
except Exception as e:
|
||||
logger.info(f'插入预测数据失败:{e}')
|
||||
|
||||
|
||||
# 模型报告
|
||||
# logger.info('制作报告ing')
|
||||
# title = f'{settings}--{end_time}-预测报告' # 报告标题
|
||||
# reportname = f'聚烯烃PP大模型月度预测--{end_time}.pdf' # 报告文件名
|
||||
# reportname = reportname.replace(':', '-') # 替换冒号
|
||||
# pp_export_pdf(dataset=dataset, num_models=5 if is_fivemodels else 22, time=end_time,
|
||||
# reportname=reportname, sqlitedb=sqlitedb),
|
||||
|
||||
# logger.info('制作报告end')
|
||||
|
||||
|
||||
|
||||
# # LSTM 单变量模型
|
||||
# ex_Lstm(df,input_seq_len=input_size,output_seq_len=horizon,is_debug=is_debug,dataset=dataset)
|
||||
|
||||
# # lstm 多变量模型
|
||||
# ex_Lstm_M(df,n_days=input_size,out_days=horizon,is_debug=is_debug,datasetpath=dataset)
|
||||
|
||||
# # GRU 模型
|
||||
# # ex_GRU(df)
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
global_config['logger'].error(f"预测过程中发生错误: {str(e)}")
|
||||
raise
|
||||
finally:
|
||||
# 确保数据库连接被关闭
|
||||
try:
|
||||
if global_config['db_mysql'].is_connected():
|
||||
global_config['db_mysql'].close()
|
||||
global_config['logger'].info("数据库连接已关闭")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"关闭数据库连接时发生错误: {str(e)}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# global end_time
|
||||
# 遍历2024-11-25 到 2024-12-3 之间的工作日日期
|
||||
# for i_time in pd.date_range('2025-7-24', '2025-8-12', freq='B'):
|
||||
# for i_time in pd.date_range('2025-8-14', '2025-9-1', freq='B'):
|
||||
# try:
|
||||
# global_config['end_time'] = i_time.strftime('%Y-%m-%d')
|
||||
# global_config['db_mysql'].connect()
|
||||
@ -547,7 +577,29 @@ if __name__ == '__main__':
|
||||
# logger.info(f'预测失败:{e}')
|
||||
# continue
|
||||
|
||||
# global_config['end_time'] = '2025-08-14'
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--end_time', type=str, default='2025-10-01')
|
||||
args = parser.parse_args()
|
||||
global_config['end_time'] = args.end_time
|
||||
|
||||
|
||||
# 交易日检查
|
||||
# 将 end_time 转换为 YYYYMMDD 格式
|
||||
end_time_str = global_config['end_time'].replace('-', '')
|
||||
logger.info(f"开始检查预测日期 {global_config['end_time']} 是否为交易日")
|
||||
|
||||
# 使用 global_config 中的交易日检查参数
|
||||
is_trading = check_trading_day(end_time_str, global_config)
|
||||
if not is_trading:
|
||||
logger.info(f"预测日期 {global_config['end_time']} 不是交易日,跳过预测任务")
|
||||
exit(0)
|
||||
else:
|
||||
logger.info(f"预测日期 {global_config['end_time']} 是交易日,开始执行预测任务")
|
||||
except Exception as e:
|
||||
logger.error(f"交易日检查失败: {str(e)}")
|
||||
logger.info("由于交易日检查失败,继续执行预测任务")
|
||||
|
||||
|
||||
predict_main()
|
||||
# push_market_value()
|
||||
# sql_inset_predict(global_config)
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
# 读取配置
|
||||
# 读取配置
|
||||
|
||||
from lib.dataread import *
|
||||
from config_juxiting_zhoudu import *
|
||||
from lib.tools import SendMail, exception_logger, convert_df_to_pydantic_pp, exception_logger, find_best_models, get_modelsname
|
||||
from models.nerulforcastmodels import ex_Model_Juxiting, model_losss_juxiting, pp_export_pdf
|
||||
import datetime
|
||||
import torch
|
||||
torch.set_float32_matmul_precision("high")
|
||||
torch.set_num_threads(4)
|
||||
import argparse
|
||||
# import torch
|
||||
# torch.set_float32_matmul_precision("high")
|
||||
# torch.set_num_threads(4)
|
||||
|
||||
global_config.update({
|
||||
# 核心参数
|
||||
@ -60,6 +61,10 @@ global_config.update({
|
||||
'upload_data': upload_data,
|
||||
'upload_warning_url': upload_warning_url,
|
||||
'warning_data': warning_data,
|
||||
'tqbz_login_url': tqbz_login_url,
|
||||
'tqbz_login_data': tqbz_login_data,
|
||||
'is_trading_day_data': is_trading_day_data,
|
||||
'query_is_trading_day_url': query_is_trading_day_url,
|
||||
|
||||
# 查询接口
|
||||
'query_data_list_item_nos_url': query_data_list_item_nos_url,
|
||||
@ -88,7 +93,6 @@ global_config.update({
|
||||
'edbdatapushurl': edbdatapushurl,
|
||||
'edbdeleteurl': edbdeleteurl,
|
||||
'edbbusinessurl': edbbusinessurl,
|
||||
'ClassifyId': ClassifyId,
|
||||
'classifylisturl': classifylisturl,
|
||||
|
||||
# 数据库配置
|
||||
@ -230,12 +234,11 @@ def sql_inset_predict(global_config):
|
||||
affected_rows = config.db_mysql.execute_batch_insert(
|
||||
insert_query, params_list)
|
||||
config.logger.info(f"成功插入或更新 {affected_rows} 条记录")
|
||||
config.db_mysql.close()
|
||||
|
||||
|
||||
def predict_main():
|
||||
"""
|
||||
主预测函数,用于从 ETA 获取数据、处理数据、训练模型并进行预测。
|
||||
|
||||
|
||||
参数:
|
||||
signature (BinanceAPI): Binance API 实例。
|
||||
@ -272,246 +275,271 @@ def predict_main():
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
end_time = global_config['end_time']
|
||||
signature = BinanceAPI(APPID, SECRET)
|
||||
etadata = EtaReader(signature=signature,
|
||||
classifylisturl=global_config['classifylisturl'],
|
||||
classifyidlisturl=global_config['classifyidlisturl'],
|
||||
edbcodedataurl=global_config['edbcodedataurl'],
|
||||
edbcodelist=global_config['edbcodelist'],
|
||||
edbdatapushurl=global_config['edbdatapushurl'],
|
||||
edbdeleteurl=global_config['edbdeleteurl'],
|
||||
edbbusinessurl=global_config['edbbusinessurl'],
|
||||
classifyId=global_config['ClassifyId'],
|
||||
)
|
||||
# 获取数据
|
||||
if is_eta:
|
||||
logger.info('从eta获取数据...')
|
||||
|
||||
df_zhibiaoshuju, df_zhibiaoliebiao = etadata.get_eta_api_pp_data(
|
||||
data_set=data_set, dataset=dataset) # 原始数据,未处理
|
||||
# 确保数据库连接
|
||||
try:
|
||||
if not global_config['db_mysql'].is_connected():
|
||||
global_config['logger'].info("数据库连接已断开,正在重新连接...")
|
||||
global_config['db_mysql'].connect()
|
||||
global_config['logger'].info("数据库连接正常")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"数据库连接失败: {str(e)}")
|
||||
return
|
||||
|
||||
try:
|
||||
end_time = global_config['end_time']
|
||||
signature = BinanceAPI(APPID, SECRET)
|
||||
etadata = EtaReader(signature=signature,
|
||||
classifylisturl=global_config['classifylisturl'],
|
||||
classifyidlisturl=global_config['classifyidlisturl'],
|
||||
edbcodedataurl=global_config['edbcodedataurl'],
|
||||
edbcodelist=global_config['edbcodelist'],
|
||||
edbdatapushurl=global_config['edbdatapushurl'],
|
||||
edbdeleteurl=global_config['edbdeleteurl'],
|
||||
edbbusinessurl=global_config['edbbusinessurl'],
|
||||
classifyId=global_config['ClassifyId'],
|
||||
)
|
||||
# 获取数据
|
||||
if is_eta:
|
||||
logger.info('从eta获取数据...')
|
||||
|
||||
if is_market:
|
||||
logger.info('从市场信息平台获取数据...')
|
||||
try:
|
||||
# 如果是测试环境,最高价最低价取excel文档
|
||||
if server_host == '192.168.100.53':
|
||||
logger.info('从excel文档获取市场信息平台指标')
|
||||
df_zhibiaoshuju = get_shujuxiang_data(df_zhibiaoshuju)
|
||||
else:
|
||||
logger.info('从市场信息平台获取数据')
|
||||
df_zhibiaoshuju = get_market_data(
|
||||
end_time, df_zhibiaoshuju)
|
||||
df_zhibiaoshuju, df_zhibiaoliebiao = etadata.get_eta_api_pp_data(
|
||||
data_set=data_set, dataset=dataset) # 原始数据,未处理
|
||||
|
||||
except:
|
||||
logger.info('市场信息平台数据项-eta数据项 拼接失败')
|
||||
|
||||
# 保存到xlsx文件的sheet表
|
||||
with pd.ExcelWriter(os.path.join(dataset, data_set)) as file:
|
||||
df_zhibiaoshuju.to_excel(file, sheet_name='指标数据', index=False)
|
||||
df_zhibiaoliebiao.to_excel(file, sheet_name='指标列表', index=False)
|
||||
|
||||
# 数据处理
|
||||
df = datachuli_juxiting(df_zhibiaoshuju, df_zhibiaoliebiao, y=global_config['y'], dataset=dataset, add_kdj=add_kdj, is_timefurture=is_timefurture,
|
||||
end_time=end_time)
|
||||
|
||||
else:
|
||||
# 读取数据
|
||||
logger.info('读取本地数据:' + os.path.join(dataset, data_set))
|
||||
df, df_zhibiaoliebiao = getdata_juxiting(filename=os.path.join(dataset, data_set), y=y, dataset=dataset, add_kdj=add_kdj,
|
||||
is_timefurture=is_timefurture, end_time=end_time) # 原始数据,未处理
|
||||
|
||||
# 更改预测列名称
|
||||
df.rename(columns={y: 'y'}, inplace=True)
|
||||
|
||||
if is_edbnamelist:
|
||||
df = df[edbnamelist]
|
||||
df.to_csv(os.path.join(dataset, '指标数据.csv'), index=False)
|
||||
# 保存最新日期的y值到数据库
|
||||
# 取第一行数据存储到数据库中
|
||||
first_row = df[['ds', 'y']].tail(1)
|
||||
# 判断y的类型是否为float
|
||||
if not isinstance(first_row['y'].values[0], float):
|
||||
logger.info(f'{end_time}预测目标数据为空,跳过')
|
||||
return None
|
||||
|
||||
# 将最新真实值保存到数据库
|
||||
if not sqlitedb.check_table_exists('trueandpredict'):
|
||||
first_row.to_sql('trueandpredict', sqlitedb.connection, index=False)
|
||||
else:
|
||||
for row in first_row.itertuples(index=False):
|
||||
row_dict = row._asdict()
|
||||
config.logger.info(f'要保存的真实值:{row_dict}')
|
||||
# 判断ds是否为字符串类型,如果不是则转换为字符串类型
|
||||
if isinstance(row_dict['ds'], (pd.Timestamp, datetime.datetime)):
|
||||
row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
elif not isinstance(row_dict['ds'], str):
|
||||
if is_market:
|
||||
logger.info('从市场信息平台获取数据...')
|
||||
try:
|
||||
row_dict['ds'] = pd.to_datetime(
|
||||
row_dict['ds']).strftime('%Y-%m-%d')
|
||||
# 如果是测试环境,最高价最低价取excel文档
|
||||
if server_host == '192.168.100.53':
|
||||
logger.info('从excel文档获取市场信息平台指标')
|
||||
df_zhibiaoshuju = get_shujuxiang_data(df_zhibiaoshuju)
|
||||
else:
|
||||
logger.info('从市场信息平台获取数据')
|
||||
df_zhibiaoshuju = get_market_data(
|
||||
end_time, df_zhibiaoshuju)
|
||||
|
||||
except:
|
||||
logger.warning(f"无法解析的时间格式: {row_dict['ds']}")
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d %H:%M:%S')
|
||||
check_query = sqlitedb.select_data(
|
||||
'trueandpredict', where_condition=f"ds = '{row.ds}'")
|
||||
if len(check_query) > 0:
|
||||
set_clause = ", ".join(
|
||||
[f"{key} = '{value}'" for key, value in row_dict.items()])
|
||||
sqlitedb.update_data(
|
||||
'trueandpredict', set_clause, where_condition=f"ds = '{row.ds}'")
|
||||
continue
|
||||
sqlitedb.insert_data('trueandpredict', tuple(
|
||||
row_dict.values()), columns=row_dict.keys())
|
||||
logger.info('市场信息平台数据项-eta数据项 拼接失败')
|
||||
|
||||
# 更新accuracy表的y值
|
||||
if not sqlitedb.check_table_exists('accuracy'):
|
||||
pass
|
||||
else:
|
||||
update_y = sqlitedb.select_data(
|
||||
'accuracy', where_condition="y is null")
|
||||
if len(update_y) > 0:
|
||||
logger.info('更新accuracy表的y值')
|
||||
# 找到update_y 中ds且df中的y的行
|
||||
update_y = update_y[update_y['ds'] <= end_time]
|
||||
logger.info(f'要更新y的信息:{update_y}')
|
||||
# try:
|
||||
for row in update_y.itertuples(index=False):
|
||||
try:
|
||||
row_dict = row._asdict()
|
||||
yy = df[df['ds'] == row_dict['ds']]['y'].values[0]
|
||||
LOW = df[df['ds'] == row_dict['ds']]['Brentzdj'].values[0]
|
||||
HIGH = df[df['ds'] == row_dict['ds']]['Brentzgj'].values[0]
|
||||
# 保存到xlsx文件的sheet表
|
||||
with pd.ExcelWriter(os.path.join(dataset, data_set)) as file:
|
||||
df_zhibiaoshuju.to_excel(file, sheet_name='指标数据', index=False)
|
||||
df_zhibiaoliebiao.to_excel(file, sheet_name='指标列表', index=False)
|
||||
|
||||
# 数据处理
|
||||
df = datachuli_juxiting(df_zhibiaoshuju, df_zhibiaoliebiao, y=global_config['y'], dataset=dataset, add_kdj=add_kdj, is_timefurture=is_timefurture,
|
||||
end_time=end_time)
|
||||
|
||||
else:
|
||||
# 读取数据
|
||||
logger.info('读取本地数据:' + os.path.join(dataset, data_set))
|
||||
df, df_zhibiaoliebiao = getdata_juxiting(filename=os.path.join(dataset, data_set), y=y, dataset=dataset, add_kdj=add_kdj,
|
||||
is_timefurture=is_timefurture, end_time=end_time) # 原始数据,未处理
|
||||
|
||||
# 更改预测列名称
|
||||
df.rename(columns={y: 'y'}, inplace=True)
|
||||
|
||||
if is_edbnamelist:
|
||||
df = df[edbnamelist]
|
||||
df.to_csv(os.path.join(dataset, '指标数据.csv'), index=False)
|
||||
# 保存最新日期的y值到数据库
|
||||
# 取第一行数据存储到数据库中
|
||||
first_row = df[['ds', 'y']].tail(1)
|
||||
# 判断y的类型是否为float
|
||||
if not isinstance(first_row['y'].values[0], float):
|
||||
logger.info(f'{end_time}预测目标数据为空,跳过')
|
||||
return None
|
||||
|
||||
# 将最新真实值保存到数据库
|
||||
if not sqlitedb.check_table_exists('trueandpredict'):
|
||||
first_row.to_sql('trueandpredict', sqlitedb.connection, index=False)
|
||||
else:
|
||||
for row in first_row.itertuples(index=False):
|
||||
row_dict = row._asdict()
|
||||
config.logger.info(f'要保存的真实值:{row_dict}')
|
||||
# 判断ds是否为字符串类型,如果不是则转换为字符串类型
|
||||
if isinstance(row_dict['ds'], (pd.Timestamp, datetime.datetime)):
|
||||
row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
elif not isinstance(row_dict['ds'], str):
|
||||
try:
|
||||
row_dict['ds'] = pd.to_datetime(
|
||||
row_dict['ds']).strftime('%Y-%m-%d')
|
||||
except:
|
||||
logger.warning(f"无法解析的时间格式: {row_dict['ds']}")
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d %H:%M:%S')
|
||||
check_query = sqlitedb.select_data(
|
||||
'trueandpredict', where_condition=f"ds = '{row.ds}'")
|
||||
if len(check_query) > 0:
|
||||
set_clause = ", ".join(
|
||||
[f"{key} = '{value}'" for key, value in row_dict.items()])
|
||||
sqlitedb.update_data(
|
||||
'accuracy', f"y = {yy},LOW_PRICE = {LOW},HIGH_PRICE = {HIGH}", where_condition=f"ds = '{row_dict['ds']}'")
|
||||
except:
|
||||
logger.info(f'更新accuracy表的y值失败:{row_dict}')
|
||||
# except Exception as e:
|
||||
# logger.info(f'更新accuracy表的y值失败:{e}')
|
||||
'trueandpredict', set_clause, where_condition=f"ds = '{row.ds}'")
|
||||
continue
|
||||
sqlitedb.insert_data('trueandpredict', tuple(
|
||||
row_dict.values()), columns=row_dict.keys())
|
||||
|
||||
# 判断当前日期是不是周一
|
||||
is_weekday = datetime.datetime.now().weekday() == 0
|
||||
# if is_weekday:
|
||||
# logger.info('今天是周一,更新预测模型')
|
||||
# # 计算最近60天预测残差最低的模型名称
|
||||
# model_results = sqlitedb.select_data(
|
||||
# 'trueandpredict', order_by="ds DESC", limit="60")
|
||||
# # 删除空值率为90%以上的列
|
||||
# if len(model_results) > 10:
|
||||
# model_results = model_results.dropna(
|
||||
# thresh=len(model_results)*0.1, axis=1)
|
||||
# # 删除空行
|
||||
# model_results = model_results.dropna()
|
||||
# modelnames = model_results.columns.to_list()[2:-2]
|
||||
# for col in model_results[modelnames].select_dtypes(include=['object']).columns:
|
||||
# model_results[col] = model_results[col].astype(np.float32)
|
||||
# # 计算每个预测值与真实值之间的偏差率
|
||||
# for model in modelnames:
|
||||
# model_results[f'{model}_abs_error_rate'] = abs(
|
||||
# model_results['y'] - model_results[model]) / model_results['y']
|
||||
# # 获取每行对应的最小偏差率值
|
||||
# min_abs_error_rate_values = model_results.apply(
|
||||
# lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].min(), axis=1)
|
||||
# # 获取每行对应的最小偏差率值对应的列名
|
||||
# min_abs_error_rate_column_name = model_results.apply(
|
||||
# lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].idxmin(), axis=1)
|
||||
# # 将列名索引转换为列名
|
||||
# min_abs_error_rate_column_name = min_abs_error_rate_column_name.map(
|
||||
# lambda x: x.split('_')[0])
|
||||
# # 取出现次数最多的模型名称
|
||||
# most_common_model = min_abs_error_rate_column_name.value_counts().idxmax()
|
||||
# logger.info(f"最近60天预测残差最低的模型名称:{most_common_model}")
|
||||
# # 保存结果到数据库
|
||||
# if not sqlitedb.check_table_exists('most_model'):
|
||||
# sqlitedb.create_table(
|
||||
# 'most_model', columns="ds datetime, most_common_model TEXT")
|
||||
# sqlitedb.insert_data('most_model', (datetime.datetime.now().strftime(
|
||||
# '%Y-%m-%d %H:%M:%S'), most_common_model,), columns=('ds', 'most_common_model',))
|
||||
# 更新accuracy表的y值
|
||||
if not sqlitedb.check_table_exists('accuracy'):
|
||||
pass
|
||||
else:
|
||||
update_y = sqlitedb.select_data(
|
||||
'accuracy', where_condition="y is null")
|
||||
if len(update_y) > 0:
|
||||
logger.info('更新accuracy表的y值')
|
||||
# 找到update_y 中ds且df中的y的行
|
||||
update_y = update_y[update_y['ds'] <= end_time]
|
||||
logger.info(f'要更新y的信息:{update_y}')
|
||||
# try:
|
||||
for row in update_y.itertuples(index=False):
|
||||
try:
|
||||
row_dict = row._asdict()
|
||||
yy = df[df['ds'] == row_dict['ds']]['y'].values[0]
|
||||
LOW = df[df['ds'] == row_dict['ds']]['Brentzdj'].values[0]
|
||||
HIGH = df[df['ds'] == row_dict['ds']]['Brentzgj'].values[0]
|
||||
sqlitedb.update_data(
|
||||
'accuracy', f"y = {yy},LOW_PRICE = {LOW},HIGH_PRICE = {HIGH}", where_condition=f"ds = '{row_dict['ds']}'")
|
||||
except:
|
||||
# logger.info(f'更新accuracy表的y值失败:{row_dict}')
|
||||
pass
|
||||
# except Exception as e:
|
||||
# logger.info(f'更新accuracy表的y值失败:{e}')
|
||||
|
||||
if is_corr:
|
||||
df = corr_feature(df=df)
|
||||
# 判断当前日期是不是周一
|
||||
is_weekday = datetime.datetime.now().weekday() == 0
|
||||
# if is_weekday:
|
||||
# logger.info('今天是周一,更新预测模型')
|
||||
# # 计算最近60天预测残差最低的模型名称
|
||||
# model_results = sqlitedb.select_data(
|
||||
# 'trueandpredict', order_by="ds DESC", limit="60")
|
||||
# # 删除空值率为90%以上的列
|
||||
# if len(model_results) > 10:
|
||||
# model_results = model_results.dropna(
|
||||
# thresh=len(model_results)*0.1, axis=1)
|
||||
# # 删除空行
|
||||
# model_results = model_results.dropna()
|
||||
# modelnames = model_results.columns.to_list()[2:-2]
|
||||
# for col in model_results[modelnames].select_dtypes(include=['object']).columns:
|
||||
# model_results[col] = model_results[col].astype(np.float32)
|
||||
# # 计算每个预测值与真实值之间的偏差率
|
||||
# for model in modelnames:
|
||||
# model_results[f'{model}_abs_error_rate'] = abs(
|
||||
# model_results['y'] - model_results[model]) / model_results['y']
|
||||
# # 获取每行对应的最小偏差率值
|
||||
# min_abs_error_rate_values = model_results.apply(
|
||||
# lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].min(), axis=1)
|
||||
# # 获取每行对应的最小偏差率值对应的列名
|
||||
# min_abs_error_rate_column_name = model_results.apply(
|
||||
# lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].idxmin(), axis=1)
|
||||
# # 将列名索引转换为列名
|
||||
# min_abs_error_rate_column_name = min_abs_error_rate_column_name.map(
|
||||
# lambda x: x.split('_')[0])
|
||||
# # 取出现次数最多的模型名称
|
||||
# most_common_model = min_abs_error_rate_column_name.value_counts().idxmax()
|
||||
# logger.info(f"最近60天预测残差最低的模型名称:{most_common_model}")
|
||||
# # 保存结果到数据库
|
||||
# if not sqlitedb.check_table_exists('most_model'):
|
||||
# sqlitedb.create_table(
|
||||
# 'most_model', columns="ds datetime, most_common_model TEXT")
|
||||
# sqlitedb.insert_data('most_model', (datetime.datetime.now().strftime(
|
||||
# '%Y-%m-%d %H:%M:%S'), most_common_model,), columns=('ds', 'most_common_model',))
|
||||
|
||||
df1 = df.copy() # 备份一下,后面特征筛选完之后加入ds y 列用
|
||||
logger.info(f"开始训练模型...")
|
||||
row, col = df.shape
|
||||
if is_corr:
|
||||
df = corr_feature(df=df)
|
||||
|
||||
now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
ex_Model_Juxiting(df,
|
||||
horizon=global_config['horizon'],
|
||||
input_size=global_config['input_size'],
|
||||
train_steps=global_config['train_steps'],
|
||||
val_check_steps=global_config['val_check_steps'],
|
||||
early_stop_patience_steps=global_config['early_stop_patience_steps'],
|
||||
is_debug=global_config['is_debug'],
|
||||
dataset=global_config['dataset'],
|
||||
is_train=global_config['is_train'],
|
||||
is_fivemodels=global_config['is_fivemodels'],
|
||||
val_size=global_config['val_size'],
|
||||
test_size=global_config['test_size'],
|
||||
settings=global_config['settings'],
|
||||
now=now,
|
||||
etadata=etadata,
|
||||
modelsindex=global_config['modelsindex'],
|
||||
data=data,
|
||||
is_eta=global_config['is_eta'],
|
||||
end_time=global_config['end_time'],
|
||||
)
|
||||
df1 = df.copy() # 备份一下,后面特征筛选完之后加入ds y 列用
|
||||
logger.info(f"开始训练模型...")
|
||||
row, col = df.shape
|
||||
|
||||
logger.info('模型训练完成')
|
||||
now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
ex_Model_Juxiting(df,
|
||||
horizon=global_config['horizon'],
|
||||
input_size=global_config['input_size'],
|
||||
train_steps=global_config['train_steps'],
|
||||
val_check_steps=global_config['val_check_steps'],
|
||||
early_stop_patience_steps=global_config['early_stop_patience_steps'],
|
||||
is_debug=global_config['is_debug'],
|
||||
dataset=global_config['dataset'],
|
||||
is_train=global_config['is_train'],
|
||||
is_fivemodels=global_config['is_fivemodels'],
|
||||
val_size=global_config['val_size'],
|
||||
test_size=global_config['test_size'],
|
||||
settings=global_config['settings'],
|
||||
now=now,
|
||||
etadata=etadata,
|
||||
modelsindex=global_config['modelsindex'],
|
||||
data=data,
|
||||
is_eta=global_config['is_eta'],
|
||||
end_time=global_config['end_time'],
|
||||
)
|
||||
|
||||
# logger.info('训练数据绘图ing')
|
||||
# model_results3 = model_losss_juxiting(
|
||||
# sqlitedb, end_time=global_config['end_time'], is_fivemodels=global_config['is_fivemodels'])
|
||||
# logger.info('训练数据绘图end')
|
||||
logger.info('模型训练完成')
|
||||
|
||||
# # # 模型报告
|
||||
# logger.info('制作报告ing')
|
||||
# title = f'{settings}--{end_time}-预测报告' # 报告标题
|
||||
# reportname = f'聚烯烃PP大模型周度预测--{end_time}.pdf' # 报告文件名
|
||||
# reportname = reportname.replace(':', '-') # 替换冒号
|
||||
# pp_export_pdf(dataset=dataset, num_models=5 if is_fivemodels else 22, time=end_time,
|
||||
# reportname=reportname, sqlitedb=sqlitedb),
|
||||
# logger.info('训练数据绘图ing')
|
||||
# model_results3 = model_losss_juxiting(
|
||||
# sqlitedb, end_time=global_config['end_time'], is_fivemodels=global_config['is_fivemodels'])
|
||||
# logger.info('训练数据绘图end')
|
||||
|
||||
# logger.info('制作报告end')
|
||||
# # # 模型报告
|
||||
# logger.info('制作报告ing')
|
||||
# title = f'{settings}--{end_time}-预测报告' # 报告标题
|
||||
# reportname = f'聚烯烃PP大模型周度预测--{end_time}.pdf' # 报告文件名
|
||||
# reportname = reportname.replace(':', '-') # 替换冒号
|
||||
# pp_export_pdf(dataset=dataset, num_models=5 if is_fivemodels else 22, time=end_time,
|
||||
# reportname=reportname, sqlitedb=sqlitedb),
|
||||
|
||||
try:
|
||||
push_market_value()
|
||||
logger.info('推送市场值完成')
|
||||
# logger.info('制作报告end')
|
||||
|
||||
try:
|
||||
push_market_value()
|
||||
logger.info('推送市场值完成')
|
||||
except Exception as e:
|
||||
logger.info(f'推送市场值失败:{e}')
|
||||
|
||||
try:
|
||||
sql_inset_predict(global_config)
|
||||
logger.info('插入预测数据完成')
|
||||
except Exception as e:
|
||||
logger.info(f'插入预测数据失败:{e}')
|
||||
|
||||
# # LSTM 单变量模型
|
||||
# ex_Lstm(df,input_seq_len=input_size,output_seq_len=horizon,is_debug=is_debug,dataset=dataset)
|
||||
|
||||
# # lstm 多变量模型
|
||||
# ex_Lstm_M(df,n_days=input_size,out_days=horizon,is_debug=is_debug,datasetpath=dataset)
|
||||
|
||||
# # GRU 模型
|
||||
# # ex_GRU(df)
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
|
||||
except Exception as e:
|
||||
logger.info(f'推送市场值失败:{e}')
|
||||
|
||||
try:
|
||||
sql_inset_predict(global_config)
|
||||
logger.info('插入预测数据完成')
|
||||
except Exception as e:
|
||||
logger.info(f'插入预测数据失败:{e}')
|
||||
|
||||
# # LSTM 单变量模型
|
||||
# ex_Lstm(df,input_seq_len=input_size,output_seq_len=horizon,is_debug=is_debug,dataset=dataset)
|
||||
|
||||
# # lstm 多变量模型
|
||||
# ex_Lstm_M(df,n_days=input_size,out_days=horizon,is_debug=is_debug,datasetpath=dataset)
|
||||
|
||||
# # GRU 模型
|
||||
# # ex_GRU(df)
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
global_config['logger'].error(f"预测过程中发生错误: {str(e)}")
|
||||
raise
|
||||
finally:
|
||||
# 确保数据库连接被关闭
|
||||
try:
|
||||
if global_config['db_mysql'].is_connected():
|
||||
global_config['db_mysql'].close()
|
||||
global_config['logger'].info("数据库连接已关闭")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"关闭数据库连接时发生错误: {str(e)}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# global end_time
|
||||
# 遍历2024-11-25 到 2024-12-3 之间的工作日日期
|
||||
# for i_time in pd.date_range('2025-3-3', '2025-5-30', freq='B'):
|
||||
# for i_time in pd.date_range('2025-8-14', '2025-9-1', freq='B'):
|
||||
# try:
|
||||
# global_config['end_time'] = i_time.strftime('%Y-%m-%d')
|
||||
# global_config['db_mysql'].connect()
|
||||
@ -520,8 +548,24 @@ if __name__ == '__main__':
|
||||
# logger.info(f'预测失败:{e}')
|
||||
# continue
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--end_time', type=str, default='2025-10-07')
|
||||
args = parser.parse_args()
|
||||
global_config['end_time'] = args.end_time
|
||||
|
||||
# global_config['end_time'] = '2025-08-14'
|
||||
|
||||
# 交易日检查
|
||||
# 将 end_time 转换为 YYYYMMDD 格式
|
||||
end_time_str = global_config['end_time'].replace('-', '')
|
||||
logger.info(f"开始检查预测日期 {global_config['end_time']} 是否为交易日")
|
||||
|
||||
# 使用 global_config 中的交易日检查参数
|
||||
is_trading = check_trading_day(end_time_str, global_config)
|
||||
if not is_trading:
|
||||
logger.info(f"预测日期 {global_config['end_time']} 不是交易日,跳过预测任务")
|
||||
exit(0)
|
||||
else:
|
||||
logger.info(f"预测日期 {global_config['end_time']} 是交易日,开始执行预测任务")
|
||||
predict_main()
|
||||
|
||||
|
||||
|
||||
651
main_yuanyou.py
651
main_yuanyou.py
@ -1,5 +1,6 @@
|
||||
# 读取配置
|
||||
|
||||
import argparse
|
||||
from lib.dataread import *
|
||||
from config_jingbo import *
|
||||
from lib.tools import SendMail, convert_df_to_pydantic, exception_logger, get_modelsname
|
||||
@ -72,6 +73,12 @@ global_config.update({
|
||||
'get_waring_data_value_list_url': get_waring_data_value_list_url,
|
||||
'get_waring_data_value_list_data': get_waring_data_value_list_data,
|
||||
|
||||
# 套期保值api
|
||||
"tqbz_login_url":tqbz_login_url,
|
||||
"tqbz_login_data":tqbz_login_data,
|
||||
'query_is_trading_day_url': query_is_trading_day_url,
|
||||
'is_trading_day_data': is_trading_day_data,
|
||||
|
||||
# eta 配置
|
||||
'APPID': APPID,
|
||||
'SECRET': SECRET,
|
||||
@ -234,348 +241,339 @@ def sql_inset_predict(global_config):
|
||||
affected_rows = config.db_mysql.execute_batch_insert(
|
||||
insert_query, params_list)
|
||||
config.logger.info(f"成功插入或更新 {affected_rows} 条记录")
|
||||
config.db_mysql.close()
|
||||
|
||||
|
||||
def predict_main():
|
||||
"""
|
||||
主预测函数,用于从 ETA 获取数据、处理数据、训练模型并进行预测。
|
||||
|
||||
参数:
|
||||
signature (BinanceAPI): Binance API 实例。
|
||||
etadata (EtaReader): ETA 数据读取器实例。
|
||||
is_eta (bool): 是否从 ETA 获取数据。
|
||||
data_set (str): 数据集名称。
|
||||
dataset (str): 数据集路径。
|
||||
add_kdj (bool): 是否添加 KDJ 指标。
|
||||
is_timefurture (bool): 是否添加时间衍生特征。
|
||||
end_time (str): 结束时间。
|
||||
is_edbnamelist (bool): 是否使用 EDB 名称列表。
|
||||
edbnamelist (list): EDB 名称列表。
|
||||
y (str): 预测目标列名。
|
||||
sqlitedb (SQLiteDB): SQLite 数据库实例。
|
||||
is_corr (bool): 是否进行相关性分析。
|
||||
horizon (int): 预测时域。
|
||||
input_size (int): 输入数据大小。
|
||||
train_steps (int): 训练步数。
|
||||
val_check_steps (int): 验证检查步数。
|
||||
early_stop_patience_steps (int): 早停耐心步数。
|
||||
is_debug (bool): 是否调试模式。
|
||||
dataset (str): 数据集名称。
|
||||
is_train (bool): 是否训练模型。
|
||||
is_fivemodels (bool): 是否使用五个模型。
|
||||
val_size (float): 验证集大小。
|
||||
test_size (float): 测试集大小。
|
||||
settings (dict): 模型设置。
|
||||
now (str): 当前时间。
|
||||
etadata (EtaReader): ETA 数据读取器实例。
|
||||
modelsindex (list): 模型索引列表。
|
||||
data (str): 数据类型。
|
||||
is_eta (bool): 是否从 ETA 获取数据。
|
||||
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
end_time = global_config['end_time']
|
||||
signature = BinanceAPI(APPID, SECRET)
|
||||
etadata = EtaReader(signature=signature,
|
||||
classifylisturl=global_config['classifylisturl'],
|
||||
classifyidlisturl=global_config['classifyidlisturl'],
|
||||
edbcodedataurl=global_config['edbcodedataurl'],
|
||||
edbcodelist=global_config['edbcodelist'],
|
||||
edbdatapushurl=global_config['edbdatapushurl'],
|
||||
edbdeleteurl=global_config['edbdeleteurl'],
|
||||
edbbusinessurl=global_config['edbbusinessurl'],
|
||||
classifyId=global_config['ClassifyId'],
|
||||
)
|
||||
# 获取数据
|
||||
if is_eta:
|
||||
logger.info('从eta获取数据...')
|
||||
|
||||
df_zhibiaoshuju, df_zhibiaoliebiao = etadata.get_eta_api_yuanyou_data(
|
||||
data_set=data_set, dataset=dataset) # 原始数据,未处理
|
||||
|
||||
if is_market:
|
||||
logger.info('从市场信息平台获取数据...')
|
||||
try:
|
||||
# 如果是测试环境,最高价最低价取excel文档
|
||||
if server_host == '192.168.100.53':
|
||||
logger.info('从excel文档获取最高价最低价')
|
||||
df_zhibiaoshuju = get_high_low_data(df_zhibiaoshuju)
|
||||
else:
|
||||
logger.info('从市场信息平台获取数据')
|
||||
df_zhibiaoshuju = get_market_data(
|
||||
end_time, df_zhibiaoshuju)
|
||||
|
||||
except:
|
||||
logger.info('最高最低价拼接失败')
|
||||
|
||||
# 保存到xlsx文件的sheet表
|
||||
with pd.ExcelWriter(os.path.join(dataset, data_set)) as file:
|
||||
df_zhibiaoshuju.to_excel(file, sheet_name='指标数据', index=False)
|
||||
df_zhibiaoliebiao.to_excel(file, sheet_name='指标列表', index=False)
|
||||
|
||||
# 数据处理
|
||||
df = datachuli(df_zhibiaoshuju, df_zhibiaoliebiao, y=y, dataset=dataset, add_kdj=add_kdj, is_timefurture=is_timefurture,
|
||||
end_time=end_time)
|
||||
|
||||
else:
|
||||
# 读取数据
|
||||
logger.info('读取本地数据:' + os.path.join(dataset, data_set))
|
||||
df, df_zhibiaoliebiao = getdata(filename=os.path.join(dataset, data_set), y=y, dataset=dataset, add_kdj=add_kdj,
|
||||
is_timefurture=is_timefurture, end_time=end_time) # 原始数据,未处理
|
||||
|
||||
# 更改预测列名称
|
||||
df.rename(columns={y: 'y'}, inplace=True)
|
||||
|
||||
if is_edbnamelist:
|
||||
df = df[edbnamelist]
|
||||
df.to_csv(os.path.join(dataset, '指标数据.csv'), index=False)
|
||||
# 保存最新日期的y值到数据库
|
||||
# 取第一行数据存储到数据库中
|
||||
first_row = df[['ds', 'y']].tail(1)
|
||||
# 判断y的类型是否为float
|
||||
if not isinstance(first_row['y'].values[0], float):
|
||||
logger.info(f'{end_time}预测目标数据为空,跳过')
|
||||
return None
|
||||
|
||||
# 将最新真实值保存到数据库
|
||||
if not sqlitedb.check_table_exists('trueandpredict'):
|
||||
first_row.to_sql('trueandpredict', sqlitedb.connection, index=False)
|
||||
else:
|
||||
for row in first_row.itertuples(index=False):
|
||||
row_dict = row._asdict()
|
||||
config.logger.info(f'要保存的真实值:{row_dict}')
|
||||
# 判断ds是否为字符串类型,如果不是则转换为字符串类型
|
||||
if isinstance(row_dict['ds'], (pd.Timestamp, datetime.datetime)):
|
||||
row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
elif not isinstance(row_dict['ds'], str):
|
||||
try:
|
||||
row_dict['ds'] = pd.to_datetime(
|
||||
row_dict['ds']).strftime('%Y-%m-%d')
|
||||
except:
|
||||
logger.warning(f"无法解析的时间格式: {row_dict['ds']}")
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d %H:%M:%S')
|
||||
check_query = sqlitedb.select_data(
|
||||
'trueandpredict', where_condition=f"ds = '{row.ds}'")
|
||||
if len(check_query) > 0:
|
||||
set_clause = ", ".join(
|
||||
[f"{key} = '{value}'" for key, value in row_dict.items()])
|
||||
sqlitedb.update_data(
|
||||
'trueandpredict', set_clause, where_condition=f"ds = '{row.ds}'")
|
||||
continue
|
||||
sqlitedb.insert_data('trueandpredict', tuple(
|
||||
row_dict.values()), columns=row_dict.keys())
|
||||
|
||||
# 更新accuracy表的y值
|
||||
if not sqlitedb.check_table_exists('accuracy'):
|
||||
pass
|
||||
else:
|
||||
update_y = sqlitedb.select_data(
|
||||
'accuracy', where_condition="y is null")
|
||||
if len(update_y) > 0:
|
||||
logger.info('更新accuracy表的y值')
|
||||
# 找到update_y 中ds且df中的y的行
|
||||
update_y = update_y[update_y['ds'] <= end_time]
|
||||
logger.info(f'要更新y的信息:{update_y}')
|
||||
# try:
|
||||
for row in update_y.itertuples(index=False):
|
||||
try:
|
||||
row_dict = row._asdict()
|
||||
yy = df[df['ds'] == row_dict['ds']]['y'].values[0]
|
||||
LOW = df[df['ds'] == row_dict['ds']]['Brentzdj'].values[0]
|
||||
HIGH = df[df['ds'] == row_dict['ds']]['Brentzgj'].values[0]
|
||||
sqlitedb.update_data(
|
||||
'accuracy', f"y = {yy},LOW_PRICE = {LOW},HIGH_PRICE = {HIGH}", where_condition=f"ds = '{row_dict['ds']}'")
|
||||
except:
|
||||
logger.info(f'更新accuracy表的y值失败:{row_dict}')
|
||||
# except Exception as e:
|
||||
# logger.info(f'更新accuracy表的y值失败:{e}')
|
||||
|
||||
# 判断当前日期是不是周一
|
||||
is_weekday = datetime.datetime.now().weekday() == 0
|
||||
if is_weekday:
|
||||
logger.info('今天是周一,更新预测模型')
|
||||
# 计算最近60天预测残差最低的模型名称
|
||||
model_results = sqlitedb.select_data(
|
||||
'trueandpredict', order_by="ds DESC", limit="60")
|
||||
# 删除空值率为90%以上的列
|
||||
if len(model_results) > 10:
|
||||
model_results = model_results.dropna(
|
||||
thresh=len(model_results)*0.1, axis=1)
|
||||
# 删除空行
|
||||
model_results = model_results.dropna()
|
||||
modelnames = model_results.columns.to_list()[2:-1]
|
||||
for col in model_results[modelnames].select_dtypes(include=['object']).columns:
|
||||
model_results[col] = model_results[col].astype(np.float32)
|
||||
# 计算每个预测值与真实值之间的偏差率
|
||||
for model in modelnames:
|
||||
model_results[f'{model}_abs_error_rate'] = abs(
|
||||
model_results['y'] - model_results[model]) / model_results['y']
|
||||
# 获取每行对应的最小偏差率值
|
||||
min_abs_error_rate_values = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].min(), axis=1)
|
||||
# 获取每行对应的最小偏差率值对应的列名
|
||||
min_abs_error_rate_column_name = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].idxmin(), axis=1)
|
||||
# 将列名索引转换为列名
|
||||
min_abs_error_rate_column_name = min_abs_error_rate_column_name.map(
|
||||
lambda x: x.split('_')[0])
|
||||
# 取出现次数最多的模型名称
|
||||
most_common_model = min_abs_error_rate_column_name.value_counts().idxmax()
|
||||
logger.info(f"最近60天预测残差最低的模型名称:{most_common_model}")
|
||||
# 保存结果到数据库
|
||||
if not sqlitedb.check_table_exists('most_model'):
|
||||
sqlitedb.create_table(
|
||||
'most_model', columns="ds datetime, most_common_model TEXT")
|
||||
sqlitedb.insert_data('most_model', (datetime.datetime.now().strftime(
|
||||
'%Y-%m-%d %H:%M:%S'), most_common_model,), columns=('ds', 'most_common_model',))
|
||||
|
||||
# try:
|
||||
# # if is_weekday:
|
||||
# if True:
|
||||
# logger.info('今天是周一,发送特征预警')
|
||||
# # 上传预警信息到数据库
|
||||
# warning_data_df = df_zhibiaoliebiao.copy()
|
||||
# warning_data_df = warning_data_df[warning_data_df['停更周期'] > 3][[
|
||||
# '指标名称', '指标id', '频度', '更新周期', '指标来源', '最后更新时间', '停更周期']]
|
||||
# # 重命名列名
|
||||
# warning_data_df = warning_data_df.rename(columns={'指标名称': 'INDICATOR_NAME', '指标id': 'INDICATOR_ID', '频度': 'FREQUENCY',
|
||||
# '更新周期': 'UPDATE_FREQUENCY', '指标来源': 'DATA_SOURCE', '最后更新时间': 'LAST_UPDATE_DATE', '停更周期': 'UPDATE_SUSPENSION_CYCLE'})
|
||||
# from sqlalchemy import create_engine
|
||||
# import urllib
|
||||
# global password
|
||||
# if '@' in password:
|
||||
# password = urllib.parse.quote_plus(password)
|
||||
|
||||
# engine = create_engine(
|
||||
# f'mysql+pymysql://{dbusername}:{password}@{host}:{port}/{dbname}')
|
||||
# warning_data_df['WARNING_DATE'] = datetime.date.today().strftime(
|
||||
# "%Y-%m-%d %H:%M:%S")
|
||||
# warning_data_df['TENANT_CODE'] = 'T0004'
|
||||
# # 插入数据之前查询表数据然后新增id列
|
||||
# existing_data = pd.read_sql(f"SELECT * FROM {table_name}", engine)
|
||||
# if not existing_data.empty:
|
||||
# max_id = existing_data['ID'].astype(int).max()
|
||||
# warning_data_df['ID'] = range(
|
||||
# max_id + 1, max_id + 1 + len(warning_data_df))
|
||||
# else:
|
||||
# warning_data_df['ID'] = range(1, 1 + len(warning_data_df))
|
||||
# warning_data_df.to_sql(
|
||||
# table_name, con=engine, if_exists='append', index=False)
|
||||
# if is_update_warning_data:
|
||||
# upload_warning_info(len(warning_data_df))
|
||||
# except:
|
||||
# logger.info('上传预警信息到数据库失败')
|
||||
|
||||
# 确保数据库连接
|
||||
try:
|
||||
# if is_weekday:
|
||||
if True:
|
||||
logger.info('发送特征预警')
|
||||
# 获取取消订阅的指标ID
|
||||
quxiaodingyueidlist = get_waring_data()
|
||||
# 上传预警信息到数据库
|
||||
warning_data_df = df_zhibiaoliebiao.copy()
|
||||
warning_data_df = warning_data_df[warning_data_df['停更周期'] > 3][[
|
||||
'指标名称', '指标id', '频度', '更新周期', '指标来源', '最后更新时间', '停更周期']]
|
||||
# 重命名列名
|
||||
warning_data_df = warning_data_df.rename(columns={'指标名称': 'indicatorName', '指标id': 'indicatorId', '频度': 'frequency',
|
||||
'更新周期': 'UPDATE_FREQUENCY', '指标来源': 'DATA_SOURCE', '最后更新时间': 'LAST_UPDATE_DATE', '停更周期': 'updateSuspensionCycle'})
|
||||
if global_config['db_mysql'] is None:
|
||||
global_config['logger'].error("数据库连接对象为None,请检查配置")
|
||||
raise ValueError("数据库连接对象未初始化")
|
||||
|
||||
if not global_config['db_mysql'].is_connected():
|
||||
global_config['logger'].info("数据库连接已断开,正在重新连接...")
|
||||
global_config['db_mysql'].connect()
|
||||
global_config['logger'].info("数据库连接正常")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"数据库连接失败: {str(e)}")
|
||||
exit(1)
|
||||
|
||||
try:
|
||||
end_time = global_config['end_time']
|
||||
signature = BinanceAPI(APPID, SECRET)
|
||||
etadata = EtaReader(signature=signature,
|
||||
classifylisturl=global_config['classifylisturl'],
|
||||
classifyidlisturl=global_config['classifyidlisturl'],
|
||||
edbcodedataurl=global_config['edbcodedataurl'],
|
||||
edbcodelist=global_config['edbcodelist'],
|
||||
edbdatapushurl=global_config['edbdatapushurl'],
|
||||
edbdeleteurl=global_config['edbdeleteurl'],
|
||||
edbbusinessurl=global_config['edbbusinessurl'],
|
||||
classifyId=global_config['ClassifyId'],
|
||||
)
|
||||
# 获取数据
|
||||
if is_eta:
|
||||
logger.info('从eta获取数据...')
|
||||
|
||||
warning_data_df['warningDate'] = datetime.date.today().strftime(
|
||||
"%Y-%m-%d %H:%M:%S")
|
||||
warning_data_df['dataSource'] = 8
|
||||
# 去掉取消订阅的指标
|
||||
print(warning_data_df.shape)
|
||||
warning_data_df = warning_data_df[~warning_data_df['indicatorId'].isin(
|
||||
quxiaodingyueidlist)]
|
||||
print(warning_data_df.shape)
|
||||
warning_data = warning_data_df.to_json(
|
||||
orient='records', force_ascii=False)
|
||||
warning_data = warning_data.replace('日度', '1')
|
||||
warning_data = warning_data.replace('周度', '2')
|
||||
warning_data = warning_data.replace('月度', '3')
|
||||
warning_data = json.loads(warning_data)
|
||||
push_waring_market_data(warning_data)
|
||||
# if is_update_warning_data:
|
||||
# upload_warning_info(len(warning_data_df))
|
||||
except:
|
||||
logger.info('上传预警信息到数据库失败')
|
||||
df_zhibiaoshuju, df_zhibiaoliebiao = etadata.get_eta_api_yuanyou_data(
|
||||
data_set=data_set, dataset=dataset) # 原始数据,未处理
|
||||
|
||||
if is_corr:
|
||||
df = corr_feature(df=df)
|
||||
if is_market:
|
||||
logger.info('从市场信息平台获取数据...')
|
||||
try:
|
||||
# 如果是测试环境,最高价最低价取excel文档
|
||||
if server_host == '192.168.100.53':
|
||||
logger.info('从excel文档获取最高价最低价')
|
||||
df_zhibiaoshuju = get_high_low_data(df_zhibiaoshuju)
|
||||
else:
|
||||
logger.info('从市场信息平台获取数据')
|
||||
df_zhibiaoshuju = get_market_data(
|
||||
end_time, df_zhibiaoshuju)
|
||||
|
||||
df1 = df.copy() # 备份一下,后面特征筛选完之后加入ds y 列用
|
||||
logger.info(f"开始训练模型...")
|
||||
row, col = df.shape
|
||||
except:
|
||||
logger.info('最高最低价拼接失败')
|
||||
|
||||
now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
ex_Model(df,
|
||||
horizon=global_config['horizon'],
|
||||
input_size=global_config['input_size'],
|
||||
train_steps=global_config['train_steps'],
|
||||
val_check_steps=global_config['val_check_steps'],
|
||||
early_stop_patience_steps=global_config['early_stop_patience_steps'],
|
||||
is_debug=global_config['is_debug'],
|
||||
dataset=global_config['dataset'],
|
||||
is_train=global_config['is_train'],
|
||||
is_fivemodels=global_config['is_fivemodels'],
|
||||
val_size=global_config['val_size'],
|
||||
test_size=global_config['test_size'],
|
||||
settings=global_config['settings'],
|
||||
now=now,
|
||||
etadata=etadata,
|
||||
modelsindex=global_config['modelsindex'],
|
||||
data=data,
|
||||
is_eta=global_config['is_eta'],
|
||||
end_time=global_config['end_time'],
|
||||
)
|
||||
# 保存到xlsx文件的sheet表
|
||||
with pd.ExcelWriter(os.path.join(dataset, data_set)) as file:
|
||||
df_zhibiaoshuju.to_excel(file, sheet_name='指标数据', index=False)
|
||||
df_zhibiaoliebiao.to_excel(file, sheet_name='指标列表', index=False)
|
||||
|
||||
logger.info('模型训练完成')
|
||||
# 数据处理
|
||||
df = datachuli(df_zhibiaoshuju, df_zhibiaoliebiao, y=y, dataset=dataset, add_kdj=add_kdj, is_timefurture=is_timefurture,
|
||||
end_time=end_time)
|
||||
|
||||
logger.info('训练数据绘图ing')
|
||||
model_results3 = model_losss(sqlitedb, end_time=end_time)
|
||||
logger.info('训练数据绘图end')
|
||||
else:
|
||||
# 读取数据
|
||||
logger.info('读取本地数据:' + os.path.join(dataset, data_set))
|
||||
df, df_zhibiaoliebiao = getdata(filename=os.path.join(dataset, data_set), y=y, dataset=dataset, add_kdj=add_kdj,
|
||||
is_timefurture=is_timefurture, end_time=end_time) # 原始数据,未处理
|
||||
|
||||
# 模型报告
|
||||
logger.info('制作报告ing')
|
||||
title = f'{settings}--{end_time}-预测报告' # 报告标题
|
||||
reportname = f'Brent原油大模型日度预测--{end_time}.pdf' # 报告文件名
|
||||
reportname = reportname.replace(':', '-') # 替换冒号
|
||||
brent_export_pdf(dataset=dataset,
|
||||
num_models=5 if is_fivemodels else 22, time=end_time,
|
||||
reportname=reportname,
|
||||
inputsize=global_config['horizon'],
|
||||
sqlitedb=sqlitedb
|
||||
),
|
||||
# 更改预测列名称
|
||||
df.rename(columns={y: 'y'}, inplace=True)
|
||||
|
||||
logger.info('制作报告end')
|
||||
logger.info('模型训练完成')
|
||||
if is_edbnamelist:
|
||||
df = df[edbnamelist]
|
||||
df.to_csv(os.path.join(dataset, '指标数据.csv'), index=False)
|
||||
# 保存最新日期的y值到数据库
|
||||
# 取第一行数据存储到数据库中
|
||||
first_row = df[['ds', 'y']].tail(1)
|
||||
# 判断y的类型是否为float
|
||||
if not isinstance(first_row['y'].values[0], float):
|
||||
logger.info(f'{end_time}预测目标数据为空,跳过')
|
||||
return None
|
||||
|
||||
push_market_value()
|
||||
sql_inset_predict(global_config)
|
||||
# 将最新真实值保存到数据库
|
||||
if not sqlitedb.check_table_exists('trueandpredict'):
|
||||
first_row.to_sql('trueandpredict', sqlitedb.connection, index=False)
|
||||
else:
|
||||
for row in first_row.itertuples(index=False):
|
||||
row_dict = row._asdict()
|
||||
config.logger.info(f'要保存的真实值:{row_dict}')
|
||||
# 判断ds是否为字符串类型,如果不是则转换为字符串类型
|
||||
if isinstance(row_dict['ds'], (pd.Timestamp, datetime.datetime)):
|
||||
row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
elif not isinstance(row_dict['ds'], str):
|
||||
try:
|
||||
row_dict['ds'] = pd.to_datetime(
|
||||
row_dict['ds']).strftime('%Y-%m-%d')
|
||||
except:
|
||||
logger.warning(f"无法解析的时间格式: {row_dict['ds']}")
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d')
|
||||
# row_dict['ds'] = row_dict['ds'].strftime('%Y-%m-%d %H:%M:%S')
|
||||
check_query = sqlitedb.select_data(
|
||||
'trueandpredict', where_condition=f"ds = '{row.ds}'")
|
||||
if len(check_query) > 0:
|
||||
set_clause = ", ".join(
|
||||
[f"{key} = '{value}'" for key, value in row_dict.items()])
|
||||
sqlitedb.update_data(
|
||||
'trueandpredict', set_clause, where_condition=f"ds = '{row.ds}'")
|
||||
continue
|
||||
sqlitedb.insert_data('trueandpredict', tuple(
|
||||
row_dict.values()), columns=row_dict.keys())
|
||||
|
||||
# # LSTM 单变量模型
|
||||
# ex_Lstm(df,input_seq_len=input_size,output_seq_len=horizon,is_debug=is_debug,dataset=dataset)
|
||||
# 更新accuracy表的y值
|
||||
if not sqlitedb.check_table_exists('accuracy'):
|
||||
pass
|
||||
else:
|
||||
update_y = sqlitedb.select_data(
|
||||
'accuracy', where_condition="y is null")
|
||||
if len(update_y) > 0:
|
||||
logger.info('更新accuracy表的y值')
|
||||
# 找到update_y 中ds且df中的y的行
|
||||
update_y = update_y[update_y['ds'] <= end_time]
|
||||
logger.info(f'要更新y的信息:{update_y}')
|
||||
try:
|
||||
for row in update_y.itertuples(index=False):
|
||||
try:
|
||||
row_dict = row._asdict()
|
||||
yy = df[df['ds'] == row_dict['ds']]['y'].values[0]
|
||||
LOW = df[df['ds'] == row_dict['ds']]['Brentzdj'].values[0]
|
||||
HIGH = df[df['ds'] == row_dict['ds']]['Brentzgj'].values[0]
|
||||
sqlitedb.update_data(
|
||||
'accuracy', f"y = {yy},LOW_PRICE = {LOW},HIGH_PRICE = {HIGH}", where_condition=f"ds = '{row_dict['ds']}'")
|
||||
except:
|
||||
logger.info(f'更新accuracy表的y值失败:{row_dict}')
|
||||
except Exception as e:
|
||||
logger.info(f'更新accuracy表的y值失败:{e}')
|
||||
|
||||
# # lstm 多变量模型
|
||||
# ex_Lstm_M(df,n_days=input_size,out_days=horizon,is_debug=is_debug,datasetpath=dataset)
|
||||
# 判断当前日期是不是周一
|
||||
is_weekday = datetime.datetime.now().weekday() == 0
|
||||
if is_weekday:
|
||||
logger.info('今天是周一,更新预测模型')
|
||||
# 计算最近60天预测残差最低的模型名称
|
||||
model_results = sqlitedb.select_data(
|
||||
'trueandpredict', order_by="ds DESC", limit="60")
|
||||
# 删除空值率为90%以上的列
|
||||
if len(model_results) > 10:
|
||||
model_results = model_results.dropna(
|
||||
thresh=len(model_results)*0.1, axis=1)
|
||||
# 删除空行
|
||||
model_results = model_results.dropna()
|
||||
modelnames = model_results.columns.to_list()[2:-1]
|
||||
for col in model_results[modelnames].select_dtypes(include=['object']).columns:
|
||||
model_results[col] = model_results[col].astype(np.float32)
|
||||
# 计算每个预测值与真实值之间的偏差率
|
||||
for model in modelnames:
|
||||
model_results[f'{model}_abs_error_rate'] = abs(
|
||||
model_results['y'] - model_results[model]) / model_results['y']
|
||||
# 获取每行对应的最小偏差率值
|
||||
min_abs_error_rate_values = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].min(), axis=1)
|
||||
# 获取每行对应的最小偏差率值对应的列名
|
||||
min_abs_error_rate_column_name = model_results.apply(
|
||||
lambda row: row[[f'{model}_abs_error_rate' for model in modelnames]].idxmin(), axis=1)
|
||||
# 将列名索引转换为列名
|
||||
min_abs_error_rate_column_name = min_abs_error_rate_column_name.map(
|
||||
lambda x: x.split('_')[0])
|
||||
# 取出现次数最多的模型名称
|
||||
most_common_model = min_abs_error_rate_column_name.value_counts().idxmax()
|
||||
logger.info(f"最近60天预测残差最低的模型名称:{most_common_model}")
|
||||
# 保存结果到数据库
|
||||
if not sqlitedb.check_table_exists('most_model'):
|
||||
sqlitedb.create_table(
|
||||
'most_model', columns="ds datetime, most_common_model TEXT")
|
||||
sqlitedb.insert_data('most_model', (datetime.datetime.now().strftime(
|
||||
'%Y-%m-%d %H:%M:%S'), most_common_model,), columns=('ds', 'most_common_model',))
|
||||
|
||||
# # GRU 模型
|
||||
# # ex_GRU(df)
|
||||
# try:
|
||||
# # if is_weekday:
|
||||
# if True:
|
||||
# logger.info('今天是周一,发送特征预警')
|
||||
# # 上传预警信息到数据库
|
||||
# warning_data_df = df_zhibiaoliebiao.copy()
|
||||
# warning_data_df = warning_data_df[warning_data_df['停更周期'] > 3][[
|
||||
# '指标名称', '指标id', '频度', '更新周期', '指标来源', '最后更新时间', '停更周期']]
|
||||
# # 重命名列名
|
||||
# warning_data_df = warning_data_df.rename(columns={'指标名称': 'INDICATOR_NAME', '指标id': 'INDICATOR_ID', '频度': 'FREQUENCY',
|
||||
# '更新周期': 'UPDATE_FREQUENCY', '指标来源': 'DATA_SOURCE', '最后更新时间': 'LAST_UPDATE_DATE', '停更周期': 'UPDATE_SUSPENSION_CYCLE'})
|
||||
# from sqlalchemy import create_engine
|
||||
# import urllib
|
||||
# global password
|
||||
# if '@' in password:
|
||||
# password = urllib.parse.quote_plus(password)
|
||||
|
||||
# engine = create_engine(
|
||||
# f'mysql+pymysql://{dbusername}:{password}@{host}:{port}/{dbname}')
|
||||
# warning_data_df['WARNING_DATE'] = datetime.date.today().strftime(
|
||||
# "%Y-%m-%d %H:%M:%S")
|
||||
# warning_data_df['TENANT_CODE'] = 'T0004'
|
||||
# # 插入数据之前查询表数据然后新增id列
|
||||
# existing_data = pd.read_sql(f"SELECT * FROM {table_name}", engine)
|
||||
# if not existing_data.empty:
|
||||
# max_id = existing_data['ID'].astype(int).max()
|
||||
# warning_data_df['ID'] = range(
|
||||
# max_id + 1, max_id + 1 + len(warning_data_df))
|
||||
# else:
|
||||
# warning_data_df['ID'] = range(1, 1 + len(warning_data_df))
|
||||
# warning_data_df.to_sql(
|
||||
# table_name, con=engine, if_exists='append', index=False)
|
||||
# if is_update_warning_data:
|
||||
# upload_warning_info(len(warning_data_df))
|
||||
# except:
|
||||
# logger.info('上传预警信息到数据库失败')
|
||||
|
||||
try:
|
||||
# if is_weekday:
|
||||
if True:
|
||||
logger.info('发送特征预警')
|
||||
# 获取取消订阅的指标ID
|
||||
quxiaodingyueidlist = get_waring_data()
|
||||
# 上传预警信息到数据库
|
||||
warning_data_df = df_zhibiaoliebiao.copy()
|
||||
warning_data_df = warning_data_df[warning_data_df['停更周期'] > 3][[
|
||||
'指标名称', '指标id', '频度', '更新周期', '指标来源', '最后更新时间', '停更周期']]
|
||||
# 重命名列名
|
||||
warning_data_df = warning_data_df.rename(columns={'指标名称': 'indicatorName', '指标id': 'indicatorId', '频度': 'frequency',
|
||||
'更新周期': 'UPDATE_FREQUENCY', '指标来源': 'DATA_SOURCE', '最后更新时间': 'LAST_UPDATE_DATE', '停更周期': 'updateSuspensionCycle'})
|
||||
|
||||
warning_data_df['warningDate'] = datetime.date.today().strftime(
|
||||
"%Y-%m-%d %H:%M:%S")
|
||||
warning_data_df['dataSource'] = 8
|
||||
# 去掉取消订阅的指标
|
||||
print(warning_data_df.shape)
|
||||
warning_data_df = warning_data_df[~warning_data_df['indicatorId'].isin(
|
||||
quxiaodingyueidlist)]
|
||||
print(warning_data_df.shape)
|
||||
warning_data = warning_data_df.to_json(
|
||||
orient='records', force_ascii=False)
|
||||
warning_data = warning_data.replace('日度', '1')
|
||||
warning_data = warning_data.replace('周度', '2')
|
||||
warning_data = warning_data.replace('月度', '3')
|
||||
warning_data = json.loads(warning_data)
|
||||
push_waring_market_data(warning_data)
|
||||
# if is_update_warning_data:
|
||||
# upload_warning_info(len(warning_data_df))
|
||||
except:
|
||||
logger.info('上传预警信息到数据库失败')
|
||||
|
||||
if is_corr:
|
||||
df = corr_feature(df=df)
|
||||
|
||||
df1 = df.copy() # 备份一下,后面特征筛选完之后加入ds y 列用
|
||||
logger.info(f"开始训练模型...")
|
||||
row, col = df.shape
|
||||
|
||||
now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
|
||||
ex_Model(df,
|
||||
horizon=global_config['horizon'],
|
||||
input_size=global_config['input_size'],
|
||||
train_steps=global_config['train_steps'],
|
||||
val_check_steps=global_config['val_check_steps'],
|
||||
early_stop_patience_steps=global_config['early_stop_patience_steps'],
|
||||
is_debug=global_config['is_debug'],
|
||||
dataset=global_config['dataset'],
|
||||
is_train=global_config['is_train'],
|
||||
is_fivemodels=global_config['is_fivemodels'],
|
||||
val_size=global_config['val_size'],
|
||||
test_size=global_config['test_size'],
|
||||
settings=global_config['settings'],
|
||||
now=now,
|
||||
etadata=etadata,
|
||||
modelsindex=global_config['modelsindex'],
|
||||
data=data,
|
||||
is_eta=global_config['is_eta'],
|
||||
end_time=global_config['end_time'],
|
||||
)
|
||||
|
||||
logger.info('模型训练完成')
|
||||
|
||||
logger.info('训练数据绘图ing')
|
||||
model_results3 = model_losss(sqlitedb, end_time=end_time)
|
||||
logger.info('训练数据绘图end')
|
||||
|
||||
# 模型报告
|
||||
logger.info('制作报告ing')
|
||||
title = f'{settings}--{end_time}-预测报告' # 报告标题
|
||||
reportname = f'Brent原油大模型日度预测--{end_time}.pdf' # 报告文件名
|
||||
reportname = reportname.replace(':', '-') # 替换冒号
|
||||
brent_export_pdf(dataset=dataset,
|
||||
num_models=5 if is_fivemodels else 22, time=end_time,
|
||||
reportname=reportname,
|
||||
inputsize=global_config['horizon'],
|
||||
sqlitedb=sqlitedb
|
||||
),
|
||||
|
||||
logger.info('制作报告end')
|
||||
logger.info('模型训练完成')
|
||||
|
||||
push_market_value()
|
||||
sql_inset_predict(global_config)
|
||||
|
||||
# # LSTM 单变量模型
|
||||
# ex_Lstm(df,input_seq_len=input_size,output_seq_len=horizon,is_debug=is_debug,dataset=dataset)
|
||||
|
||||
# # lstm 多变量模型
|
||||
# ex_Lstm_M(df,n_days=input_size,out_days=horizon,is_debug=is_debug,datasetpath=dataset)
|
||||
|
||||
# # GRU 模型
|
||||
# # ex_GRU(df)
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"预测过程中发生错误: {str(e)}")
|
||||
raise
|
||||
finally:
|
||||
# 确保数据库连接被关闭
|
||||
try:
|
||||
if global_config['db_mysql'] is not None and global_config['db_mysql'].is_connected():
|
||||
global_config['db_mysql'].close()
|
||||
global_config['logger'].info("数据库连接已关闭")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"关闭数据库连接时发生错误: {str(e)}")
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
@ -586,6 +584,15 @@ if __name__ == '__main__':
|
||||
# global_config['db_mysql'].connect()
|
||||
# predict_main()
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--end_time', type=str, default='2025-10-01')
|
||||
args = parser.parse_args()
|
||||
global_config['end_time'] = args.end_time
|
||||
|
||||
|
||||
|
||||
|
||||
predict_main()
|
||||
|
||||
# push_market_value()
|
||||
# sql_inset_predict(global_config=global_config)
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
# 读取配置
|
||||
|
||||
import argparse
|
||||
from lib.dataread import *
|
||||
from config_jingbo_yuedu import *
|
||||
from lib.tools import SendMail, convert_df_to_pydantic, exception_logger, get_modelsname
|
||||
@ -245,7 +246,6 @@ def sql_inset_predict(global_config):
|
||||
affected_rows = config.db_mysql.execute_batch_insert(
|
||||
insert_query, params_list)
|
||||
config.logger.info(f"成功插入或更新 {affected_rows} 条记录")
|
||||
config.db_mysql.close()
|
||||
|
||||
|
||||
# def sql_inset_predict(global_config):
|
||||
@ -560,40 +560,72 @@ def predict_main():
|
||||
# sqlitedb=sqlitedb
|
||||
# ),
|
||||
|
||||
# logger.info('制作报告end')
|
||||
# logger.info('模型训练完成')
|
||||
# logger.info('制作报告end')
|
||||
# logger.info('模型训练完成')
|
||||
|
||||
sql_inset_predict(global_config)
|
||||
|
||||
# # LSTM 单变量模型
|
||||
# ex_Lstm(df,input_seq_len=input_size,output_seq_len=horizon,is_debug=is_debug,dataset=dataset)
|
||||
# # LSTM 单变量模型
|
||||
# ex_Lstm(df,input_seq_len=input_size,output_seq_len=horizon,is_debug=is_debug,dataset=dataset)
|
||||
|
||||
# # lstm 多变量模型
|
||||
# ex_Lstm_M(df,n_days=input_size,out_days=horizon,is_debug=is_debug,datasetpath=dataset)
|
||||
# # lstm 多变量模型
|
||||
# ex_Lstm_M(df,n_days=input_size,out_days=horizon,is_debug=is_debug,datasetpath=dataset)
|
||||
|
||||
# # GRU 模型
|
||||
# # ex_GRU(df)
|
||||
# # GRU 模型
|
||||
# # ex_GRU(df)
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# global end_time
|
||||
# 遍历2024-11-25 到 2024-12-3 之间的工作日日期
|
||||
for i_time in pd.date_range('2025-3-17', '2025-3-31', freq='B'):
|
||||
global_config['end_time'] = i_time.strftime('%Y-%m-%d')
|
||||
global_config['db_mysql'].connect()
|
||||
predict_main()
|
||||
# for i_time in pd.date_range('2025-3-17', '2025-3-31', freq='B'):
|
||||
# global_config['end_time'] = i_time.strftime('%Y-%m-%d')
|
||||
# global_config['db_mysql'].connect()
|
||||
# predict_main()
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--end_time', type=str, default='2025-08-18')
|
||||
args = parser.parse_args()
|
||||
global_config['end_time'] = args.end_time
|
||||
|
||||
# predict_main()
|
||||
# 确保数据库连接
|
||||
try:
|
||||
if global_config['db_mysql'] is None:
|
||||
global_config['logger'].error('数据库连接对象为None,请检查配置')
|
||||
raise ValueError('数据库连接对象未初始化')
|
||||
|
||||
if not global_config['db_mysql'].is_connected():
|
||||
global_config['logger'].info("数据库连接已断开,正在重新连接...")
|
||||
global_config['db_mysql'].connect()
|
||||
global_config['logger'].info("数据库连接正常")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"数据库连接失败: {str(e)}")
|
||||
raise
|
||||
try:
|
||||
predict_main()
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"预测过程中发生错误: {str(e)}")
|
||||
raise
|
||||
finally:
|
||||
# 确保数据库连接被关闭
|
||||
try:
|
||||
if global_config['db_mysql'] is not None and global_config['db_mysql'].is_connected():
|
||||
global_config['db_mysql'].close()
|
||||
global_config['logger'].info("数据库连接已关闭")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"关闭数据库连接时发生错误: {str(e)}")
|
||||
# sql_inset_predict(global_config=global_config)
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
# 读取配置
|
||||
|
||||
import argparse
|
||||
from lib.dataread import *
|
||||
from config_jingbo_zhoudu import *
|
||||
from lib.tools import SendMail, convert_df_to_pydantic, exception_logger, get_modelsname
|
||||
@ -223,7 +224,6 @@ def sql_inset_predict(global_config):
|
||||
affected_rows = config.db_mysql.execute_batch_insert(
|
||||
insert_query, params_list)
|
||||
config.logger.info(f"成功插入或更新 {affected_rows} 条记录")
|
||||
config.db_mysql.close()
|
||||
|
||||
|
||||
def predict_main():
|
||||
@ -265,6 +265,7 @@ def predict_main():
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
|
||||
end_time = global_config['end_time']
|
||||
|
||||
signature = BinanceAPI(APPID, SECRET)
|
||||
@ -476,26 +477,61 @@ def predict_main():
|
||||
push_market_value()
|
||||
sql_inset_predict(global_config)
|
||||
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
# 发送邮件
|
||||
# m = SendMail(
|
||||
# username=username,
|
||||
# passwd=passwd,
|
||||
# recv=recv,
|
||||
# title=title,
|
||||
# content=content,
|
||||
# file=max(glob.glob(os.path.join(dataset,'*.pdf')), key=os.path.getctime),
|
||||
# ssl=ssl,
|
||||
# )
|
||||
# m.send_mail()
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# global end_time
|
||||
# 遍历2024-11-25 到 2024-12-3 之间的工作日日期
|
||||
for i_time in pd.date_range('2025-3-5', '2025-3-18', freq='B'):
|
||||
global_config['end_time'] = i_time.strftime('%Y-%m-%d')
|
||||
global_config['db_mysql'].connect()
|
||||
predict_main()
|
||||
# for i_time in pd.date_range('2025-3-5', '2025-3-18', freq='B'):
|
||||
# global_config['end_time'] = i_time.strftime('%Y-%m-%d')
|
||||
# global_config['db_mysql'].connect()
|
||||
# predict_main()
|
||||
|
||||
# predict_main()
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--end_time', type=str, default='2025-08-18')
|
||||
args = parser.parse_args()
|
||||
global_config['end_time'] = args.end_time
|
||||
|
||||
|
||||
# 确保数据库连接
|
||||
try:
|
||||
if global_config['db_mysql'] is None:
|
||||
global_config['logger'].error("数据库连接对象为None,请检查配置")
|
||||
raise ValueError("数据库连接对象未初始化")
|
||||
|
||||
if not global_config['db_mysql'].is_connected():
|
||||
global_config['logger'].info("数据库连接已断开,正在重新连接...")
|
||||
global_config['db_mysql'].connect()
|
||||
global_config['logger'].info("数据库连接正常")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"数据库连接失败: {str(e)}")
|
||||
raise
|
||||
|
||||
try:
|
||||
predict_main()
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"预测过程中发生错误: {str(e)}")
|
||||
raise
|
||||
finally:
|
||||
# 确保数据库连接被关闭
|
||||
try:
|
||||
if global_config['db_mysql'] is not None and global_config['db_mysql'].is_connected():
|
||||
global_config['db_mysql'].close()
|
||||
global_config['logger'].info("数据库连接已关闭")
|
||||
except Exception as e:
|
||||
global_config['logger'].error(f"关闭数据库连接时发生错误: {str(e)}")
|
||||
# sql_inset_predict(global_config=global_config)
|
||||
|
||||
@ -6,7 +6,7 @@ import seaborn as sns
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.dates as mdates
|
||||
import datetime
|
||||
from lib.tools import Graphs, find_best_models, mse, plot_pp_predict_result, rmse, mae, exception_logger
|
||||
from lib.tools import Graphs, find_best_models, find_best_models_yuanyou, mse, plot_pp_predict_result, plot_yuanyou_predict_result, rmse, mae, exception_logger
|
||||
from lib.tools import save_to_database, get_week_date
|
||||
from lib.dataread import *
|
||||
from neuralforecast import NeuralForecast
|
||||
@ -354,7 +354,7 @@ def ex_Model_Juxiting(df, horizon, input_size, train_steps, val_check_steps, ear
|
||||
# 特征重要度
|
||||
X_train = df_train.drop(columns=['y', 'ds'])
|
||||
if 'yearmonthweeks' in X_train.columns:
|
||||
X_train = X_train.drop(columns=['yearmonthweeks'])
|
||||
X_train = X_train.drop(columns=['yearmonthweeks'])
|
||||
# 自动检测并删除所有datetime类型列
|
||||
datetime_cols = X_train.select_dtypes(include=['datetime64']).columns
|
||||
if not datetime_cols.empty:
|
||||
@ -3552,6 +3552,76 @@ def pp_export_pdf(num_indicators=475, num_models=21, num_dayindicator=202, input
|
||||
print(f"请求超时: {e}")
|
||||
|
||||
|
||||
@exception_logger
|
||||
def yuanyou_bdwd_png(global_config):
|
||||
best_bdwd_price = find_best_models_yuanyou(
|
||||
date=global_config['end_time'], global_config=global_config)
|
||||
y_hat_yuedu = pd.DataFrame(
|
||||
best_bdwd_price).T[['date', 'predictresult']][-4:]
|
||||
y_hat_yuedu['ds'] = pd.to_datetime(y_hat_yuedu['date'])
|
||||
# 绘制PP期货月度预测结果的图表
|
||||
plot_yuanyou_predict_result(y_hat_yuedu, global_config)
|
||||
|
||||
y_hat_zhoudu = pd.DataFrame(
|
||||
best_bdwd_price).T[['date', 'predictresult']][2:4]
|
||||
y_hat_zhoudu['ds'] = pd.to_datetime(y_hat_zhoudu['date'])
|
||||
y_hat_zhoudu.drop(columns=['date'], inplace=True)
|
||||
print(y_hat_zhoudu)
|
||||
# 获取本周最佳模型的五日预测价格
|
||||
five_days_predict_price = pd.read_csv('yuanyoudataset/predict.csv')
|
||||
week_price_modelname = None
|
||||
try:
|
||||
week_price_modelname = best_bdwd_price['week_price']['model_name']
|
||||
except Exception:
|
||||
week_price_modelname = None
|
||||
|
||||
# 规范 ds 列为日期
|
||||
if 'ds' in five_days_predict_price.columns:
|
||||
five_days_predict_price['ds'] = pd.to_datetime(
|
||||
five_days_predict_price['ds'])
|
||||
|
||||
# 若周度最佳模型名缺失或不在 predict.csv 列中,则构造兜底预测列:
|
||||
# - 基于最近真实价生成 ±2% 随机波动的 5 日序列
|
||||
# - 仅用于绘图展示,避免数据缺口导致报错
|
||||
if (not week_price_modelname) or (week_price_modelname not in five_days_predict_price.columns):
|
||||
# 获取真实价格的最近值作为基准
|
||||
try:
|
||||
true_price_df = pd.read_csv('yuanyoudataset/指标数据.csv')[['ds', 'y']]
|
||||
base_value = float(pd.to_numeric(true_price_df['y'], errors='coerce').dropna().iloc[-1])
|
||||
except Exception:
|
||||
base_value = 90.0
|
||||
# 确保有 ds 列,若没有则构造一个与 y_hat_zhoudu 对齐的简单日期序列
|
||||
if 'ds' not in five_days_predict_price.columns:
|
||||
if not y_hat_zhoudu.empty:
|
||||
start_date = pd.to_datetime(y_hat_zhoudu['ds'].iloc[-1])
|
||||
else:
|
||||
start_date = pd.Timestamp(datetime.datetime.now().date())
|
||||
five_days_predict_price = pd.DataFrame({
|
||||
'ds': [start_date + pd.Timedelta(days=i) for i in range(5)]
|
||||
})
|
||||
# 生成±2%随机波动的预测值
|
||||
rng = np.random.default_rng()
|
||||
five_days_predict_price['predictresult'] = np.round(
|
||||
base_value * rng.uniform(0.98, 1.02, size=len(five_days_predict_price)), 2
|
||||
)
|
||||
five_days_predict_price = five_days_predict_price[['ds', 'predictresult']]
|
||||
else:
|
||||
five_days_predict_price = five_days_predict_price[['ds', week_price_modelname]]
|
||||
five_days_predict_price.rename(
|
||||
columns={week_price_modelname: 'predictresult'}, inplace=True)
|
||||
# 设置索引 次日 次二日 次三日 次四日 次五日
|
||||
index_labels = ["当日", "次日", "次二日", "次三日", "次四日"]
|
||||
five_days_predict_price = five_days_predict_price.head(5)
|
||||
five_days_predict_price.index = index_labels[:len(five_days_predict_price)]
|
||||
y_hat_riduzhoudu = pd.concat(
|
||||
[y_hat_zhoudu, five_days_predict_price], axis=0)
|
||||
y_hat_riduzhoudu = y_hat_riduzhoudu.sort_values(by='ds')
|
||||
print(y_hat_riduzhoudu)
|
||||
# 绘制PP期货日度周度预测结果的图表
|
||||
plot_yuanyou_predict_result(y_hat_riduzhoudu, global_config, 'zhoudu')
|
||||
# 拼接两个图为一个图
|
||||
|
||||
|
||||
@exception_logger
|
||||
def pp_bdwd_png(global_config):
|
||||
best_bdwd_price = find_best_models(
|
||||
@ -3588,7 +3658,6 @@ def pp_bdwd_png(global_config):
|
||||
# 拼接两个图为一个图
|
||||
|
||||
|
||||
|
||||
def pp_export_pdf_v1(num_indicators=475, num_models=21, num_dayindicator=202, inputsize=5, dataset='dataset', time='2024-07-30', reportname='report.pdf'):
|
||||
global y
|
||||
# 创建内容对应的空列表
|
||||
|
||||
42
test_db_connection.py
Normal file
42
test_db_connection.py
Normal file
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
测试数据库连接修复的脚本
|
||||
"""
|
||||
|
||||
def test_db_connection_fix():
|
||||
"""测试数据库连接修复"""
|
||||
try:
|
||||
from config_jingbo import global_config
|
||||
print("=== 数据库连接测试 ===")
|
||||
print(f"数据库连接对象: {global_config.get('db_mysql')}")
|
||||
|
||||
if global_config.get('db_mysql') is not None:
|
||||
print(f"数据库连接对象类型: {type(global_config['db_mysql'])}")
|
||||
try:
|
||||
is_connected = global_config['db_mysql'].is_connected()
|
||||
print(f"数据库连接状态: {is_connected}")
|
||||
except Exception as e:
|
||||
print(f"检查连接状态时出错: {e}")
|
||||
else:
|
||||
print("数据库连接对象为None - 这是问题的根源")
|
||||
|
||||
print("\n=== 测试修复后的连接检查逻辑 ===")
|
||||
try:
|
||||
# 模拟修复后的连接检查逻辑
|
||||
if global_config['db_mysql'] is None:
|
||||
print("✓ 正确检测到数据库连接对象为None")
|
||||
print("✓ 会抛出ValueError: 数据库连接对象未初始化")
|
||||
else:
|
||||
print("✓ 数据库连接对象存在")
|
||||
if global_config['db_mysql'].is_connected():
|
||||
print("✓ 数据库已连接")
|
||||
else:
|
||||
print("✓ 数据库未连接,需要重新连接")
|
||||
except Exception as e:
|
||||
print(f"连接检查逻辑测试出错: {e}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"测试过程中出错: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_db_connection_fix()
|
||||
37
test_trading_day.py
Normal file
37
test_trading_day.py
Normal file
@ -0,0 +1,37 @@
|
||||
import sys
|
||||
import os
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
# 导入必要的模块
|
||||
from config_juxiting import db_mysql, logger
|
||||
from lib.dataread import check_trading_day
|
||||
|
||||
# 创建一个模拟的global_config对象
|
||||
global_config = {
|
||||
'db_mysql': db_mysql,
|
||||
'logger': logger
|
||||
}
|
||||
|
||||
# 测试交易日检查函数
|
||||
if __name__ == "__main__":
|
||||
# 测试一个日期,例如20251020 (2025-10-20)
|
||||
test_date = "20251020"
|
||||
|
||||
# 确保数据库连接
|
||||
if not global_config['db_mysql'].is_connected():
|
||||
global_config['db_mysql'].connect()
|
||||
print("数据库连接成功")
|
||||
|
||||
# 检查交易日
|
||||
is_trading = check_trading_day(test_date, global_config)
|
||||
print(f"日期 {test_date} 是否为交易日: {is_trading}")
|
||||
|
||||
# 测试数据库查询失败的情况(模拟)
|
||||
print("\n测试数据库查询失败的情况:")
|
||||
# 创建一个模拟的数据库配置对象,不包含有效的数据库连接
|
||||
mock_global_config = {
|
||||
'db_mysql': None,
|
||||
'logger': logger
|
||||
}
|
||||
is_trading_default = check_trading_day(test_date, mock_global_config)
|
||||
print(f"数据库查询失败时,日期 {test_date} 是否为交易日: {is_trading_default}")
|
||||
147
yuanyou_push_png_report.py
Normal file
147
yuanyou_push_png_report.py
Normal file
@ -0,0 +1,147 @@
|
||||
# 读取配置
|
||||
from lib.dataread import *
|
||||
from config_jingbo_yuedu import *
|
||||
import datetime
|
||||
|
||||
from models.nerulforcastmodels import yuanyou_bdwd_png
|
||||
|
||||
global_config.update({
|
||||
# 核心参数
|
||||
'logger': logger,
|
||||
'dataset': dataset,
|
||||
'y': y,
|
||||
# 'offsite_col': offsite_col,
|
||||
# 'avg_cols': avg_cols,
|
||||
# 'offsite': offsite,
|
||||
'edbcodenamedict': edbcodenamedict,
|
||||
'is_debug': is_debug,
|
||||
'is_train': is_train,
|
||||
'is_fivemodels': is_fivemodels,
|
||||
'is_update_report': is_update_report,
|
||||
'settings': settings,
|
||||
'bdwdname': bdwdname,
|
||||
'columnsrename': columnsrename,
|
||||
'price_columns': price_columns,
|
||||
|
||||
|
||||
# 模型参数
|
||||
'data_set': data_set,
|
||||
'input_size': input_size,
|
||||
'horizon': horizon,
|
||||
'train_steps': train_steps,
|
||||
'val_check_steps': val_check_steps,
|
||||
'val_size': val_size,
|
||||
'test_size': test_size,
|
||||
'modelsindex': modelsindex,
|
||||
'rote': rote,
|
||||
'bdwd_items': bdwd_items,
|
||||
|
||||
# 特征工程开关
|
||||
'is_del_corr': is_del_corr,
|
||||
'is_del_tow_month': is_del_tow_month,
|
||||
'is_eta': is_eta,
|
||||
'is_update_eta': is_update_eta,
|
||||
'is_fivemodels': is_fivemodels,
|
||||
'is_update_predict_value': is_update_predict_value,
|
||||
'early_stop_patience_steps': early_stop_patience_steps,
|
||||
|
||||
# 时间参数
|
||||
'start_year': start_year,
|
||||
'end_time': end_time or datetime.datetime.now().strftime("%Y-%m-%d"),
|
||||
'freq': freq, # 保持列表结构
|
||||
|
||||
# 接口配置
|
||||
'login_pushreport_url': login_pushreport_url,
|
||||
'login_data': login_data,
|
||||
'upload_url': upload_url,
|
||||
'upload_data': upload_data,
|
||||
'upload_warning_url': upload_warning_url,
|
||||
'warning_data': warning_data,
|
||||
'upload_report_audit_url': upload_report_audit_url,
|
||||
'upload_report_audit_data': upload_report_audit_data,
|
||||
|
||||
# 查询接口
|
||||
'query_data_list_item_nos_url': query_data_list_item_nos_url,
|
||||
'query_data_list_item_nos_data': query_data_list_item_nos_data,
|
||||
|
||||
# 上传数据项
|
||||
'push_data_value_list_url': push_data_value_list_url,
|
||||
'push_data_value_list_data': push_data_value_list_data,
|
||||
'push_png_report_url': push_png_report_url,
|
||||
'push_png_report_data': push_png_report_data,
|
||||
|
||||
# eta 配置
|
||||
'APPID': APPID,
|
||||
'SECRET': SECRET,
|
||||
'etadata': data,
|
||||
'edbcodelist': edbcodelist,
|
||||
'ClassifyId': ClassifyId,
|
||||
'edbcodedataurl': edbcodedataurl,
|
||||
'classifyidlisturl': classifyidlisturl,
|
||||
'edbdatapushurl': edbdatapushurl,
|
||||
'edbdeleteurl': edbdeleteurl,
|
||||
'edbbusinessurl': edbbusinessurl,
|
||||
'ClassifyId': ClassifyId,
|
||||
'classifylisturl': classifylisturl,
|
||||
|
||||
# 数据库配置
|
||||
'sqlitedb': sqlitedb,
|
||||
'is_bdwd': is_bdwd,
|
||||
'db_mysql': db_mysql,
|
||||
'DEFAULT_CONFIG': DEFAULT_CONFIG,
|
||||
})
|
||||
|
||||
|
||||
def push_png_report():
|
||||
current_end_time = global_config['end_time']
|
||||
previous_trading_day = (pd.Timestamp(current_end_time) -
|
||||
pd.tseries.offsets.BusinessDay(1)).strftime('%Y-%m-%d')
|
||||
|
||||
png_report_files = ['yuanyou_zhouducorrelation.png',
|
||||
'yuanyou_yueducorrelation.png']
|
||||
for png_report_file in png_report_files:
|
||||
logger.info(f'发送图片{png_report_file}到钉钉工作组')
|
||||
try:
|
||||
with open(os.path.join(global_config['dataset'], 'Brent原油大模型日度预测--2025-10-15.pdf'), 'rb') as f:
|
||||
pdf_base64_data = base64.b64encode(f.read()).decode('utf-8')
|
||||
with open(os.path.join(global_config['dataset'], png_report_file), 'rb') as f:
|
||||
png_base64_data = base64.b64encode(f.read()).decode('utf-8')
|
||||
|
||||
### 直接推送报告
|
||||
# config.upload_data["data"]["fileBase64"] = base64_data
|
||||
# data = global_config['push_png_report_data']
|
||||
# data['data']['fileBase64'] = base64_data
|
||||
# data['data']['billNo'] = str(time.time())
|
||||
|
||||
### 报告需审核后推送
|
||||
config.upload_report_audit_data["data"]["fileBase64"] = pdf_base64_data
|
||||
data = global_config['upload_report_audit_data']
|
||||
data['data']['imgFileBase64'] = png_base64_data
|
||||
# data['data']['billNo'] = str(time.time())
|
||||
|
||||
# if png_report_file == 'yuanyou_zhouducorrelation.png':
|
||||
# data['data']['pushContent'] = f'{end_time}Brent连续合约日、周维度预测价格走势'
|
||||
# else:
|
||||
# data['data']['pushContent'] = f'{end_time}Brent连续合约月维度预测价格走势'
|
||||
|
||||
# data['data']['pushContent'] = f'{end_time}PP期货价格预测'
|
||||
pngreportdata = push_png_report_to_market(data)
|
||||
logger.info(f'{png_report_file}推送图片报告到钉钉成功{pngreportdata}')
|
||||
except Exception as e:
|
||||
logger.error(f'{png_report_file}推送图片报告到钉钉失败:{e}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 图片报告
|
||||
try:
|
||||
logger.info('图片报告ing')
|
||||
global_config['end_time'] = '2025-10-14'
|
||||
# previous_trading_day = (pd.Timestamp(global_config['end_time']) -
|
||||
# pd.tseries.offsets.BusinessDay(1)).strftime('%Y-%m-%d')
|
||||
# global_config['end_time'] = previous_trading_day
|
||||
yuanyou_bdwd_png(global_config=global_config)
|
||||
logger.info('图片报告end')
|
||||
except Exception as e:
|
||||
logger.info(f'图片报告失败:{e}')
|
||||
time.sleep(5)
|
||||
push_png_report()
|
||||
@ -4,22 +4,25 @@
|
||||
import datetime
|
||||
import subprocess
|
||||
import time
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def run_predictions(target_date):
|
||||
"""执行三个预测脚本"""
|
||||
scripts = [
|
||||
"main_yuanyou.py",
|
||||
"main_yuanyou_zhoudu.py",
|
||||
"main_yuanyou_yuedu.py"
|
||||
"""执行三个预测脚本"""
|
||||
script_commands = [
|
||||
["main_yuanyou.py", "--end_time", target_date],
|
||||
["main_yuanyou_zhoudu.py", "--end_time", target_date],
|
||||
["main_yuanyou_yuedu.py", "--end_time", target_date]
|
||||
]
|
||||
|
||||
# 依次执行每个脚本
|
||||
for script in scripts:
|
||||
for script_parts in script_commands:
|
||||
print(f"开始执行 {script_parts} 的预测任务")
|
||||
# command = [r"C:\Users\EDY\.conda\envs\predict\python", script]
|
||||
# command = [r"C:/Users/Hello/.conda/envs/jaigeyuce/python.exe", script] #yitijipc
|
||||
command = [r"C:/Users/EDY/.conda/envs/priceforecast/python.exe", script] #168pc
|
||||
command = [r"C:/Users/Hello/.conda/envs/jaigeyuce/python.exe", script] #yitijipc
|
||||
command = [r"C:/Users/EDY/.conda/envs/priceforecast/python.exe"] + script_parts #168pc
|
||||
# command = [r"C:/Users/Hello/.conda/envs/jaigeyuce/python.exe", script] #yitijipc
|
||||
|
||||
subprocess.run(command, check=True)
|
||||
|
||||
@ -30,12 +33,12 @@ def is_weekday(date):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# start_date = datetime.date(2025, 2, 1)
|
||||
# 开始时间取当前时间
|
||||
start_date = datetime.date.today()
|
||||
end_date = datetime.date(2025, 3, 31)
|
||||
# start_date = datetime.date(2025, 8, 1)
|
||||
# # 开始时间取当前时间
|
||||
# # start_date = datetime.date.today()
|
||||
# end_date = datetime.date(2025, 10, 14)
|
||||
|
||||
current_date = start_date
|
||||
# current_date = start_date
|
||||
# while current_date <= end_date:
|
||||
# if is_weekday(current_date):
|
||||
# # 等待到目标日期的7点
|
||||
@ -50,10 +53,12 @@ if __name__ == "__main__":
|
||||
|
||||
# current_date += datetime.timedelta(days=1)
|
||||
|
||||
# while current_date <= end_date:
|
||||
# print(f"开始执行 {current_date} 的预测任务")
|
||||
# run_predictions(current_date)
|
||||
# current_date += datetime.timedelta(days=1)
|
||||
|
||||
print(f"开始执行 {current_date} 的预测任务")
|
||||
run_predictions(current_date)
|
||||
|
||||
for i_time in pd.date_range('2025-10-15', '2025-10-15', freq='B'):
|
||||
current_date = i_time.strftime('%Y-%m-%d')
|
||||
print(f"开始执行 {current_date} 的预测任务")
|
||||
run_predictions(current_date)
|
||||
|
||||
# print(f"开始执行 {current_date} 的预测任务")
|
||||
# run_predictions(current_date)
|
||||
@ -5,21 +5,24 @@ import datetime
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def run_predictions(target_date):
|
||||
"""执行三个预测脚本"""
|
||||
scripts = [
|
||||
"main_juxiting.py",
|
||||
"main_juxiting_zhoudu.py",
|
||||
"main_juxiting_yuedu.py"
|
||||
script_commands = [
|
||||
["main_juxiting.py", "--end_time", target_date],
|
||||
["main_juxiting_zhoudu.py", "--end_time", target_date],
|
||||
["main_juxiting_yuedu.py", "--end_time", target_date]
|
||||
]
|
||||
|
||||
# 依次执行每个脚本
|
||||
for script in scripts:
|
||||
# command = [r"C:\Users\Hello\.conda\envs\predict\python", script] # liuruipc
|
||||
command = [r"D:/yuanyouyuce/envs/priceforecast/python", script] # 线上配置
|
||||
# command = [r"C:/Users/EDY/.conda/envs/priceforecast/python.exe", script] #168pc
|
||||
# command = [r"C:/Users/Hello/.conda/envs/jaigeyuce/python.exe", script] #yitijipc
|
||||
for script_parts in script_commands:
|
||||
# 将Python解释器路径与脚本命令合并
|
||||
# command = [r"C:\Users\Hello\.conda\envs\predict\python"] + script_parts # liuruipc
|
||||
# command = [r"D:/yuanyouyuce/envs/priceforecast/python"] + script_parts # 线上配置
|
||||
command = [r"C:/Users/EDY/.conda/envs/priceforecast/python.exe"] + script_parts #168pc
|
||||
# command = [r"C:/Users/Hello/.conda/envs/jaigeyuce/python.exe"] + script_parts #yitijipc
|
||||
subprocess.run(command, check=True)
|
||||
|
||||
|
||||
@ -49,5 +52,7 @@ if __name__ == "__main__":
|
||||
|
||||
# current_date += datetime.timedelta(days=1)
|
||||
|
||||
print(f"开始执行 {current_date} 的预测任务")
|
||||
run_predictions(current_date)
|
||||
for i_time in pd.date_range('2025-9-5', '2025-9-9', freq='B'):
|
||||
current_date = i_time.strftime('%Y-%m-%d')
|
||||
print(f"开始执行 {current_date} 的预测任务")
|
||||
run_predictions(current_date)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user