GithubHelp home page GithubHelp logo

simfin / simfin Goto Github PK

View Code? Open in Web Editor NEW
287.0 287.0 38.0 418 KB

Simple financial data for Python

Home Page: https://simfin.com/

License: Other

Python 85.02% Jupyter Notebook 14.98%
finance financial-data python simfin

simfin's Introduction

docs downloads

SimFin - Simple financial data for Python

SimFin makes it easy to obtain and use financial and stock-market data in Python. It automatically downloads share-prices and fundamental data from the SimFin server, saves the data to disk for future use, and loads the data into Pandas DataFrames.

Installation

pip install simfin

More detailed installation instructions can be found below.

API-Key

To download data from SimFin you need an API-key, you can get one for free by registering on simfin.com. Once you registered, you can find your API-key here. The free datasets contain less data than the paid SimFin+ datasets and some datasets are only available to SimFin+ users. Visit SimFin for a comparison of the free and paid data versions.

Example

Once the simfin package has been installed and you got your API-key, the following Python program will automatically download all Income Statements for US companies, and print the Revenue and Net Income for Microsoft.

import simfin as sf
from simfin.names import *

# Set your API-key for downloading data.
# Replace YOUR_API_KEY with your actual API-key.
sf.set_api_key('YOUR_API_KEY')

# Set the local directory where data-files are stored.
# The dir will be created if it does not already exist.
sf.set_data_dir('~/simfin_data/')

# Load the annual Income Statements for all companies in the US.
# The data is automatically downloaded if you don't have it already.
df = sf.load_income(variant='annual', market='us')

# Print all Revenue and Net Income for Microsoft (ticker MSFT).
print(df.loc['MSFT', [REVENUE, NET_INCOME]])

This produces the following output:

                  Revenue   Net Income
Report Date
2008-06-30   6.042000e+10  17681000000
2009-06-30   5.843700e+10  14569000000
2010-06-30   6.248400e+10  18760000000
2011-06-30   6.994300e+10  23150000000
2012-06-30   7.372300e+10  16978000000
2013-06-30   7.784900e+10  21863000000
2014-06-30   8.683300e+10  22074000000
2015-06-30   9.358000e+10  12193000000
2016-06-30   9.115400e+10  20539000000
2017-06-30   9.657100e+10  25489000000
2018-06-30   1.103600e+11  16571000000
2019-06-30   1.258430e+11  39240000000

We can also load the daily share-prices and plot the closing share-price for Microsoft (ticker MSFT):

# Load daily share-prices for all companies in USA.
# The data is automatically downloaded if you don't have it already.
df_prices = sf.load_shareprices(market='us', variant='daily')

# Plot the closing share-prices for ticker MSFT.
df_prices.loc['MSFT', CLOSE].plot(grid=True, figsize=(20,10), title='MSFT Close')

This produces the following image:

Share-price for MSFT

Documentation

Installation (Detailed Instructions)

The best way to install simfin and use it in your own project, is to use a virtual environment. You write the following in a Linux terminal:

virtualenv simfin-env

You can also use Anaconda instead of a virtualenv:

conda create --name simfin-env python=3

Then you can install the simfin package inside that virtual environment:

source activate simfin-env
pip install simfin

If the last command fails, or if you want to install the latest development version from this GitHub repository, then you can run the following instead:

pip install git+https://github.com/simfin/simfin.git

Now try and put the above example in a file called test.py and run:

python test.py

When you are done working on the project you can deactivate the virtualenv:

source deactivate

Development

If you want to modify your own version of the simfin package, then you should clone the GitHub repository to your local disk, using this command in a terminal:

git clone https://github.com/simfin/simfin.git

This will create a directory named simfin on your disk. Then you need to create a new virtual environment, where you install your local copy of the simfin package using these commands:

conda create --name simfin-dev python=3
source activate simfin-dev
cd simfin
pip install --editable .

You should now be able to edit the files inside the simfin directory and use them whenever you have a Python module that imports the simfin package, while you have the virtual environment simfin-dev active.

Testing

Two kinds of tests are provided with the simfin package:

Unit Tests

Unit-tests ensure the various functions of the simfin package can run without raising exceptions. The unit-tests generally do not test whether the data is valid. These tests are mainly used by developers when they make changes to the simfin package.

The unit-tests are run with the following commands from the root directory of the simfin package:

source activate simfin-env
pytest

Data Tests

Data-tests ensure the bulk-data downloaded from the SimFin servers is valid. These tests are mainly used by SimFin's database admin to ensure the data is always valid, but the end-user may also run these tests to ensure the downloaded data is valid.

First you need to install nbval, which enables support for Jupyter Notebooks in the pytest framework. This is not automatically installed with the simfin package, so as to keep the number of dependencies minimal for normal users of simfin. To install nbval run the following commands:

source activate simfin-env
pip install nbval

Then you can run the following commands from the root directory of the simfin package to execute both the unit-tests and data-tests:

pytest --nbval-lax

The following command only runs the data-tests:

pytest --nbval-lax -v tests/test_bulk_data.ipynb

More Tests

