Анастасия commited on
Commit
e6e1c35
·
1 Parent(s): 6c92f5c
pages/1_📈_Прогноз_индекса. Prophet.py ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import yfinance as yf
3
+ import pandas as pd
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ from datetime import date
7
+ from prophet import Prophet
8
+ from prophet.plot import plot_plotly
9
+ from plotly import graph_objs as go
10
+ from prophet.make_holidays import make_holidays_df
11
+ from sklearn.metrics import mean_absolute_error, mean_squared_error
12
+
13
+ st.set_page_config(layout='wide', initial_sidebar_state='expanded')
14
+ st.set_option('deprecation.showPyplotGlobalUse', False)
15
+ st.title('ML Wall Street')
16
+ st.image('images/img.png')
17
+
18
+ START = "2021-01-01"
19
+ TODAY = date.today().strftime("%Y-%m-%d")
20
+
21
+ period = st.slider('Количество дней прогноза:', 1, 14, 14)
22
+
23
+ # @st.cache_data
24
+ def load_data():
25
+ dji = yf.download('^DJI', START, TODAY)
26
+ dji.reset_index(inplace=True)
27
+ data_500 = yf.download('^GSPC', START, TODAY)
28
+ data_500.reset_index(inplace=True)
29
+ sse = yf.download('000001.SS', START, TODAY)
30
+ sse.reset_index(inplace=True)
31
+ imoex = yf.download('IMOEX.ME', START, TODAY)
32
+ imoex.reset_index(inplace=True)
33
+ return dji, data_500, sse, imoex
34
+
35
+ dji, data_500, sse, imoex = load_data()
36
+ latest_date = dji['Date'].iloc[-1].strftime('%Y-%m-%d')
37
+ st.markdown(f"<h3 style='text-align: center;'>Цены актуальны на последнюю дату закрытия торгов {latest_date}</h3>", unsafe_allow_html=True)
38
+ # # Добавляем кнопку обновления данных
39
+ # if st.button("Обновить данные", type="primary"):
40
+ # dji = yf.download('^DJI', START, TODAY)
41
+ # dji.reset_index(inplace=True)
42
+ # data_500 = yf.download('^GSPC', START, TODAY)
43
+ # data_500.reset_index(inplace=True)
44
+ # sse = yf.download('000001.SS', START, TODAY)
45
+ # sse.reset_index(inplace=True)
46
+ # imoex = yf.download('IMOEX.ME', START, TODAY)
47
+ # imoex.reset_index(inplace=True)
48
+ # st.success("Данные успешно обновлены!")
49
+
50
+ # if st.button("или Обновить данные", type="primary"):
51
+ # dji, data_500, sse, imoex = load_data()
52
+
53
+ def evaluate_trend_first_day(predicted_value, actual_value):
54
+ # Разница между первым днем прогноза и последним днем тестовых данных
55
+ forecast_diff_first_last = predicted_value - actual_value
56
+
57
+ # Оценка тренда на первый день: рост, падение, стабильность
58
+ if forecast_diff_first_last > 0:
59
+ return "Тенденция на первый день: Рост"
60
+ elif forecast_diff_first_last < 0:
61
+ return "Тенденция на первый день: Падение"
62
+ else:
63
+ return "Тенденция на первый день: Стабильность"
64
+
65
+ def evaluate_trend_period(forecast_14_days):
66
+ # Разница между первым и последним значением прогноза
67
+ forecast_diff = forecast_14_days['yhat'].iloc[-1] - forecast_14_days['yhat'].iloc[0]
68
+
69
+ # Оценка тренда на весь период прогноза: рост, падение, стабильность
70
+ print("Разница между первым и последним значением прогноза:", forecast_diff)
71
+
72
+ if forecast_diff > 0:
73
+ return "Тенденция на период прогноза: Рост"
74
+ elif forecast_diff < 0:
75
+ return "Тенденция на период прогноза: Падение"
76
+ else:
77
+ return "Тенденция на период прогноза: Стабильность"
78
+
79
+
80
+ # Формирование календаря для США
81
+ year_2023 = 2023
82
+ # Создаем DataFrame с встроенными праздниками для 2023
83
+ holidays_df_2023 = make_holidays_df(year_list=[year_2023], country='US')
84
+ # Преобразуем входные строки в datetime
85
+ holidays_df_2023['ds'] = pd.to_datetime(holidays_df_2023['ds'])
86
+ # Создаем DataFrame с кастомными праздниками для 2024 года
87
+ custom_holidays_2024 = pd.DataFrame({
88
+ 'holiday': 'custom',
89
+ 'ds': pd.to_datetime([
90
+ '2024-01-01', # Новый год
91
+ '2024-01-15', # День Мартина Лютера Кинга младшего
92
+ '2024-02-19', # День рождения Дж. Вашингтона (Washington’s Birthday)
93
+ '2024-03-29', # Страстная пятница (Good Friday)
94
+ '2024-05-27', # День Памяти (Memorial Day)
95
+ '2024-06-19', # День национальной независимости | Juneteenth
96
+ '2024-07-04', # День независимости
97
+ '2024-09-02', # День труда
98
+ '2024-11-28', # День Благодарения
99
+ '2024-12-24', # Рождество
100
+ ]),
101
+ 'lower_window': 0,
102
+ 'upper_window': 1,
103
+ })
104
+ # Объединяем все DataFrame с праздниками
105
+ all_holidays_US = pd.concat([holidays_df_2023, custom_holidays_2024]).drop_duplicates(subset=['ds']).sort_values(by=['ds'])
106
+ # Создаем DataFrame с датами праздников
107
+ holidays_df_US = pd.DataFrame({
108
+ 'ds': all_holidays_US['ds'],
109
+ 'holiday': 'holiday',
110
+ })
111
+
112
+ # Формирование календаря для Китая
113
+ year_2023 = 2023
114
+ holidays_ch_2023 = make_holidays_df(year_list=[year_2023], country='China')
115
+ # Преобразуем входные строки в datetime
116
+ holidays_ch_2023['ds'] = pd.to_datetime(holidays_ch_2023['ds'])
117
+ # Создаем DataFrame с кастомными праздниками для 2024 года
118
+ custom_holidays_2024_ch = pd.DataFrame({
119
+ 'holiday': 'custom',
120
+ 'ds': pd.to_datetime([
121
+ '2024-01-01', # Новый год
122
+ '2024-02-12', # Китайский Новый Год
123
+ '2024-02-13', # Китайский Новый Год
124
+ '2024-03-29', # Страстная пятница (Good Friday)
125
+ '2024-04-01', # Пасхальный понедельник
126
+ '2024-04-04', # День ухода за могилами
127
+ '2024-05-01', # Праздник Труда
128
+ '2024-05-15', # День рождения Будды
129
+ '2024-06-10', # Фестиваль Туен Нг
130
+ '2024-07-01' # Праздник Специального Административного района
131
+ ]),
132
+ 'lower_window': 0,
133
+ 'upper_window': 1,
134
+ })
135
+ # Объединяем все DataFrame с праздниками
136
+ all_holidays_China = pd.concat([holidays_ch_2023, custom_holidays_2024_ch]).drop_duplicates(subset=['ds']).sort_values(by=['ds'])
137
+ # Создаем DataFrame с датами праздников
138
+ holidays_df_China = pd.DataFrame({
139
+ 'ds': all_holidays_China['ds'],
140
+ 'holiday': 'holiday',
141
+ })
142
+
143
+ # Формирование календаря для России
144
+ year_2023 = 2023
145
+ holidays_r_2023 = make_holidays_df(year_list=[year_2023], country='Russia')
146
+ # Преобразуем входные строки в datetime
147
+ holidays_r_2023['ds'] = pd.to_datetime(holidays_r_2023['ds'])
148
+ # Создаем DataFrame с кастомными праздниками для 2024 года
149
+ custom_holidays_2024_r = pd.DataFrame({
150
+ 'holiday': 'custom',
151
+ 'ds': pd.to_datetime([
152
+ '2024-01-01',
153
+ '2024-01-02',
154
+ '2024-02-23',
155
+ '2024-03-8',
156
+ '2024-05-01',
157
+ '2024-05-09',
158
+ '2024-06-12',
159
+ '2024-11-04'
160
+ ]),
161
+ 'lower_window': 0,
162
+ 'upper_window': 1,
163
+ })
164
+ # Объединяем все DataFrame с праздниками
165
+ all_holidays_r = pd.concat([holidays_r_2023, custom_holidays_2024_r]).drop_duplicates(subset=['ds']).sort_values(by=['ds'])
166
+ # Создаем DataFrame с датами праздников
167
+ all_holidays_r = pd.DataFrame({
168
+ 'ds': all_holidays_China['ds'],
169
+ 'holiday': 'holiday',
170
+ })
171
+
172
+ def index(ind, holidays_df, text1, text2, k=0):
173
+ data = ind
174
+ data = data.rename(columns={'Date': 'ds', 'Adj Close': 'y'})
175
+ # Сортируем данные по дате
176
+ data = data.sort_values(by='ds')
177
+ # Определяем индекс для разделения
178
+ split_index = len(data) - period
179
+
180
+ # Разделяем данные на обучающую и тестовую выборки
181
+ full_train_data3 = data.iloc[:split_index].copy()
182
+ full_test_data3 = data.iloc[split_index:].copy()
183
+
184
+ # Удаляем временную зону из столбца ds
185
+ full_train_data3['ds'] = full_train_data3['ds'].dt.tz_localize(None)
186
+ full_test_data3['ds'] = full_test_data3['ds'].dt.tz_localize(None)
187
+
188
+ # Создаем модель Prophet
189
+ model = Prophet(interval_width=0.95)
190
+ model.fit(full_train_data3)
191
+ # Создаем фрейм для прогноза на тестовых данных, исключая даты праздников
192
+ last_date = full_test_data3['ds'].max()
193
+ future = model.make_future_dataframe(periods=full_test_data3.shape[0]+k, freq='B')
194
+ future = future[~future['ds'].isin(holidays_df['ds'])]
195
+ forecast_test = model.predict(future)
196
+ # latest_date2 = forecast_test['ds'].iloc[-1]
197
+ # st.write(latest_date2)
198
+ # Создаем фрейм для прогноза на +14 дней после последней даты
199
+ future_14_days = model.make_future_dataframe(periods=period, freq='B', include_history=False)
200
+ future_14_days['ds'] = pd.date_range(start=last_date + pd.DateOffset(1), periods=period, freq='B')
201
+ forecast_14_days = model.predict(future_14_days)
202
+
203
+ # Отрисовка графика
204
+ fig = go.Figure()
205
+ fig = plot_plotly(model, forecast_test)
206
+ # full_test_data3 = full_test_data3.loc[full_test_data3['ds'].isin(forecast_test['ds'])]
207
+ fig.add_trace(go.Scatter(x=full_test_data3['ds'],
208
+ y=full_test_data3['y'],
209
+ mode='markers',
210
+ marker=dict(color='orchid'),
211
+ name='Факт тест'))
212
+ fig.add_trace(go.Scatter(x=forecast_test['ds'].iloc[-period:],
213
+ y=forecast_test['yhat'].iloc[-period:],
214
+ mode='lines+markers',
215
+ marker=dict(color='blue'),
216
+ name='Прогноз тест'))
217
+ fig.add_trace(go.Scatter(x=forecast_14_days['ds'], y=forecast_14_days['yhat'], mode='lines+markers', name='Прогноз будущее'))
218
+ fig.update_layout(title_text=text1, xaxis_rangeslider_visible=True, xaxis_title='', yaxis_title='')
219
+ fig.update_traces(showlegend=True)
220
+ st.plotly_chart(fig, use_container_width=True, range_slider_visible=True)
221
+ # Расчет метрик на тестовой выборке
222
+ actual_values_test = full_test_data3['y'].values
223
+ predicted_values_test = forecast_test['yhat'].iloc[-period:].values
224
+ mape_test = np.mean(np.abs((actual_values_test - predicted_values_test) / actual_values_test)) * 100
225
+ rmse_test = np.sqrt(mean_squared_error(actual_values_test, predicted_values_test))
226
+ check = st.checkbox(text2)
227
+ if check:
228
+ col1, col2 = st.columns([1, 1])
229
+ with col1:
230
+ st.write("**Информация.** \
231
+ Прогноз составлен на тестовой выборке с возможностью выбора периода до 14 дней. \
232
+ Дополнительно приведен прогноз для будущего периода с указанием тенденции дельнейшего развития.")
233
+ st.markdown("**Метрики для тестовой выборки:**")
234
+ st.write(f"MAPE: {mape_test:.2f}%")
235
+ st.write(f"RMSE: {rmse_test:.2f}")
236
+ # Оценка тренда на первый день
237
+ trend_evaluation_first_day = evaluate_trend_first_day(forecast_14_days['yhat'].iloc[0], full_test_data3['y'].iloc[-1])
238
+ st.write(trend_evaluation_first_day)
239
+ # Оценка тренда на период прогноза
240
+ trend_evaluation_period = evaluate_trend_period(forecast_14_days[['ds', 'yhat']])
241
+ st.write(trend_evaluation_period)
242
+ with col2:
243
+ forecast_results = pd.DataFrame({
244
+ 'Дата': forecast_14_days['ds'].iloc[-period:].values,
245
+ 'Прогноз': forecast_14_days['yhat'].iloc[-period:].values.round(2)
246
+ })
247
+ st.dataframe(forecast_results.set_index('Дата'))
248
+
249
+ text1_dji = f'График прогноза для {period} дней по индексу Dow Jones, USD 🇺🇸'
250
+ text2_dji = f"Результаты прогноза по Dow Jones Industrial Average"
251
+ index(dji, holidays_df_US, text1_dji, text2_dji, 1)
252
+
253
+ text1_500 = f'График прогноза для {period} дней по индексу S&P 500, USD 🇺🇸'
254
+ text2_500 = f"Результаты прогноза по S&P 500"
255
+ index(data_500, holidays_df_US, text1_500, text2_500, 1)
256
+
257
+ text1_sse = f'График прогноза для {period} дней по индексу SSE Composite, CNY 🇨🇳'
258
+ text2_sse = f"Результаты прогноза по SSE Composite Index"
259
+ index(sse, holidays_df_China, text1_sse, text2_sse)
260
+
261
+ text1_imoex = f'График прогноза для {period} дней по индексу MOEX Russia, RUB 🇷🇺'
262
+ text2_imoex = f"Результаты прогноза по MOEX Russia Index"
263
+ index(imoex, all_holidays_r, text1_imoex, text2_imoex, 0)
pages/2_💲 _Прогноз_акций. Prophet.py ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import yfinance as yf
3
+ import pandas as pd
4
+ import numpy as np
5
+ import matplotlib.pyplot as plt
6
+ from datetime import date
7
+ from sklearn.model_selection import train_test_split
8
+ from prophet import Prophet
9
+ from prophet.plot import plot_plotly
10
+ from plotly import graph_objs as go
11
+ from prophet.make_holidays import make_holidays_df
12
+ from sklearn.metrics import mean_absolute_error, mean_squared_error
13
+
14
+ st.set_page_config(layout='wide', initial_sidebar_state='expanded')
15
+ st.set_option('deprecation.showPyplotGlobalUse', False)
16
+ st.title('ML Wall Street')
17
+ st.image('images/img.png')
18
+
19
+ START = "2020-01-01"
20
+ TODAY = date.today().strftime("%Y-%m-%d")
21
+
22
+ stocks = ('AAPL', 'UNH', 'MSFT', 'GS', 'HD', 'AMGN', 'MCD', 'CAT', 'CRM', 'V', 'BA', 'HON', 'TRV', 'AXP', 'JPM', 'IBM', 'JNJ', 'WMT', 'PG', 'CVX', 'MRK', 'MMM', 'NKE', 'DIS', 'KO', 'DOW', 'CSCO', 'INTC', 'VZ', 'WBA')
23
+ selected_stock = st.selectbox('Выберите тикер из индекса Dow Jones', stocks)
24
+
25
+ period = st.slider('Количество дней прогноза:', 1, 14, 14)
26
+
27
+ # @st.cache_data
28
+ def load_data(ticker):
29
+ data = yf.download(ticker, START, TODAY)
30
+ data.reset_index(inplace=True)
31
+ return data
32
+
33
+ data = load_data(selected_stock)
34
+ latest_date = data['Date'].iloc[-1].strftime('%Y-%m-%d')
35
+ st.markdown(f"<h3 style='text-align: center;'>Цены актуальны на последнюю дату закрытия торгов {latest_date}</h3>", unsafe_allow_html=True)
36
+
37
+ def evaluate_trend_first_day(predicted_value, actual_value):
38
+ # Разница между первым днем прогноза и последним днем тестовых данных
39
+ forecast_diff_first_last = predicted_value - actual_value
40
+
41
+ # Оценка тренда на первый день: рост, падение, стабильность
42
+ if forecast_diff_first_last > 0:
43
+ return "Тенденция на первый день: Рост"
44
+ elif forecast_diff_first_last < 0:
45
+ return "Тенденция на первый день: Падение"
46
+ else:
47
+ return "Тенденция на первый день: Стабильность"
48
+
49
+ def evaluate_trend_period(forecast_14_days):
50
+ # Разница между первым и последним значением прогноза
51
+ forecast_diff = forecast_14_days['yhat'].iloc[-1] - forecast_14_days['yhat'].iloc[0]
52
+
53
+ # Оценка тренда на весь период прогноза: рост, падение, стабильность
54
+ print("Разница между первым и последним значением прогноза:", forecast_diff)
55
+
56
+ if forecast_diff > 0:
57
+ return "Тенденция на период прогноза: Рост"
58
+ elif forecast_diff < 0:
59
+ return "Тенденция на период прогноза: Падение"
60
+ else:
61
+ return "Тенденция на период прогноза: Стабильность"
62
+
63
+ # Формирование календаря для США
64
+ year_2023 = 2023
65
+ # Создаем DataFrame с встроенными праздниками для 2023
66
+ holidays_df_2023 = make_holidays_df(year_list=[year_2023], country='US')
67
+ # Преобразуем входные строки в datetime
68
+ holidays_df_2023['ds'] = pd.to_datetime(holidays_df_2023['ds'])
69
+ # Создаем DataFrame с кастомными праздниками для 2024 года
70
+ custom_holidays_2024 = pd.DataFrame({
71
+ 'holiday': 'custom',
72
+ 'ds': pd.to_datetime([
73
+ '2024-01-01', # Новый год
74
+ '2024-01-15', # День Мартина Лютера Кинга младшего
75
+ '2024-02-19', # День рождения Дж. Вашингтона (Washington’s Birthday)
76
+ '2024-03-29', # Страстная пятница (Good Friday)
77
+ '2024-05-27', # День Памяти (Memorial Day)
78
+ '2024-06-19', # День национальной независимости | Juneteenth
79
+ '2024-07-04', # День независимости
80
+ '2024-09-02', # День труда
81
+ '2024-11-28', # День Благодарения
82
+ '2024-12-24', # Рождество
83
+ ]),
84
+ 'lower_window': 0,
85
+ 'upper_window': 1,
86
+ })
87
+ # Объединяем все DataFrame с праздниками
88
+ all_holidays_US = pd.concat([holidays_df_2023, custom_holidays_2024]).drop_duplicates(subset=['ds']).sort_values(by=['ds'])
89
+ # Создаем DataFrame с датами праздников
90
+ holidays_df_US = pd.DataFrame({
91
+ 'ds': all_holidays_US['ds'],
92
+ 'holiday': 'holiday',
93
+ })
94
+
95
+ def ticker(data, holidays_df, text1, text2, k):
96
+ data = data
97
+ data = data.rename(columns={'Date': 'ds', 'Adj Close': 'y'})
98
+ # Сортируем данные по дате
99
+ data = data.sort_values(by='ds')
100
+ # Определяем индекс для разделения
101
+ split_index = len(data) - period
102
+
103
+ # Разделяем данные на ��бучающую и тестовую выборки
104
+ full_train_data3 = data.iloc[:split_index].copy()
105
+ full_test_data3 = data.iloc[split_index:].copy()
106
+
107
+ # Удаляем временную зону из столбца ds
108
+ full_train_data3['ds'] = full_train_data3['ds'].dt.tz_localize(None)
109
+ full_test_data3['ds'] = full_test_data3['ds'].dt.tz_localize(None)
110
+ # st.write(full_test_data3)
111
+
112
+ # Создаем модель Prophet
113
+ model = Prophet(interval_width=0.95)
114
+ model.fit(full_train_data3)
115
+ # Создаем фрейм для прогноза на тестовых данных, исключая даты праздников
116
+ last_date = full_test_data3['ds'].max()
117
+ future = model.make_future_dataframe(periods=full_test_data3.shape[0]+k, freq='B')
118
+ future = future[~future['ds'].isin(holidays_df['ds'])]
119
+ forecast_test = model.predict(future)
120
+ # Создаем фрейм для прогноза на +14 дней после последней даты
121
+ future_14_days = model.make_future_dataframe(periods=14, freq='B', include_history=False)
122
+ future_14_days['ds'] = pd.date_range(start=last_date + pd.DateOffset(1), periods=14, freq='B')
123
+ forecast_14_days = model.predict(future_14_days)
124
+
125
+ # Отрисовка графика
126
+ fig = go.Figure()
127
+ fig = plot_plotly(model, forecast_test)
128
+ fig.add_trace(go.Scatter(x=full_test_data3['ds'],
129
+ y=full_test_data3['y'],
130
+ mode='markers',
131
+ marker=dict(color='orchid'),
132
+ name='Факт тест'))
133
+ fig.add_trace(go.Scatter(x=forecast_test['ds'].iloc[-period:],
134
+ y=forecast_test['yhat'].iloc[-period:],
135
+ mode='lines+markers',
136
+ marker=dict(color='blue'),
137
+ name='Прогноз тест'))
138
+ fig.add_trace(go.Scatter(x=forecast_14_days['ds'], y=forecast_14_days['yhat'], mode='lines+markers', name='Прогноз будущее'))
139
+ fig.update_layout(title_text=text1, xaxis_rangeslider_visible=True, xaxis_title='', yaxis_title='')
140
+ fig.update_traces(showlegend=True)
141
+ st.plotly_chart(fig, use_container_width=True, range_slider_visible=True)
142
+ # Расчет метрик на тестовой выборке
143
+ actual_values_test = full_test_data3['y'].values
144
+ predicted_values_test = forecast_test['yhat'].iloc[-period:].values
145
+ mape_test = np.mean(np.abs((actual_values_test - predicted_values_test) / actual_values_test)) * 100
146
+ rmse_test = np.sqrt(mean_squared_error(actual_values_test, predicted_values_test))
147
+ # Рассчитываем кастомную метрику точности прогноза для 1 дня с учетом весов предыдущих 7 дней
148
+ forecast_values = forecast_test['yhat'].tail(period).values
149
+ predicted_value = forecast_values[0] # Выбираем первый предсказанный день из последних 14
150
+ actual_values = full_test_data3['y'].tail(7).values
151
+ weights = np.array([1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4])
152
+ custom_mape = np.dot(weights, np.abs((actual_values - predicted_value) / actual_values)) / np.sum(weights) * 100
153
+ check = st.checkbox(text2)
154
+ if check:
155
+ col1, col2 = st.columns([1, 1])
156
+ with col1:
157
+ st.write("**Информация.** \
158
+ Прогноз составлен на тестовой выборке с возможностью выбора периода до 14 дней. \
159
+ Дополнительно приведен прогноз для будущего периода с указанием тенденции дельнейшего развития.")
160
+ st.markdown("**Метрики для тестовой выборки:**")
161
+ st.write(f"RMSE: {rmse_test:.2f}")
162
+ st.write(f"MAPE: {mape_test:.2f}%")
163
+ st.write(f"Weighted MAPE: {custom_mape:.2f}%")
164
+ # Оценка тренда на первый день
165
+ trend_evaluation_first_day = evaluate_trend_first_day(forecast_14_days['yhat'].iloc[0], full_test_data3['y'].iloc[-1])
166
+ st.write(trend_evaluation_first_day)
167
+ # Оценка тренда на период прогноза
168
+ trend_evaluation_period = evaluate_trend_period(forecast_14_days[['ds', 'yhat']])
169
+ st.write(trend_evaluation_period)
170
+ with col2:
171
+ forecast_results = pd.DataFrame({
172
+ 'Дата': forecast_14_days['ds'].iloc[-period:].values,
173
+ 'Прогноз': forecast_14_days['yhat'].iloc[-period:].values.round(2)
174
+ })
175
+ st.dataframe(forecast_results.set_index('Дата'))
176
+ # fig2 = data.plot_components(future_14_days)
177
+ # st.write(fig2)
178
+
179
+ text1 = f'График прогноза для {period} дней по акции {selected_stock}, USD 🇺🇸'
180
+ text2 = f"Резу��ьтаты прогноза {selected_stock}"
181
+ ticker(data, holidays_df_US, text1, text2, 1)
requirements.txt CHANGED
@@ -1,119 +1,10 @@
1
- altair==5.2.0
2
- annotated-types==0.6.0
3
- anyio==3.7.1
4
- appdirs==1.4.4
5
- appnope==0.1.3
6
- asttokens==2.4.1
7
- attrs==23.1.0
8
- beautifulsoup4==4.12.3
9
- blinker==1.7.0
10
- cachetools==5.3.2
11
- certifi==2023.11.17
12
- charset-normalizer==3.3.2
13
- click==8.1.7
14
- cmdstanpy==1.2.0
15
- comm==0.2.0
16
- contourpy==1.2.0
17
- cycler==0.12.1
18
- debugpy==1.8.0
19
- decorator==5.1.1
20
- exceptiongroup==1.2.0
21
- executing==2.0.1
22
- faiss-cpu==1.7.4
23
- fastapi==0.105.0
24
- filelock==3.13.1
25
- fonttools==4.46.0
26
- frozendict==2.4.0
27
- fsspec==2023.12.2
28
- gitdb==4.0.11
29
- GitPython==3.1.40
30
- h11==0.14.0
31
- holidays==0.41
32
- html5lib==1.1
33
- huggingface-hub==0.19.4
34
- idna==3.6
35
- importlib-metadata==6.11.0
36
- importlib-resources==6.1.1
37
- ipykernel==6.27.1
38
- ipython==8.18.1
39
- jedi==0.19.1
40
- Jinja2==3.1.2
41
- joblib==1.3.2
42
- jsonschema==4.20.0
43
- jsonschema-specifications==2023.11.2
44
- jupyter_client==8.6.0
45
- jupyter_core==5.5.0
46
- kiwisolver==1.4.5
47
- lxml==5.1.0
48
- markdown-it-py==3.0.0
49
- MarkupSafe==2.1.3
50
- matplotlib==3.8.2
51
- matplotlib-inline==0.1.6
52
- mdurl==0.1.2
53
- mpmath==1.3.0
54
- multitasking==0.0.11
55
- nest-asyncio==1.5.8
56
- networkx==3.2.1
57
- numpy==1.26.2
58
- packaging==23.2
59
- pandas==2.1.4
60
- parso==0.8.3
61
- peewee==3.17.0
62
- pexpect==4.9.0
63
- php==1.2.1
64
- Pillow==10.1.0
65
- platformdirs==4.1.0
66
  plotly==5.18.0
67
- prompt-toolkit==3.0.43
 
 
 
68
  prophet==1.1.5
69
- protobuf==4.25.1
70
- psutil==5.9.6
71
- ptyprocess==0.7.0
72
- pure-eval==0.2.2
73
- pyarrow==14.0.1
74
- pydantic==2.5.2
75
- pydantic_core==2.14.5
76
- pydeck==0.8.1b0
77
- Pygments==2.17.2
78
- pyparsing==3.1.1
79
- python-dateutil==2.8.2
80
- python-multipart==0.0.6
81
- pytz==2023.3.post1
82
- PyYAML==6.0.1
83
- pyzmq==25.1.2
84
- referencing==0.32.0
85
- regex==2023.10.3
86
- requests==2.31.0
87
- rich==13.7.0
88
- rpds-py==0.13.2
89
- safetensors==0.4.1
90
  scikit-learn==1.3.2
91
- scipy==1.11.4
92
- six==1.16.0
93
- smmap==5.0.1
94
- sniffio==1.3.0
95
- soupsieve==2.5
96
- stack-data==0.6.3
97
- stanio==0.3.0
98
- starlette==0.27.0
99
- streamlit==1.29.0
100
- sympy==1.12
101
- tenacity==8.2.3
102
- threadpoolctl==3.2.0
103
- tokenizers==0.15.0
104
- toml==0.10.2
105
- toolz==0.12.0
106
- tornado==6.4
107
- tqdm==4.66.1
108
- traitlets==5.14.0
109
- transformers==4.36.1
110
- typing_extensions==4.9.0
111
- tzdata==2023.3
112
- tzlocal==5.2
113
- urllib3==2.1.0
114
- uvicorn==0.24.0.post1
115
- validators==0.22.0
116
- wcwidth==0.2.12
117
- webencodings==0.5.1
118
- yfinance==0.2.36
119
- zipp==3.17.0
 
1
+ streamlit==1.28.1
2
+ pandas==2.1.2
3
+ yfinance==0.2.31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  plotly==5.18.0
5
+ plotly-express==0.4.1
6
+ numpy==1.26.1
7
+ matplotlib==3.8.1
8
+ matplotlib-inline==0.1.6
9
  prophet==1.1.5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  scikit-learn==1.3.2