ep-sdk-4pd 3.0.0.dev0__tar.gz → 3.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/PKG-INFO +1 -1
- ep_sdk_4pd-3.0.1/ep_sdk_4pd/__init__.py +1 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/ep_sdk_4pd/ep_data.py +14 -4
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/ep_sdk_4pd/ep_system.py +3 -3
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/ep_sdk_4pd/models.py +6 -2
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/ep_sdk_4pd.egg-info/PKG-INFO +1 -1
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/ep_sdk_4pd.egg-info/SOURCES.txt +1 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/setup.py +1 -1
- ep_sdk_4pd-3.0.1/tests/test.py +498 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/tests/test_predict_data.py +1 -3
- ep_sdk_4pd-3.0.0.dev0/ep_sdk_4pd/__init__.py +0 -1
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/README.md +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/ep_sdk_4pd.egg-info/dependency_links.txt +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/ep_sdk_4pd.egg-info/requires.txt +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/ep_sdk_4pd.egg-info/top_level.txt +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/setup.cfg +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/tests/test_call_train_done.py +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/tests/test_get_run_strategy.py +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/tests/test_get_system_date.py +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/tests/test_history_data.py +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1}/tests/test_model_output_dir.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ep_sdk_4pd
|
3
|
-
Version: 3.0.
|
3
|
+
Version: 3.0.1
|
4
4
|
Summary: 4paradigm Electricity Platform Service SDK Library for Python
|
5
5
|
Home-page: https://gitlab.4pd.io/electricityproject/electricity-platform-sdk
|
6
6
|
Author: 4paradigm Electricity Platform SDK
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = '3.0.1'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import json
|
2
|
+
import os
|
2
3
|
from datetime import timedelta, datetime
|
3
4
|
|
4
5
|
import requests
|
@@ -8,13 +9,13 @@ from ep_sdk_4pd.ep_system import EpSystem
|
|
8
9
|
from ep_sdk_4pd.models import HistoryDataRequest, PredictDataRequest
|
9
10
|
|
10
11
|
# test 地址
|
11
|
-
endpoint = 'http://172.27.88.56:6001'
|
12
|
+
# endpoint = 'http://172.27.88.56:6001'
|
12
13
|
|
13
14
|
# prod 地址
|
14
15
|
# endpoint = 'http://172.27.88.56:6601'
|
15
16
|
|
16
17
|
# 外网 地址
|
17
|
-
|
18
|
+
endpoint = 'http://82.157.231.254:6001'
|
18
19
|
|
19
20
|
Authorization = 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJlbGVjdHJpY2l0eS1wbGF0Zm9ybSIsInN1YiI6IjEyMyIsImlhdCI6MTc0NjYwNjQ4NSwianRpIjoiMTIzXzE3NDY1Nzc2ODUxNDYiLCJ0eXBlIjoiYWNjZXNzIn0.Clrz_8j3aJlXTWPX-4DS0NxXN9idTcUIc0AtXOMIjd8'
|
20
21
|
|
@@ -31,10 +32,13 @@ class EpData:
|
|
31
32
|
calculated_date = datetime.strptime(date_str, "%Y-%m-%d")
|
32
33
|
system_date = calculated_date.strftime("%Y-%m-%d") # 转换回字符串
|
33
34
|
|
35
|
+
strategy_id = os.getenv('STRATEGY_ID')
|
36
|
+
|
34
37
|
request = HistoryDataRequest(
|
35
38
|
scope=scope,
|
36
39
|
system_date=system_date,
|
37
40
|
days=days,
|
41
|
+
strategy_id=int(strategy_id)
|
38
42
|
)
|
39
43
|
response = EpData.history_data(request=request)
|
40
44
|
|
@@ -57,7 +61,8 @@ class EpData:
|
|
57
61
|
payload = {
|
58
62
|
'scope': request.scope,
|
59
63
|
'system_date': request.system_date,
|
60
|
-
'days': request.days
|
64
|
+
'days': request.days,
|
65
|
+
'strategy_id': request.strategy_id
|
61
66
|
}
|
62
67
|
|
63
68
|
response = requests.request(
|
@@ -88,9 +93,13 @@ class EpData:
|
|
88
93
|
# if is_test:
|
89
94
|
# system_date = test_time
|
90
95
|
|
96
|
+
# strategy_id = os.getenv('STRATEGY_ID')
|
97
|
+
strategy_id = 41
|
98
|
+
|
91
99
|
request = PredictDataRequest(
|
92
100
|
scope=scope,
|
93
101
|
system_date=system_date,
|
102
|
+
strategy_id=int(strategy_id)
|
94
103
|
)
|
95
104
|
response = EpData.predict_data(request=request)
|
96
105
|
|
@@ -112,7 +121,8 @@ class EpData:
|
|
112
121
|
|
113
122
|
payload = {
|
114
123
|
'scope': request.scope,
|
115
|
-
'system_date': request.system_date
|
124
|
+
'system_date': request.system_date,
|
125
|
+
'strategy_id': request.strategy_id
|
116
126
|
}
|
117
127
|
|
118
128
|
response = requests.request(
|
@@ -12,13 +12,13 @@ from ep_sdk_4pd import models as ep_sdk_4pd_models
|
|
12
12
|
from ep_sdk_4pd.models import RunStrategyRequest, CallTrainDoneRequest, RsaKeyRequest
|
13
13
|
|
14
14
|
# test 地址
|
15
|
-
endpoint = 'http://172.27.88.56:6001'
|
15
|
+
# endpoint = 'http://172.27.88.56:6001'
|
16
16
|
|
17
17
|
# prod 地址
|
18
18
|
# endpoint = 'http://172.27.88.56:6601'
|
19
19
|
|
20
20
|
# 外网 地址
|
21
|
-
|
21
|
+
endpoint = 'http://82.157.231.254:6001'
|
22
22
|
|
23
23
|
Authorization = 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJlbGVjdHJpY2l0eS1wbGF0Zm9ybSIsInN1YiI6IjEyMyIsImlhdCI6MTc0NjYwNjQ4NSwianRpIjoiMTIzXzE3NDY1Nzc2ODUxNDYiLCJ0eXBlIjoiYWNjZXNzIn0.Clrz_8j3aJlXTWPX-4DS0NxXN9idTcUIc0AtXOMIjd8'
|
24
24
|
|
@@ -85,7 +85,7 @@ class EpSystem:
|
|
85
85
|
# 线下环境
|
86
86
|
system_date = "2024-12-31"
|
87
87
|
|
88
|
-
return
|
88
|
+
return "2025-04-12"
|
89
89
|
|
90
90
|
@staticmethod
|
91
91
|
def get_run_strategy(is_online: bool = True):
|
@@ -31,17 +31,19 @@ class HistoryDataRequest(BaseRequest):
|
|
31
31
|
特别注意:get_history_data 或 get_predict_data 会get_system_date进行检测,不可获取system_date以后得数据,避免数据穿越现象
|
32
32
|
"""
|
33
33
|
|
34
|
-
def __init__(self, scope: str = None, system_date: str = None, days: int = None):
|
34
|
+
def __init__(self, scope: str = None, system_date: str = None, days: int = None, strategy_id: int = None):
|
35
35
|
"""
|
36
36
|
Args:
|
37
37
|
scope: "weather","plant","market"
|
38
38
|
system_date: 系统时间
|
39
39
|
days: 表示systemDate之前days的数据
|
40
|
+
strategy_id
|
40
41
|
"""
|
41
42
|
|
42
43
|
self.scope = scope
|
43
44
|
self.system_date = system_date
|
44
45
|
self.days = days
|
46
|
+
self.strategy_id = strategy_id
|
45
47
|
|
46
48
|
super().__init__()
|
47
49
|
self.api = f'/ep/api/sdk/get_history_data'
|
@@ -69,15 +71,17 @@ class PredictDataRequest(BaseRequest):
|
|
69
71
|
获取当前系统时间的预测数据(按照抓取时间,最晚时间为当前系统时间的d-1
|
70
72
|
"""
|
71
73
|
|
72
|
-
def __init__(self, scope: str = None, system_date: str = None):
|
74
|
+
def __init__(self, scope: str = None, system_date: str = None, strategy_id: int = None):
|
73
75
|
"""
|
74
76
|
Args:
|
75
77
|
scope: "weather","market"
|
76
78
|
system_date: 系统时间
|
79
|
+
strategy_id
|
77
80
|
"""
|
78
81
|
|
79
82
|
self.scope = scope
|
80
83
|
self.system_date = system_date
|
84
|
+
self.strategy_id = strategy_id
|
81
85
|
|
82
86
|
super().__init__()
|
83
87
|
self.api = f'/ep/api/sdk/get_predict_data'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ep_sdk_4pd
|
3
|
-
Version: 3.0.
|
3
|
+
Version: 3.0.1
|
4
4
|
Summary: 4paradigm Electricity Platform Service SDK Library for Python
|
5
5
|
Home-page: https://gitlab.4pd.io/electricityproject/electricity-platform-sdk
|
6
6
|
Author: 4paradigm Electricity Platform SDK
|
@@ -8,7 +8,7 @@ DESCRIPTION = '4paradigm Electricity Platform Service SDK Library for Python'
|
|
8
8
|
AUTHOR = '4paradigm Electricity Platform SDK'
|
9
9
|
AUTHOR_EMAIL = ''
|
10
10
|
URL = 'https://gitlab.4pd.io/electricityproject/electricity-platform-sdk'
|
11
|
-
VERSION = '3.0.
|
11
|
+
VERSION = '3.0.1'
|
12
12
|
REQUIRES = ['requests']
|
13
13
|
|
14
14
|
LONG_DESCRIPTION = ''
|
@@ -0,0 +1,498 @@
|
|
1
|
+
import datetime
|
2
|
+
import pickle
|
3
|
+
import requests
|
4
|
+
import os
|
5
|
+
|
6
|
+
import lightgbm as lgb
|
7
|
+
import numpy as np
|
8
|
+
import pandas as pd
|
9
|
+
import holidays
|
10
|
+
import tempfile
|
11
|
+
#
|
12
|
+
#
|
13
|
+
from ep_sdk_4pd.ep_system import EpSystem
|
14
|
+
from ep_sdk_4pd.ep_data import EpData
|
15
|
+
|
16
|
+
|
17
|
+
#
|
18
|
+
|
19
|
+
|
20
|
+
def simple_reg_price_step(train, train_label, times=1, cate_fea=[], lr=0.3, steps=500):
|
21
|
+
EARLY_STOP_ROUNDS = 50
|
22
|
+
#
|
23
|
+
# lr = 0.3
|
24
|
+
#
|
25
|
+
model_list = []
|
26
|
+
#
|
27
|
+
for i in range(times):
|
28
|
+
dtrain = lgb.Dataset(train, train_label, categorical_feature=cate_fea, free_raw_data=False)
|
29
|
+
# dval = lgb.Dataset(test,test_label, categorical_feature=cate_fea,reference = dtrain,free_raw_data=False)
|
30
|
+
#
|
31
|
+
params = {
|
32
|
+
# "min_data_in_bin": 5,
|
33
|
+
#
|
34
|
+
'num_leaves': 5,
|
35
|
+
'min_data_in_leaf': 40,
|
36
|
+
'objective': 'regression',
|
37
|
+
'max_depth': 4,
|
38
|
+
'learning_rate': lr,
|
39
|
+
"boosting": "gbdt",
|
40
|
+
"feature_fraction": 0.4,
|
41
|
+
"bagging_fraction": 0.2,
|
42
|
+
"bagging_freq": 1,
|
43
|
+
"bagging_seed": 1,
|
44
|
+
"metric": 'mse',
|
45
|
+
"lambda_l1": 0.01,
|
46
|
+
"lambda_l2": 0.01,
|
47
|
+
"random_state": 1022 + i,
|
48
|
+
"num_threads": -1,
|
49
|
+
'verbose': 1,
|
50
|
+
#
|
51
|
+
'early_stopping_round': EARLY_STOP_ROUNDS,
|
52
|
+
'verbose_eval': 10,
|
53
|
+
}
|
54
|
+
model = lgb.train(
|
55
|
+
params,
|
56
|
+
dtrain,
|
57
|
+
num_boost_round=steps,
|
58
|
+
# feval=calc_wauc,
|
59
|
+
valid_sets=[dtrain],
|
60
|
+
# verbose_eval=10,
|
61
|
+
# early_stopping_rounds=EARLY_STOP_ROUNDS
|
62
|
+
)
|
63
|
+
model_list.append(model)
|
64
|
+
#
|
65
|
+
# meta_prob = None
|
66
|
+
# meta_prob = np.zeros(len(test_label))
|
67
|
+
# for m in model_list:
|
68
|
+
# meta_prob += m.predict(test)
|
69
|
+
# meta_prob /= len(model_list)
|
70
|
+
|
71
|
+
return model_list[0]
|
72
|
+
|
73
|
+
|
74
|
+
#
|
75
|
+
|
76
|
+
|
77
|
+
def get_data_label(market, power, weather=None, istrain=True):
|
78
|
+
#
|
79
|
+
#
|
80
|
+
float_names = ["win_out", "sun_out", "tongdiao", "lianluo"] \
|
81
|
+
+ ["bwin_out", "bsun_out", "btongdiao", "blianluo"] \
|
82
|
+
+ ["bshui_huo", "shui_huo"] \
|
83
|
+
+ ["real_fact_price", "before_fact_price"] \
|
84
|
+
+ ["idx"] \
|
85
|
+
+ ["power_pred"] \
|
86
|
+
#
|
87
|
+
wnames = [col for col in weather.columns if
|
88
|
+
col not in ["time_point", "ref_date", "gfs_time"]] if weather is not None else []
|
89
|
+
weather = [row for idx, row in weather.iterrows()] if weather is not None else []
|
90
|
+
#
|
91
|
+
float_names = float_names + wnames
|
92
|
+
#
|
93
|
+
#
|
94
|
+
price_names = ["before_price", "real_price", "diff_price", "diff_pos"] if istrain else []
|
95
|
+
#
|
96
|
+
all_datas = {
|
97
|
+
name: [] for name in ["datetime"] + float_names + price_names
|
98
|
+
#
|
99
|
+
}
|
100
|
+
#
|
101
|
+
market = sorted(market, key=lambda x: x["timestamp"], reverse=False)
|
102
|
+
power = sorted(power, key=lambda x: x["timestamp"], reverse=False)
|
103
|
+
# market = sorted(market, key=lambda x: [-int(x["datetime"].split("-")[0]), x["datetime"].split("-")[1]])
|
104
|
+
#
|
105
|
+
# power_pred = power["predicted_power"].tolist()
|
106
|
+
power_pred = [p["predicted_power"] for p in power]
|
107
|
+
#
|
108
|
+
#
|
109
|
+
for idx, row in enumerate(power):
|
110
|
+
if istrain:
|
111
|
+
if idx < 96 * 2:
|
112
|
+
continue
|
113
|
+
#
|
114
|
+
sup_now = market[idx] if idx < len(market) else None
|
115
|
+
if sup_now is None:
|
116
|
+
print(f"Warning: Missing market data at index {idx}")
|
117
|
+
continue
|
118
|
+
sup_before = market[idx]
|
119
|
+
if istrain:
|
120
|
+
sup_before = market[idx - 96 * 2]
|
121
|
+
#
|
122
|
+
time_str = str(row['timestamp']).strip()
|
123
|
+
#
|
124
|
+
print(f"sup_before timestamp: {sup_before['timestamp']}")
|
125
|
+
#
|
126
|
+
date_part, time_part = time_str.split(' ')
|
127
|
+
if time_part == '24:00:00':
|
128
|
+
day = datetime.datetime.strptime(date_part, '%Y-%m-%d') + datetime.timedelta(days=1)
|
129
|
+
day = day.replace(hour=0, minute=0, second=0)
|
130
|
+
else:
|
131
|
+
day = datetime.datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
|
132
|
+
#
|
133
|
+
day_now = datetime.datetime.strftime(day, '%Y-%m-%d %H:%M:%S')
|
134
|
+
all_datas["datetime"].append(day_now)
|
135
|
+
#
|
136
|
+
#
|
137
|
+
#
|
138
|
+
all_datas["bwin_out"].append(sup_before['wind_power_day_ahead'])
|
139
|
+
all_datas["bsun_out"].append(sup_before['pv_power_day_ahead'])
|
140
|
+
all_datas["btongdiao"].append(sup_before['provincial_load_forecast'])
|
141
|
+
all_datas["blianluo"].append(-sup_before['day_ahead_tieline_power'])
|
142
|
+
all_datas["bshui_huo"].append(
|
143
|
+
sup_before['provincial_load_forecast'] - sup_before['day_ahead_tieline_power'] - sup_before[
|
144
|
+
'pv_power_day_ahead'] - sup_before['wind_power_day_ahead'])
|
145
|
+
#
|
146
|
+
#
|
147
|
+
all_datas["win_out"].append(sup_before['wind_power_actual_value'])
|
148
|
+
all_datas["sun_out"].append(sup_before['pv_actual_value'])
|
149
|
+
all_datas["tongdiao"].append(sup_before['system_load_actual_value'])
|
150
|
+
all_datas["lianluo"].append(-sup_before['tie_line_out_actual_value'])
|
151
|
+
all_datas["shui_huo"].append(
|
152
|
+
sup_before['system_load_actual_value'] - sup_before['tie_line_out_actual_value'] - sup_before[
|
153
|
+
'pv_actual_value'] - sup_before['wind_power_actual_value'])
|
154
|
+
#
|
155
|
+
all_datas["before_fact_price"].append(sup_before['day_ahead_price'])
|
156
|
+
all_datas["real_fact_price"].append(sup_before['electricity_price'])
|
157
|
+
all_datas["idx"].append(idx % 96)
|
158
|
+
all_datas["power_pred"].append(power_pred[idx])
|
159
|
+
# #
|
160
|
+
#
|
161
|
+
#
|
162
|
+
for key in wnames:
|
163
|
+
all_datas[key].append(weather[idx][key])
|
164
|
+
#
|
165
|
+
if istrain:
|
166
|
+
all_datas["before_price"].append(sup_now['day_ahead_price'])
|
167
|
+
all_datas["real_price"].append(sup_now['electricity_price'])
|
168
|
+
all_datas["diff_price"].append(sup_now['day_ahead_price'] - sup_now['electricity_price'])
|
169
|
+
all_datas["diff_pos"].append(1 if sup_now['day_ahead_price'] - sup_now['electricity_price'] > 0 else 0)
|
170
|
+
#
|
171
|
+
#
|
172
|
+
float_names = [name for name in float_names if name not in []]
|
173
|
+
# float_names = [name for name in float_names if name not in ["power_pred"]]
|
174
|
+
#
|
175
|
+
all_datas = pd.DataFrame(all_datas)
|
176
|
+
return all_datas, float_names
|
177
|
+
|
178
|
+
|
179
|
+
#
|
180
|
+
|
181
|
+
|
182
|
+
def train():
|
183
|
+
#
|
184
|
+
cn_holidays = holidays.CountryHoliday('CN')
|
185
|
+
#
|
186
|
+
# system_date = EpSystem.get_system_date() # 输出 eg:2025-01-01
|
187
|
+
system_date = datetime.datetime(
|
188
|
+
year=2025,
|
189
|
+
month=4,
|
190
|
+
day=12
|
191
|
+
).strftime("%Y-%m-%d")
|
192
|
+
dt1 = datetime.datetime.strptime("2024-01-01", "%Y-%m-%d")
|
193
|
+
dt2 = datetime.datetime.strptime(system_date, "%Y-%m-%d")
|
194
|
+
dt3 = datetime.datetime.strptime('2025-01-01', "%Y-%m-%d")
|
195
|
+
gaps = dt2 - dt1
|
196
|
+
gap_days = gaps.days
|
197
|
+
#
|
198
|
+
print(f"system_date: {system_date}")
|
199
|
+
print(f"gap_days: {gap_days}")
|
200
|
+
#
|
201
|
+
# gap_days = 1000
|
202
|
+
#
|
203
|
+
# system_date - 1: 所有字段
|
204
|
+
data = EpData.get_history_data(scope="weather,plant,market", days=gap_days)
|
205
|
+
# data = EpData.get_history_data(scope=["weather","plant","market"], days=gap_days)
|
206
|
+
#
|
207
|
+
#
|
208
|
+
gaps = dt3 - dt1
|
209
|
+
gap_days = gaps.days
|
210
|
+
examples = gap_days * 96
|
211
|
+
#
|
212
|
+
weather = data.get("weather")
|
213
|
+
plant = data.get("plant")[:examples]
|
214
|
+
market = data.get("market")[:examples]
|
215
|
+
#
|
216
|
+
# weather = data["weather"]
|
217
|
+
# plant = data["plant"]
|
218
|
+
# market = data["market"]
|
219
|
+
#
|
220
|
+
#
|
221
|
+
all_datas, float_names = get_data_label(market, plant, weather=None, istrain=True)
|
222
|
+
#
|
223
|
+
#
|
224
|
+
all_datas["datetime"] = all_datas["datetime"].apply(
|
225
|
+
lambda x: datetime.datetime.strptime(str(x).strip(), '%Y-%m-%d %H:%M:%S'))
|
226
|
+
#
|
227
|
+
all_datas["weekday"] = all_datas["datetime"].apply(lambda x: x.weekday())
|
228
|
+
all_datas["hour"] = all_datas["datetime"].apply(lambda x: x.hour)
|
229
|
+
all_datas["month"] = all_datas["datetime"].apply(lambda x: x.month)
|
230
|
+
all_datas["holiday"] = all_datas["datetime"].apply(lambda x: 1 if x.date() in cn_holidays else 0)
|
231
|
+
#
|
232
|
+
#
|
233
|
+
cate_names = ["weekday", "hour", "month", "holiday"]
|
234
|
+
print(f"cate_names: {cate_names}")
|
235
|
+
#
|
236
|
+
#
|
237
|
+
for name in cate_names:
|
238
|
+
all_datas[name] = all_datas[name].astype('category')
|
239
|
+
for name in float_names:
|
240
|
+
all_datas[name] = all_datas[name].astype(float)
|
241
|
+
#
|
242
|
+
#
|
243
|
+
#
|
244
|
+
target = "before_price" # before_price, real_price, diff_price
|
245
|
+
X_train, y_train = all_datas[float_names + cate_names], all_datas[target]
|
246
|
+
model_before = simple_reg_price_step(X_train, y_train, 1, cate_fea=cate_names, lr=0.15, steps=73)
|
247
|
+
#
|
248
|
+
target = "real_price" # before_price, real_price, diff_price
|
249
|
+
X_train, y_train = all_datas[float_names + cate_names], all_datas[target]
|
250
|
+
model_real = simple_reg_price_step(X_train, y_train, 1, cate_fea=cate_names, lr=0.05, steps=192)
|
251
|
+
#
|
252
|
+
#
|
253
|
+
reqian_res = {}
|
254
|
+
reqian_res['model_before'] = model_before
|
255
|
+
reqian_res['float_names'] = float_names
|
256
|
+
reqian_res['cate_names'] = cate_names
|
257
|
+
reqian_res['model_real'] = model_real
|
258
|
+
#
|
259
|
+
# shishi_res = {}
|
260
|
+
# shishi_res['float_names'] = float_names
|
261
|
+
# shishi_res['cate_names'] = cate_names
|
262
|
+
#
|
263
|
+
base = "./tmp"
|
264
|
+
if not os.path.exists(base):
|
265
|
+
os.makedirs(base)
|
266
|
+
#
|
267
|
+
with open(f'{base}/riqian_price.pickle', 'wb') as handle:
|
268
|
+
pickle.dump(reqian_res, handle)
|
269
|
+
# with open(f'{EpSystem.model_output_dir()}/shishi_price.pickle', 'wb') as handle:
|
270
|
+
# pickle.dump(shishi_res, handle)
|
271
|
+
#
|
272
|
+
#
|
273
|
+
EpSystem.call_train_done()
|
274
|
+
|
275
|
+
|
276
|
+
#
|
277
|
+
|
278
|
+
|
279
|
+
#
|
280
|
+
#
|
281
|
+
inited = False
|
282
|
+
riqian_model = None
|
283
|
+
riqian_cate = None
|
284
|
+
riqian_float = None
|
285
|
+
shishi_model = None
|
286
|
+
cn_holidays = holidays.CountryHoliday('CN')
|
287
|
+
|
288
|
+
|
289
|
+
def initialize():
|
290
|
+
global inited, riqian_model, riqian_cate, riqian_float, shishi_model
|
291
|
+
#
|
292
|
+
#
|
293
|
+
#
|
294
|
+
base = "./tmp"
|
295
|
+
path = f'{base}/riqian_price.pickle'
|
296
|
+
#
|
297
|
+
# url = f'{EpSystem.model_output_dir()}/riqian_price.pickle'
|
298
|
+
# response = requests.get(url)
|
299
|
+
# response.raise_for_status()
|
300
|
+
# #
|
301
|
+
# with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
|
302
|
+
# tmp_file.write(response.content)
|
303
|
+
# path = tmp_file.name
|
304
|
+
#
|
305
|
+
with open(path, 'rb') as f:
|
306
|
+
# riqian_res = pickle.load(f)ode-file/20250522041137_submit_0521.py/riqian_price.pickle'
|
307
|
+
#
|
308
|
+
riqian_res = pickle.load(f)
|
309
|
+
riqian_model = riqian_res["model_before"]
|
310
|
+
riqian_cate = riqian_res["cate_names"]
|
311
|
+
riqian_float = riqian_res["float_names"]
|
312
|
+
shishi_model = riqian_res["model_real"]
|
313
|
+
#
|
314
|
+
#
|
315
|
+
inited = True
|
316
|
+
#
|
317
|
+
|
318
|
+
|
319
|
+
#
|
320
|
+
|
321
|
+
|
322
|
+
def get_baoliang(riqian_pred, shishi_pred, power_pred):
|
323
|
+
#
|
324
|
+
min_report, max_report, step = 0, 50, 0.1
|
325
|
+
|
326
|
+
#
|
327
|
+
def get_factor(diff1, diff2, p_power):
|
328
|
+
# [0, 1000] -> [1, 0.1]
|
329
|
+
#
|
330
|
+
maxv = 250
|
331
|
+
diff1 = min(diff1, maxv)
|
332
|
+
factor1 = ((maxv - diff1) / maxv) ** 2 + 0.00
|
333
|
+
#
|
334
|
+
rate = min(diff2 / (0.4 * max(p_power, 0.1)), 3) + 0.00
|
335
|
+
#
|
336
|
+
return factor1 * rate
|
337
|
+
|
338
|
+
#
|
339
|
+
punish = 0.22
|
340
|
+
|
341
|
+
def get_profit(baoliang, r_price, s_price, p_power, bad_point):
|
342
|
+
#
|
343
|
+
risk = 0
|
344
|
+
profit_factor = (baoliang - p_power) * (r_price - s_price)
|
345
|
+
#
|
346
|
+
#
|
347
|
+
punish_factor = punish
|
348
|
+
#
|
349
|
+
if bad_point:
|
350
|
+
punish_factor = punish_factor * 100
|
351
|
+
#
|
352
|
+
normal = abs(baoliang - p_power) / (max_report - p_power) if baoliang > p_power else (
|
353
|
+
abs(baoliang - p_power) / p_power if p_power != 0 else 0)
|
354
|
+
#
|
355
|
+
if profit_factor > 0:
|
356
|
+
profit_factor = min(abs(baoliang - p_power), 0.4 * p_power) * abs(r_price - s_price)
|
357
|
+
factor = get_factor(abs(r_price - s_price), abs(baoliang - p_power), p_power)
|
358
|
+
risk = punish_factor * abs(baoliang - p_power) * abs(r_price - s_price) * factor
|
359
|
+
#
|
360
|
+
profit_withdraw = profit_factor + p_power * r_price
|
361
|
+
#
|
362
|
+
#
|
363
|
+
return profit_withdraw - risk
|
364
|
+
# return baoliang * r_price + (p_power - baoliang) * s_price - punish * normal * abs(baoliang - p_power) * abs(r_price - s_price)
|
365
|
+
|
366
|
+
#
|
367
|
+
#
|
368
|
+
day_point = 96
|
369
|
+
baoliang_profit_map = []
|
370
|
+
#
|
371
|
+
for idx, (r_pred, s_pred, p_pred) in enumerate(zip(riqian_pred, shishi_pred, power_pred)):
|
372
|
+
#
|
373
|
+
# fadian = p_pred
|
374
|
+
# fadian = p_pred + 1.5
|
375
|
+
fadian = p_pred + 3.5
|
376
|
+
#
|
377
|
+
bad_point = idx < 6 * 4 or idx > 22 * 4
|
378
|
+
#
|
379
|
+
except_profits = []
|
380
|
+
baoliang = min_report
|
381
|
+
#
|
382
|
+
while baoliang < max_report:
|
383
|
+
profit = get_profit(baoliang, r_pred, s_pred, fadian, bad_point)
|
384
|
+
except_profits.append(profit)
|
385
|
+
#
|
386
|
+
baoliang += step
|
387
|
+
baoliang_profit_map.append(except_profits)
|
388
|
+
#
|
389
|
+
#
|
390
|
+
# order1_max = 4.5
|
391
|
+
order1_max = 3.7
|
392
|
+
# order1_max = 3
|
393
|
+
#
|
394
|
+
range_skip = int(order1_max / step)
|
395
|
+
#
|
396
|
+
#
|
397
|
+
posi_num = int(max_report / step)
|
398
|
+
#
|
399
|
+
start = 0
|
400
|
+
pre_best = [[i for i in range(posi_num)]]
|
401
|
+
for point in range(start + 1, start + day_point):
|
402
|
+
best_pre = []
|
403
|
+
for idx in range(posi_num):
|
404
|
+
min_pos, max_pos = max(0, idx - range_skip), min(posi_num - 1, idx + range_skip)
|
405
|
+
index = np.argmax(baoliang_profit_map[point - 1][min_pos:max_pos]) + min_pos
|
406
|
+
baoliang_profit_map[point][idx] += baoliang_profit_map[point - 1][index]
|
407
|
+
best_pre.append(index)
|
408
|
+
pre_best.append(best_pre)
|
409
|
+
#
|
410
|
+
last_max = np.argmax(baoliang_profit_map[start + day_point - 1])
|
411
|
+
#
|
412
|
+
pre_list = [last_max]
|
413
|
+
for idx in range(len(pre_best) - 1, 0, -1):
|
414
|
+
last_max = pre_best[idx][last_max]
|
415
|
+
pre_list.append(last_max)
|
416
|
+
pre_list.reverse()
|
417
|
+
#
|
418
|
+
baoliangs = [v * step for v in pre_list]
|
419
|
+
#
|
420
|
+
return baoliangs
|
421
|
+
|
422
|
+
|
423
|
+
#
|
424
|
+
|
425
|
+
def predict():
|
426
|
+
global cn_holidays, inited, riqian_model, riqian_cate, riqian_float, shishi_model
|
427
|
+
#
|
428
|
+
if not inited:
|
429
|
+
initialize()
|
430
|
+
#
|
431
|
+
#
|
432
|
+
target_date = EpSystem.get_system_date()
|
433
|
+
#
|
434
|
+
# system_date + 1: plant/weather
|
435
|
+
data = EpData.get_predict_data(scope="plant,weather")
|
436
|
+
# data = EpData.get_predict_data(scope=["plant","weather"])
|
437
|
+
#
|
438
|
+
#
|
439
|
+
if data is None or len(data) == 0:
|
440
|
+
return None
|
441
|
+
plant = data["plant"]
|
442
|
+
weather = data["weather"]
|
443
|
+
#
|
444
|
+
# system_date - 1: market
|
445
|
+
data = EpData.get_history_data(scope="market", days=1)
|
446
|
+
# data = EpData.get_history_data(scope=["market"], date=1)
|
447
|
+
market = data["market"]
|
448
|
+
#
|
449
|
+
#
|
450
|
+
price_data, float_names = get_data_label(market, plant, weather=None, istrain=False)
|
451
|
+
#
|
452
|
+
price_data = price_data.tail(96)
|
453
|
+
#
|
454
|
+
#
|
455
|
+
#
|
456
|
+
price_data["datetime"] = price_data["datetime"].apply(
|
457
|
+
lambda x: datetime.datetime.strptime(str(x).strip(), '%Y-%m-%d %H:%M:%S'))
|
458
|
+
#
|
459
|
+
price_data["weekday"] = price_data["datetime"].apply(lambda x: x.weekday())
|
460
|
+
price_data["hour"] = price_data["datetime"].apply(lambda x: x.hour)
|
461
|
+
price_data["month"] = price_data["datetime"].apply(lambda x: x.month)
|
462
|
+
price_data["holiday"] = price_data["datetime"].apply(lambda x: 1 if x.date() in cn_holidays else 0)
|
463
|
+
#
|
464
|
+
#
|
465
|
+
for col in riqian_cate:
|
466
|
+
price_data[col] = price_data[col].astype('category')
|
467
|
+
for col in riqian_float:
|
468
|
+
price_data[col] = price_data[col].astype('float')
|
469
|
+
#
|
470
|
+
#
|
471
|
+
riqian_test = price_data[riqian_model.feature_name()]
|
472
|
+
riqian_pred = list(riqian_model.predict(riqian_test))
|
473
|
+
#
|
474
|
+
shishi_test = price_data[shishi_model.feature_name()]
|
475
|
+
shishi_pred = list(shishi_model.predict(shishi_test))
|
476
|
+
#
|
477
|
+
# fadianpred = [v1 + v2 for v1, v2 in zip(fadianpred, price_data["power_pred"].tolist())]
|
478
|
+
fadianpred = [40.96, 40.96, 40.96, 72.62, 33.18, 72.62, 33.18, 72.62, 33.18, 72.66, 33.05, 72.66, 33.05, 72.66, 33.05, 40.7, 40.7, 40.7, 72.76, 32.93, 40.52, 40.52, 40.52, 72.76, 32.93, 72.76, 32.93, 40.38, 40.38, 72.95, 32.76, 72.95, 32.76, 72.95, 32.76, 40.38, 73.21, 32.47, 73.21, 32.47, 73.21, 32.47, 40.29, 40.29, 40.29, 40.19, 40.19, 40.19, 73.47, 32.37, 73.47, 32.37, 73.47, 32.37, 40.04, 73.74, 32.32, 73.74, 32.32, 73.74, 32.32, 40.04, 40.04, 73.91, 32.34, 73.91, 32.34, 39.93, 39.93, 39.93, 73.91, 32.34, 39.8, 39.8, 39.8, 73.99, 32.38, 73.99, 32.38, 73.99, 32.38, 74.1, 32.44, 74.1, 32.44, 74.1, 32.44, 39.67, 39.67, 39.67, 74.2, 32.48, 39.58, 39.58, 39.58, 74.2]
|
479
|
+
#
|
480
|
+
baoliangs = get_baoliang(riqian_pred, shishi_pred, fadianpred)
|
481
|
+
#
|
482
|
+
center = 13 * 4
|
483
|
+
baoliangs = [
|
484
|
+
val * (abs(idx - center) ** 4 / 40000 + 0.45) if idx >= 10 * 4 and idx <= 16 * 4 else val for idx, val in
|
485
|
+
enumerate(baoliangs)
|
486
|
+
]
|
487
|
+
baoliangs = [f"{val:.2f}" for val in baoliangs]
|
488
|
+
#
|
489
|
+
print(f'target_date={target_date},riqian_pred={riqian_pred}, shishi_pred={shishi_pred}, fadianpred={fadianpred}')
|
490
|
+
#
|
491
|
+
|
492
|
+
|
493
|
+
if __name__ == '__main__':
|
494
|
+
train()
|
495
|
+
|
496
|
+
initialize()
|
497
|
+
|
498
|
+
predict()
|
@@ -4,9 +4,7 @@ from ep_sdk_4pd.ep_data import EpData
|
|
4
4
|
def test_predict_data():
|
5
5
|
print('-------------test_predict_data-------------')
|
6
6
|
|
7
|
-
data = EpData.get_predict_data()
|
8
|
-
weather = data['weather']
|
9
|
-
plant = data['plant']
|
7
|
+
data = EpData.get_predict_data(scope="plant")
|
10
8
|
print(data)
|
11
9
|
print('-------------------------------------')
|
12
10
|
|
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = '3.0.0.dev0'
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|