The tutorials provide more realistic use-cases of the simfin package, and they can also be run and tested automatically using pytest. See the tutorials' README for details.

Credits

The database is created by SimFin. The Python API and download system was originally designed and implemented by Hvass Labs. Further development of the Python API by SimFin and the community.

License (MIT)

This is published under the MIT License which allows very broad use for both academic and commercial purposes.

You are very welcome to modify and use this source-code in your own project. Please keep a link to the original repository.

simfin's People

Contributors

hvass-labs avatar shivam-nirhali avatar srnirhali avatar thf24 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

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

simfin's Issues

Bug Report

Bug Report

If you experience errors or bugs, please make a serious effort to solve the
problem yourself before asking here. The problem is quite likely in your own
code and a simple Google search for the error-message may help you solve it.
If it is a problem directly related to simfin, then please search the closed
GitHub issues, because it may already have been answered there.

Please make sure you have the latest simfin package installed by running:

pip install --upgrade simfin

And make sure you have downloaded fresh data-files from the SimFin server
by setting refresh_days=0 (see example below).

If you still cannot solve the problem and need our help, then please provide
the following.

Description

Please write a brief description of the bug / error you have experienced.

System Details

  • Python version 3.12
  • Simfin version 1.0.0
  • Other relevant package versions
  • Operation System and version
  • Computer's CPU, RAM-size, free HD space, etc.
  • Other relevant system information

Code Example

Please write a minimal source-code example that reproduces the problem.
You can indent the code-block to get proper code-formatting, for example:

import simfin as sf

# Print SimFin version.
print(sf.__version__)

# Configure simfin.
sf.set_data_dir('~/simfin_data/')
sf.load_api_key(path='~/simfin_api_key.txt', default_key='free')
#  Calculate Growth signals
df_growth_signals = sf.growth_signals(df_prices=df_prices,
                      df_income_ttm=df_income_ttm,
                      df_income_qrt=df_income_qrt,
                      df_balance_ttm=df_balance_ttm,
                      df_balance_qrt=df_balance_qrt,
                      df_cashflow_ttm=df_cashflow_ttm,
                      df_cashflow_qrt=df_cashflow_qrt,
                      fill_method='ffill')

print(df_growth_signals.info())
#  Calculate value signals
df_value_signals = sf.val_signals(df_prices=df_prices,
                                df_income_ttm=df_income_ttm,
                                df_balance_ttm=df_balance_ttm,
                                df_cashflow_ttm=df_cashflow_ttm,
                                fill_method='ffill')
print(df_value_signals.info())
#  Calculate financial signals
df_financial_signals = sf.fin_signals(df_prices=df_prices,
                                df_income_ttm=df_income_ttm,
                                df_balance_ttm=df_balance_ttm,
                                df_cashflow_ttm=df_cashflow_ttm,
                                fill_method='ffill')
print(df_financial_signals.info())

Result / Error

Please write the full output and error message you received. You can also
indent this text-block by pressing the tab-key to get proper formatting
of the error-message.

InvalidIndexError                         Traceback (most recent call last)
Cell In[12], [line 13](vscode-notebook-cell:?execution_count=12&line=13)
      [1](vscode-notebook-cell:?execution_count=12&line=1) #  Calculate Growth signals
      [2](vscode-notebook-cell:?execution_count=12&line=2) # df_growth_signals = sf.growth_signals(df_prices=df_prices,
      [3](vscode-notebook-cell:?execution_count=12&line=3) #                       df_income_ttm=df_income_ttm,
   (...)
     [11](vscode-notebook-cell:?execution_count=12&line=11) # print(df_growth_signals.info())
     [12](vscode-notebook-cell:?execution_count=12&line=12) #  Calculate value signals
---> [13](vscode-notebook-cell:?execution_count=12&line=13) df_value_signals = sf.val_signals(df_prices=df_prices,
     [14](vscode-notebook-cell:?execution_count=12&line=14)                                 df_income_ttm=df_income_ttm,
     [15](vscode-notebook-cell:?execution_count=12&line=15)                                 df_balance_ttm=df_balance_ttm,
     [16](vscode-notebook-cell:?execution_count=12&line=16)                                 df_cashflow_ttm=df_cashflow_ttm,
     [17](vscode-notebook-cell:?execution_count=12&line=17)                                 fill_method='ffill')
     [18](vscode-notebook-cell:?execution_count=12&line=18) print(df_value_signals.info())
     [19](vscode-notebook-cell:?execution_count=12&line=19) #  Calculate financial signals

File [~/.local/lib/python3.12/site-packages/simfin/cache.py:201](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:201), in cache.<locals>.wrapper(cache_name, cache_refresh, cache_format, **kwargs)
    [146](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:146) """
    [147](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:147) This uses more advanced Python features to wrap `func` using a
    [148](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:148) function-decorator, which are not explained so well in the
   (...)
    [196](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:196)     or the results from computing the wrapped function.
    [197](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:197) """
    [199](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:199) if cache_refresh is None:
    [200](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:200)     # Never use the cache, always just compute the function.
