Construirea unui serviciu de flacon pentru a obține date Yfinance – partea I

URMĂREȘTE-NE
16,065FaniÎmi place
1,142CititoriConectați-vă

(Acest articol a fost publicat pentru prima dată pe Laboratorul software al lui Adamși a contribuit cu drag la R-Bloggers). (Puteți raporta problema despre conținutul de pe această pagină aici)


Doriți să vă împărtășiți conținutul pe R-Bloggers? Faceți clic aici dacă aveți un blog sau aici dacă nu.

Introducere

Recent, am făcut o analiză a portofoliului și am dat peste un videoclip interesant: cum să calculez valoarea intrinsecă a unui stoc precum Benjamin Graham. Deoarece nu toate datele sunt disponibile în Excel, am crezut că ar putea fi util să automatizați calculul folosind datele de la (excelent) yfinance Biblioteca Python. Formula în sine, scrisă în Python, este destul de simplă. Provocarea a fost să obțineți parametrii și intrările individuale și să fiți capabili să apelați funcția Python dintr -o foaie de lucru Excel.

Ar fi fost frumos să poți folosi suportul Python de la Excel Py =. Dar se dovedește că importul yfinance produce un Modulul nu a găsit eroare.

Conform documentației yfinance nu este una dintre bibliotecile open source pe care le acceptă distribuția SCELN SECUR Excel Python.

Așadar, pentru a elimina decalajul dintre Excel și Python, m -am gândit că ar putea fi o idee bună să scrii o API de flacon. Acest aranjament ne permite accesul la ecosistemul Python și oferă un mijloc (relativ) simplu prin care putem consuma datele în Excel folosind conectorul Web de interogare Powery.

Acest blog este împărțit în două părți. În partea I, descriu YfinanceService. Acesta este un serviciu de bază de flacon cu API -uri pentru a efectua calculul evaluării stocului și, în general, pentru a obține date de bilet folosind yfinance.

În partea a II -a, descriu cum să folosesc YfinanceService De la interogarea Excel Power pentru a automatiza procesul de efectuare a unui calcul al evaluării stocului și pentru a obține un tabel simplu de date despre căpușe.

Există mai multe abordări alternative. S-ar putea încerca un supliment Python personalizat pentru Excel. Dacă aveți date nefinanciare, utilizați, probabil, suportul Python încorporat Excel. Abordarea adoptată aici este o modalitate simplă și destul de generică de a avea acces la Python și la ecosistemul său. Vă permite să obțineți date și să invocați / să efectuați calcule.

Calculați valoarea intrinsecă a unui stoc folosind formula lui Graham

În general, calcularea valorilor stocului este destul de implicată. Există o serie de metode diferite fiecare cu avantajele și dezavantajele lor. De exemplu, pur și simplu Wall St. descrie o serie de abordări mai complicate. Abordarea adoptată aici este de a utiliza formula lui Graham pentru a calcula valoarea intrinsecă a unui stoc pentru a determina dacă este ieftină sau costisitoare în comparație cu prețul său curent. Codul Python este următorul:

"""
Estimates the intrinsic value of a stock
"""


def stock_valuation_graham(eps: float, pe_base: float, g: float, avg_yield: float, cur_yield: float) -> float:
    """
    Calculate the intrinsic value of a stock using Graham's formula
    Reference: https://stablebread.com/how-to-calculate-the-intrinsic-value-of-a-company-like-benjamin-graham/

        V = (eps * (pe_base + 2g) * avg_yield) / cur_yield

    where:
    V = intrinsic value per share (over the next 7-10 years)
        EPS = earnings per share (over the trailing twelve months (TTM))
        8.5 = price-to-earnings (P/E) base for a no-growth company
        g = reasonably expected annual growth rate (over the next 7-10 years)
        avg_yield = average yield of AAA Corporate Bonds
        cur_yield = current yield of AAA Corporate Bonds
    """

    V = (eps * (pe_base + 1.1 * g) * avg_yield) / cur_yield

    return V

Formula în sine este autoexplicativă. O explicație mai detaliată a calculului este disponibilă aici. Parametrii sunt împărțiți în acele valori pe care le obținem pe căpușă și unele valori globale. Astfel, EPS și rata de creștere anuală preconizată sunt obținute din informațiile despre căpușă folosind yfinance. Pe de altă parte, randamentul mediu al obligațiunilor corporative AAA și randamentul curent al obligațiunilor corporative AAA sunt configurate ca parametri de intrare.

În cele din urmă, atât baza prețurilor la câștig (P/E) pentru o companie fără creștere, cât și factorul aplicat creșterii anuale preconizate sunt codate. Baza de preț la câștig (P/E) pentru o companie fără creștere este stabilită la 8.5. Factorul aplicat la creșterea anuală preconizată – 2g mi s -a părut oarecum agresiv, astfel încât să ne reducem așteptările la 1.1g. Ulterior, ambele aceste valori pot fi configurate ca parametri de intrare.

Serviciul de yfinance

YfinanceService constă din patru API -uri principale (puncte finale):

  • Tickerinfo
  • Tickerdata
  • Valoare intrinsecă
  • Valori intrinsecice

Acestea sunt declarate în yfinanceService.py.

# Flask application
app = Flask(__name__)
api = Api(app)

# Register Endpoints
api.namespace('YFinanceService', description='YFinance Service API')

api.add_resource(VersionInfo, '/YFinanceService/VersionInfo')
api.add_resource(TickerInfo, '/YFinanceService/TickerInfo')
api.add_resource(TickerData, '/YFinanceService/TickerData')
api.add_resource(IntrinsicValue, '/YFinanceService/IntrinsicValue')
api.add_resource(IntrinsicValues, '/YFinanceService/IntrinsicValues')


if __name__ == '__main__':
    DEBUG = False
    HOST = environ.get('SERVER_HOST', 'localhost')
    try:
        PORT = int(environ.get('SERVER_PORT', '5000'))
    except ValueError:
        PORT = 5000
    # run our Flask app
    app.run(HOST, PORT, DEBUG)

Rularea YfinanceService

YfinanceService poate fi rulat de la linia de comandă. CD la YFinanceService subdirector. La promptul de comandă, tastați python YFinanceService.py. În mod alternativ, poate fi rulat direct cu debuggerul din VScode.

Ar trebui să vedeți un mesaj similar cu următoarele:

Începând YfinanceServiceÎncepând YfinanceService

Pentru a testa serviciul dintr -un browser, introduceți bara de adrese: http: // localhost: 5000/yfinanceService/versionInfo și ar trebui să vedeți pachetul de răspuns JSON: {"VersionInfo": {"flask": "3.1.0", "yfinance": "0.2.54", "pandas": "2.2.3"}}

Puncte finale YfinanceService

Odată cu funcționarea serviciului, punctele finale API pot fi exercitate prin intermediul unui browser folosind exemplele de mai jos (presupunând că serviciul rulează pe portul 5000).

IntrinsicValue API

API -ul Flak IntrinsicValue Susține doar metoda GET. Celelalte metode de odihnă (PUT, POST etc.) nu sunt definite. API -ul GET ia trei parametri:

  • Ticker – simbolul ticker
  • AVG_YIELD – Randamentul mediu al obligațiunilor corporative AAA
  • cur_yield – randamentul curent al obligațiunilor corporative AAA

Funcția GET este împărțită în două părți. Prima parte obține parametrii (necesari). A doua parte apelează la o funcție de înveliș stock_valuation.

class IntrinsicValue(Resource):
    """ Calculate the intrinsic value of a single stock using Graham's formula. """
    def get(self):

        parser = reqparse.RequestParser()

        parser.add_argument("ticker", type=str, required=True, help="The ticker symbol of the stock")
        parser.add_argument("avg_yield", type=float, required=True, help="Average yield of AAA Corporate Bonds")
        parser.add_argument("cur_yield", type=float, required=True, help="Current yield of AAA Corporate Bonds")

        args = parser.parse_args()

        symbol: str = args.get("ticker")
        avg_yield: float = args.get("avg_yield")
        cur_yield: float = args.get("cur_yield")

        v: float = stock_valuation(symbol, avg_yield, cur_yield)

        return {"value": v}, 200  # return info and 200 OK code

stock_valuation funcția obține ticker.info dicționar din yfinanceși folosește acest lucru pentru a obține EPS -ul final. Baza de preț la câștig (P/E) pentru o companie fără creștere este codată 8.5. Rata de creștere preconizată g este obținut din biblioteca Yahoo Finance Stock Info. În cele din urmă, stock_valuation_graham Funcția este numită cu toți parametrii necesari și valoarea intrinsecă este returnată.

De exemplu, pentru a determina valoarea instrumentică a GM, putem folosi următoarea interogare: http: // localhost: 5000/yfinanceService/intrinsicValue? Ticker = gm & avg_yield = 4.25 & cur_yield = 3.25.

Aceasta returnează un dicționar cu o singură valoare: {„valoare”: 82.07549}. Comparând acest lucru cu prețul curent al GM (46,72), am putea concluziona că stocul este subestimat.

