File size: 3,922 Bytes
d39b93e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import pandas as pd
import requests
import time
import apimoex

from datetime import datetime, timedelta
from news import NewsData

class GetNewData:
    def __init__(self, stock_name) -> None:
        """Этот класс парсит данные"""
        self.news = NewsData() 
        self.stock_name = stock_name # Название акции
       
    def downolad_stock(self):
        # Исправляем название акции, просто акция поменяла свое названия
        if self.stock_name == 'YNDX':
            self.stock_name = 'YDEX'
        
        # Тут мы будем делать до 5 итерацыя, если возниканет ошибка с сервером московской биржы, иногда он просто не находит акции
        for _ in range(5):
            try:
                # Дата с которой будет начинатся наш датасет
                new_date = datetime.now().replace(minute=0, second=0, microsecond=0) - timedelta(days=24*30) 
                new_date = str(new_date.strftime('%Y-%m-%d %H:%M')) 

                # Запросы к московской бирже, и создания датасета 
                with requests.Session() as session:
                    # Получаем данные с биржи
                    market_data = apimoex.get_board_candles(session, security=self.stock_name, market='shares', columns=['close', 'begin', 'volume'],
                                                 start=new_date, interval=60)
                    
                    df = pd.DataFrame(market_data)
                    df.columns = ['CLOSE', 'DATE', 'VOL']

                df['DATE'] = pd.to_datetime(df['DATE'])
                df['day'] = df['DATE'].dt.day
                df['year'] = df['DATE'].dt.year
                df['month'] = df['DATE'].dt.month
                df['hour'] = df['DATE'].dt.hour
                
                # Генерим лаги для модели
                for i in range(1, 10+1):
                    df[f'lag_{i+24}'] = df['CLOSE'].shift(i)

                df['lag_24'] = df['CLOSE']
                break
            except:
                # Если возникнет ошибка, то мы будем ждать 5 секунд и повторять все действия снова
                time.sleep(5)
        return df 
    
    def get_full_data(self):
        """Функция для получения полного датасета"""
        articles_data = self.news.get_data() # Получаем данные о новостями
        stock = self.downolad_stock() # Получаем данные о биржи

        # Обеденяем датасеты
        news_ = articles_data.drop(columns=['DATE']).groupby(['day', 'month', 'year', 'hour']).agg({
            'sentiment_negative': 'mean',  
            'sentiment_neutral': 'mean',
            'sentiment_positive': 'mean',
            'url': lambda x: list(x),
            'title': lambda x: list(x)
        }).reset_index()

        merged_df = pd.merge(stock, news_, how='left', on=['year', 'month', 'day', 'hour'], suffixes=('', '_y')).bfill().ffill()
        merged_df = merged_df.sort_values(by=['DATE'])
        
        # Расчитываем важность статей
        merged_df['super'] =  merged_df['sentiment_positive'] + merged_df['sentiment_neutral']

        string = ''
        string += '\n Самые полезные статьи для прогнозов: \n'

        for url, v, title  in merged_df[-72:].sort_values('super', ascending=False)[['url', 'super', 'title']].values[:10]:
            for u, t in zip(url, title):
                string += f'- [New: {t}]({u}), важность признака: {v} \n'
            
        return merged_df, string