Coder Social home page Coder Social logo

ymyke / tessa Goto Github PK

View Code? Open in Web Editor NEW
41.0 3.0 3.0 547 KB

tessa โ€“ simple, hassle-free access to price information of financial assets ๐Ÿ“‰๐Ÿค“๐Ÿ“ˆ

Home Page: https://ymyke.github.io/tessa/tessa.html

License: MIT License

Python 100.00%
coingecko financial-data investing python pycoingecko finance financial-analysis investment-analysis yahoo yfinance

tessa's Introduction

tessa โ€“ simple, hassle-free access to price information of financial assets ๐Ÿ“‰๐Ÿค“๐Ÿ“ˆ

tessa is a Python library to help you easily search asset identifiers (e.g., tickers) and retrieve price information for assets from different sources such as Yahoo or Coingecko. It takes care of the different APIs, caching, rate limiting, and other hassles.

tessa provides a Symbol class that encapsulates nicely the methods relevant for a symbol. tessa also provides functionality to manage collections of symbols, store and load them, and extend their functionality.

Finally, tessa makes sure to be nice to the sites being accessed and tries to prevent users from being blocked by 429 rate limiting errors by 1) caching results upon retrieval and 2) keeping track of request timestamps and waiting appropriate amounts of time if necessary. tessa also automatically waits and retries requests that fail with a 5xx error.

โ†’ Check out the full documentation. ๐Ÿ“–

How to use

Here's a longer example that quickly shows all aspects of the library. Refer to submodules symbol, search, and price for more information.

  • Imports:
from tessa import Symbol, SymbolCollection, search
  • Create a symbol for MSFT and access some functions:
s1 = Symbol("MSFT")         # will use "yahoo" as the default source
s1.price_latest()           # get latest price
  • Create another symbol from a bloomberg ticker as it is used by Yahoo Finance:
s2 = Symbol("SREN.SW")
s2.price_point("2022-06-30")    # get price at specific point in time
  • Create a symbol from the coingecko source with an id as it is used by coingecko:
s3 = Symbol("bitcoin", source="coingecko")
s3.price_graph()            # show price graph
  • Search for a crypto ticker on coingecko:
res = search("name")        # search and print search result summary
filtered = res.filter(source="coingecko")  # filter results
filtered.p()                # print summary of filtered results
filtered.buckets[1].symbols # review the 2nd bucket in the filtered results
s4 = filtered.buckets[1].symbols[2]   # our symbol is the 3rd in that list
s4.price_history()          # get entire history
  • Build a collection of several symbols and use the collection to retrieve symbols:
sc = SymbolCollection([s1, s2, s3, s4])
sc.add(Symbol("AAPL"))      # add another one
sc.find_one("SREN").price_graph()
  • Store and load a symbol collection:
sc.save_yaml("my_symbols.yaml")
sc_new = SymbolCollection()
sc_new.load_yaml("my_symbols.yaml")
  • Use a different currency preference:
sc.find_one("ens").price_latest()   # will return price in USD
Symbol.currency_preference = "CHF"
sc.find_one("ens").price_latest()   # will return price in CHF

Note that currency_preference will only have an effect with sources that support it. It is supported for Coingecko but not for Yahoo. So you should always verify the effective currency you receive in the result.

Data sources

tessa builds on yfinance and pycoingecko and offers a simplified and unified interface.

Why these two sources? Yahoo Finance (via yfinance) is fast and offers an extensive database that also contains many non-US markets. Coingecko (via pycoingecko) offers great access to crypto prices. While Yahoo Finance also offers crypto information, pycoingecko has the advantage that you can have the prices quoted in many more currency preferences (a function that is also exposed via tessa).

More sources can be added in the future. Let me know in the issues of you have a particular request.

Main submodules

  • symbol: working with symbols and symbol collections.
  • search: searching the different sources.
  • price: accessing price functions directly instead of via the Symbol class.
  • sources: if you'd like to add additional sources to the library.

How to install

pip install tessa

Prerequisites

