SharedCrypto Hurst-Upload.ipynbOpen in CoCalc
Crypto advanced strategy

Notebook Instructions

You can run the notebook document sequentially (one cell at a time) by pressing shift + enter. While a cell is running, a [*] will display on the left. When it has been run, a number will display indicating the order in which it was run in the notebook [8].

Enter edit mode by pressing Enter or using the mouse to click on a cell's editor area. Edit mode is indicated by a green cell border and a prompt showing in the editor area.

This course is based on specific versions of python packages. You can find the details of the same in this manual. The manual also explains how to use these codes in other versions of python packages.

Hurst exponent strategy

In this notebook, we will create a strategy using the Hurst exponent and the RSI. The strategy works as follows:

  1. Fetch the minute data for Ethereum/USDT from a csv file
  2. Convert the unix epoch time to normal datetime format and set it as index
  3. Compute the hurst value for the entire price series
  4. Compute the rolling hurst values for with a lookback period of 240 minutes
  5. Compute the signals to indicate the persistent nature of the market
  6. Calculate the RSI values
  7. Calcualte the market returns
  8. Calcualte the strategy returns
  9. Compute the cumulative strategy return and plot it
  10. Compute the slippage
  11. Calculate the net profit after slippage

Import data and libraries

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
#import talib as ta
from hurst import compute_Hc
--------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) <ipython-input-8-53613acd3550> in <module>() 3 import pandas as pd 4 #import talib as ta ----> 5 from hurst import compute_Hc ModuleNotFoundError: No module named 'hurst'
# If you do not have the hurst library please install it by running this cell
!pip install hurst
!pip install ta-lib
Collecting ta-lib Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ConnectTimeoutError(<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f676cd82790>, 'Connection to pypi.org timed out. (connect timeout=15)')': /simple/ta-lib/ Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ConnectTimeoutError(<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f676cd82490>, 'Connection to pypi.org timed out. (connect timeout=15)')': /simple/ta-lib/ Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ConnectTimeoutError(<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f676cd82b10>, 'Connection to pypi.org timed out. (connect timeout=15)')': /simple/ta-lib/ Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ConnectTimeoutError(<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f676cd82fd0>, 'Connection to pypi.org timed out. (connect timeout=15)')': /simple/ta-lib/ Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ConnectTimeoutError(<pip._vendor.urllib3.connection.VerifiedHTTPSConnection object at 0x7f676cd82e90>, 'Connection to pypi.org timed out. (connect timeout=15)')': /simple/ta-lib/ Could not find a version that satisfies the requirement ta-lib (from versions: ) No matching distribution found for ta-lib
df1=pd.read_csv("Binance_1min_ETHUSDT-Upload.csv").iloc[-100000:]
# Set the timestamp to be the index for the data
df1=df1.set_index('Timestamp')

Convert the unix time stamp to datetime

df1.index=pd.to_datetime(df1.index, unit='ms')
df1.head()
Open High Low Close
Timestamp
2018-07-27 13:21:00 460.89 461.71 460.79 461.71
2018-07-27 13:22:00 461.49 461.67 461.16 461.44
2018-07-27 13:23:00 461.38 461.86 461.33 461.52
2018-07-27 13:24:00 461.60 461.78 461.33 461.59
2018-07-27 13:25:00 461.59 462.17 460.05 460.51

Compute the hurst value for the data

series=df1.Close
H = compute_Hc(series, kind='price')[0]
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-6-25de63032651> in <module>() 1 series=df1.Close ----> 2 H = compute_Hc(series, kind='price')[0] NameError: name 'compute_Hc' is not defined
print("Hurst Exponent H={:.4f}".format(H))
Hurst Exponent H=0.6204
# Let us visualize the data to confirm if it really was trending for the given time frame
plt.figure(figsize=(10,7))
plt.plot(df1.Close)
[<matplotlib.lines.Line2D at 0x7fcda59abb70>]

Compute the rolling hurst values

df1['H']=0

We are using the past 4 hour data to calculate the hurst exponent.

for i in range(240,len(df1)):
    df1.H.iloc[i]=compute_Hc(df1.Close.iloc[i-240:i-1], kind='price')[0]
C:\Users\udish\Anaconda3\envs\py35\lib\site-packages\pandas\core\indexing.py:189: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy self._setitem_with_indexer(indexer, value)
# Let us plot the hurst values to visualize it
# We will be using threshold values of 0.65 and 0.35 to avoid trading for the noise
plt.figure(figsize=(10,7))
df1.H.plot()
plt.axhline(0.35,color='g')
plt.axhline(0.65,color='r')
<matplotlib.lines.Line2D at 0x14ab2f2e2e8>

Generate the persitence signals

df1['Signal']= 0
df1['Signal']=np.where( df1.H>0.65,1,df1.Signal)
df1['Signal']=np.where( df1.H<0.35,-1,df1.Signal)

Compute the RSI

df1['RSI'] = ta.RSI(df1.Close.shift(1).values,14)

Compute the market return

# Since we use the Close price to calculate the RSI and Hurst values, we assume that the execution will happen 
# at the Open of the next candle. Hence returns are calculated on an open to open basis
df1['Return']=df1.Open.shift(-1).pct_change()

Compute the strategy returns

We use RSI here to gauge the overbought/oversold condition of the market.

We buy when

  1. RSI is more than 75 and Persistence signal is 1
  2. RSI is less than 25 and Persistence signal is -1

We sell when

  1. RSI is more than 75 and Persistence signal is -1
  2. RSI is less than 25 and Persistence signal is 1
df1['StrReturn']=0
df1['StrReturn']= np.where(((df1.RSI>75) & (df1.Signal==-1)),-df1.Return,df1.StrReturn)
df1['StrReturn']= np.where(((df1.RSI<25) & (df1.Signal==-1)),df1.Return,df1.StrReturn)
df1['StrReturn']= np.where(((df1.RSI>75) & (df1.Signal==1)),df1.Return,df1.StrReturn)
df1['StrReturn']= np.where(((df1.RSI<25) & (df1.Signal==1)),-df1.Return,df1.StrReturn)

Compute the total slipapge cost

# When we execute a strategy based on market orders our strategy can experience a significant slippage,
# if the bid-ask prices are far away. So, we have taken an average bid-ask spread of 0.05 based on the orderbook 
# data from cryptoexchanges.

total_slippage_cost=len(df1[df1.StrReturn!=0])*0.05/df1.Close.mean()
total_slippage_cost
0.12154918747761748
Cumulative_Returns=df1.StrReturn.expanding().sum()

Plot the cumulative returns of the strategy

plt.figure(figsize=(10,7))
Cumulative_Returns.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x14ab3cd1a20>

Compute the net profit after slippage

Final_percentage_retuns=(Cumulative_Returns.iloc[-1]-total_slippage_cost)*100
Final_percentage_retuns
7.69077023698744