--> [201](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:201)     df_result = func(**kwargs)
    [202](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:202) else:
    [203](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:203)     # We want to use a cache-file. Determine if it should be refreshed.
    [204](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:204) 
    [205](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:205)     # Ensure the cache-format is a valid string.
    [206](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:206)     assert cache_format.startswith('pickle') or \
    [207](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/cache.py:207)            cache_format in ['parquet', 'feather']

File [~/.local/lib/python3.12/site-packages/simfin/signals.py:793](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/signals.py:793), in val_signals(df_prices, df_income_ttm, df_balance_ttm, df_cashflow_ttm, fill_method, offset, func, date_index, shares_index, group_index, banks, insurance)
    [790](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/signals.py:790) df_cf = df_cashflow_ttm[columns]
    [792](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/signals.py:792) # Combine all the data. This creates a new copy that we can add columns to.
--> [793](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/signals.py:793) df = pd.concat([df_inc, df_bal, df_cf], axis=1)
    [795](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/signals.py:795) # Calculate derived financial data such as Free Cash Flow (FCF),
    [796](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/signals.py:796) # and add it as new columns to the DataFrame.
    [797](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/signals.py:797) # This is only TTM data with 4 data-points per year, so it is
    [798](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/signals.py:798) # faster than calculating it for the daily data-points below.
    [799](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/simfin/signals.py:799) df[FCF] = free_cash_flow(df_cashflow_ttm)

File [~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:393](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:393), in concat(objs, axis, join, ignore_index, keys, levels, names, verify_integrity, sort, copy)
    [378](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:378)     copy = False
    [380](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:380) op = _Concatenator(
    [381](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:381)     objs,
    [382](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:382)     axis=axis,
   (...)
    [390](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:390)     sort=sort,
    [391](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:391) )
--> [393](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:393) return op.get_result()

File [~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:676](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:676), in _Concatenator.get_result(self)
    [674](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:674)         obj_labels = obj.axes[1 - ax]
    [675](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:675)         if not new_labels.equals(obj_labels):
--> [676](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:676)             indexers[ax] = obj_labels.get_indexer(new_labels)
    [678](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:678)     mgrs_indexers.append((obj._mgr, indexers))
    [680](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:680) new_data = concatenate_managers(
    [681](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:681)     mgrs_indexers, self.new_axes, concat_axis=self.bm_axis, copy=self.copy
    [682](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/reshape/concat.py:682) )

File [~/.local/lib/python3.12/site-packages/pandas/core/indexes/base.py:3875](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/indexes/base.py:3875), in Index.get_indexer(self, target, method, limit, tolerance)
   [3872](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/indexes/base.py:3872) self._check_indexing_method(method, limit, tolerance)
   [3874](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/indexes/base.py:3874) if not self._index_as_unique:
-> [3875](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/indexes/base.py:3875)     raise InvalidIndexError(self._requires_unique_msg)
   [3877](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/indexes/base.py:3877) if len(target) == 0:
   [3878](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/futuresight/python-projects/~/.local/lib/python3.12/site-packages/pandas/core/indexes/base.py:3878)     return np.array([], dtype=np.intp)

InvalidIndexError: Reindexing only valid with uniquely valued Index objects

it is the same for all three functions. Please take a look

Bug Report

While transforming https://github.com/SimFin/simfin/blob/master/simfin/names.py to Java Enum, found some duplicate declarations:

Line 64: CAPEX = 'Capital Expenditures'
Line 90: CAPEX = CHG_FIX_ASSETS_INT = 'Change in Fixed Assets & Intangibles'

Line 397: NET_CHG_INTERBANK_ASSETS = 'Net Change in Interbank Assets'
Line 413: NET_CHG_INTERBANK_ASSETS = 'Net Change of Interbank Assets'

Line 401: NET_CHG_INVEST = 'Net Change in Investments'
Line 417: NET_CHG_INVEST = 'Net Change of Investments'

Is it a bug or a feature?

Best,

stud0709

Data Error

Hi,
Is it possible not to include the latest figures of the fundamental data for every published report? I mean, to not overwrite the original published figure with the restated figure. Otherwise, the whole fundamental data is biased! (survivorship and look-ahead bias is not being taken into account)
thank you very much,

Nico

Bug Report

Bug Report

If you experience errors or bugs, please make a serious effort to solve the
problem yourself before asking here. The problem is quite likely in your own
code and a simple Google search for the error-message may help you solve it.
If it is a problem directly related to simfin, then please search the closed
GitHub issues, because it may already have been answered there.

Please make sure you have the latest simfin package installed by running:

pip install --upgrade simfin

And make sure you have downloaded fresh data-files from the SimFin server
by setting refresh_days=0 (see example below).

If you still cannot solve the problem and need our help, then please provide
the following.

Description

Please write a brief description of the bug / error you have experienced.

Getting an error when trying to download simfin data.
image

System Details

  • Python version: 3.9.2
  • Simfin version: 0.8.3
  • Other relevant package versions
  • Operation System and version: Windows 10
  • Computer's CPU, RAM-size, free HD space, etc: Intel, 8GB RAM, +100GB free space
  • Other relevant system information

Code Example

