File size: 6,179 Bytes
ccd9626
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import marimo

__generated_with = "0.9.15"
app = marimo.App(width="medium")


@app.cell(hide_code=True)
def __(mo):
    mo.md(r"""# Cryptocurrency Minuet Dashboard""")
    return


@app.cell(hide_code=True)
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,
    )


@app.cell(hide_code=True)
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


@app.cell(hide_code=True)
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,
    )


@app.cell(hide_code=True)
def __(mo):
    mo.md("""## Highest Returns in the since Yesterday""")
    return


@app.cell(hide_code=True)
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,
    )


@app.cell(hide_code=True)
def __(top_callout):
    top_callout
    return


@app.cell(hide_code=True)
def __(callouts_top):
    callouts_top
    return


@app.cell(hide_code=True)
def __(callouts_bottom):
    callouts_bottom
    return


@app.cell(hide_code=True)
def __(mo):
    mo.md(r"""## Log Returns Correlation""")
    return


@app.cell(hide_code=True)
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


@app.cell
def __(log_returns, plt, sns):
    plt.figure(figsize=(6, 5))
    sns.heatmap(log_returns.corr(), cmap="YlGnBu", annot=True)
    plt.gca()
    return


@app.cell
def __():
    return


@app.cell
def __():
    return


if __name__ == "__main__":
    app.run()