Spaces:
Running
Running
import marimo | |
__generated_with = "0.9.15" | |
app = marimo.App(width="medium") | |
def __(mo): | |
mo.md(r"""# Cryptocurrency Minuet Dashboard""") | |
return | |
def __(): | |
import marimo as mo | |
import pandas as pd | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import seaborn as sns | |
import yfinance as yf | |
import mplfinance as mpf | |
import altair as alt | |
from datetime import date, timedelta, datetime | |
from sklearn.preprocessing import MinMaxScaler | |
return ( | |
MinMaxScaler, | |
alt, | |
date, | |
datetime, | |
mo, | |
mpf, | |
np, | |
pd, | |
plt, | |
sns, | |
timedelta, | |
yf, | |
) | |
def __(datetime, timedelta, yf): | |
tickers = [f'{ticker}-USD' for ticker in [ | |
'BTC', 'ETH', 'AR', 'SOL', 'ADA', 'XMR', | |
'DOGE', 'SHIB', 'PEPE24478', 'BNB', 'AVAX', | |
]] | |
yesterday = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d') | |
data = yf.download(tickers, start=yesterday, interval='5m') | |
closes = data['Close'] | |
return closes, data, tickers, yesterday | |
def __(closes): | |
highest_percentage_change = {} | |
for ticker in closes.columns: | |
# Group by day and calculate min and max within the day | |
daily_high = closes[ticker].resample('D').max() | |
daily_low = closes[ticker].resample('D').min() | |
# Calculate percentage change | |
daily_percentage_change = ((daily_high - daily_low) / daily_low) * 100 | |
# Get the highest percentage change within the day | |
highest_percentage_change[ticker] = daily_percentage_change.max() | |
return ( | |
daily_high, | |
daily_low, | |
daily_percentage_change, | |
highest_percentage_change, | |
ticker, | |
) | |
def __(mo): | |
mo.md("""## Highest Returns in the since Yesterday""") | |
return | |
def __(highest_percentage_change, mo, tickers): | |
def show_highest_percentage(ticker): | |
percentage = highest_percentage_change[ticker] | |
up = 'success' if percentage > 0 else 'danger' | |
percentage_text = '%.2f%%' % percentage if percentage is not None else 'N/A' | |
return mo.callout(value=f'{ticker} {percentage_text}', kind=up) | |
# Calculate and sort percentage changes | |
highest_percentage_sorted = sorted(highest_percentage_change.items(), key=lambda x: x[1], reverse=True) | |
highest, second_highest = highest_percentage_sorted[0], highest_percentage_sorted[1] | |
lowest, second_lowest = highest_percentage_sorted[-1], highest_percentage_sorted[-2] | |
# Generate markdown explanations | |
callouts_length = int(len(tickers) / 2) | |
top_callout = mo.md(f""" | |
### Overview of Highest and Lowest Daily Percentage Changes | |
The **highest daily percentage change** was recorded by `{highest[0]}` at {highest[1]:.2f}%. The **second highest** was `{second_highest[0]}` with a change of {second_highest[1]:.2f}%. | |
The **lowest daily percentage change** occurred for `{lowest[0]}` at {lowest[1]:.2f}%. The **second lowest** was `{second_lowest[0]}` with a change of {second_lowest[1]:.2f}%. | |
""") | |
callouts_top = mo.hstack([show_highest_percentage(ticker) for ticker in tickers[:callouts_length]]) | |
callouts_bottom = mo.hstack([show_highest_percentage(ticker) for ticker in tickers[callouts_length:]]) | |
# mo.vstack([top_callout, callouts_top, callouts_bottom], align='start', heights='equal') | |
return ( | |
callouts_bottom, | |
callouts_length, | |
callouts_top, | |
highest, | |
highest_percentage_sorted, | |
lowest, | |
second_highest, | |
second_lowest, | |
show_highest_percentage, | |
top_callout, | |
) | |
def __(top_callout): | |
top_callout | |
return | |
def __(callouts_top): | |
callouts_top | |
return | |
def __(callouts_bottom): | |
callouts_bottom | |
return | |
def __(mo): | |
mo.md(r"""## Log Returns Correlation""") | |
return | |
def __(closes, mo, np): | |
# Calculate log returns and correlation matrix | |
log_returns = np.log(closes / closes.shift(1)) | |
correlation_matrix = log_returns.corr() | |
# Identify the highest and lowest correlations | |
highest_corr = correlation_matrix.unstack().sort_values(ascending=False).drop_duplicates().iloc[1] | |
lowest_corr = correlation_matrix.unstack().sort_values().drop_duplicates().iloc[0] | |
mo.md(f""" | |
### Highest Correlation\n\nThe highest correlation is between `{highest_corr}` and `{highest_corr}` with a value of **{highest_corr:.2f}**, indicating a strong positive relationship. This suggests that these two assets move similarly over the selected period.\n | |
### Lowest Correlation\n\nThe lowest correlation is between `{lowest_corr}` and `{lowest_corr}` with a value of **{lowest_corr:.2f}**, indicating a weak or almost no relationship. These assets may provide diversification benefits in a portfolio. | |
### Additional Insights | |
- **High Positive Correlations**: Assets with high correlations tend to respond similarly to market events, which can be useful for **trend-following strategies**. | |
- **Low or Negative Correlations**: Assets with low or negative correlations might help reduce overall portfolio risk, making them useful for **diversification**. | |
- **Portfolio Strategy**: If you're seeking to **balance risk**, consider assets with lower correlations, while highly correlated assets can be beneficial for **momentum-based** portfolios. | |
""") | |
return correlation_matrix, highest_corr, log_returns, lowest_corr | |
def __(log_returns, plt, sns): | |
plt.figure(figsize=(6, 5)) | |
sns.heatmap(log_returns.corr(), cmap="YlGnBu", annot=True) | |
plt.gca() | |
return | |
def __(): | |
return | |
def __(): | |
return | |
if __name__ == "__main__": | |
app.run() | |