fastquant is a python package that allows you easily access stock data from PSE Edge with as few as 2 lines of python code.
Its goal is to promote data driven investments by making quantitative analysis in finance accessible to everyone.
Raise awareness, and guide beginners to get a sufficient foundation by teaching the basics of quant analysis with lectures presented via medium articles & online lectures
Make quant analysis simple and easy w/ a high level python API that allows for lower level configuration for more advanced users - development of an easy to use python package to facilitate data driven investments
Objective | Strategy |
---|---|
Raise awareness, and guide beginners | Tutorials via Medium articles & lectures| Make quant analysis simple and easy | Beginner friendly high level python API
We start w/ immediate usefulness and then work towards “deep” understanding later as more experience is gained. This approach will be reflected in the design of the blog posts, lectures, and the fastquant package.
medium article + notebook -> webinar
Medium article + notebook takes 1-2 weeks, while webinar will take 1-2 weeks. So the pace will generally be 1-2 webinars per month.
Webinars will be recorded and posted as content on facebook/youtube.
1. Lecture 1: Accessing PSE data in 3 lines of code
1. Accessing PSE data in 3 lines of code
2. Plotting a basic SMAC strategy
3. The idea of backtesting
2. Lecture 2: Backtest your trading strategy with 5 lines of code
3. Lecture 3: Relative Strength Index (Intro + backtesting)
4. Lecture 4: Bollinger Bands (Intro + backtesting)
5. Lecture 5: Moving Average Convergence Divergence (Intro + backtesting)
6. Lecture 6: Backtesting multiple strategies at the same time
1. Let's make sure everyone gets Google Colab working
2. Show github and encourage people to make an account (if they want to contribute to fastquant).
3. Please star the repo if you find it useful! :)
Installing fastquant
is super simple since it's on pypi!
!pip install fastquant
Requirement already satisfied: fastquant in /usr/local/lib/python3.6/dist-packages (0.1.2.5) Requirement already satisfied: requests-oauthlib==1.3.0 in /usr/local/lib/python3.6/dist-packages (from fastquant) (1.3.0) Requirement already satisfied: certifi==2019.11.28 in /usr/local/lib/python3.6/dist-packages (from fastquant) (2019.11.28) Requirement already satisfied: tweepy==3.8.0 in /usr/local/lib/python3.6/dist-packages (from fastquant) (3.8.0) Requirement already satisfied: black==19.10b0 in /usr/local/lib/python3.6/dist-packages (from fastquant) (19.10b0) Requirement already satisfied: requests==2.22.0 in /usr/local/lib/python3.6/dist-packages (from fastquant) (2.22.0) Requirement already satisfied: six==1.13.0 in /usr/local/lib/python3.6/dist-packages (from fastquant) (1.13.0) Requirement already satisfied: numpy==1.18.0 in /usr/local/lib/python3.6/dist-packages (from fastquant) (1.18.0) Requirement already satisfied: urllib3==1.25.7 in /usr/local/lib/python3.6/dist-packages (from fastquant) (1.25.7) Requirement already satisfied: bs4==0.0.1 in /usr/local/lib/python3.6/dist-packages (from fastquant) (0.0.1) Requirement already satisfied: chardet==3.0.4 in /usr/local/lib/python3.6/dist-packages (from fastquant) (3.0.4) Requirement already satisfied: soupsieve==1.9.5 in /usr/local/lib/python3.6/dist-packages (from fastquant) (1.9.5) Requirement already satisfied: python-dateutil==2.8.1 in /usr/local/lib/python3.6/dist-packages (from fastquant) (2.8.1) Requirement already satisfied: oauthlib==3.1.0 in /usr/local/lib/python3.6/dist-packages (from fastquant) (3.1.0) Requirement already satisfied: pandas==0.25.3 in /usr/local/lib/python3.6/dist-packages (from fastquant) (0.25.3) Requirement already satisfied: idna==2.8 in /usr/local/lib/python3.6/dist-packages (from fastquant) (2.8) Requirement already satisfied: matplotlib==3.1.2 in /usr/local/lib/python3.6/dist-packages (from fastquant) (3.1.2) Requirement already satisfied: beautifulsoup4==4.8.2 in /usr/local/lib/python3.6/dist-packages (from fastquant) (4.8.2) Requirement already satisfied: lxml==4.4.2 in /usr/local/lib/python3.6/dist-packages (from fastquant) (4.4.2) Requirement already satisfied: PySocks==1.7.1 in /usr/local/lib/python3.6/dist-packages (from fastquant) (1.7.1) Requirement already satisfied: backtrader==1.9.74.123 in /usr/local/lib/python3.6/dist-packages (from fastquant) (1.9.74.123) Requirement already satisfied: pytz==2019.3 in /usr/local/lib/python3.6/dist-packages (from fastquant) (2019.3) Requirement already satisfied: pathspec<1,>=0.6 in /usr/local/lib/python3.6/dist-packages (from black==19.10b0->fastquant) (0.7.0) Requirement already satisfied: toml>=0.9.4 in /usr/local/lib/python3.6/dist-packages (from black==19.10b0->fastquant) (0.10.0) Requirement already satisfied: appdirs in /usr/local/lib/python3.6/dist-packages (from black==19.10b0->fastquant) (1.4.3) Requirement already satisfied: click>=6.5 in /usr/local/lib/python3.6/dist-packages (from black==19.10b0->fastquant) (7.0) Requirement already satisfied: typed-ast>=1.4.0 in /usr/local/lib/python3.6/dist-packages (from black==19.10b0->fastquant) (1.4.1) Requirement already satisfied: regex in /usr/local/lib/python3.6/dist-packages (from black==19.10b0->fastquant) (2019.12.20) Requirement already satisfied: attrs>=18.1.0 in /usr/local/lib/python3.6/dist-packages (from black==19.10b0->fastquant) (19.3.0) Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib==3.1.2->fastquant) (1.1.0) Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.6/dist-packages (from matplotlib==3.1.2->fastquant) (0.10.0) Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib==3.1.2->fastquant) (2.4.6) Requirement already satisfied: setuptools in /usr/local/lib/python3.6/dist-packages (from kiwisolver>=1.0.1->matplotlib==3.1.2->fastquant) (42.0.2)
from fastquant import get_pse_data
df = get_pse_data('JFC', '2018-01-01', '2019-01-01')
df.head()
Stock table exists! Reading stock_table.csv ...
open | high | low | close | value | |
---|---|---|---|---|---|
dt | |||||
2018-01-03 | 253.4 | 256.8 | 253.0 | 255.4 | 190253754.0 |
2018-01-04 | 255.4 | 255.4 | 253.0 | 255.0 | 157152856.0 |
2018-01-05 | 255.6 | 257.4 | 255.0 | 255.0 | 242201952.0 |
2018-01-08 | 257.4 | 259.0 | 253.4 | 256.0 | 216069242.0 |
2018-01-09 | 256.0 | 258.0 | 255.0 | 255.8 | 250188588.0 |
help(get_pse_data)
Help on function get_pse_data in module fastquant.fastquant: get_pse_data(symbol, start_date, end_date, stock_table_fp='stock_table.csv', disclosures=False) Returns pricing data for a specified stock. Parameters ---------- symbol : str Symbol of the stock in the PSE. You can refer to this link: https://www.pesobility.com/stock. start_date : str Starting date (YYYY-MM-DD) of the period that you want to get data on end_date : str Ending date (YYYY-MM-DD) of the period you want to get data on stock_table_fp : str File path of an existing stock table or where a newly downloaded table should be saved Returns ------- pandas.DataFrame Stock data (in OHLCV format) for the specified company and date range
For this part, we'll want to import a plotting package, matplotlib, to be able to visualize the closing prices of Jollibee. Don't worry if you don't understand how this works - for now, just take the code as is.
from matplotlib import pyplot as plt
df.close.plot(figsize=(10, 6))
plt.title("Daily Closing Prices of JFC\nfrom 2018-01-01 to 2019-01-01", fontsize=20)
Text(0.5, 1.0, 'Daily Closing Prices of JFC\nfrom 2018-01-01 to 2019-01-01')
Now that we have the data ready, let's visualize a sample SMAC strategy.
First, let's import the pandas library (general purpose library for handling tabular data).
import pandas as pd
Next, we calculate the 30 day moving average of Jollibee's closing price and combine it with the original closing price data.
ma30 = df.close.rolling(30).mean()
close_ma30 = pd.concat([df.close, ma30], axis=1).dropna()
close_ma30.columns = ['Closing Price', 'Simple Moving Average (30 day)']
ma30.dropna()
dt 2018-02-13 276.586667 2018-02-14 277.340000 2018-02-15 278.340000 2018-02-19 279.340000 2018-02-20 280.340000 ... 2018-12-20 287.446667 2018-12-21 288.193333 2018-12-26 288.660000 2018-12-27 289.360000 2018-12-28 289.993333 Name: close, Length: 214, dtype: float64
ma30.dropna().plot(figsize=(10, 6))
<matplotlib.axes._subplots.AxesSubplot at 0x7f639ebea668>
Lastly, we plot the trends for the daily crossing prices and the 30 day SMA together
close_ma30.plot(figsize=(10, 6))
plt.title("Daily Closing Prices vs 30 day SMA of JFC\nfrom 2018-01-01 to 2019-01-01", fontsize=20)
Text(0.5, 1.0, 'Daily Closing Prices vs 30 day SMA of JFC\nfrom 2018-01-01 to 2019-01-01')
from fastquant import get_company_disclosures
jfc_disclosures = get_company_disclosures('JFC', from_date='06-26-2018', to_date='06-26-2019')
help(get_company_disclosures)
Help on function get_company_disclosures in module fastquant.fastquant: get_company_disclosures(symbol, from_date='06-26-2017', to_date='06-26-2019') symbol str - Ticker of the pse stock of choice from_date date str %m-%d-%Y - Beginning date of the disclosure data pull to_date date str %m-%d-%Y - Ending date of the disclosure data pull
jfc_disclosures.iloc[0]
Company Name Jollibee Foods Corporation Template Name [Amend-2]Notice of Annual or Special Stockhold... PSE Form Number 7-1 Announce Date and Time 2019-05-29 11:41:00 Circular Number C03719-2019 edge_no 8a9a820ee365687cefdfc15ec263a54d url https://edge.pse.com.ph/openDiscViewer.do?edge... Name: 1, dtype: object
jfc_disclosures.iloc[0].url
'https://edge.pse.com.ph/openDiscViewer.do?edge_no=8a9a820ee365687cefdfc15ec263a54d'
jfc_disclosures.iloc[15]['Template Name']
'[Amend-1]Amendments to By-Laws'
Question: how can we apply a sentiment analysis to company disclosures?
Rafael - can contribute to 1) refactoring, 2) sentiment analysis on content