import simfin as sf
from simfin.names import *

sf.set_data_dir('./data/')
sf.set_api_key(api_key=API_KEY)

data = sf.load(dataset='income', variant='annual', market='us', index=[TICKER, REPORT_DATE], refresh_days=0)

Result / Error

Please write the full output and error message you received. You can also
indent this text-block by pressing the tab-key to get proper formatting
of the error-message.

image

Partially updating and syncing large CSV-files

Introduction

Partial updating and syncing of the CSV-files, was originally a part of the idea for this project, so it would only download the full CSV-files the first time, and the following downloads would only be partial, so as to sync your local CSV-files with the server's new data.

It turned out this wasn't necessary for the fundamental data (Income Statements, Balance Sheets, Cash-Flow Statements) because the CSV-files are fairly small and the compressed ZIP-files that are being downloaded from the server, are typically only a few MB each, so it is much easier and probably also faster to download the full data-files each time a user wants to update them, rather than have the server create different subsets of the data and send that to each individual user.

However, the dataset with share-prices could benefit from an efficient data-syncing method, because the ZIP-file is currently about 70 MB and it unpacks into a CSV-file that is nearly 400 MB, and these files will grow with time.

So a data-syncing method might become necessary eventually, and the idea is therefore described here, in case someone will implement it in the future. The idea is explained for CSV-files in general.

Overall Idea

The overall idea is that we need a timestamp associated with each CSV-file, which tells us when the most recent data-item in the CSV-file was actually added to the SimFin server's database. Sometimes this timestamp can be read directly from the data, other times it must be provided by the SimFin server e.g. in a separate file called 'timestamp.txt' inside the ZIP-file for each dataset.

If a user does not have the dataset and timestamp on their local harddisk, then the entire dataset is downloaded from the SimFin server. This can be done very quickly, because the server just needs to send a pre-packaged ZIP-file like it is doing now.

But when the user already has a version of the dataset and timestamp on their local harddisk, then the timestamp is first read from disk and sent to the SimFin server along with the other arguments that specify which dataset is wanted. Then the server looks up all the data from the given dataset, where the timestamp is more recent than the timestamp provided by the user. The data is then put into a new CSV-file, along with a new timestamp for the most recent data in the CSV-file, and this is compressed into a ZIP-file which is sent to the user. Afterwards the temporary CSV-file and ZIP-file can be deleted on the server.

The user then unpacks the ZIP-file they received from the server, and simply appends the new CSV-file to the end of the old CSV-file already located on the harddisk.

The local CSV-file can be appended daily with new data from the SimFin server. This means that data for each ticker will be spread throughout the local CSV-file. It is also possible that the dates will be unsorted in the local CSV-file, if older data should ever be added to the SimFin server's database in the future. But when the data is loaded using Pandas and a DataFrame is created with a multi-level index of e.g. the Ticker and Date, then it will also be sorted correctly.

All of this would be handled automatically by SimFin's Python API and server, so the user never knows it is happening behind the scenes. The user would just call the normal function for loading a dataset.

In order for this to work, the server must be reasonably fast at generating the ZIP-files with new data, and that is why it probably doesn't make sense to do it for smaller datasets of only a few MB, because it is probably faster for the server to just send a pre-packaged ZIP-file.

Deprecation warning for `date_parser` in Pandas `read_csv` function.

I currently encounter a deprecation warning when using the pd.read_csv function with date_parser.

FutureWarning: The argument 'date_parser' is deprecated and will be removed in a future version. Please use 'date_format' instead, or read your data in as 'object' dtype and then call 'to_datetime'.

this is supported by the Pandas documentation, which states:

Deprecated since version 2.0.0: Use date_format instead, or read in as object and then apply to_datetime() as-needed.

this warning was obtained whilst running the following line of code:

simfin/simfin/load.py

Lines 154 to 155 in 413ec16

df = pd.read_csv(path, sep=';', header=0,
parse_dates=parse_dates, date_parser=date_parser)

as per the warning and the supporting Pandas documentation, I'm recommending that we read data in as object dtype and then call pd.to_datetime() to convert each of these columns from object dtype to datetime64[ns] dtype.

I've submitted a pull request here.

ty

Add "Cash from (Repurchase of) Equity" to Data Finder

Feature Suggestion

Could you add "Cash from (Repurchase of) Equity" to data finder under Financial Statements (Cash Flow) dropdown box? It is a very common data value that could be added for SimFin+ paid users in data finder since it is found in bulk data already.

Description

The data finder is commonly used for those users that prefer this functionality over the API. In order to obtain useful info the dropdown feature was added which is good. It would be great if "Cash from (Repurchase of) Equity" was added to the Financial Statements dropdown, under Cash flow.

Code

N/a

Example

N/a

Dataset "us-income-ttm" not on disk.

Bug Report

Please make sure you have the latest simfin package installed by running:

pip install --upgrade simfin

And make sure you have downloaded fresh data-files from the SimFin server
by setting refresh_days=0 (see example below).

If you still cannot solve the problem and need our help, then please provide
the following.

Description

