Есть ли способ векторизации функции, которая вычисляет строку, зависящую от предыдущих строк? - PullRequest
0 голосов
/ 21 октября 2019

Я добавляю индикаторы к данным фондового рынка, но мое решение по поиску ATR слишком медленное. Есть ли способ векторизовать эту проблему?

Я использую библиотеку yfinance, чтобы получить цены на акции. Сначала я сделал простой цикл for, но потом понял, что это займет слишком много времени, и теперь я использую Index для получения данных предыдущих строк. Я попытался использовать функцию .shift (), но мне нужно получить часть предыдущих данных, потому что, если бы я использовал в среднем 174, было бы сложно написать. Например, у меня есть эта таблица:Дата Открыто Высоко Низко Закрыто0 2017-10-23 156.839996 157.039993 155.949997 156.5099951 2017-10-23 156.529999 156.550095 155.929901 156.3399962 2017-10-23 156.320007 157.600006 156.119995 157.5939943 2017-10-23 157.599899 157.679993 157.279999 157.2799994 2017-10-23 157.297501 157.369995 156.559998 156.619995

И я хотел бы добавить столбец ATR, который рассчитывается по следующей формуле:Текущий ATR = (Предыдущий ATR + Текущий TR) / 2, в которомCurrent TR = max [(high-low), (high - previous_close), (low-previous_close)]

import yfinance as yf
import numpy as np
import pandas as pd

def get_prices(stock):
    ul = yf.Ticker(stock)
    pdate = (datetime.now() - timedelta(days=729)).date()
    df = ul.history(start=pdate, interval="1H").drop(["Volume","Dividends", "Stock Splits"], axis=1)
    df = df.reset_index()
    return df

def addATR_(row, df, av=13):
    if(row.Index>av):
        lrid = row.Index-1
        high = row.High
        low = row.Low
        prev_close = df.loc[df.index==(lrid),"Close"]
        matr = df[row.Index-av:row.Index]["ATR"].sum()
        tr=[(high - low),np.abs(high - prev_close).values,np.abs(low - prev_close).values] 
        return (matr + np.max(tr))/(av+1)

def add_ATR(df):
    df.insert(5,"ATR", 0.2)
    df['Index'] = df.index
    df["ATR"] = df.apply(lambda row: addATR_(row, df), axis=1)
    df = df.drop(range(14))
    df = df.reset_index().drop(["index","Index"],axis=1)
    print("Added ATR")
    return df

print(add_ATR(get_prices("msft")))

Я действительно хочу ускорить процесс, потому что мне требуется 9 секунд, чтобы добавить только однуИндикатор.

...