Работа с финансовыми данными - часть II. - Временные ряды

RedDeveloper
11.04.2023 13:38
Работа с финансовыми данными - часть II. - Временные ряды

То, над чем мы работали ранее:

import requests
import pandas as pd
import numpy as np
from typing import Any

def simple_request(url: str) -> Any:
    assert isinstance(url, str), ‘url has to be a str’
    
    # Start the request workflow
    response = requests.get(url)
    
    if response.status_code != 200:
        return None
    
    response = response.json()

    # Check the results (Sometimes its 200, but empty content)
    if not response:
        print(‘Result is empty’)
        return None
    
    # Response was successfull
    return response


class Company:
    
    def __init__(self, symbol, api_key, api_key_fmp):
        # Replace it with YOUR Alpha Vantage API KEY and fmp key
        self.symbol = symbol
        self.api_key = api_key
        self.api_key_fmp = api_key_fmp  
        
        # An overview of static information and dynamically such as EPS
        self.overview = self.get_overview()
        
        # Add the price targets as attributes
        price_targets = self.get_analysis_price_target()
        if price_targets:
            self.target_low = price_targets.get("targetLow")
            self.target_hgih = price_targets.get("targetHigh")
            self.target_consensus = price_targets.get("targetConsensus")
            self.target_median = price_targets.get("targetMedian")
        
    def get_analysis_price_target(self) -> dict:
        url = f"https://financialmodelingprep.com/api/v4/price-target-consensus?symbol = {self.symbol}&apikey = {self.api_key_fmp}"
        
        data = simple_request(url)
        if data:
            return data[0]
    
    def get_overview(self):
        url = f’https://www.alphavantage.co/query?function=OVERVIEW&symbol = {self.symbol}&apikey = {self.api_key}’
        data = simple_request(url)
        return data

# Now lets call our created Company class
# Replace the empty strings with your api keys

AAPL = Company(
   symbol = "AAPL", api_key = "", api_key_fmp = ""
)
print(AAPL.__dict__)

Эта часть серии должна охватить тему работы с данными временных рядов на простом python. Мы будем использовать некоторые требования:

pip install numpy
pip install pandas
pip install matplotlib

Мы создадим еще один класс под названием TimeSeries, который впоследствии будет подключен к нашему классу Company.

import decimal
import matplotlib

class TimeSeries:
    """Time Series class for working with financial OHLCV data"""
    
    def __init__(self, **kwargs):
        if not "api_key" or not "symbol" in kwargs.keys():
            raise ValueError
            
        for k, v in kwargs.items():
            setattr(self, k, v)
    
    def get_adjusted_timeseries(self):
        url = f"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol = {self.symbol}&apikey = {self.api_key}"
        data = simple_request(url)
        if data:
            data = data['Time Series (Daily)']
        return data
    
    def clean_adjusted_close(self):
        """Return a list with 2-tuple consisting of data, adjusted close"""
        data = self.get_adjusted_timeseries()
        
        if not data:
            return None
        
        resulting_timeframes = []
        
        for date, data_dict in data.items():

            adj_close = round(float(data_dict.get("5. adjusted close")), 2)
    
            resulting_timeframes.append(
                {"date": date, "adjusted close": adj_close}
            )
            
        return resulting_timeframes
            
    def conversion_to_pandas(self):
        """We want to continue with pandas"""
        data = self.clean_adjusted_close()
        
        if not data:
            return None
        
        df = pd.DataFrame.from_records(data)
        return df
    
    def plot_df(self):
        df = self.conversion_to_pandas()
        df_plot = df.plot(x = "date", y = "adjusted close",)
        return df_plot
        

О коде:

  • Мы используем другой метод построения __init__, в котором мы автоматически назначаем ключевые слова в качестве атрибутов. Обратите внимание, что api_key и symbol по-прежнему необходимы!
  • Сначала мы вызываем api, получаем правильные значения и после этого очищаем его, чтобы собрать список, включающий (дата, скорректированное закрытие) для всех данных, которые мы собрали, вызвав api
  • Для этого мы используем цикл + преобразуем строку в float, чтобы работать с ней как с числовым значением. Мы также округляем его до 2 знаков после запятой.
  • Наконец, мы определяем конвертер для использования pandas DataFrame, а не встроенных типов данных, таких как список

Давайте протестируем его:

x = TimeSeries(
    symbol = "AAPl", api_key = "" # replace it with your Alpha Vatage Key
)
print(x.conversion_to_pandas())

Выходные данные должны выглядеть примерно так:

Отлично, вы создали фрейм данных pandas. Следующий шаг - как бы соединить его с нашим классом Comapany, но только если вы этого хотите, вы также можете оставить логику как есть. Вот как вы объедините его:

x = Company(
    symbol = "AAPl", api_key = "", api_key_fmp = "".   # INSERT YOUR KEYS HERE
)

# The objects
print(x.timeseries)
print(x)

# The data workflow we defined in ‘TimeSeries’
print(x.get_timeseries_data())
Отлично вы создали фрейм данных pandas Следующий шаг - как бы соединить его с нашим

Отлично, следующим шагом будет создание функции plot modelfunction для детального просмотра графика. Поэтому мы уже определили следующий код в нашем менеджере TimeSeries

  def plot_df(self):
        df = self.conversion_to_pandas()
        df_plot = df.plot(x = "date", y = "adjusted close",)
        return df_plot


# Now lets review the result 
# Therefore call it via a TimeSeries object f.ex. AAPL