I am getting error message Dataset "us-income-ttm" not on disk. when attempting to download data into colab notebook. I also get this error message when running tutorials that have the same code as mine. This did not happen with the previous version. I was able to down signal dataset prior to Feb 22, 2023 update. I have the latest version 0.9.0.

System Details

  • Python version
  • Simfin version : 0.9.0
  • Other relevant package versions
  • Operation System and version
  • Computer's CPU, RAM-size, free HD space, etc.
  • Other relevant system information

Code Example

Import the main functionality from the SimFin Python API.

import simfin as sf

Import names used for easy access to SimFin's data-columns.

from simfin.names import *

import seaborn as sns

# Configure simfin.
sf.set_data_dir('~/simfin_data/')
sf.load_api_key(path='~/simfin_api_key.txt', default_key='free')

# Interested in the US stock-market.
market = 'us'

offset = pd.DateOffset(days=60)

Refresh the fundamental datasets (Income Statements etc.)

every 30 days.

refresh_days = 30

# Refresh the dataset with shareprices every 10 days.
 refresh_days_shareprices = 10

%%time
hub = sf.StockHub(market=market, tickers=tickers, offset=offset,
              refresh_days=refresh_days,
              refresh_days_shareprices=refresh_days_shareprices)

#try to download data using StockHub Object

 %%time
 df_fin_signals = hub.fin_signals(variant='daily')

also tried same code from SimFin tutorial https://github.com/SimFin/simfin-tutorials/blob/master/05_Data_Hubs.ipynb but get #similar error message

Result / Error

Dataset "us-income-ttm" not on disk.

HTTPError Traceback (most recent call last)
in

/usr/local/lib/python3.8/dist-packages/simfin/hubs.py in fin_signals(self, variant, func)
619 # This is only really necessary if the cache-file needs refreshing,
620 # but it is easier to program like this and the overhead is small.
--> 621 df_income_ttm = self.load_income(variant='ttm')
622 df_balance_ttm = self.load_balance(variant='ttm')
623 df_cashflow_ttm = self.load_cashflow(variant='ttm')

5 frames
/usr/local/lib/python3.8/dist-packages/requests/models.py in raise_for_status(self)
941
942 if http_error_msg:
--> 943 raise HTTPError(http_error_msg, response=self)
944
945 def close(self):

HTTPError: 401 Client Error: Unauthorized for url: https://backend.simfin.com/api/bulk-download?dataset=income&variant=ttm&market=us

Feature suggestion: better error handling in case sf.set_data_dir is omitted

Description

If the line sf.set_data_dir is omitted, the following error is raised:

TypeError: expected str, bytes or os.PathLike object, not NoneType

This error is very cryptic and it's not clear for the user that the explicit setting of the data path is missing.
A solution would be to either display an error message like:
Error: Data directory not specified, please specify a data directory using sf.set_data_dir
OR
select the home directory of the user by default (and append simfin_data) if no data directory is specified explicitely:

from pathlib import Path
import os
home = str(Path.home())
default_directory = os.path.join(home, "simfin_data")

Full Code to Reproduce Error

import pandas as pd

# Import the main functionality from the SimFin Python API.
import simfin as sf

# Import names used for easy access to SimFin's data-columns.
from simfin.names import *

df1 = sf.load(dataset='income', variant='annual', market='us')

.csv files (as in legacy site)

Hello,

My students and I for several years purchased .csv files of US annual data from simfin.com to analyze statistically. Unfortunately we are having difficulties navigating the new website and locating these SimFin+ .csv files. Can anyone point us in the right direction?

All the Best,

Mr. Harrington

hub.fin_signals - cannot handle a non-unique multi-index! error

Bug Report

Description

When I try to run the hub.fin_signals function I get the error below. This has suddenly started today. The same code worked fine yesterday.

System Details

--- USING GOOGLE COLAB

  • Python version
  • Simfin version
  • Other relevant package versions
  • Operation System and version
  • Computer's CPU, RAM-size, free HD space, etc.
  • Other relevant system information

Code Example

Please write a minimal source-code example that reproduces the problem.
You can indent the code-block to get proper code-formatting, for example:

!pip install simfin

%matplotlib inline
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.optimize import differential_evolution
from datetime import datetime, timedelta
import os

# Import the main functionality from the SimFin Python API.
import simfin as sf

# Import names used for easy access to SimFin's data-columns.
from simfin.names import *

# CONFIG
sf.set_data_dir('~/simfin_data/')
sf.set_api_key(api_key='XXXXXX')
sns.set_style("whitegrid")

# HUB CREATION
# We are interested in the US stock-market.
market = 'us'
# Add this date-offset to the fundamental data such as
# Income Statements etc., because the REPORT_DATE is not
# when it was actually made available to the public,
# which can be 1, 2 or even 3 months after the Report Date.
offset = pd.DateOffset(days=60)
# Refresh the fundamental datasets (Income Statements etc.)
# every 30 days.
refresh_days = 30
# Refresh the dataset with shareprices every 1 days.
refresh_days_shareprices = 1
hub = sf.StockHub(market=market, offset=offset, refresh_days=refresh_days, refresh_days_shareprices=refresh_days_shareprices)
    
