Title
Bitcoin Technical Analysis
Introdution
This notebook includes conducting a technical analysis on Bitcoin Data. Cryptocurrency markets are highly volatile and although, 70-80% of it is based upon sentiments and social media, an extensive technical analysis might provide some insights into how the trend works. For now, 2 datasets have been used, one of which contains 1-minute data of Bitcoin and the other one contains daily Bitcoin data.
The technical analysis metrics consists of
Moving Averages
- This metric can be used to get a decent idea of the asset's established trend. This metric can't be used to predict future trends.Average True Range
- It is the average of the true ranges over the specified period. It measures the volatility in the market. A typical ATR calculation is of 14 days.Relative Strength Index
- The tool measures the strength of the dynamics and the trend of the digital asset. In other terms, it can be used to predict the momentum and the divergence of the asset.Bollinger Bands
- It is useful to in measuring volatility and trends. The upper band is 2 standard deviation above mean and the lower band is 2 standard deviation below mean.
Table of Contents:
import warnings
import numpy as np
import pandas as pd
import seaborn as sns
import plotly.express as px
from termcolor import colored
import matplotlib.pyplot as plt
import plotly.graph_objects as go
warnings.filterwarnings("ignore")
from plotly.subplots import make_subplots
print('Packages successfully imported...')
df = pd.read_parquet('/kaggle/input/binance-full-history/BTC-USDT.parquet')
# The 1-day data for Bitcoin
daily = pd.read_csv('../input/cryptocurrency-data/BTC-USD-2.csv', parse_dates = [0])
print('Data successfully imported...')
df.head()
df.index.rename('date',inplace=True)
df.drop(['quote_asset_volume','taker_buy_base_asset_volume','taker_buy_quote_asset_volume'],inplace = True,axis=1)
df.isnull().sum()
daily.head()
daily.set_index('Date',inplace=True)
daily.isnull().sum()
daily.fillna(method='ffill',inplace=True, axis=0)
daily.isnull().sum()
daily.head()
df.head()
fig = go.Figure(data=[go.Candlestick(x=daily.index,
open=daily['Open'],
high=daily['High'],
low=daily['Low'],
close=daily['Close'])],
layout = go.Layout({
'title':{
'text':'Bitcoin Daily data',
'font':{
'size':25
}
}
})
)
fig.update_layout({"template":"plotly_dark"})
fig.show()
Moving average cuts down the noise in the price chart. The direction of the MA
might give an idea of the trend of the chart. A subtle observation can be made from the plot that is whenever the candlestick cuts the MA
threshold level to rise above it, the price is likely to go high for some duration of time before which there's a change in direction of price to due to other factors. In the same way, when the candlestick cuts the MA
threshold level to rise below it, the price is likely to fall for some duration. At the rising cut-point, a trader can enter the market and at the falling cut-point, a trader might sell. This is also called as a crossover.
avg_20 = daily.Close.rolling(window=20, min_periods=1).mean()
avg_50 = daily.Close.rolling(window=50, min_periods=1).mean()
avg_100 = daily.Close.rolling(window=100, min_periods=1).mean()
set_1 = {
'x':daily.index,
'open': daily.Open,
'close':daily.Close,
'high':daily.High,
'low':daily.Low,
'type':'candlestick'
}
set_2 = {
'x':daily.index,
'y':avg_20,
'type':'scatter',
'mode':'lines',
'line':{
'width':2,
'color':'white'
},
'name':'Moving average of 20 days'
}
set_3 = {
'x':daily.index,
'y':avg_50,
'type':'scatter',
'mode':'lines',
'line':{
'width':2,
'color':'yellow'
},
'name':'Moving average of 50 days'
}
set_4 = {
'x':daily.index,
'y':avg_100,
'type':'scatter',
'mode':'lines',
'line':{
'width':2,
'color':'orange'
},
'name':'Moving average of 100 days'
}
data = [set_1, set_2, set_3, set_4]
layout = go.Layout({
'title':{
'text':'Moving averages',
'font':{
'size':25
}
}
})
fig = go.Figure(data=data, layout=layout)
fig.update_layout({"template":"plotly_dark"})
fig.show()
The true range indicator is taken as the greatest of the following: current high less the current low; the absolute value of the current high less the previous close; and the absolute value of the current low less the previous close. The ATR is then a moving average, generally using 14 days, of the true ranges. Simply put, a stock experiencing a high level of volatility has a higher ATR, and a low volatility stock has a lower ATR.
high_low = daily['High'] - daily['Low']
high_close = np.abs(daily['High'] - daily['Close'].shift())
low_close = np.abs(daily['Low'] - daily['Close'].shift())
ranges = pd.concat([high_low, high_close, low_close], axis=1)
true_range = np.max(ranges, axis=1)
atr = true_range.rolling(14).sum()/14
atr_daily = daily
atr_daily['atr'] = atr
atr_daily['High_atr'] = atr_daily['High'] + atr_daily['atr']
atr_daily['Low_atr'] = atr_daily['Low'] - atr_daily['atr']
fig = make_subplots(rows=2, cols=1, row_heights=[0.5, 0.5], vertical_spacing=.3, subplot_titles=["Bitcoin Daily Data", "Average True Range"])
fig.append_trace(go.Candlestick(x=daily.index,
open=atr_daily['Open'],
high=atr_daily['High'],
low=atr_daily['Low'],
close=atr_daily['Close']),
row=1,col=1)
fig.append_trace(go.Scatter(x=atr_daily.index,
y=atr_daily.atr,
line_color='Orange'
),row=2,col=1)
fig.update_layout(
margin=dict(l=20, r=20, t=20, b=20),
)
fig.update_layout({"template":"plotly_dark"})
fig.show()
Though ATR doesn't give much of an idea about the trend of the chart, but it can be used by traders to put stop losses. An ATR value above close
or high
can be used as a potential exit point. An ATR value below open
or low
can be used as a potential exit point as well in case of down fall of the price.
set_1 = go.Candlestick(x=daily.index,
open=atr_daily['Open'],
high=atr_daily['High'],
low=atr_daily['Low'],
close=atr_daily['Close'])
set_2 = go.Scatter(x=atr_daily.index,
y=atr_daily.High_atr,
line_color='Orange')
set_3 = go.Scatter(x=atr_daily.index,
y=atr_daily.Low_atr,
line_color='Yellow')
data = [set_1, set_2, set_3]
layout = go.Layout({
'title':{
'text':'Upper/Lower limit of ATR values for trading',
'font':{
'size':25
}
}
})
fig = go.Figure(data=data, layout=layout)
fig.update_layout({"template":"plotly_dark"})
fig.show()