stock_valuation funcția este de asemenea folosită de IntrinsicValues API. Acest lucru face același lucru cu IntrinsicValue API, dar pentru o listă de tichete. Din acest motiv, stock_valuation Funcția gestionează orice erori și excepții și returnări 0.0 De exemplu, dacă nu se găsește un ticker sau elementul de date nu este disponibil. Dacă aceasta ar fi făcut parte dintr -o aplicație web, am putea fi returnat un cod de eroare și un mesaj de excepție prin API într -o pagină HTML. Cu toate acestea, în acest aranjament, clientul este Excel și, în special, conectorul Web de interogare Power. Așadar, pentru a simplifica procesarea clientului (Excel), am încercat să facem apelurile API cât mai rezistente.

De exemplu, următoarele: http: // localhost: 5000/yfinanceservice/intrinsesicvalues? Tickers = san.mc, bbva.mc, ibe.mc, aena.mc & avg_yield = 3.25 și cur_yield = 1.25 interogări pentru valorile intrinseci ale patru stocuri spaniole. Rezultatele sunt returnate ca tabel separate de virgulă cu două coloane: tickerul și valoarea intrinsecă.

API TickerData

API -ul Flak TickerData De asemenea, acceptă doar metoda GET. Scopul API este de a prelua unul sau mai multe câmpuri din yfinance Informații despre căpușe pentru o listă dată de simboluri de bilet. Ieșirea este un CSV șir care poate fi analizat într -un tabel, cu anteturile coloanei fiind numele câmpurilor și rândurile fiind datele corespunzătoare fiecărui căscător.

class TickerData(Resource):
    """ Retrieve the specified fields from the input tickers """
    def get(self):

        parser = reqparse.RequestParser()

        parser.add_argument("tickers", type=str, action='split', required=True, help="One or more ticker symbols")
        parser.add_argument("fields", type=str, action='split', required=True, help="One or more fields")

        args = parser.parse_args()

        symbols: list = args.get("tickers")
        fields: list = args.get("fields")

        headers: list = ('Ticker')
        for field in fields:
            headers.append(field)

        rows: list = ()

        try:

            for symbol in symbols:
                rows.append(get_items(symbol, fields))

        except Exception:
            print("An error occured")

        df = pd.DataFrame(rows, columns=headers)

        return df.to_csv(index=False, header=True), 200  # return info and 200 OK code

Ca anterior, API -ul este împărțit în două părți. Prima parte obține parametrii, verifică dacă sunt prezenți parametrii necesari și stabilește anteturile tabelului. A doua parte iterează pe lista de intrare a simbolurilor de bilet și pentru fiecare simbol solicită elementele de date din ticker.info structura. Fiecare rând este anexat la o listă de rânduri. În cele din urmă, CSV tabelul este returnat folosind DataFrame.to_csv metodă.

Parametrii sunt o listă de simboluri separată de virgulă și o listă de câmpuri separată de virgule (nume cheie din ticker.info dicţionar). Aceasta oferă un mod relativ flexibil de a obține date financiare ale stocurilor.

De exemplu, pentru a obține următorii indicatori:

  • CALELINGPEGRATIO
  • CALELINGPE
  • Forwardpe

Pentru simboluri: MSFT, AMZN, WAL și TSLA Putem crea următoarea interogare: http: // localhost: 5000/yfinanceservice/tickerdata? tickers = msft, amzn, wal, tsla & câmps = trailingpegratio, trailingpe, forwardpe

Ca și înainte, gestionarea erorilor este rezistentă și nu informativă. Tabelul va fi construit cu valori goale dacă există o problemă de obținere a datelor, dacă cheia nu există sau dacă simbolul ticker este indisponibil și așa mai departe. Acest lucru nu este neapărat ideal, dar simplifică procesarea clientului.

Învelire

Acest blog a introdus YfinanceServiceun serviciu simplu de flacon care definește unele puncte finale care să ne permită să efectuăm un calcul al evaluării stocului și, în general, să obținem date despre căpușă folosind Python yfinance bibliotecă. În partea a II -a a blogului, descriu cum să folosești brut API -uri în Excel prin intermediul conectorului Web Power Query.

Dominic Botezariu
Dominic Botezariuhttps://www.noobz.ro/
Creator de site și redactor-șef.

Cele mai noi știri

Pe același subiect

LĂSAȚI UN MESAJ

Vă rugăm să introduceți comentariul dvs.!
Introduceți aici numele dvs.