# LOAD DATASETS
# Fundamental signals: Current ratio, ROA, ROE
df_fin_signals = hub.fin_signals(variant='daily')


Result / Error

Dataset "us-income-ttm" not on disk.
- Downloading ... 100.0%
- Extracting zip-file ... Done!
- Loading from disk ... Done!
Dataset "us-balance-ttm" not on disk.
- Downloading ... 100.0%
- Extracting zip-file ... Done!
- Loading from disk ... Done!
Dataset "us-cashflow-ttm" not on disk.
- Downloading ... 100.0%
- Extracting zip-file ... Done!
- Loading from disk ... Done!
Dataset "us-shareprices-daily" not on disk.
- Downloading ... 100.0%
- Extracting zip-file ... Done!
- Loading from disk ... Done!
Cache-file 'fin_signals-2a38bb7d.pickle' not on disk.
- Running function fin_signals() ... 
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-d3b3a780f45f> in <module>()
     21 # LOAD DATASETS
     22 # Fundamental signals: Current ratio, ROA, ROE
---> 23 df_fin_signals = hub.fin_signals(variant='daily')

5 frames
/usr/local/lib/python3.7/dist-packages/pandas/core/indexes/multi.py in reindex(self, target, method, level, limit, tolerance)
   2317                     )
   2318                 else:
-> 2319                     raise ValueError("cannot handle a non-unique multi-index!")
   2320 
   2321         if not isinstance(target, MultiIndex):

ValueError: cannot handle a non-unique multi-index!

Advanced logging

Feature Suggestion

Using the logging module, rather than directly printing to stdout and stderr.

Description

I understand this would add an additional dependency, but I think the logging module is fairly standard and accepted. I have an issue handling SimFin output in my applications, since I already use stdout as one of my logging streams.

Code

I can create a PR if there is interest, there are only a few print statements.

Example

It would be a matter of replacing all calls to print, with corresponding calls to logging.

Examples:

  • print(msg, file=sys.stderr) would become logging.error(msg)
  • print(msg) would become logging.info(msg)

Bug Report: pandas.errors.InvalidIndexError: Reindexing only valid with uniquely valued Index objects for 'growth_signals()'

Bug Report

Description

During following up the tutorial in here, I got the error, pandas.errors.InvalidIndexError: Reindexing only valid with uniquely valued Index objects, in
sf.StockHub.growth_signals(variant='daily').

Similar issue here: #26

System Details

  • Python version == 3.11.5
  • Simfin version == 1.0.1
  • Other relevant package versions
    • pandas == 2.2.2
  • Operation System and version
    • macOS Ventura 13.4
  • Computer's CPU, RAM-size, free HD space, etc.
    • 16G RAM
    • Apple M2
    • (302GB / 494.38GB)
  • Other relevant system information

Code Example

   # Copied from the Simfin tutorial

    import simfin as sf

    # Configure simfin.
    sf.set_data_dir('~/simfin_data/')
    sf.load_api_key(path='~/simfin_api_key.txt', default_key='free')

    market = 'us'
    
    offset = pd.DateOffset(days=60)
    
    refresh_days = 0
    refresh_days_shareprices = 10
    
    hub = sf.StockHub(market=market, offset=offset,
                      refresh_days=refresh_days,
                      refresh_days_shareprices=refresh_days_shareprices)
    
    df_growth_signals = hub.growth_signals(variant='daily') # Error here
    df_fin_signals = hub.fin_signals(variant='daily')
    df_val_signals = hub.val_signals(variant='daily')
    
    dfs = [df_fin_signals, df_growth_signals, df_val_signals]
    df_signals = pd.concat(dfs, axis=1)

Result / Error