x = TimeSeries(
    symbol = "AAPL", api_key = "" # REPLACE IT
)
print(x.plot_df())

Вывод:

Вывод

Выглядит нормально, но не битюг, я бы сказал, так что давайте создадим лучший вид.

   def plot_df(self):
        df = self.conversion_to_pandas()
   
    # old look
        df_plot = df.plot(x = "date", y = "adjusted close",)

        # new look
        df_plot = df.plot(
            x=’date’, y=’adjusted close’, 
            title=’Stock Prices’, color=’green’, linestyle=’--’, figsize=(10,5)
        )

        return df_plot

Вывод при повторении первого вызова plot_df:

Вывод при повторении первого вызова plot_df

Определенно стоит проверить следующую документацию, чтобы изменить стиль вашего графика:

Pandas.DataFrame.plot - документация pandas 2.0.0

Давайте соберем все это вместе, чтобы получить доступ к нему из класса Company:

class Company:
    
    def __init__(self, symbol, api_key, api_key_fmp):
        # Replace it with YOUR Alpha Vantage API KEY and fmp key
        self.symbol = symbol
        self.api_key = api_key
        self.api_key_fmp = api_key_fmp  
        
        # Create a connected object for timeseries management
        self.timeseries = TimeSeries(
            symbol=symbol, api_key=api_key
        )
        
        # An overview of static information and dynamically such as EPS
        self.overview = self.get_overview()
        
        # Add the price targets as attributes
        price_targets = self.get_analysis_price_target()
        if price_targets:
            self.target_low = price_targets.get("targetLow")
            self.target_hgih = price_targets.get("targetHigh")
            self.target_consensus = price_targets.get("targetConsensus")
            self.target_median = price_targets.get("targetMedian")
    
    def get_timeseries_data(self):
        return self.timeseries.conversion_to_pandas()
    
    def plot_adjusted_closes(self):
        return self.timeseries.plot_df()
    
    def get_analysis_price_target(self) -> dict:
        url = f"https://financialmodelingprep.com/api/v4/price-target-consensus?symbol = {self.symbol}&apikey = {self.api_key_fmp}"
        
        data = simple_request(url)
        if data:
            return data[0]
    
    def get_overview(self):
        url = f’https://www.alphavantage.co/query?function=OVERVIEW&symbol = {self.symbol}&apikey = {self.api_key}’
        data = simple_request(url)
        return data
    

# Our Timseries class:

import decimal
import matplotlib

class TimeSeries:
    """Time Series class for working with financial OHLCV data"""
    
    def __init__(self, **kwargs):
        if not "api_key" or not "symbol" in kwargs.keys():
            raise ValueError
            
        for k, v in kwargs.items():
            setattr(self, k, v)
    
    def get_adjusted_timeseries(self):
        url = f"https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&symbol = {self.symbol}&apikey = {self.api_key}"
        data = simple_request(url)
        if data:
            data = data['Time Series (Daily)']
        return data
    
    def clean_adjusted_close(self):
        """Return a list with 2-tuple consisting of data, adjusted close"""
        data = self.get_adjusted_timeseries()
        
        if not data:
            return None
        
        resulting_timeframes = []
        
        for date, data_dict in data.items():

            adj_close = round(float(data_dict.get("5. adjusted close")), 2)
    
            resulting_timeframes.append(
                {"date": date, "adjusted close": adj_close}
            )
            
        return resulting_timeframes
            
    def conversion_to_pandas(self):
        """We want to continue with pandas"""
        data = self.clean_adjusted_close()
        
        if not data:
            return None
        
        df = pd.DataFrame.from_records(data)
        return df
    
    def plot_df(self):
        df = self.conversion_to_pandas()
        df_plot = df.plot(x = "date", y = "adjusted close",)
        # Change the df_plot code 
        df_plot = df.plot(
            x='date', y='adjusted close', 
            title='Stock Prices', color='green', linestyle='--', figsize=(10,5)
        )

        return df_plot
        

Надеюсь, я помог некоторым из вас начать работу с обработкой финансовых данных в python. У меня есть еще несколько тем, о которых я хотел бы написать:

Некоторые из тем, которые приходят мне в голову:

  • Как использовать финансовые данные в реальном веб-приложении (подводные камни, рабочие процессы и концепции) (я сделал это с помощью https://palmy-investing.com и могу объяснить процесс).
  • Как локально работать с ней? Как локально подключить мои данные к бесплатной базе данных?
  • Как периодически вызывать API? Каждую неделю, каждую секунду? И то, и другое; в реальном приложении и локально.
  • Как создавать графики OHLCV? Какие библиотеки использовать? Опять же, я могу написать о том и о другом; о применении и локальном использовании.
  • Подробный обзор API. Какой API является объективно лучшим для вас?
  • Как проводить анализ настроений? Где я могу получить новостные статьи, связанные с акциями и криптовалютами?

Не стесняйтесь поделиться своей сферой интересов + задавайте сопутствующие вопросы, и я с радостью отвечу как можно скорее :)

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?

05.05.2023 14:00

Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.

Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом

05.05.2023 11:59

Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря своим методам, они делают код очень простым для понимания и читабельным.

JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы

05.05.2023 11:57

Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний, то, не теряя времени, практикуйте наш бесплатный онлайн тест 1100+ JavaScript MCQs и развивайте свои навыки и знания.

Массив зависимостей в React
Массив зависимостей в React

05.05.2023 09:44

Все о массиве Dependency и его связи с useEffect.