I found good information on the usage of ta-lib with Python here.
Author: christinanorwood
The Technical Analysis (TA) Library
There’s a library of fast technical analysis indicator functions for which the Python wrapper is talib. I found a course I did a couple of years ago that used this library because I was having some trouble with the docs. Quite easy really. Here I’ve added a MACD indicator to a time series.
import talib.abstract as ta
import pandas as pd
df = pd.read_csv('data/ADA.csv', index_col=0, parse_dates=True)
macd = ta.MACD(df)
# Information about the class/function
print(ta.MACD)
and here’s the resultant dataframe (part of it anyway)
date,macd,macdsignal,macdhist
2021-03-21,0.06283678579937213,0.06975973998121408,-0.006922954181841953
2021-03-22,0.051024886860298935,0.06601276935703106,-0.014987882496732122
2021-03-23,0.04237687616033803,0.06128559071769245,-0.01890871455735442
2021-03-24,0.03133963841922505,0.055296400257998965,-0.02395676183877392
2021-03-25,0.024455424936367764,0.049128205193672725,-0.02467278025730496
2021-03-26,0.02824408474397111,0.0449513811037324,-0.016707296359761294
2021-03-27,0.027905466818372693,0.04154219824666046,-0.013636731428287766
2021-03-28,0.028775604149389844,0.03898887942720634,-0.010213275277816493
So we get the macd value, the macdsignal value and the macdhist value as a DataFrame. Nice.
The website can be found here. Usage is described in another post.
TradInformed
Mark Ursell at TradInformed has several ebooks (which I have acquired through Amazon) describing various trading strategies and backtesting primarily using MS Excel (or equivalent spreadsheet software such as LibreOffice or Google Sheets). His website appears to have other offerings which I haven’t explored.
Udemy
Udemy portal for online learning.
Econometrics by Ben Lambert
Ben Lambert’s Youtube channel on econometrics.
TradingView
TradingView – where would we be without it?
Stationarity
Testing for stationarity of a time series is important for certain trading strategies, particulary mean-reversion strategies. Stationarity means that the (rolling) mean and variance are fairly constant. There are various Python libraries that provide the necessary functionality. The example below demonstrates the use of the Augmented Dickey Fuller (ADF) test from the statsmodels package on a year’s worth of daily data for the ADABTC trading pair.
import pandas as pd
import numpy as np
import requests
import json
from datetime import datetime
from statsmodels.tsa.stattools import adfuller
root_url = 'https://api.binance.com/api/v1/klines'
symbol = 'ADABTC'
interval = '1d'
limit = '360'
url = root_url + '?symbol=' + symbol + '&interval=' + interval + '&limit=' + limit
data = json.loads(requests.get(url).text)
df = pd.DataFrame(data)
df.columns = ['date', 'open', 'high', 'low', 'close', 'v', 'close_time', 'qav',
'num_trades', 'taker_base_vol', 'taker_quote_vol', 'ignore']
df['date'] = [datetime.utcfromtimestamp(x/1000.0).date() for x in df.date]
df = df.set_index('date')
df['close'] = df['close'].astype(float)
# extracting only the close prices using values attribute of the DataFrame/Series
values = df['close'].values
# passing the extracted close prices to adfuller function.
res = adfuller(values)
# Printing the statistical result of the adfuller test
print('p-value: %f \n' % res[1])
print('Augmneted Dickey_fuller Statistic: %f \n' % res[0])
# printing the critical values at different alpha levels.
print('critical values at different levels:')
for k, v in res[4].items():
print('\t%s: %.3f' % (k, v))
The generally accepted level is 95% confidence level, in this case being a p value of 0.05 as the null hypothesis is that the series is not stationary.
Dr. E. Chan – Quantitative Finance
WEKA Course Videos
Here’s a link to the videos for the 3 courses conducted by the University of Waikato relating to WEKA, the machine learning workbench developed by the CS dept at that university. This material is also available on YouTube.
Append Data Directly to an Existing File
There are several ways to update a CSV file with new data. This method shows how to write the new data directly to file.
''' Append data directly to an existing CSV file '''
from datetime import datetime, timezone
import requests # for making http requests to binance
import json # for parsing what binance sends back to us
import pandas as pd # for storing and manipulating the data we get back
root_url = 'https://api.binance.com/api/v1/klines'
coin = 'BTC'
symbol = coin + 'USDT'
interval = '1d'
limit = '1000'
date = datetime(2020, 9, 27, 0, 0, 0, tzinfo=timezone.utc)
startDate = int(datetime.timestamp(date)) * 1000
startTime = str(startDate)
url = root_url + '?symbol=' + symbol + '&interval=' + interval + '&startTime=' + startTime + '&limit=' + limit
data = json.loads(requests.get(url).text)
df = pd.DataFrame(data)
df.columns = ['date', 'open', 'high', 'low', 'close', 'v', 'close_time', 'qav',
'num_trades', 'taker_base_vol', 'taker_quote_vol', 'ignore']
df['date'] = [datetime.utcfromtimestamp(x/1000.0) for x in df.date]
df = df.set_index('date')
with open('data/BTCUSDT.csv', 'a') as f:
for i, row in df.iterrows():
date = i.strftime("%Y-%m-%d")
f.write(date + ',' + row['close'] + '\n')
Getting kline data from Binance REST API
The following code can be used to get kline data from Binance.
from datetime import datetime, timezone
import requests # for making http requests to binance
import json # for parsing what binance sends back to us
import pandas as pd # for storing and manipulating the data we get back
root_url = 'https://api.binance.com/api/v1/klines'
coin = 'BTC'
symbol = coin + 'USDT'
interval = '1d'
limit = '1000'
date = datetime(2020, 9, 3, 0, 0, 0, tzinfo=timezone.utc)
startDate = int(datetime.timestamp(date)) * 1000
startTime = str(startDate)
url = root_url + '?symbol=' + symbol + '&interval=' + interval + '&startTime=' + startTime + '&limit=' + limit
data = json.loads(requests.get(url).text)
df = pd.DataFrame(data)
df.columns = ['date', 'open', 'high', 'low', 'close', 'v', 'close_time', 'qav',
'num_trades', 'taker_base_vol', 'taker_quote_vol', 'ignore']
df['date'] = [datetime.utcfromtimestamp(x/1000.0) for x in df.date]
df = df.set_index('date')
In the root URL data can replace api. Apparently v1, v2, v3 or v4 all function the same. If no start date is provided the most recent entries are sent. Default LIMIT is 500, 1000 is the maximum for one request. Consult the API docs for available frequencies.