Skip to content
Bitcoin Price Analysis
import pandas as pd
import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.stattools import adfuller
from statsmodels.stats.diagnostic import acorr_ljungbox
from scipy.stats import shapiro
Data Collection
Daily data: CSV
# Load the CSV file from the 'csv data' folder
btc_daily = pd.read_csv('CSV Data/btc_data_daily.csv')
# Display the first few rows of the dataframe to verify loading
btc_daily.head()
Hourly data: CSV
# Read the data from CSV into a DataFrame
minute_data = pd.read_csv('CSV Data/btcusd_1-min_data.csv')
# Convert the 'Timestamp' column to datetime format
minute_data['Timestamp'] = pd.to_datetime(minute_data['Timestamp'], unit='s')
# Filter minute_data for timestamps at the full hour
hour_data = minute_data[minute_data['Timestamp'].dt.minute == 0]
# Display the first few rows of the DataFrame to verify the data
hour_data.head()
hour_data['Timestamp'] = pd.to_datetime(hour_data['Timestamp'])
hour_data[hour_data['Timestamp'] > pd.to_datetime('2024-11-04')]
Data cleaning
btc_daily.dtypes
# Rename columns to avoid confusion
btc_daily = btc_daily.rename(columns={'Price': 'Close', 'Start': 'Date'})
# Convert the relevant columns to float, if necessary
#btc_daily['Close'] = btc_daily['Close'].str.replace(',', '').astype(float)
#btc_daily['Open'] = btc_daily['Open'].str.replace(',', '').astype(float)
#btc_daily['High'] = btc_daily['High'].str.replace(',', '').astype(float)
#btc_daily['Low'] = btc_daily['Low'].str.replace(',', '').astype(float)
#btc_daily['Vol.'] = btc_daily['Vol.'].str.replace('K', 'e3').str.replace('M', 'e6').str.replace('B', 'e9').str.replace(',', '').astype(float)
#btc_daily['Change %'] = btc_daily['Change %'].str.replace('%', '').astype(float)
# Convert the 'Date' column to a datetime object for easier manipulation and analysis.
btc_daily['Date'] = pd.to_datetime(btc_daily['Date'])
# Calculate the range of each day's price as the difference between 'High' and 'Low' columns,
# and store it in a new column named 'Range'.
btc_daily['Range'] = btc_daily['High'] - btc_daily['Low']
# Sort the DataFrame by the 'Date' column in ascending order and reset the index.
# The drop=True parameter prevents the old index from being added as a new column.
btc_daily = btc_daily.sort_values('Date').reset_index(drop=True)
# Drop the 'End' column from the DataFrame as it's no longer needed for the analysis.
btc_daily = btc_daily.drop('End', axis=1)
# Display the resulting DataFrame.
btc_daily
btc_daily.isna().any()
Exploring Changes in Bitcoin Prices
# Calculate the 28-day moving average of Range
btc_daily['Range_MA'] = btc_daily['Range'].rolling(window=7).mean()
# Create the plot with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])
# Add the 7-day moving average of Range (green line with alpha 0.5)
fig.add_trace(
go.Scatter(
x=btc_daily['Date'],
y=btc_daily['Range_MA'],
mode='lines',
name='7-Day MA of Range',
line=dict(color='#03EF62', width=2), # Set the line color to green
opacity=0.3
),
secondary_y=True
)
# Add the BTC daily close prices (white line)
fig.add_trace(
go.Scatter(
x=btc_daily['Date'],
y=btc_daily['Close'],
mode='lines',
name='BTC Close Price',
line=dict(color='#FF931E') # Set the line color to white
),
secondary_y=False
)
# Update layout with adjusted font sizes
fig.update_layout(
title='Bitcoin Daily Close Prices with 7-Day Moving Average of Range',
title_font=dict(size=24),
xaxis=dict(
title='Date',
title_font=dict(size=16),
tickfont=dict(size=14),
gridcolor="rgba(33, 49, 71, 0.5)"
),
yaxis=dict(
title='Close Price (USD)',
title_font=dict(size=16),
tickfont=dict(size=14),
gridcolor="rgba(33, 49, 71, 0.5)"
),
yaxis2=dict(
title='7-Day MA of Range',
title_font=dict(size=16),
tickfont=dict(size=14),
gridcolor="rgba(33, 49, 71, 0.5)"
),
legend=dict(
font=dict(size=16, color='white')
),
showlegend=True,
plot_bgcolor='#05192D',
paper_bgcolor='#05192D',
font=dict(color='white'),
width=1200,
height=675
)
fig.show()