See pyproject.toml. Major prerequisites are the yfinance and pycoingecko packages to access finance information as well as the beautifulsoup4 package to do some scraping for searching on Yahoo Finance.

Repository

https://github.com/ymyke/tessa

Future Work

This is an initial version. There are a number of ideas on how to extend. Please leave your suggestions and comments in the Issues section.

On terminology

I'm using symbol instead of ticker because a ticker is mainly used for stock on stock markets, whereas tessa is inteded to be used for any kind of financial assets, e.g. also crypto.

Other noteworthy libraries

  • strela: A python package for financial alerts.
  • pypme: A Python package for PME (Public Market Equivalent) calculation.

On investpy as a data source

Tessa used to use the investpy package as the main source of information until mid 2022 until investing.com introduced Cloudflare, which broke access by investpy. ๐Ÿ˜– It is currently unclear if investpy will be available again in the future. You can follow the developments in issue 600. The old tessa/investpy code is still available in the add-symbols-based-on-investpy branch.

tessa's People

Contributors

douwem avatar ymyke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

tessa's Issues

Python version compatibility

Hi! Can you make this package compatible with python 3.8 as well. I'm getting compatibility issue when trying to install the package

Yahoo Search no longer working

Searching via Yahoo no longer works, i.e., yields no results.

Example:

from tessa.search.yahoo import yahoo_search
res = yahoo_search("apple")
res.p()

Produces only empty buckets/results.

This also causes the test test_yahoo_search_returns_plausible_results to fail.

Presumably the reason is that Yahoo Finance started to redirect to a cookie page when it gets a new visitor/session.

  • How much of a problem is this for tessa users?
  • Is this a problem only in certain markets (e.g., Europe)?
  • What would be a simple solution? What's a simple way to accept cookies in this case from Python and get the session id?

price_latest yeilds same value in same context

Hey, so the issue is pretty simple. I believe, price_latest() is somehow caching per context. Iterating inside a loop and printing the stock value, will always yield same result. The value always remain the same, even when I tried printing each 5 minutes. However, killing the script and re-running yield different value.

Version: 0.8.0
Python 3.10.7

Both code snippets below produce the bug.

Code Snippet 1

while True:
    for _ in range(1):
        print(Symbol("GOOGL").price_latest().price, "\n")
        time.sleep(20)

Code Snippet 2

from tessa import Symbol
from apscheduler.schedulers.background import BlockingScheduler

sched = BlockingScheduler()
sched.add_job(lambda: print(Symbol("GOOGL").price_latest().price, "\n"), 'interval', seconds = 60)
sched.start()

I don't know what I am doing wrong, I could not find any relevant documentation for this issue. I saw that you use a rate limiter, could this be related?

Compatibility with yfinance / yahoofinance ?

I would love to have compatibility with yfinance / yahoofinance.
By that, I mean being able to replace calls to yfinance / yahoofinance by calls to investpy / tessa without having to modify the arguments.

Reason : a lot of investing python scripts are available based on yfinance / yahoofinance, I'd like to be able to reuse them as easily as possible with investpy / tessa, where there are lots more financial assets.

Fix FutureWarnings around calling float on a single element Series

