Last active
August 7, 2022 09:46
-
-
Save yhilpisch/b98e13bb470efe4d1bffa3bdcc3c7ed9 to your computer and use it in GitHub Desktop.
Algo Trading Bootcamp @ For Python Quants
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Welcome to the Algo Trading Bootcamp | |
==================================== | |
WIFI | |
==== | |
Ft1ch#2016#! | |
Quant Platform | |
============== | |
http://fpqlon.pqp.io | |
(follow registration link) | |
Miniconda | |
========= | |
http://conda.pydata.org/miniconda.html | |
http://conda.pydata.org/docs/using/envs.html | |
Environment | |
=========== | |
conda create -n algobc python=3.5 | |
source activate algobc (Linux/Mac) | |
activate algobc (Windows) | |
conda install ipython | |
conda install numpy | |
conda install matplotlib | |
conda install pandas-datareader | |
conda install seaborn | |
conda install scikit-learn | |
ipython | |
[1]: print('python') | |
Crypto Workshop | |
=============== | |
https://github.com/mintegration/crypto_workshop | |
git clone https://github.com/mintegration/crypto_workshop | |
Video about central technologies used in the cryptocurrency space (explained by using Python): | |
https://www.youtube.com/watch?v=8ke8xn60MIc | |
pip install ConfigParser |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
conda create -n crypto python=2.7 | |
source activate crypto | |
pip install ConfigParser | |
conda install requests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[api] | |
key = YOUR_API_KEY | |
secret_key = YOUR_SECRET_API_KEY | |
url = https://api.sandbox.gemini.com/v1/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Algo Trading Bootcamp | |
# Gemini Crypto Exchange | |
# | |
# For Python Quants Bootcamp | |
# | |
# Nick Kirk | |
# | |
import hmac, hashlib, time | |
import ConfigParser | |
import base64 | |
import json | |
import requests | |
# Create custom authentication for Exchange | |
class GeminiAuth(object): | |
def __init__(self): | |
configParser = ConfigParser.RawConfigParser() | |
configFilePath = r'gemini.cfg' | |
configParser.read(configFilePath) | |
self.api_key = configParser.get('api', 'key') | |
self.secret_key = configParser.get('api', 'secret_key') | |
def setNonce(self): | |
return str(int(time.time() * 1e6)) | |
def _generateSig(self, b64): | |
return hmac.new(self.secret_key, b64, hashlib.sha384).hexdigest() | |
def generateHeaders(self, b64): | |
return { 'X-GEMINI-APIKEY': self.api_key, | |
'X-GEMINI-PAYLOAD': b64, | |
'X-GEMINI-SIGNATURE': self._generateSig(b64) } | |
class GeminiRestAPI(object): | |
def __init__(self): | |
configParser = ConfigParser.RawConfigParser() | |
configFilePath = r'gemini.cfg' | |
configParser.read(configFilePath) | |
self.api_url = configParser.get('api', 'url') | |
self.auth = GeminiAuth() | |
def getTicker(self, symbol): | |
return requests.get(self.api_url + 'pubticker/' + symbol, timeout = 10).json() | |
def postLimitOrder(self, symbol, side, amount, price): | |
b64 = base64.b64encode(json.dumps({ "request": "/v1/order/new", | |
"nonce": self.auth.setNonce(), | |
"symbol": symbol, | |
"amount": str(amount), | |
"price": str(price), | |
"side": side, | |
"type": "exchange limit"})) | |
headers = self.auth.generateHeaders(b64) | |
return requests.post(self.api_url + 'order/new', headers = headers, timeout = 10).json() | |
def postAvailableBalances(self): | |
b64 = base64.b64encode(json.dumps({ "request": "/v1/balances", | |
"nonce": self.auth.setNonce() })) | |
headers = self.auth.generateHeaders(b64) | |
return requests.post(self.api_url + 'balances', headers = headers, timeout = 10).json() | |
if __name__ == '__main__': | |
# Get a list of trading accounts | |
geminiRestAPI = GeminiRestAPI() | |
tradingAccounts = geminiRestAPI.postAvailableBalances() | |
print('\nAccounts: %s' % tradingAccounts) | |
# Ticker | |
ticker = geminiRestAPI.getTicker('btcusd') | |
geminiASK = float(ticker.get('ask')) | |
geminiBID = float(ticker.get('bid')) | |
print('\nTicker: %s' % ticker) | |
print('\nASK: [%s]' % geminiASK) | |
print('BID: [%s]' % geminiBID) | |
# BUY Limit Order | |
geminiOrder = geminiRestAPI.postLimitOrder('btcusd', 'buy', 0.01, geminiASK) | |
print('\nOrder: %s' % geminiOrder) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Algo Trading Bootcamp | |
# For Python Quants | |
# | |
# The Python Quants GmbH | |
# | |
import numpy as np | |
import pandas as pd | |
from pandas_datareader import data as web | |
data = web.DataReader('AAPL', data_source='yahoo') | |
data.info() | |
h5 = pd.HDFStore('data.h5', 'w') | |
!conda install pytables | |
h5 = pd.HDFStore('data.h5', 'w') | |
h5 | |
h5['AAPL'] = data | |
h5 | |
ls -an da* | |
ls | |
h5.close() | |
h | |
h5 | |
h5 = pd.HDFStore('data.h5', 'r') | |
df = h5['AAPL'] | |
df.tail() | |
h5.close() | |
data = data['Adj Close'] | |
type(data) | |
data = pd.DataFrame(data) | |
type(data) | |
data['return'] = np.log(data / data.shift(1)) | |
data.info() | |
data.rename(columns={'Adj Close': 'price'}) | |
data.rename(columns={'Adj Close': 'price'}, inplace=True) | |
data.info() | |
data.tail() | |
import seaborn as sns; sns.set() | |
from pylab import ion | |
ion() | |
data.price.plot() | |
from pylab import plt | |
plt.show() | |
data.return.hist(bins=35) | |
data['return'].hist(bins=35) | |
data['position'] = data['return'].rolling(5).mean() | |
data.head(10) | |
data['position'] = np.sign(data['position']) | |
data.head(10) | |
data['strategy'] = data['position'].shift(1) * data['return'] | |
data.head(10) | |
data[['return', 'strategy']].dropna().cumsum().apply(np.exp).plot() | |
data[['return', 'strategy']].dropna().cumsum().apply(np.exp).tail() | |
data['position'] = data['return'].rolling(5).mean() | |
data['position'].hist(bins=35) | |
data['position'].hist(bins=35) | |
t = 0.005 | |
data['position'] = np.where(data['position'] > t, 1.0, data['position']) | |
data['position'] = np.where(data['position'] < -t, -1.0, data['position']) | |
data['position'] = np.where(np.abs(data['position']) != 1.0, 0.0, data['position']) | |
data['position'].plot(ylim=[-1.1, 1.1]) | |
data['strategy'] = data['position'].shift(1) * data['return'] | |
data[['return', 'strategy']].dropna().cumsum().apply(np.exp).tail() | |
data[['return', 'strategy']].dropna().cumsum().apply(np.exp).plot() | |
%ed | |
run_strategy(4) | |
run_strategy(5) | |
run_strategy(6) | |
run_strategy(7) | |
run_strategy(7)['strategy'] | |
for days in range(2, 15): | |
res = run_strategy(days) | |
op = res['strategy'] - res['return'] | |
print('%2d | %f' % (days, op)) | |
for days in range(2, 42): | |
res = run_strategy(days) | |
op = res['strategy'] - res['return'] | |
print('%2d | %f' % (days, op)) | |
%ed -p | |
%history -f bc_algo_01.py | |
%hist | |
data = web.DataReader('^GSPC', data_source='yahoo')['Adj Close'] | |
data = pd.DataFrame(data) | |
data['returns'] = np.log(data / data.shift(1)) | |
data.rename(columns={'Adj Close': 'prices'}, inplace=True) | |
data.head() | |
lags = 3 | |
m = np.zeros((lags + 1, len(data) - lags)) | |
for i in range(lags + 1): | |
if i == lags: | |
m[i] = data.prices.values[i:] | |
else: | |
m[i] = data.prices.values[i:i - lags] | |
m.T | |
a = np.arange(12) | |
for i in range(lags + 1): | |
if i == lags: | |
m[i] = a[i:] | |
else: | |
m[i] = a[i:i - lags] | |
m = np.zeros((lags + 1, len(a) - lags)) | |
for i in range(lags + 1): | |
if i == lags: | |
m[i] = a[i:] | |
else: | |
m[i] = a[i:i - lags] | |
m.T | |
a | |
m = np.zeros((lags + 1, len(data) - lags)) | |
for i in range(lags + 1): | |
if i == lags: | |
m[i] = data.prices.values[i:] | |
else: | |
m[i] = data.prices.values[i:i - lags] | |
reg = np.linalg.lstsq(m[:lags].T, m[lags])[0] | |
reg | |
pred = np.dot(m[:lags].T, reg) | |
pred[:10] | |
data['pred'] = 0.0 | |
data['pred'].ix[lags:] = pred | |
data[['prices', 'pred']].plot() | |
data[['prices', 'pred']].dropna().plot() | |
data[['prices', 'pred']].head() | |
data[['prices', 'pred']].ix[lags:].plot() | |
data[['prices', 'pred']][data.index > '2016-09-01'].plot() | |
data = data.dropna() | |
m = np.zeros((lags + 1, len(data) - lags)) | |
for i in range(lags + 1): | |
if i == lags: | |
m[i] = data.returns.values[i:] | |
else: | |
m[i] = data.returns.values[i:i - lags] | |
m.T | |
reg = np.linalg.lstsq(m[:lags].T, m[lags])[0] | |
reg | |
pred = np.dot(m[:lags].T, reg) | |
data['pred'].ix[lags:] = pred | |
data.head() | |
data[['returns', 'pred']].ix[lags:].plot() | |
data['hits'] = data['returns'] * data['pred'] | |
data['hits'].ix[lags:].count_values() | |
data['hits'].ix[lags:].value_counts() | |
np.sign(data['hits']).ix[lags:].value_counts() | |
np.sign(data['hits']).ix[lags:].value_counts() | |
data['position'] = np.sign(data['returns'] * data['pred']) | |
data['strategy'] = data['position'] * data['returns'] | |
data.head() | |
data['position'] = np.sign(data['pred']) | |
data['strategy'] = data['position'] * data['returns'] | |
data.head() | |
data[['returns', 'strategy']].ix[:lags].cumsum().apply(np.exp).plot() | |
data[['returns', 'strategy']].ix[lags:].cumsum().apply(np.exp).plot() | |
from sklearn import linear_model | |
lm = linear_model.LogisticRegression(C=1e4) | |
m | |
m.T | |
lm.fit(m[:lags].T, m[lags]) | |
m | |
lm.fit(m[:lags].T, np.sign(m[lags])) | |
pred = lm.predict(m[:lags].T) | |
pred | |
len(pred) | |
plt.hist(pred) | |
data['pred'].ix[lags:] = pred | |
data['position'].ix[lags:] = pred | |
data['strategy'] = data['position'] * data['returns'] | |
data[['returns', 'strategy']].ix[lags:].cumsum().apply(np.exp).plot() | |
lm = linear_model.LogisticRegression(C=1e2) | |
lm.fit(m[:lags].T, np.sign(m[lags])) | |
pred = lm.predict(m[:lags].T) | |
data['position'].ix[lags:] = pred | |
data['strategy'] = data['position'] * data['returns'] | |
data[['returns', 'strategy']].ix[lags:].cumsum().apply(np.exp).plot() | |
lm = linear_model.LogisticRegression(C=1) | |
lm.fit(m[:lags].T, np.sign(m[lags])) | |
pred = lm.predict(m[:lags].T) | |
data['position'].ix[lags:] = pred | |
data['strategy'] = data['position'] * data['returns'] | |
data[['returns', 'strategy']].ix[lags:].cumsum().apply(np.exp).plot() | |
plt.hist(pred) | |
plt.hist(pred) | |
lags = 15 | |
m = np.zeros((lags + 1, len(data) - lags)) | |
for i in range(lags + 1): | |
if i == lags: | |
m[i] = data.returns.values[i:] | |
else: | |
m[i] = data.returns.values[i:i - lags] | |
lm = linear_model.LogisticRegression(C=100) | |
lm.fit(m[:lags].T, np.sign(m[lags])) | |
pred = lm.predict(m[:lags].T) | |
data['position'].ix[lags:] = pred | |
data['strategy'] = data['position'] * data['returns'] | |
data[['returns', 'strategy']].ix[lags:].cumsum().apply(np.exp).plot() | |
data_tr = data[data.index < '2015-1-1'].copy() | |
data_te = data[data.index > '2015-1-1'].copy() | |
m = np.zeros((lags + 1, len(data_tr) - lags)) | |
for i in range(lags + 1): | |
if i == lags: | |
m[i] = data_tr.returns.values[i:] | |
else: | |
m[i] = data_tr.returns.values[i:i - lags] | |
m.T | |
lm.fit(m[:lags].T, np.sign(m[lags])) | |
m = np.zeros((lags + 1, len(data_te) - lags)) | |
for i in range(lags + 1): | |
if i == lags: | |
m[i] = data_te.returns.values[i:] | |
else: | |
m[i] = data_te.returns.values[i:i - lags] | |
pred = lm.predict(m[:lags].T) | |
pred | |
len(data_tr) | |
len(data_te) | |
len(pred) | |
data_te['pred'].ix[lags:] = pred | |
data_te['position'].ix[lags:] = pred | |
data_te['strategy'] = data_te['position'] * data_te['returns'] | |
data_te[['returns', 'strategy']].ix[lags:].cumsum().apply(np.exp).plot() | |
data_te['position'] | |
data_te['position'].diff() | |
data_te['position'].diff() != 0.0 | |
sum(data_te['position'].diff() != 0.0) | |
tc = 0.001 | |
trades = data_te['position'].diff() != 0.0 | |
data_te['strategy'] -= trades * tc | |
data_te[['returns', 'strategy']].ix[lags:].cumsum().apply(np.exp).plot() | |
%history -f bc_algo_02.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Vectorized Backtesting of Momentum Strategy | |
# | |
# The Python Quants GmbH | |
# | |
import numpy as np | |
import pandas as pd | |
from pandas_datareader import data as web | |
import seaborn as sns; sns.set() | |
data = web.DataReader('AAPL', data_source='yahoo') | |
# saving the data to disk | |
h5 = pd.HDFStore('data.h5', 'w') | |
h5['AAPL'] = data | |
h5.close() | |
# reading it from disk | |
# h5 = pd.HDFStore('data.h5', 'r') | |
# df = h5['AAPL'] | |
# h5.close() | |
data = data['Adj Close'] | |
data = pd.DataFrame(data) | |
data['return'] = np.log(data / data.shift(1)) | |
data.rename(columns={'Adj Close': 'price'}, inplace=True) | |
data['position'] = data['return'].rolling(5).mean() | |
data['position'] = np.sign(data['position']) | |
data['strategy'] = data['position'].shift(1) * data['return'] | |
data[['return', 'strategy']].dropna().cumsum().apply(np.exp).plot() | |
def run_strategy(days=5): | |
data['position'] = data['return'].rolling(days).mean() | |
data['position'] = np.sign(data['position']) | |
data['strategy'] = data['position'].shift(1) * data['return'] | |
perf = data[['return', 'strategy']].dropna().cumsum().apply(np.exp).ix[-1] | |
return perf | |
for days in range(2, 42): | |
res = run_strategy(days) | |
op = res['strategy'] - res['return'] | |
print('%2d | %f' % (days, op)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment