ep-sdk-4pd 3.0.3.dev0__tar.gz → 3.0.4.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.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/PKG-INFO +1 -1
- ep_sdk_4pd-3.0.4.dev0/ep_sdk_4pd/__init__.py +1 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/ep_sdk_4pd/ep_data.py +12 -8
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/ep_sdk_4pd/ep_system.py +2 -2
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/ep_sdk_4pd.egg-info/PKG-INFO +1 -1
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/ep_sdk_4pd.egg-info/SOURCES.txt +3 -1
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/setup.py +1 -1
- ep_sdk_4pd-3.0.4.dev0/tests/test_history_data.py +17 -0
- ep_sdk_4pd-3.0.4.dev0/tests/test_model1.py +45 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/tests/test_predict_data.py +1 -1
- ep_sdk_4pd-3.0.4.dev0/tests/test_/350/212/202/347/202/271/345/235/207/345/200/274_v2.py +834 -0
- ep_sdk_4pd-3.0.3.dev0/ep_sdk_4pd/__init__.py +0 -1
- ep_sdk_4pd-3.0.3.dev0/tests/test_history_data.py +0 -24
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/README.md +0 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/ep_sdk_4pd/models.py +0 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/ep_sdk_4pd.egg-info/dependency_links.txt +0 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/ep_sdk_4pd.egg-info/requires.txt +0 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/ep_sdk_4pd.egg-info/top_level.txt +0 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/setup.cfg +0 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/tests/test.py +0 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/tests/test_call_train_done.py +0 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/tests/test_get_run_strategy.py +0 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.dev0}/tests/test_get_system_date.py +0 -0
- {ep_sdk_4pd-3.0.3.dev0 → ep_sdk_4pd-3.0.4.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.4.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.4.dev0'
|
@@ -9,13 +9,13 @@ from ep_sdk_4pd.ep_system import EpSystem
|
|
9
9
|
from ep_sdk_4pd.models import HistoryDataRequest, PredictDataRequest
|
10
10
|
|
11
11
|
# test 地址
|
12
|
-
endpoint = 'http://172.27.88.56:6001'
|
12
|
+
# endpoint = 'http://172.27.88.56:6001'
|
13
13
|
|
14
14
|
# prod 地址
|
15
15
|
# endpoint = 'http://172.27.88.56:6601'
|
16
16
|
|
17
17
|
# 外网 地址
|
18
|
-
|
18
|
+
endpoint = 'http://82.157.231.254:6001'
|
19
19
|
|
20
20
|
Authorization = 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJlbGVjdHJpY2l0eS1wbGF0Zm9ybSIsInN1YiI6IjEyMyIsImlhdCI6MTc0NjYwNjQ4NSwianRpIjoiMTIzXzE3NDY1Nzc2ODUxNDYiLCJ0eXBlIjoiYWNjZXNzIn0.Clrz_8j3aJlXTWPX-4DS0NxXN9idTcUIc0AtXOMIjd8'
|
21
21
|
|
@@ -25,14 +25,18 @@ class EpData:
|
|
25
25
|
@staticmethod
|
26
26
|
def get_history_data(
|
27
27
|
scope="weather,plant,market",
|
28
|
-
days=0
|
28
|
+
days=0,
|
29
|
+
is_test=False
|
29
30
|
):
|
30
31
|
# 最晚时间为系统时间 D-2
|
31
32
|
date_str = EpSystem.get_system_date(is_online=True)
|
32
33
|
calculated_date = datetime.strptime(date_str, "%Y-%m-%d")
|
33
34
|
system_date = calculated_date.strftime("%Y-%m-%d") # 转换回字符串
|
34
35
|
|
35
|
-
|
36
|
+
if is_test:
|
37
|
+
strategy_id = 3
|
38
|
+
else:
|
39
|
+
strategy_id = os.getenv('STRATEGY_ID')
|
36
40
|
|
37
41
|
request = HistoryDataRequest(
|
38
42
|
scope=scope,
|
@@ -90,10 +94,10 @@ class EpData:
|
|
90
94
|
system_date = calculated_date.strftime("%Y-%m-%d")
|
91
95
|
|
92
96
|
# 测试
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
+
if is_test:
|
98
|
+
strategy_id = 3
|
99
|
+
else:
|
100
|
+
strategy_id = os.getenv('STRATEGY_ID')
|
97
101
|
|
98
102
|
request = PredictDataRequest(
|
99
103
|
scope=scope,
|
@@ -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
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ep_sdk_4pd
|
3
|
-
Version: 3.0.
|
3
|
+
Version: 3.0.4.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
|
@@ -14,5 +14,7 @@ tests/test_call_train_done.py
|
|
14
14
|
tests/test_get_run_strategy.py
|
15
15
|
tests/test_get_system_date.py
|
16
16
|
tests/test_history_data.py
|
17
|
+
tests/test_model1.py
|
17
18
|
tests/test_model_output_dir.py
|
18
|
-
tests/test_predict_data.py
|
19
|
+
tests/test_predict_data.py
|
20
|
+
tests/test_节点均值_v2.py
|
@@ -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.4.dev0'
|
12
12
|
REQUIRES = ['requests']
|
13
13
|
|
14
14
|
LONG_DESCRIPTION = ''
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import datetime
|
2
|
+
from turtle import pd
|
3
|
+
|
4
|
+
from ep_sdk_4pd.ep_data import EpData
|
5
|
+
from ep_sdk_4pd.ep_system import EpSystem
|
6
|
+
|
7
|
+
|
8
|
+
def test_history_data():
|
9
|
+
print('-------------test_history_data-------------')
|
10
|
+
|
11
|
+
data = EpData.get_history_data(scope="plant",days=1)
|
12
|
+
print(data.get("plant"))
|
13
|
+
print('-------------------------------------')
|
14
|
+
|
15
|
+
|
16
|
+
if __name__ == '__main__':
|
17
|
+
test_history_data()
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from ep_sdk_4pd.ep_system import EpSystem
|
2
|
+
from ep_sdk_4pd.ep_data import EpData
|
3
|
+
import numpy as np
|
4
|
+
import pandas as pd
|
5
|
+
|
6
|
+
|
7
|
+
def train():
|
8
|
+
EpSystem.call_train_done()
|
9
|
+
|
10
|
+
|
11
|
+
def initialize():
|
12
|
+
return
|
13
|
+
|
14
|
+
|
15
|
+
def predict():
|
16
|
+
target_date = EpSystem.get_system_date() # 应该需要增加一天表示预测第二天
|
17
|
+
plant_forecast_power = EpData.get_predict_data(scope="plant")
|
18
|
+
plant_forecast = [float(item['predicted_power']) for item in plant_forecast_power['plant']]
|
19
|
+
|
20
|
+
market_history_data = EpData.get_history_data(scope="market", days=30)
|
21
|
+
df_market = pd.DataFrame(market_history_data['market'])
|
22
|
+
# Add datetime and hour columns if not already present
|
23
|
+
if 'hour' not in df_market.columns:
|
24
|
+
df_market['datetime'] = pd.to_datetime(df_market['timestamp'])
|
25
|
+
df_market['hour'] = df_market['datetime'].dt.hour
|
26
|
+
|
27
|
+
# Compute proportion where day_ahead_price > electricity_price for each hour
|
28
|
+
result = df_market.groupby('hour').apply(
|
29
|
+
lambda g: (g['day_ahead_price'] > g['electricity_price']).mean()
|
30
|
+
).reset_index(name='proportion')
|
31
|
+
|
32
|
+
# Find hours where the proportion is greater than 0.5
|
33
|
+
hours_with_high_proportion = result[result['proportion'] > 0.5]['hour'].tolist()
|
34
|
+
|
35
|
+
print(f"hours to explode = {hours_with_high_proportion}")
|
36
|
+
|
37
|
+
noon = [4 * hour + i for hour in [9, 10, 11, 12, 13, 14, 15, 16] for i in range(4)]
|
38
|
+
inflation_index = [4 * hour + i for hour in hours_with_high_proportion for i in range(4)]
|
39
|
+
baoliang_pred = [
|
40
|
+
value * 1.4 if index in inflation_index else value
|
41
|
+
for index, value in enumerate(plant_forecast)
|
42
|
+
]
|
43
|
+
baoliang_pred = np.array(baoliang_pred)
|
44
|
+
baoliang_pred = np.maximum(np.minimum(50, baoliang_pred), 0)
|
45
|
+
return list(baoliang_pred)
|
@@ -4,7 +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(scope="plant,weather")
|
7
|
+
data = EpData.get_predict_data(scope="plant,weather",is_test=True)
|
8
8
|
print(data)
|
9
9
|
if data is None or len(data['plant']) == 0:
|
10
10
|
return print("空空")
|
@@ -0,0 +1,834 @@
|
|
1
|
+
import datetime
|
2
|
+
import pickle
|
3
|
+
import requests
|
4
|
+
import os
|
5
|
+
from copy import deepcopy
|
6
|
+
import logging
|
7
|
+
|
8
|
+
import lightgbm as lgb
|
9
|
+
import numpy as np
|
10
|
+
import pandas as pd
|
11
|
+
import holidays
|
12
|
+
import tempfile
|
13
|
+
#
|
14
|
+
#
|
15
|
+
from ep_sdk_4pd.ep_system import EpSystem
|
16
|
+
from ep_sdk_4pd.ep_data import EpData
|
17
|
+
|
18
|
+
#
|
19
|
+
|
20
|
+
|
21
|
+
logger = logging.getLogger(__name__)
|
22
|
+
|
23
|
+
EARLY_STOP_ROUNDS = 30
|
24
|
+
#
|
25
|
+
# lr = 0.3
|
26
|
+
params = {
|
27
|
+
# "min_data_in_bin": 5,
|
28
|
+
#
|
29
|
+
'num_leaves': 5,
|
30
|
+
'min_data_in_leaf': 30,
|
31
|
+
'objective': 'regression',
|
32
|
+
'max_depth': 4,
|
33
|
+
'learning_rate': 0.1,
|
34
|
+
"boosting": "gbdt",
|
35
|
+
"feature_fraction": 0.8,
|
36
|
+
"bagging_fraction": 0.2,
|
37
|
+
"bagging_freq": 1,
|
38
|
+
"bagging_seed": 1,
|
39
|
+
"metric": 'mse',
|
40
|
+
"lambda_l1": 0.5,
|
41
|
+
"lambda_l2": 1,
|
42
|
+
"random_state": 1022,
|
43
|
+
"num_threads": -1,
|
44
|
+
'verbose': 0,
|
45
|
+
#
|
46
|
+
'early_stopping_round': EARLY_STOP_ROUNDS,
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
#
|
51
|
+
def simple_reg_price(train, train_label, test, test_label, cate_fea=[], lr=0.3):
|
52
|
+
#
|
53
|
+
#
|
54
|
+
dtrain = lgb.Dataset(train, train_label, categorical_feature=cate_fea, free_raw_data=False)
|
55
|
+
dval = lgb.Dataset(test, test_label, categorical_feature=cate_fea, reference=dtrain, free_raw_data=False)
|
56
|
+
#
|
57
|
+
params['learning_rate'] = lr
|
58
|
+
model = lgb.train(
|
59
|
+
params,
|
60
|
+
dtrain,
|
61
|
+
num_boost_round=500,
|
62
|
+
# feval=calc_wauc,
|
63
|
+
valid_sets=[dtrain, dval],
|
64
|
+
# verbose_eval=10,
|
65
|
+
# early_stopping_rounds=EARLY_STOP_ROUNDS
|
66
|
+
)
|
67
|
+
#
|
68
|
+
valid_prob = model.predict(test)
|
69
|
+
train_prob = model.predict(train)
|
70
|
+
|
71
|
+
return valid_prob, train_prob, model
|
72
|
+
|
73
|
+
|
74
|
+
#
|
75
|
+
#
|
76
|
+
def eval_reg_price(train, train_label, num_round, cate_fea=[], lr=0.3):
|
77
|
+
#
|
78
|
+
dtrain = lgb.Dataset(train, train_label, categorical_feature=cate_fea, free_raw_data=False)
|
79
|
+
#
|
80
|
+
#
|
81
|
+
eval_param = deepcopy(params)
|
82
|
+
eval_param.pop("early_stopping_round")
|
83
|
+
eval_param['learning_rate'] = lr
|
84
|
+
#
|
85
|
+
model = lgb.train(
|
86
|
+
eval_param,
|
87
|
+
dtrain,
|
88
|
+
num_boost_round=num_round,
|
89
|
+
# # feval=calc_wauc,
|
90
|
+
# valid_sets=[dtrain,dval],
|
91
|
+
# # verbose_eval=10,
|
92
|
+
# # early_stopping_rounds=EARLY_STOP_ROUNDS
|
93
|
+
)
|
94
|
+
#
|
95
|
+
return model
|
96
|
+
|
97
|
+
|
98
|
+
#
|
99
|
+
|
100
|
+
|
101
|
+
def get_data_label(market, power, weather=None, istrain=False):
|
102
|
+
#
|
103
|
+
#
|
104
|
+
float_names = ["win_out", "sun_out", "tongdiao", "lianluo"] \
|
105
|
+
+ ["bwin_out", "bsun_out", "btongdiao", "blianluo"] \
|
106
|
+
+ ["bshui_huo", "shui_huo"] \
|
107
|
+
+ ["real_fact_price", "before_fact_price"] \
|
108
|
+
+ ["idx"] \
|
109
|
+
+ ["power_pred"] \
|
110
|
+
+ ["before_smooth_5", "real_smooth_5"] \
|
111
|
+
+ ["feng_riqian_10", "guang_riqian_10", "tong_riqian_10", "lian_riqian_10", "feng_shiji_10",
|
112
|
+
"guang_shiji_10", "tong_shiji_10", "lian_shiji_10"] \
|
113
|
+
+ ["shuihuo_riqian_10", "shuihuo_shiji_10"] \
|
114
|
+
+ ["feng_riqian_5", "guang_riqian_5", "tong_riqian_5", "lian_riqian_5", "feng_shiji_5",
|
115
|
+
"guang_shiji_5", "tong_shiji_5", "lian_shiji_5"] \
|
116
|
+
+ ["shuihuo_riqian_5", "shuihuo_shiji_5"] \
|
117
|
+
+ ["feng_riqian_3", "guang_riqian_3", "tong_riqian_3", "lian_riqian_3", "feng_shiji_3",
|
118
|
+
"guang_shiji_3", "tong_shiji_3", "lian_shiji_3"] \
|
119
|
+
+ ["shuihuo_riqian_3", "shuihuo_shiji_3"] \
|
120
|
+
#
|
121
|
+
#
|
122
|
+
weather = [row for idx, row in weather.iterrows()]
|
123
|
+
date_weather = {
|
124
|
+
row["timestamp"]: row for row in weather
|
125
|
+
}
|
126
|
+
wea_keys = list(sorted([key for key in weather[0].keys() if key != "timestamp"]))
|
127
|
+
#
|
128
|
+
#
|
129
|
+
float_names = float_names + wea_keys
|
130
|
+
#
|
131
|
+
price_names = ["before_price", "real_price", "diff_price"] + ["power_fact"] if istrain else []
|
132
|
+
#
|
133
|
+
all_datas = {
|
134
|
+
name: [] for name in ["datetime"] + float_names + price_names
|
135
|
+
#
|
136
|
+
}
|
137
|
+
power_pred = power["predicted_power"].tolist()
|
138
|
+
#
|
139
|
+
power_fact = power["power"].tolist() if istrain else []
|
140
|
+
#
|
141
|
+
# weather = [row for idx, row in weather.iterrows()] if weather is not None else []
|
142
|
+
#
|
143
|
+
for idx, row in market.iterrows():
|
144
|
+
if istrain:
|
145
|
+
if idx < 96 * 3:
|
146
|
+
continue
|
147
|
+
#
|
148
|
+
sup_now = market.iloc[idx]
|
149
|
+
sup_before = market.iloc[idx]
|
150
|
+
if istrain:
|
151
|
+
sup_before = market.iloc[idx - 96 * 2]
|
152
|
+
#
|
153
|
+
#
|
154
|
+
#
|
155
|
+
time_str = str(sup_now['timestamp']).strip()
|
156
|
+
date_part, time_part = time_str.split(' ')
|
157
|
+
if time_part == '24:00':
|
158
|
+
day = datetime.datetime.strptime(date_part, '%Y-%m-%d') + datetime.timedelta(days=1)
|
159
|
+
day = day.replace(hour=0, minute=0, second=0)
|
160
|
+
else:
|
161
|
+
day = datetime.datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
|
162
|
+
#
|
163
|
+
# pre_day = day - datetime.timedelta(days=2)
|
164
|
+
# date_str = datetime.datetime.strftime(pre_day, '%Y-%m-%d %H:%M:%S')[:10]
|
165
|
+
date_str = time_str[:10]
|
166
|
+
wea_data = date_weather[date_str]
|
167
|
+
for key in wea_keys:
|
168
|
+
all_datas[key].append(wea_data[key])
|
169
|
+
#
|
170
|
+
#
|
171
|
+
day_now = datetime.datetime.strftime(day, '%Y-%m-%d %H:%M:%S')
|
172
|
+
all_datas["datetime"].append(day_now)
|
173
|
+
#
|
174
|
+
#
|
175
|
+
#
|
176
|
+
all_datas["bwin_out"].append(sup_before['wind_power_day_ahead'])
|
177
|
+
all_datas["bsun_out"].append(sup_before['pv_power_day_ahead'])
|
178
|
+
all_datas["btongdiao"].append(sup_before['provincial_load_forecast'])
|
179
|
+
all_datas["blianluo"].append(-sup_before['day_ahead_tieline_power'])
|
180
|
+
all_datas["bshui_huo"].append(
|
181
|
+
sup_before['provincial_load_forecast'] - sup_before['day_ahead_tieline_power'] - sup_before[
|
182
|
+
'pv_power_day_ahead'] - sup_before['wind_power_day_ahead'])
|
183
|
+
#
|
184
|
+
#
|
185
|
+
all_datas["win_out"].append(sup_before['wind_power_actual_value'])
|
186
|
+
all_datas["sun_out"].append(sup_before['pv_actual_value'])
|
187
|
+
all_datas["tongdiao"].append(sup_before['system_load_actual_value'])
|
188
|
+
all_datas["lianluo"].append(-sup_before['tie_line_out_actual_value'])
|
189
|
+
all_datas["shui_huo"].append(
|
190
|
+
sup_before['system_load_actual_value'] - sup_before['tie_line_out_actual_value'] - sup_before[
|
191
|
+
'pv_actual_value'] - sup_before['wind_power_actual_value'])
|
192
|
+
#
|
193
|
+
all_datas["before_fact_price"].append(sup_before['day_ahead_price'])
|
194
|
+
all_datas["real_fact_price"].append(sup_before['electricity_price'])
|
195
|
+
all_datas["idx"].append(idx % 96)
|
196
|
+
all_datas["power_pred"].append(power_pred[idx])
|
197
|
+
# #
|
198
|
+
all_datas["before_smooth_5"].append(sup_before["before_smooth_5"])
|
199
|
+
all_datas["real_smooth_5"].append(sup_before["real_smooth_5"])
|
200
|
+
#
|
201
|
+
#
|
202
|
+
all_datas["feng_riqian_10"].append(sup_before["feng_riqian_10"])
|
203
|
+
all_datas["guang_riqian_10"].append(sup_before["guang_riqian_10"])
|
204
|
+
all_datas["tong_riqian_10"].append(sup_before["tong_riqian_10"])
|
205
|
+
all_datas["lian_riqian_10"].append(sup_before["lian_riqian_10"])
|
206
|
+
all_datas["shuihuo_riqian_10"].append(
|
207
|
+
sup_before["tong_riqian_10"] - sup_before["lian_riqian_10"] - sup_before["feng_riqian_10"] - sup_before[
|
208
|
+
"guang_riqian_10"])
|
209
|
+
all_datas["feng_shiji_10"].append(sup_before["feng_shiji_10"])
|
210
|
+
all_datas["guang_shiji_10"].append(sup_before["guang_shiji_10"])
|
211
|
+
all_datas["tong_shiji_10"].append(sup_before["tong_shiji_10"])
|
212
|
+
all_datas["lian_shiji_10"].append(sup_before["lian_shiji_10"])
|
213
|
+
all_datas["shuihuo_shiji_10"].append(
|
214
|
+
sup_before["tong_shiji_10"] - sup_before["lian_shiji_10"] - sup_before["feng_shiji_10"] - sup_before[
|
215
|
+
"guang_shiji_10"])
|
216
|
+
#
|
217
|
+
all_datas["feng_riqian_5"].append(sup_before["feng_riqian_5"])
|
218
|
+
all_datas["guang_riqian_5"].append(sup_before["guang_riqian_5"])
|
219
|
+
all_datas["tong_riqian_5"].append(sup_before["tong_riqian_5"])
|
220
|
+
all_datas["lian_riqian_5"].append(sup_before["lian_riqian_5"])
|
221
|
+
all_datas["shuihuo_riqian_5"].append(
|
222
|
+
sup_before["tong_riqian_5"] - sup_before["lian_riqian_5"] - sup_before["feng_riqian_5"] - sup_before[
|
223
|
+
"guang_riqian_5"])
|
224
|
+
all_datas["feng_shiji_5"].append(sup_before["feng_shiji_5"])
|
225
|
+
all_datas["guang_shiji_5"].append(sup_before["guang_shiji_5"])
|
226
|
+
all_datas["tong_shiji_5"].append(sup_before["tong_shiji_5"])
|
227
|
+
all_datas["lian_shiji_5"].append(sup_before["lian_shiji_5"])
|
228
|
+
all_datas["shuihuo_shiji_5"].append(
|
229
|
+
sup_before["tong_shiji_5"] - sup_before["lian_shiji_5"] - sup_before["feng_shiji_5"] - sup_before[
|
230
|
+
"guang_shiji_5"])
|
231
|
+
#
|
232
|
+
all_datas["feng_riqian_3"].append(sup_before["feng_riqian_3"])
|
233
|
+
all_datas["guang_riqian_3"].append(sup_before["guang_riqian_3"])
|
234
|
+
all_datas["tong_riqian_3"].append(sup_before["tong_riqian_3"])
|
235
|
+
all_datas["lian_riqian_3"].append(sup_before["lian_riqian_3"])
|
236
|
+
all_datas["shuihuo_riqian_3"].append(
|
237
|
+
sup_before["tong_riqian_3"] - sup_before["lian_riqian_3"] - sup_before["feng_riqian_3"] - sup_before[
|
238
|
+
"guang_riqian_3"])
|
239
|
+
all_datas["feng_shiji_3"].append(sup_before["feng_shiji_3"])
|
240
|
+
all_datas["guang_shiji_3"].append(sup_before["guang_shiji_3"])
|
241
|
+
all_datas["tong_shiji_3"].append(sup_before["tong_shiji_3"])
|
242
|
+
all_datas["lian_shiji_3"].append(sup_before["lian_shiji_3"])
|
243
|
+
all_datas["shuihuo_shiji_3"].append(
|
244
|
+
sup_before["tong_shiji_3"] - sup_before["lian_shiji_3"] - sup_before["feng_shiji_3"] - sup_before[
|
245
|
+
"guang_shiji_3"])
|
246
|
+
#
|
247
|
+
#
|
248
|
+
#
|
249
|
+
if istrain:
|
250
|
+
all_datas["power_fact"].append(power_fact[idx])
|
251
|
+
all_datas["before_price"].append(sup_now['day_ahead_price'])
|
252
|
+
all_datas["real_price"].append(sup_now['electricity_price'])
|
253
|
+
all_datas["diff_price"].append(sup_now['day_ahead_price'] - sup_now['electricity_price'])
|
254
|
+
#
|
255
|
+
#
|
256
|
+
#
|
257
|
+
float_names = [name for name in float_names if name not in []]
|
258
|
+
# float_names = [name for name in float_names if name not in ["power_pred"]]
|
259
|
+
cate_names = []
|
260
|
+
#
|
261
|
+
all_datas = pd.DataFrame(all_datas)
|
262
|
+
#
|
263
|
+
all_datas["datetime"] = all_datas["datetime"].apply(
|
264
|
+
lambda x: datetime.datetime.strptime(str(x).strip(), '%Y-%m-%d %H:%M:%S'))
|
265
|
+
#
|
266
|
+
all_datas["weekday"] = all_datas["datetime"].apply(lambda x: x.weekday())
|
267
|
+
all_datas["hour"] = all_datas["datetime"].apply(lambda x: x.hour)
|
268
|
+
all_datas["month"] = all_datas["datetime"].apply(lambda x: x.month)
|
269
|
+
all_datas["holiday"] = all_datas["datetime"].apply(lambda x: 1 if x.date() in cn_holidays else 0)
|
270
|
+
all_datas["day"] = all_datas["datetime"].apply(lambda x: x.day)
|
271
|
+
#
|
272
|
+
# all_datas["next_month_first"] = all_datas["datetime"].apply(lambda x: datetime.datetime(x.year, x.month + 1, 1) if x.month != 12 else datetime.datetime(x.year + 1, 1, 1))
|
273
|
+
# all_datas["day_to_end"] = all_datas.apply(lambda x: (x["next_month_first"] - datetime.datetime(x["datetime"].year, x["datetime"].month, x["datetime"].day)).days, axis=1)
|
274
|
+
#
|
275
|
+
date_names = ["weekday", "hour", "month", "holiday"]
|
276
|
+
date_names = ["weekday", "hour", "month", "holiday", "day"]
|
277
|
+
# date_names = ["weekday", "hour", "month", "holiday", "day", "day_to_end"]
|
278
|
+
#
|
279
|
+
cate_names = cate_names + date_names
|
280
|
+
# float_names = float_names + date_names
|
281
|
+
#
|
282
|
+
return all_datas, float_names, cate_names
|
283
|
+
|
284
|
+
|
285
|
+
#
|
286
|
+
|
287
|
+
|
288
|
+
def smooth_data(power_fact, wind_half=5):
|
289
|
+
datas = []
|
290
|
+
for idx in range(len(power_fact)):
|
291
|
+
left = max(0, idx - wind_half)
|
292
|
+
right = min(len(power_fact), idx + wind_half + 1)
|
293
|
+
#
|
294
|
+
datas.append(sum(power_fact[left:right]) / (right - left))
|
295
|
+
return datas
|
296
|
+
|
297
|
+
|
298
|
+
#
|
299
|
+
|
300
|
+
|
301
|
+
def smooth_data_double(power_fact, date_points=96, wind_half=5):
|
302
|
+
if len(power_fact) % date_points != 0:
|
303
|
+
return power_fact
|
304
|
+
#
|
305
|
+
dates_num = len(power_fact) // date_points
|
306
|
+
#
|
307
|
+
power_fact = power_fact.reshape(-1, date_points)
|
308
|
+
#
|
309
|
+
logger.info(f"date_points: {dates_num, date_points}")
|
310
|
+
#
|
311
|
+
power_fact_smooth = [[0.0] * date_points for i in range(dates_num)]
|
312
|
+
for idx in range(date_points):
|
313
|
+
#
|
314
|
+
for idy in range(dates_num):
|
315
|
+
left = max(0, idy - wind_half)
|
316
|
+
right = min(dates_num, idy + wind_half + 1)
|
317
|
+
#
|
318
|
+
power_fact_smooth[idy][idx] = sum(power_fact[left:right, idx]) / (right - left)
|
319
|
+
#
|
320
|
+
power_fact_smooth = np.array(power_fact_smooth).reshape(-1)
|
321
|
+
return power_fact_smooth
|
322
|
+
|
323
|
+
|
324
|
+
#
|
325
|
+
|
326
|
+
|
327
|
+
def smooth_data_left(power_fact, date_points=96, wind_half=5):
|
328
|
+
if len(power_fact) % date_points != 0:
|
329
|
+
return power_fact
|
330
|
+
#
|
331
|
+
dates_num = len(power_fact) // date_points
|
332
|
+
#
|
333
|
+
power_fact = power_fact.reshape(-1, date_points)
|
334
|
+
#
|
335
|
+
logger.info(f"date_points: {dates_num, date_points}")
|
336
|
+
#
|
337
|
+
power_fact_smooth = [[0.0] * date_points for i in range(dates_num)]
|
338
|
+
for idx in range(date_points):
|
339
|
+
#
|
340
|
+
for idy in range(dates_num):
|
341
|
+
left = max(0, idy - wind_half)
|
342
|
+
right = idy + 1
|
343
|
+
#
|
344
|
+
power_fact_smooth[idy][idx] = sum(power_fact[left:right, idx]) / (right - left)
|
345
|
+
#
|
346
|
+
power_fact_smooth = np.array(power_fact_smooth).reshape(-1)
|
347
|
+
return power_fact_smooth
|
348
|
+
|
349
|
+
|
350
|
+
#
|
351
|
+
|
352
|
+
def smooth_left_data(power_fact, wind_half=5):
|
353
|
+
datas = []
|
354
|
+
for idx in range(len(power_fact)):
|
355
|
+
left = max(0, idx - wind_half)
|
356
|
+
# right = min(len(power_fact), idx + wind_half + 1)
|
357
|
+
right = idx + 1
|
358
|
+
#
|
359
|
+
datas.append(sum(power_fact[left:right]) / (right - left))
|
360
|
+
return datas
|
361
|
+
|
362
|
+
|
363
|
+
#
|
364
|
+
|
365
|
+
|
366
|
+
def process_market(market, day_point=96):
|
367
|
+
#
|
368
|
+
# market['day_ahead_price'] = smooth_data_double(market['day_ahead_price'].to_numpy(), date_points=day_point, wind_half=5)
|
369
|
+
# market['electricity_price'] = smooth_data_double(market['electricity_price'].to_numpy(), date_points=day_point, wind_half=5)
|
370
|
+
#
|
371
|
+
market['day_ahead_price'] = smooth_data_left(market['day_ahead_price'].to_numpy(), date_points=day_point,
|
372
|
+
wind_half=5)
|
373
|
+
market['electricity_price'] = smooth_data_left(market['electricity_price'].to_numpy(), date_points=day_point,
|
374
|
+
wind_half=5)
|
375
|
+
#
|
376
|
+
market['feng_riqian_10'] = smooth_data_left(market['wind_power_day_ahead'].to_numpy(), date_points=day_point,
|
377
|
+
wind_half=10)
|
378
|
+
market['guang_riqian_10'] = smooth_data_left(market['pv_power_day_ahead'].to_numpy(), date_points=day_point,
|
379
|
+
wind_half=10)
|
380
|
+
market['tong_riqian_10'] = smooth_data_left(market['provincial_load_forecast'].to_numpy(), date_points=day_point,
|
381
|
+
wind_half=10)
|
382
|
+
market['lian_riqian_10'] = smooth_data_left(market['day_ahead_tieline_power'].to_numpy(), date_points=day_point,
|
383
|
+
wind_half=10)
|
384
|
+
#
|
385
|
+
market['feng_shiji_10'] = smooth_data_left(market['wind_power_actual_value'].to_numpy(), date_points=day_point,
|
386
|
+
wind_half=10)
|
387
|
+
market['guang_shiji_10'] = smooth_data_left(market['pv_actual_value'].to_numpy(), date_points=day_point,
|
388
|
+
wind_half=10)
|
389
|
+
market['tong_shiji_10'] = smooth_data_left(market['system_load_actual_value'].to_numpy(), date_points=day_point,
|
390
|
+
wind_half=10)
|
391
|
+
market['lian_shiji_10'] = smooth_data_left(market['tie_line_out_actual_value'].to_numpy(), date_points=day_point,
|
392
|
+
wind_half=10)
|
393
|
+
#
|
394
|
+
market['feng_riqian_5'] = smooth_data_left(market['wind_power_day_ahead'].to_numpy(), date_points=day_point,
|
395
|
+
wind_half=5)
|
396
|
+
market['guang_riqian_5'] = smooth_data_left(market['pv_power_day_ahead'].to_numpy(), date_points=day_point,
|
397
|
+
wind_half=5)
|
398
|
+
market['tong_riqian_5'] = smooth_data_left(market['provincial_load_forecast'].to_numpy(), date_points=day_point,
|
399
|
+
wind_half=5)
|
400
|
+
market['lian_riqian_5'] = smooth_data_left(market['day_ahead_tieline_power'].to_numpy(), date_points=day_point,
|
401
|
+
wind_half=5)
|
402
|
+
#
|
403
|
+
market['feng_shiji_5'] = smooth_data_left(market['wind_power_actual_value'].to_numpy(), date_points=day_point,
|
404
|
+
wind_half=5)
|
405
|
+
market['guang_shiji_5'] = smooth_data_left(market['pv_actual_value'].to_numpy(), date_points=day_point, wind_half=5)
|
406
|
+
market['tong_shiji_5'] = smooth_data_left(market['system_load_actual_value'].to_numpy(), date_points=day_point,
|
407
|
+
wind_half=5)
|
408
|
+
market['lian_shiji_5'] = smooth_data_left(market['tie_line_out_actual_value'].to_numpy(), date_points=day_point,
|
409
|
+
wind_half=5)
|
410
|
+
#
|
411
|
+
market['feng_riqian_3'] = smooth_data_left(market['wind_power_day_ahead'].to_numpy(), date_points=day_point,
|
412
|
+
wind_half=3)
|
413
|
+
market['guang_riqian_3'] = smooth_data_left(market['pv_power_day_ahead'].to_numpy(), date_points=day_point,
|
414
|
+
wind_half=3)
|
415
|
+
market['tong_riqian_3'] = smooth_data_left(market['provincial_load_forecast'].to_numpy(), date_points=day_point,
|
416
|
+
wind_half=3)
|
417
|
+
market['lian_riqian_3'] = smooth_data_left(market['day_ahead_tieline_power'].to_numpy(), date_points=day_point,
|
418
|
+
wind_half=3)
|
419
|
+
#
|
420
|
+
market['feng_shiji_3'] = smooth_data_left(market['wind_power_actual_value'].to_numpy(), date_points=day_point,
|
421
|
+
wind_half=3)
|
422
|
+
market['guang_shiji_3'] = smooth_data_left(market['pv_actual_value'].to_numpy(), date_points=day_point, wind_half=3)
|
423
|
+
market['tong_shiji_3'] = smooth_data_left(market['system_load_actual_value'].to_numpy(), date_points=day_point,
|
424
|
+
wind_half=3)
|
425
|
+
market['lian_shiji_3'] = smooth_data_left(market['tie_line_out_actual_value'].to_numpy(), date_points=day_point,
|
426
|
+
wind_half=3)
|
427
|
+
#
|
428
|
+
#
|
429
|
+
#
|
430
|
+
market['before_smooth_5'] = smooth_data_left(market['day_ahead_price'].to_numpy(), date_points=day_point,
|
431
|
+
wind_half=5)
|
432
|
+
market['real_smooth_5'] = smooth_data_left(market['electricity_price'].to_numpy(), date_points=day_point,
|
433
|
+
wind_half=5)
|
434
|
+
#
|
435
|
+
return market
|
436
|
+
|
437
|
+
|
438
|
+
#
|
439
|
+
|
440
|
+
def process_weather(weather):
|
441
|
+
timestamps = sorted(list(set([wea['timestamp'] for wea in weather])))
|
442
|
+
print(f"timestamps: {len(timestamps), len(weather)}")
|
443
|
+
#
|
444
|
+
wea_keys = [
|
445
|
+
"tem_day",
|
446
|
+
"tem_night",
|
447
|
+
"win_meter",
|
448
|
+
"humidity",
|
449
|
+
# "visibility",
|
450
|
+
# "pressure",
|
451
|
+
# "cloudPct",
|
452
|
+
]
|
453
|
+
|
454
|
+
weather_datas = {"timestamp": []}
|
455
|
+
for key in wea_keys:
|
456
|
+
#
|
457
|
+
weather_datas[f"{key}_max"] = []
|
458
|
+
weather_datas[f"{key}_mean"] = []
|
459
|
+
#
|
460
|
+
for idx in range(10):
|
461
|
+
suf = int(idx * 10)
|
462
|
+
weather_datas[f"{key}_{suf}"] = []
|
463
|
+
#
|
464
|
+
for idx, ts in enumerate(timestamps):
|
465
|
+
weather_ts = [wea for wea in weather if wea['timestamp'] == ts]
|
466
|
+
#
|
467
|
+
for key in wea_keys:
|
468
|
+
key_data = [wea[key] for wea in weather_ts]
|
469
|
+
key_data = sorted(key_data)
|
470
|
+
#
|
471
|
+
weather_datas[f"{key}_max"].append(key_data[-1])
|
472
|
+
weather_datas[f"{key}_mean"].append(sum(key_data) / len(key_data))
|
473
|
+
#
|
474
|
+
for idx in range(10):
|
475
|
+
suf = int(idx * 10)
|
476
|
+
weather_datas[f"{key}_{suf}"].append(key_data[int(idx * len(key_data) / 10)])
|
477
|
+
#
|
478
|
+
weather_datas[f"timestamp"].append(ts[:10])
|
479
|
+
#
|
480
|
+
weather_datas = pd.DataFrame(weather_datas)
|
481
|
+
return weather_datas, wea_keys
|
482
|
+
|
483
|
+
|
484
|
+
#
|
485
|
+
|
486
|
+
def train():
|
487
|
+
#
|
488
|
+
day_point = 96
|
489
|
+
#
|
490
|
+
#
|
491
|
+
cn_holidays = holidays.CountryHoliday('CN')
|
492
|
+
#
|
493
|
+
system_date = EpSystem.get_system_date() # 输出 eg:2025-01-01
|
494
|
+
dt1 = datetime.datetime.strptime("2024-01-01", "%Y-%m-%d")
|
495
|
+
dt2 = datetime.datetime.strptime(system_date, "%Y-%m-%d")
|
496
|
+
gaps = dt2 - dt1
|
497
|
+
gap_days = gaps.days
|
498
|
+
#
|
499
|
+
logger.info(f"system_date: {system_date}")
|
500
|
+
logger.info(f"gap_days: {gap_days}")
|
501
|
+
#
|
502
|
+
# gap_days = 500
|
503
|
+
#
|
504
|
+
# system_date - 1: 所有字段
|
505
|
+
data = EpData.get_history_data(scope="weather,plant,market", days=gap_days)
|
506
|
+
# data = EpData.get_history_data(scope=["weather","plant","market"], days=gap_days)
|
507
|
+
#
|
508
|
+
#
|
509
|
+
plant = data.get("plant")
|
510
|
+
market = data.get("market")
|
511
|
+
weather = data.get("weather")
|
512
|
+
#
|
513
|
+
plant = sorted(plant, key=lambda x: x["timestamp"])
|
514
|
+
market = sorted(market, key=lambda x: x["timestamp"])
|
515
|
+
#
|
516
|
+
#
|
517
|
+
logger.info(f"plant: {len(plant), plant[0], plant[-1]}")
|
518
|
+
logger.info(f"market: {len(market), market[0], market[-1]}")
|
519
|
+
#
|
520
|
+
#
|
521
|
+
plant = pd.DataFrame.from_dict(plant)
|
522
|
+
market = pd.DataFrame.from_dict(market)
|
523
|
+
#
|
524
|
+
market = process_market(market, day_point=day_point)
|
525
|
+
#
|
526
|
+
weather, wea_keys = process_weather(weather)
|
527
|
+
# for key in wea_keys:
|
528
|
+
# key = key + "_mean"
|
529
|
+
# weather[f"{key}_3"] = smooth_left_data(weather[key].to_numpy(), wind_half=3)
|
530
|
+
# weather[f"{key}_5"] = smooth_left_data(weather[key].to_numpy(), wind_half=5)
|
531
|
+
# # weather[f"{key}_10"] = smooth_left_data(weather[key].to_numpy(), wind_half=10)
|
532
|
+
# #
|
533
|
+
#
|
534
|
+
#
|
535
|
+
#
|
536
|
+
all_datas, float_names, cate_names = get_data_label(market, plant, weather=weather, istrain=True)
|
537
|
+
#
|
538
|
+
#
|
539
|
+
#
|
540
|
+
logger.info(f"all_datas: {len(all_datas), len(market), len(plant)}")
|
541
|
+
logger.info(f"float_names: {float_names}")
|
542
|
+
#
|
543
|
+
#
|
544
|
+
#
|
545
|
+
for name in cate_names:
|
546
|
+
all_datas[name] = all_datas[name].astype('category')
|
547
|
+
for name in float_names:
|
548
|
+
all_datas[name] = all_datas[name].astype(float)
|
549
|
+
#
|
550
|
+
#
|
551
|
+
#
|
552
|
+
day_valid = day_point * 15
|
553
|
+
#
|
554
|
+
#
|
555
|
+
train_data = all_datas[:-day_valid].reset_index(drop=True)
|
556
|
+
valid_data = all_datas[-day_valid:].reset_index(drop=True)
|
557
|
+
#
|
558
|
+
X_all_train, x_train, x_valid = all_datas[float_names + cate_names], train_data[float_names + cate_names], \
|
559
|
+
valid_data[float_names + cate_names]
|
560
|
+
#
|
561
|
+
#
|
562
|
+
#
|
563
|
+
lr_riqian = 0.15
|
564
|
+
lr_shishi = 0.12
|
565
|
+
#
|
566
|
+
target = "before_price"
|
567
|
+
y_all_train, y_train, y_valid = all_datas[target], train_data[target], valid_data[target]
|
568
|
+
#
|
569
|
+
y_valid_pred_before, y_train_pred_before, model_before = simple_reg_price(x_train, y_train, x_valid, y_valid,
|
570
|
+
cate_fea=cate_names, lr=lr_riqian)
|
571
|
+
loss_valid = np.mean((y_valid_pred_before - y_valid) ** 2)
|
572
|
+
loss_train = np.mean((y_train_pred_before - y_train) ** 2)
|
573
|
+
logger.info(f"riqian: best_iter: {model_before.best_iteration}, loss_valid: {loss_valid}, loss_train: {loss_train}")
|
574
|
+
model_before = eval_reg_price(X_all_train, y_all_train, model_before.best_iteration, cate_fea=cate_names,
|
575
|
+
lr=lr_riqian)
|
576
|
+
#
|
577
|
+
#
|
578
|
+
#
|
579
|
+
target = "real_price" # before_price, real_price, diff_price
|
580
|
+
y_all_train, y_train, y_valid = all_datas[target], train_data[target], valid_data[target]
|
581
|
+
#
|
582
|
+
y_valid_pred_shishi, y_train_pred_shishi, model_real = simple_reg_price(x_train, y_train, x_valid, y_valid,
|
583
|
+
cate_fea=cate_names, lr=lr_shishi)
|
584
|
+
loss_valid = np.mean((y_valid_pred_shishi - y_valid) ** 2)
|
585
|
+
loss_train = np.mean((y_train_pred_shishi - y_train) ** 2)
|
586
|
+
logger.info(f"shishi: best_iter: {model_real.best_iteration}, loss_valid: {loss_valid}, loss_train: {loss_train}")
|
587
|
+
model_real = eval_reg_price(X_all_train, y_all_train, model_real.best_iteration, cate_fea=cate_names, lr=lr_shishi)
|
588
|
+
#
|
589
|
+
#
|
590
|
+
#
|
591
|
+
reqian_res = {}
|
592
|
+
reqian_res['model_before'] = model_before
|
593
|
+
reqian_res['float_names'] = float_names
|
594
|
+
reqian_res['cate_names'] = cate_names
|
595
|
+
reqian_res['model_real'] = model_real
|
596
|
+
#
|
597
|
+
#
|
598
|
+
#
|
599
|
+
base = "./tmp"
|
600
|
+
if not os.path.exists(base):
|
601
|
+
os.makedirs(base)
|
602
|
+
#
|
603
|
+
with open(f'{base}/riqian_price.pickle', 'wb') as handle:
|
604
|
+
pickle.dump(reqian_res, handle)
|
605
|
+
#
|
606
|
+
#
|
607
|
+
logger.info("train done!")
|
608
|
+
#
|
609
|
+
EpSystem.call_train_done()
|
610
|
+
|
611
|
+
|
612
|
+
#
|
613
|
+
|
614
|
+
|
615
|
+
#
|
616
|
+
#
|
617
|
+
inited = False
|
618
|
+
riqian_model = None
|
619
|
+
riqian_cate = None
|
620
|
+
riqian_float = None
|
621
|
+
shishi_model = None
|
622
|
+
cn_holidays = holidays.CountryHoliday('CN')
|
623
|
+
|
624
|
+
|
625
|
+
def initialize():
|
626
|
+
global inited, riqian_model, riqian_cate, riqian_float, shishi_model
|
627
|
+
#
|
628
|
+
#
|
629
|
+
#
|
630
|
+
base = "./tmp"
|
631
|
+
path = f'{base}/riqian_price.pickle'
|
632
|
+
#
|
633
|
+
logger.info(f"loading model from {path}")
|
634
|
+
#
|
635
|
+
#
|
636
|
+
with open(path, 'rb') as f:
|
637
|
+
# riqian_res = pickle.load(f)ode-file/20250522041137_submit_0521.py/riqian_price.pickle'
|
638
|
+
#
|
639
|
+
riqian_res = pickle.load(f)
|
640
|
+
riqian_model = riqian_res["model_before"]
|
641
|
+
riqian_cate = riqian_res["cate_names"]
|
642
|
+
riqian_float = riqian_res["float_names"]
|
643
|
+
shishi_model = riqian_res["model_real"]
|
644
|
+
#
|
645
|
+
#
|
646
|
+
inited = True
|
647
|
+
#
|
648
|
+
|
649
|
+
|
650
|
+
#
|
651
|
+
|
652
|
+
|
653
|
+
def get_baoliang(riqian_pred, shishi_pred, power_pred):
|
654
|
+
#
|
655
|
+
min_report, max_report, step = 0, 50, 0.1
|
656
|
+
|
657
|
+
#
|
658
|
+
def get_factor(diff1, diff2, p_power):
|
659
|
+
# [0, 1000] -> [1, 0.1]
|
660
|
+
#
|
661
|
+
maxv = 250
|
662
|
+
diff1 = min(diff1, maxv)
|
663
|
+
factor1 = ((maxv - diff1) / maxv) ** 2 + 0.00
|
664
|
+
#
|
665
|
+
rate = min(diff2 / (0.4 * max(p_power, 0.1)), 3) + 0.00
|
666
|
+
#
|
667
|
+
return factor1 * rate
|
668
|
+
|
669
|
+
#
|
670
|
+
punish = 0.22
|
671
|
+
|
672
|
+
def get_profit(baoliang, r_price, s_price, p_power, bad_point):
|
673
|
+
#
|
674
|
+
risk = 0
|
675
|
+
profit_factor = (baoliang - p_power) * (r_price - s_price)
|
676
|
+
#
|
677
|
+
#
|
678
|
+
punish_factor = punish
|
679
|
+
#
|
680
|
+
if bad_point:
|
681
|
+
punish_factor = punish_factor * 100
|
682
|
+
#
|
683
|
+
normal = abs(baoliang - p_power) / (max_report - p_power) if baoliang > p_power else (
|
684
|
+
abs(baoliang - p_power) / p_power if p_power != 0 else 0)
|
685
|
+
#
|
686
|
+
if profit_factor > 0:
|
687
|
+
profit_factor = min(abs(baoliang - p_power), 0.4 * p_power) * abs(r_price - s_price)
|
688
|
+
factor = get_factor(abs(r_price - s_price), abs(baoliang - p_power), p_power)
|
689
|
+
risk = punish_factor * abs(baoliang - p_power) * abs(r_price - s_price) * factor
|
690
|
+
#
|
691
|
+
profit_withdraw = profit_factor + p_power * r_price
|
692
|
+
#
|
693
|
+
#
|
694
|
+
return profit_withdraw - risk
|
695
|
+
# return baoliang * r_price + (p_power - baoliang) * s_price - punish * normal * abs(baoliang - p_power) * abs(r_price - s_price)
|
696
|
+
|
697
|
+
#
|
698
|
+
#
|
699
|
+
day_point = 96
|
700
|
+
baoliang_profit_map = []
|
701
|
+
#
|
702
|
+
for idx, (r_pred, s_pred, p_pred) in enumerate(zip(riqian_pred, shishi_pred, power_pred)):
|
703
|
+
#
|
704
|
+
# fadian = p_pred
|
705
|
+
fadian = p_pred + 1.5
|
706
|
+
# fadian = p_pred + 3.5
|
707
|
+
#
|
708
|
+
# bad_point = idx < 6 * 4 or idx > 22 * 4
|
709
|
+
bad_point = idx < 4 * 4 or idx > 22 * 4
|
710
|
+
#
|
711
|
+
except_profits = []
|
712
|
+
baoliang = min_report
|
713
|
+
#
|
714
|
+
while baoliang < max_report:
|
715
|
+
profit = get_profit(baoliang, r_pred, s_pred, fadian, bad_point)
|
716
|
+
except_profits.append(profit)
|
717
|
+
#
|
718
|
+
baoliang += step
|
719
|
+
baoliang_profit_map.append(except_profits)
|
720
|
+
#
|
721
|
+
#
|
722
|
+
# order1_max = 4.5
|
723
|
+
order1_max = 3.7
|
724
|
+
# order1_max = 3
|
725
|
+
#
|
726
|
+
range_skip = int(order1_max / step)
|
727
|
+
#
|
728
|
+
#
|
729
|
+
posi_num = int(max_report / step)
|
730
|
+
#
|
731
|
+
start = 0
|
732
|
+
pre_best = [[i for i in range(posi_num)]]
|
733
|
+
for point in range(start + 1, start + day_point):
|
734
|
+
best_pre = []
|
735
|
+
for idx in range(posi_num):
|
736
|
+
min_pos, max_pos = max(0, idx - range_skip), min(posi_num - 1, idx + range_skip)
|
737
|
+
index = np.argmax(baoliang_profit_map[point - 1][min_pos:max_pos]) + min_pos
|
738
|
+
baoliang_profit_map[point][idx] += baoliang_profit_map[point - 1][index]
|
739
|
+
best_pre.append(index)
|
740
|
+
pre_best.append(best_pre)
|
741
|
+
#
|
742
|
+
last_max = np.argmax(baoliang_profit_map[start + day_point - 1])
|
743
|
+
#
|
744
|
+
pre_list = [last_max]
|
745
|
+
for idx in range(len(pre_best) - 1, 0, -1):
|
746
|
+
last_max = pre_best[idx][last_max]
|
747
|
+
pre_list.append(last_max)
|
748
|
+
pre_list.reverse()
|
749
|
+
#
|
750
|
+
baoliangs = [v * step for v in pre_list]
|
751
|
+
#
|
752
|
+
return baoliangs
|
753
|
+
|
754
|
+
|
755
|
+
#
|
756
|
+
|
757
|
+
def predict():
|
758
|
+
global cn_holidays, inited, riqian_model, riqian_cate, riqian_float, shishi_model
|
759
|
+
#
|
760
|
+
# if not inited:
|
761
|
+
# initialize()
|
762
|
+
# #
|
763
|
+
initialize()
|
764
|
+
#
|
765
|
+
day_point = 96
|
766
|
+
#
|
767
|
+
target_date = EpSystem.get_system_date()
|
768
|
+
#
|
769
|
+
# system_date + 1: plant/weather
|
770
|
+
data = EpData.get_predict_data(scope="plant,weather")
|
771
|
+
#
|
772
|
+
#
|
773
|
+
if data is None or len(data) == 0:
|
774
|
+
return None
|
775
|
+
#
|
776
|
+
plant = data["plant"]
|
777
|
+
weather = data["weather"]
|
778
|
+
#
|
779
|
+
# system_date - 1: market
|
780
|
+
data = EpData.get_history_data(scope="market", days=11)
|
781
|
+
# data = EpData.get_history_data(scope=["market"], date=1)
|
782
|
+
market = data["market"]
|
783
|
+
#
|
784
|
+
#
|
785
|
+
plant = sorted(plant, key=lambda x: x["timestamp"])
|
786
|
+
market = sorted(market, key=lambda x: x["timestamp"])
|
787
|
+
#
|
788
|
+
# logger.info(f"plant: {len(plant), plant}")
|
789
|
+
logger.info(f"plant: {len(plant), plant[0], plant[-1]}")
|
790
|
+
logger.info(f"market: {len(market), market[0], market[-1]}")
|
791
|
+
#
|
792
|
+
#
|
793
|
+
plant = pd.DataFrame.from_dict(plant)
|
794
|
+
market = pd.DataFrame.from_dict(market)
|
795
|
+
#
|
796
|
+
market = process_market(market, day_point=day_point)
|
797
|
+
#
|
798
|
+
market = market.tail(day_point).reset_index(drop=True)
|
799
|
+
#
|
800
|
+
#
|
801
|
+
price_data, _, _ = get_data_label(market, plant, weather=None, istrain=False)
|
802
|
+
#
|
803
|
+
#
|
804
|
+
logger.info(f"price_data: {len(price_data), price_data.head(2)}")
|
805
|
+
#
|
806
|
+
#
|
807
|
+
for col in riqian_cate:
|
808
|
+
price_data[col] = price_data[col].astype('category')
|
809
|
+
for col in riqian_float:
|
810
|
+
price_data[col] = price_data[col].astype('float')
|
811
|
+
#
|
812
|
+
#
|
813
|
+
riqian_test = price_data[riqian_model.feature_name()]
|
814
|
+
riqian_pred = list(riqian_model.predict(riqian_test))
|
815
|
+
#
|
816
|
+
shishi_test = price_data[shishi_model.feature_name()]
|
817
|
+
shishi_pred = list(shishi_model.predict(shishi_test))
|
818
|
+
#
|
819
|
+
#
|
820
|
+
fadianpred = [float(v) for v in price_data["power_pred"].tolist()]
|
821
|
+
#
|
822
|
+
baoliangs = get_baoliang(riqian_pred, shishi_pred, fadianpred)
|
823
|
+
#
|
824
|
+
center = 13 * 4
|
825
|
+
baoliangs = [
|
826
|
+
val * (abs(idx - center) ** 4 / 40000 + 0.45) if idx >= 10 * 4 and idx <= 16 * 4 else val for idx, val in
|
827
|
+
enumerate(baoliangs)
|
828
|
+
]
|
829
|
+
baoliangs = [f"{val:.2f}" for val in baoliangs]
|
830
|
+
#
|
831
|
+
return baoliangs
|
832
|
+
#
|
833
|
+
|
834
|
+
|
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = '3.0.3.dev0'
|
@@ -1,24 +0,0 @@
|
|
1
|
-
import datetime
|
2
|
-
from turtle import pd
|
3
|
-
|
4
|
-
from ep_sdk_4pd.ep_data import EpData
|
5
|
-
from ep_sdk_4pd.ep_system import EpSystem
|
6
|
-
|
7
|
-
|
8
|
-
def test_history_data():
|
9
|
-
print('-------------test_history_data-------------')
|
10
|
-
|
11
|
-
system_data = EpSystem.get_system_date()
|
12
|
-
dt1 = datetime.datetime.strptime("2024-01-01", "%Y-%m-%d")
|
13
|
-
dt2 = datetime.datetime.strptime(system_data, "%Y-%m-%d")
|
14
|
-
gaps = dt2 - dt1
|
15
|
-
gap_days = gaps.days
|
16
|
-
print("gap_days:", gap_days)
|
17
|
-
|
18
|
-
data = EpData.get_history_data(scope="market",days=gap_days)
|
19
|
-
print(data)
|
20
|
-
print('-------------------------------------')
|
21
|
-
|
22
|
-
|
23
|
-
if __name__ == '__main__':
|
24
|
-
test_history_data()
|
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
|
File without changes
|