[c:\code\fignal\venv\lib\site-packages\tessa\price\price.py:67](file:///C:/code/fignal/venv/lib/site-packages/tessa/price/price.py:67): FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
  return PricePoint(when=price.name, price=float(price), currency=currency)

cf https://stackoverflow.com/questions/76256618/how-to-deal-with-futurewarning-regarding-applying-int-to-a-series-with-one-item

<class 'tessa.price.types.SymbolNotFoundError'>, 'occurred.' when using price_latest

Hello,

at the moment I'm using tessa 0.4.1 to get the etf prices from yahoo.

When I'm trying to get the price for the Yahoo ticker like MOGL.AX I get an error SymbolNotFoundError("No symbol found on source 'yahoo' for query 'MOGL.AX'.")

However, when I go to the yahoo finance and enter this ticker in search there's no problem with finding it.

To confirm is it not related to the rate limiting I was changing IP addresses (using my mobile).

The issues is happening since two weeks, at least for me.

Any advice?

UPD. The issue is most likely related to ranaroussi/yfinance#1268 - I will keep an eye

Only retrieve the entire price history when necessary?

At the moment, tessa retrieves (and caches) the entire price history of a symbol, regardless of which function is being called (price_history, price_point, or price_latest).

This is simple and straightforward, but can lead to unnecessary data retrieval and load on all participating systems, depending on the use case. For example, for an application that only needs the current price of a long list of stocks, this approach is surely wasteful. On the other hand, if an application needs several/many price points in a stock's history, retrieving and caching the entire history initially rather than hitting the network with each price point individually is likely the better approach.

A first quick experiment seemed to show that it doesn't make a difference for the rate limiters involved whether requests for large or small datasets are sent, they only react to the number of requests per unit of time.

Still, it might make sense to change price_latest and price_point to retrieve only what they need (and then also cache their results). And maybe it might make sense to leave it to the library's user to configure in which mode to work โ€“ eager or lazy, so to say.

local variable 'df' referenced before assignment

Below is the trace

File "/usr/local/lib/python3.10/dist-packages/tessa/symbol/symbol.py", line 90, in price_latest
    return price_latest(**self._create_price_args())
  File "/usr/local/lib/python3.10/dist-packages/tessa/price/price.py", line 91, in price_latest
    df, currency = price_history(query, source, currency_preference)
  File "/usr/local/lib/python3.10/dist-packages/tessa/price/price.py", line 40, in price_history
    df, effective_currency = src.get_price_history_bruteforcefully(
  File "/usr/local/lib/python3.10/dist-packages/tessa/sources/sources.py", line 43, in get_price_history_bruteforcefully
    res = self.get_price_history(query, currency_preference)
  File "/usr/local/lib/python3.10/dist-packages/tessa/price/yahoo.py", line 28, in get_price_history
    df = df.copy()

I was trying to get MSFT price like this:

s1 = Symbol("MSFT")
print(s1.price_latest())

Looking at the code, I think you may have to throw an exception if you cannot get the ticker price for any reason

Option for proxies

Hi, it would be great if you can bake proxy optionality into your code, that would easily make me switch to your package. Thanks for your work.

Should caches expire?

Thoughts on caching:

  • There should be caching in place in order to hit the APIs as little as
    possible/necessary.
  • Options to implement caching: functools.cache, requests_cache, own implementation
    (such as in the old fx module, b/c requests_cache doesn't work with investpy).
  • functools.cache seems to be the most straightforward approach and the one
    implemented.
  • The effect of caching can be further improved by retrieving few bigger chunks rather
    than many small ones.

Question:

  • What about expiration? functools.cache does not support expiration. Long-running
    applications should therefore clear the functools caches explicitly from time to
    time.

Historical Data - Bonds

Hi there! How could I get global bonds yields data (example: Germany 10Y) with tessa? I've tried to search some symbols, but I got a Exception error. Thanks in advance!

Full history ?

I'd love to have an option (argument ?) to get the full price history.
I have 2 use cases :

  • I want the full price history, not just the last 19 years (e.g. long term comparison of asset returns)
  • I want the full price history (less than 19 years), but I don't know when the price history begins (e.g. a new instrument e.g. an ETF).

bonds price history doesnt work

firstly Thanks for trying to find a solution around the 429 error , it is the bane of my existence for now .. i am glad i found this package .

the function doesn't work for Bonds

i attach the snapshot below of what the price history function throws vs what investpy api says

Screenshot 2022-05-23 at 10 05 27

Fix output in cached functions (search)

The search functions print out the search results. However, when they hit the (functools) cache, they are not executed and therefore don't print anything, which might be misleading.

Options:

  1. Get rid of print output in those functions altogether?
  2. Split the functions into two functions each: A silent, cached inner function that simply returns the results and a non-cached outer function that gets the results and prints the stats.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.