ep-sdk-4pd 3.0.0.dev0__tar.gz → 3.0.1.dev0__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.dev0}/PKG-INFO +1 -1
- ep_sdk_4pd-3.0.1.dev0/ep_sdk_4pd/__init__.py +1 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/ep_sdk_4pd/ep_data.py +12 -2
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/ep_sdk_4pd/ep_system.py +1 -1
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/ep_sdk_4pd/models.py +6 -2
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/ep_sdk_4pd.egg-info/PKG-INFO +1 -1
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/ep_sdk_4pd.egg-info/SOURCES.txt +1 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/setup.py +1 -1
- ep_sdk_4pd-3.0.1.dev0/tests/test.py +498 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/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.dev0}/README.md +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/ep_sdk_4pd.egg-info/dependency_links.txt +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/ep_sdk_4pd.egg-info/requires.txt +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/ep_sdk_4pd.egg-info/top_level.txt +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/setup.cfg +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/tests/test_call_train_done.py +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/tests/test_get_run_strategy.py +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/tests/test_get_system_date.py +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/tests/test_history_data.py +0 -0
- {ep_sdk_4pd-3.0.0.dev0 → ep_sdk_4pd-3.0.1.dev0}/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.dev0
|
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.dev0'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import json
|
2
|
+
import os
|
2
3
|
from datetime import timedelta, datetime
|
3
4
|
|
4
5
|
import requests
|
@@ -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(
|
@@ -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.dev0
|
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.dev0'
|
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
|