(base) dongpinoh@Dongpinui-MacBookPro pinsfund % python test.py
/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/pandas/core/arrays/masked.py:60: UserWarning: Pandas requires version '1.3.6' or newer of 'bottleneck' (version '1.3.5' currently installed).
  from pandas.core import (
Dataset "us-income-ttm" on disk (0 days old).
- Downloading ... 100.0%
- Extracting zip-file ... Done!
/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/simfin/load.py:154: FutureWarning: The argument 'date_parser' is deprecated and will be removed in a future version. Please use 'date_format' instead, or read your data in as 'object' dtype and then call 'to_datetime'.
  df = pd.read_csv(path, sep=';', header=0,
- Loading from disk ... Done!
Dataset "us-income-quarterly" on disk (0 days old).
- Downloading ... 100.0%
- Extracting zip-file ... Done!
/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/simfin/load.py:154: FutureWarning: The argument 'date_parser' is deprecated and will be removed in a future version. Please use 'date_format' instead, or read your data in as 'object' dtype and then call 'to_datetime'.
  df = pd.read_csv(path, sep=';', header=0,
- Loading from disk ... Done!
Dataset "us-balance-ttm" on disk (0 days old).
- Downloading ... 100.0%
- Extracting zip-file ... Done!
/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/simfin/load.py:154: FutureWarning: The argument 'date_parser' is deprecated and will be removed in a future version. Please use 'date_format' instead, or read your data in as 'object' dtype and then call 'to_datetime'.
  df = pd.read_csv(path, sep=';', header=0,
- Loading from disk ... Done!
Dataset "us-balance-quarterly" on disk (0 days old).
- Downloading ... 100.0%
- Extracting zip-file ... Done!
/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/simfin/load.py:154: FutureWarning: The argument 'date_parser' is deprecated and will be removed in a future version. Please use 'date_format' instead, or read your data in as 'object' dtype and then call 'to_datetime'.
  df = pd.read_csv(path, sep=';', header=0,
- Loading from disk ... Done!
Dataset "us-cashflow-ttm" on disk (0 days old).
- Downloading ... 100.0%
- Extracting zip-file ... Done!
/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/simfin/load.py:154: FutureWarning: The argument 'date_parser' is deprecated and will be removed in a future version. Please use 'date_format' instead, or read your data in as 'object' dtype and then call 'to_datetime'.
  df = pd.read_csv(path, sep=';', header=0,
- Loading from disk ... Done!
Dataset "us-cashflow-quarterly" on disk (0 days old).
- Downloading ... 100.0%
- Extracting zip-file ... Done!
/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/simfin/load.py:154: FutureWarning: The argument 'date_parser' is deprecated and will be removed in a future version. Please use 'date_format' instead, or read your data in as 'object' dtype and then call 'to_datetime'.
  df = pd.read_csv(path, sep=';', header=0,
- Loading from disk ... Done!
Dataset "us-shareprices-daily" on disk (0 days old).
/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/simfin/load.py:154: FutureWarning: The argument 'date_parser' is deprecated and will be removed in a future version. Please use 'date_format' instead, or read your data in as 'object' dtype and then call 'to_datetime'.
  df = pd.read_csv(path, sep=';', header=0,
- Loading from disk ... Done!
Cache-file 'growth_signals-2a38bb7d.pickle' not on disk.
- Running function growth_signals() ... Traceback (most recent call last):
  File "/Users/dongpinoh/pinsfund/test.py", line 30, in <module>
    df_growth_signals = hub.growth_signals(variant='daily')
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/simfin/hubs.py", line 582, in growth_signals
    df_result = growth_signals(df_income_ttm=df_income_ttm,
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/simfin/cache.py", line 266, in wrapper
    df_result = func(**kwargs)
                ^^^^^^^^^^^^^^
  File "/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/simfin/signals.py", line 644, in growth_signals
    df_qrt = pd.concat([df_qrt1, df_qrt2, df_qrt3], axis=1)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/pandas/core/reshape/concat.py", line 395, in concat
    return op.get_result()
           ^^^^^^^^^^^^^^^
  File "/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/pandas/core/reshape/concat.py", line 680, in get_result
    indexers[ax] = obj_labels.get_indexer(new_labels)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dongpinoh/anaconda3/lib/python3.11/site-packages/pandas/core/indexes/base.py", line 3885, in get_indexer
    raise InvalidIndexError(self._requires_unique_msg)
pandas.errors.InvalidIndexError: Reindexing only valid with uniquely valued Index objects

Signals do not work with "Bank" and "Insurance" Standardisation Schema

Description

The Signal Functions do not work with the non "General" Standardisation Schema

https://simfin.readthedocs.io/en/latest/signals.html?highlight=fin_singals

Code Example

REFRESH_DAYS = 1

income_banks_df = sf.load_income_banks(variant='ttm', market='us', refresh_days=REFRESH_DAYS)
balance_banks_df = sf.load_balance_banks(variant='ttm', market='us', refresh_days=REFRESH_DAYS)
cashflow_banks_df = sf.load_cashflow_banks(variant='ttm', market='us', refresh_days=REFRESH_DAYS)

fin_signal_bank_df = sf.fin_signals(df_income_ttm=income_banks_df,
                                df_balance_ttm=balance_banks_df,
                                df_cashflow_ttm=cashflow_banks_df,
                                **cache_args)

Result / Error

KeyError: "['Interest Expense, Net', 'Research & Development', 'Gross Profit'] not in index"

Data Error

Hi,
why the latest quartely data dose not show?
I installed Simfin - 0.8.4 and tried Python API call the quaterly data for below stock.
However, it did not show the Quarterly report for quarter ending October 1, 2021.

Ticker : ON (ON SEMICONDUCTOR CORP)

Code Example

# Configure simfin.

sf.set_data_dir('~/simfin_data/')
sf.set_api_key('***my API - Simfin+ User--')

# Download and load the dataset from the SimFin server.

try:
df_IS_Q=sf.load_income(variant='quarterly-full', market='us', refresh_days=1)
except sf.ServerException as e:
print(e)

Show the data that has errors.

df_IS_Q.loc['ON'].tail()

Data Output

It did not show the Quarterly report for quarter ending October 1, 2021.

Report Date | SimFinId | Currency | Fiscal Year | Fiscal Period | Publish Date | Restated Date | Shares (Basic)
2020-06-30 | 136025 | USD | 2020 | Q2 | 2020-08-10 | 2021-08-02 | 410100000
2020-09-30 | 136025 | USD | 2020 | Q3 | 2020-11-02 | 2020-11-02 | 410800000
2020-12-31 | 136025 | USD | 2020 | Q4 | 2021-02-16 | 2021-05-03 | 411300000
2021-03-31 | 136025 | USD | 2021 | Q1 | 2021-05-03 | 2021-05-03 | 413400000
2021-06-30 | 136025 | USD | 2021 | Q2 | 2021-08-02 | 2021-08-02 | 413400000

Generic Test

We use an automatic test-suite to ensure the data is correct and reliable.
You are very welcome to try and develop a generic test using the tools in
tests/test_bulk_data.ipynb
that can find all data errors of the type you are reporting. If you do so,
then please write the code here. Instructions for running this automated
data-test can be found in the project's README.

Deprecation warning on loads

Python 3.10 - deprecation warning load.py ...

/Users/XXX/opt/anaconda3/envs/py3_10_8_pinon/lib/python3.10/site-packages/simfin/load.py:144: FutureWarning: The argument 'date_parser' is deprecated and will be removed in a future version. Please use 'date_format' instead, or read your data in as 'object' dtype and then call 'to_datetime'.
df = pd.read_csv(path, sep=';', header=0,

I will do a pull request for this - but may be a few weeks ...

Numerous Bugs

I am a multi-year user of SimFin encountering numerous bugs this year (2023) all yielding a generic 404 error page.

Also there is no clear method for downloading .csv files of the bulk data as in the past.

I don't mind paying more for accurate data delivered through a functioning website.

Is it possible to revert to the older, usable website?

make optional loading of data into pandas dataframe in sf.load()

Feature Suggestion

Description

The load() function (in load.py) downloads the data (zip+unzip) and then directly load the data into a pandas dataframe.
Would it be possible to add an argument to only download the data (and thus return nothing), skipping the pandas dataframe creation altogether?
That would allow people only interested in downloading the data or using something different than Pandas to also use the nice functionalities implemented in _maybe_download_dataset (url, cashing, filename...).

Code

An easy non-breaking change could be to add an argument create_pandas_dataframe=True:

def load(dataset, variant=None, market=None, start_date=None, end_date=None,
         parse_dates=None, index=None, refresh_days=30, create_pandas_dataframe=True):
    """
    Load the dataset from local disk and return it as a Pandas DataFrame.
    ....
    :param create_pandas_dataframe:
        Boolean to create pandas dataframe with loaded data.

    :return:
        Pandas DataFrame with the data or None.
    """

    assert dataset is not None

    # Convert dataset name, variant, and market to lower-case.
    dataset = dataset.lower()
    if variant is not None:
        variant = variant.lower()
    if market is not None:
        market = market.lower()

    # Dict with dataset arguments.
    dataset_args = {'dataset': dataset, 'variant': variant, 'market': market}

    # Download file if it does not exist on local disk, or if it is too old.
    _maybe_download_dataset(**dataset_args, refresh_days=refresh_days)

    # Return Pandas DataFrame.
    if create_pandas_dataframe:
        # Lambda function for converting strings to dates. Format: YYYY-MM-DD
        date_parser = lambda x: pd.to_datetime(x, yearfirst=True, dayfirst=False)
    
        # Print status message.
        print('- Loading from disk ... ', end='')
    
        # Full path for the CSV-file on local disk.
        path = _path_dataset(**dataset_args)
        if start_date or end_date:
            print('\n- Applying filter ... ', end='')
            path = _filtered_file(path, start_date, end_date=end_date)
        
        # Load dataset into Pandas DataFrame.
        df = pd.read_csv(path, sep=';', header=0,
                        parse_dates=parse_dates, date_parser=date_parser)
    
        # Set the index and sort the data.
        if index is not None:
            # Set the index.
            df.set_index(index, inplace=True)
    
            # Sort the rows of the DataFrame according to the index.
            df.sort_index(ascending=True, inplace=True)
    
        # Print status message.
        print('Done!')
        
        return df

Example

import simfin as sf

# only download data
sf.load_income(variant='quarterly-full-asreported', market='us', create_pandas_dataframe=False)

# download data and return pandas dataframe
sf.load_balance(variant='quarterly-full-asreported', market='us')

Happy to make a PR if necessary. Thanks!

FAQ - Frequently Asked Questions

These are Frequently Asked Questions (FAQ) related to the Python API for SimFin. More general questions about the SimFin bulk download can be found here. Please also try and search the closed GitHub issues before you ask a new question.

  • Q: Do I need an API key to use the Python API?
    A: No! By default the Python API uses the key 'free' which lets you download the free datasets. You only need to get an API-key if you also want to buy a monthly subscription for downloading the full datasets.

  • Q: I have paid for a subscription to get recent data, but even when I use my new API key, I still only get the free datasets with older data. Why?
    A: The data is stored in a directory on your harddisk. If you have downloaded the free data before purchasing a subscription and getting an API key, the previously downloaded data will be loaded again even if you enter your new API key. You have to manually delete the entire data directory to download fresh data using your new API key. The data-dir is typically located at ~/simfin_data/

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.