Spaces:
Sleeping
Sleeping
Upload multi_crypto.py
Browse files- multi_crypto.py +91 -80
multi_crypto.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
import marimo
|
2 |
|
3 |
__generated_with = "0.9.15"
|
4 |
-
app = marimo.App(width="
|
5 |
|
6 |
|
7 |
@app.cell(hide_code=True)
|
@@ -21,6 +21,7 @@ def __():
|
|
21 |
import mplfinance as mpf
|
22 |
import altair as alt
|
23 |
from datetime import date, timedelta, datetime
|
|
|
24 |
|
25 |
from sklearn.preprocessing import MinMaxScaler
|
26 |
return (
|
@@ -33,6 +34,7 @@ def __():
|
|
33 |
np,
|
34 |
pd,
|
35 |
plt,
|
|
|
36 |
sns,
|
37 |
timedelta,
|
38 |
yf,
|
@@ -40,15 +42,61 @@ def __():
|
|
40 |
|
41 |
|
42 |
@app.cell(hide_code=True)
|
43 |
-
def __(datetime,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
tickers = [f'{ticker}-USD' for ticker in [
|
45 |
'BTC', 'ETH', 'AR', 'SOL', 'ADA', 'XMR',
|
46 |
'DOGE', 'SHIB', 'PEPE24478', 'BNB', 'AVAX',
|
47 |
]]
|
48 |
-
|
49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
closes = data['Close']
|
51 |
-
return closes, data,
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
|
54 |
@app.cell(hide_code=True)
|
@@ -78,102 +126,65 @@ def __(mo):
|
|
78 |
|
79 |
|
80 |
@app.cell(hide_code=True)
|
81 |
-
def __(highest_percentage_change,
|
82 |
def show_highest_percentage(ticker):
|
83 |
percentage = highest_percentage_change[ticker]
|
84 |
-
|
85 |
-
|
86 |
-
|
|
|
87 |
|
88 |
# Calculate and sort percentage changes
|
89 |
highest_percentage_sorted = sorted(highest_percentage_change.items(), key=lambda x: x[1], reverse=True)
|
90 |
highest, second_highest = highest_percentage_sorted[0], highest_percentage_sorted[1]
|
91 |
lowest, second_lowest = highest_percentage_sorted[-1], highest_percentage_sorted[-2]
|
92 |
|
93 |
-
#
|
94 |
-
|
95 |
-
|
96 |
-
### Overview of Highest and Lowest Daily Percentage Changes
|
97 |
-
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}%.
|
98 |
-
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}%.
|
99 |
-
""")
|
100 |
-
|
101 |
-
callouts_top = mo.hstack([show_highest_percentage(ticker) for ticker in tickers[:callouts_length]])
|
102 |
|
103 |
-
|
|
|
|
|
104 |
|
105 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
return (
|
107 |
-
callouts_bottom,
|
108 |
-
callouts_length,
|
109 |
-
callouts_top,
|
110 |
highest,
|
|
|
111 |
highest_percentage_sorted,
|
112 |
lowest,
|
|
|
113 |
second_highest,
|
114 |
second_lowest,
|
115 |
show_highest_percentage,
|
116 |
-
|
|
|
117 |
)
|
118 |
|
119 |
|
120 |
@app.cell(hide_code=True)
|
121 |
-
def __(
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
@app.cell(hide_code=True)
|
139 |
-
def __(mo):
|
140 |
-
mo.md(r"""## Log Returns Correlation""")
|
141 |
-
return
|
142 |
-
|
143 |
-
|
144 |
-
@app.cell(hide_code=True)
|
145 |
-
def __(closes, mo, np):
|
146 |
-
# Calculate log returns and correlation matrix
|
147 |
-
log_returns = np.log(closes / closes.shift(1))
|
148 |
-
correlation_matrix = log_returns.corr()
|
149 |
-
|
150 |
-
# Identify the highest and lowest correlations
|
151 |
-
highest_corr = correlation_matrix.unstack().sort_values(ascending=False).drop_duplicates().iloc[1]
|
152 |
-
lowest_corr = correlation_matrix.unstack().sort_values().drop_duplicates().iloc[0]
|
153 |
-
|
154 |
-
mo.md(f"""
|
155 |
-
### 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
|
156 |
-
### 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.
|
157 |
-
|
158 |
-
### Additional Insights
|
159 |
-
|
160 |
-
- **High Positive Correlations**: Assets with high correlations tend to respond similarly to market events, which can be useful for **trend-following strategies**.
|
161 |
-
- **Low or Negative Correlations**: Assets with low or negative correlations might help reduce overall portfolio risk, making them useful for **diversification**.
|
162 |
-
- **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.
|
163 |
-
""")
|
164 |
-
return correlation_matrix, highest_corr, log_returns, lowest_corr
|
165 |
-
|
166 |
-
|
167 |
-
@app.cell
|
168 |
-
def __(log_returns, plt, sns):
|
169 |
-
plt.figure(figsize=(6, 5))
|
170 |
-
sns.heatmap(log_returns.corr(), cmap="YlGnBu", annot=True)
|
171 |
-
plt.gca()
|
172 |
-
return
|
173 |
-
|
174 |
-
|
175 |
-
@app.cell
|
176 |
-
def __():
|
177 |
return
|
178 |
|
179 |
|
|
|
1 |
import marimo
|
2 |
|
3 |
__generated_with = "0.9.15"
|
4 |
+
app = marimo.App(width="full")
|
5 |
|
6 |
|
7 |
@app.cell(hide_code=True)
|
|
|
21 |
import mplfinance as mpf
|
22 |
import altair as alt
|
23 |
from datetime import date, timedelta, datetime
|
24 |
+
import pytz
|
25 |
|
26 |
from sklearn.preprocessing import MinMaxScaler
|
27 |
return (
|
|
|
34 |
np,
|
35 |
pd,
|
36 |
plt,
|
37 |
+
pytz,
|
38 |
sns,
|
39 |
timedelta,
|
40 |
yf,
|
|
|
42 |
|
43 |
|
44 |
@app.cell(hide_code=True)
|
45 |
+
def __(datetime, mo):
|
46 |
+
start_date_input = mo.ui.date(value=datetime.now().date())
|
47 |
+
|
48 |
+
mo.md('## Input')
|
49 |
+
return (start_date_input,)
|
50 |
+
|
51 |
+
|
52 |
+
@app.cell(hide_code=True)
|
53 |
+
def __(mo, start_date_input):
|
54 |
+
|
55 |
+
mo.md(f"""
|
56 |
+
Please enter yout start date range: {start_date_input}
|
57 |
+
""")
|
58 |
+
return
|
59 |
+
|
60 |
+
|
61 |
+
@app.cell(hide_code=True)
|
62 |
+
def __(datetime, pd, pytz, start_date_input, yf):
|
63 |
tickers = [f'{ticker}-USD' for ticker in [
|
64 |
'BTC', 'ETH', 'AR', 'SOL', 'ADA', 'XMR',
|
65 |
'DOGE', 'SHIB', 'PEPE24478', 'BNB', 'AVAX',
|
66 |
]]
|
67 |
+
|
68 |
+
# Mendapatkan waktu saat ini (jam, menit, detik)
|
69 |
+
current_time = datetime.now().time()
|
70 |
+
|
71 |
+
print(f'current time: {current_time}')
|
72 |
+
|
73 |
+
# Menggabungkan tanggal dari input dengan waktu sekarang
|
74 |
+
now = datetime.combine(start_date_input.value, current_time)
|
75 |
+
|
76 |
+
# Menambahkan zona waktu UTC
|
77 |
+
now = now.replace(tzinfo=pytz.UTC)
|
78 |
+
|
79 |
+
# Mendapatkan tanggal untuk start_date (menggunakan tanggal input)
|
80 |
+
start_date = start_date_input.value.strftime('%Y-%m-%d')
|
81 |
+
|
82 |
+
# Mendapatkan data dari Yahoo Finance
|
83 |
+
data = yf.download(tickers, start=start_date, interval='5m')
|
84 |
+
|
85 |
+
# Mengonversi index ke datetime dan mengubah zona waktunya ke UTC
|
86 |
+
data.index = pd.to_datetime(data.index).tz_convert('UTC')
|
87 |
+
|
88 |
+
# Memfilter data untuk hanya yang sebelum waktu sekarang
|
89 |
+
data = data[data.index > now]
|
90 |
+
|
91 |
+
# Mengambil harga penutupan
|
92 |
closes = data['Close']
|
93 |
+
return closes, current_time, data, now, start_date, tickers
|
94 |
+
|
95 |
+
|
96 |
+
@app.cell
|
97 |
+
def __(closes):
|
98 |
+
closes
|
99 |
+
return
|
100 |
|
101 |
|
102 |
@app.cell(hide_code=True)
|
|
|
126 |
|
127 |
|
128 |
@app.cell(hide_code=True)
|
129 |
+
def __(highest_percentage_change, pd):
|
130 |
def show_highest_percentage(ticker):
|
131 |
percentage = highest_percentage_change[ticker]
|
132 |
+
return percentage
|
133 |
+
|
134 |
+
def percentage_to_text(percentage):
|
135 |
+
return '%.2f%%' % percentage if percentage is not None else 'N/A'
|
136 |
|
137 |
# Calculate and sort percentage changes
|
138 |
highest_percentage_sorted = sorted(highest_percentage_change.items(), key=lambda x: x[1], reverse=True)
|
139 |
highest, second_highest = highest_percentage_sorted[0], highest_percentage_sorted[1]
|
140 |
lowest, second_lowest = highest_percentage_sorted[-1], highest_percentage_sorted[-2]
|
141 |
|
142 |
+
# Calculate and sort percentage changes
|
143 |
+
# Urutkan berdasarkan persentase, hasilkan tuple (ticker, persentase)
|
144 |
+
highest_percentage_sorted = sorted(highest_percentage_change.items(), key=lambda x: x[1], reverse=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
|
146 |
+
# Pisahkan ticker dan persentase yang sudah diurutkan
|
147 |
+
sorted_tickers = [ticker for ticker, _ in highest_percentage_sorted]
|
148 |
+
sorted_percentages = [percentage_to_text(percentage) for _, percentage in highest_percentage_sorted]
|
149 |
|
150 |
+
# Membuat DataFrame dengan kolom yang sudah sesuai
|
151 |
+
highest_percentage = pd.DataFrame(
|
152 |
+
{
|
153 |
+
'Ticker': sorted_tickers,
|
154 |
+
'Percentage': sorted_percentages
|
155 |
+
}
|
156 |
+
)
|
157 |
return (
|
|
|
|
|
|
|
158 |
highest,
|
159 |
+
highest_percentage,
|
160 |
highest_percentage_sorted,
|
161 |
lowest,
|
162 |
+
percentage_to_text,
|
163 |
second_highest,
|
164 |
second_lowest,
|
165 |
show_highest_percentage,
|
166 |
+
sorted_percentages,
|
167 |
+
sorted_tickers,
|
168 |
)
|
169 |
|
170 |
|
171 |
@app.cell(hide_code=True)
|
172 |
+
def __(
|
173 |
+
highest,
|
174 |
+
highest_percentage,
|
175 |
+
lowest,
|
176 |
+
mo,
|
177 |
+
second_highest,
|
178 |
+
second_lowest,
|
179 |
+
):
|
180 |
+
mo.vstack([
|
181 |
+
mo.md(f"""
|
182 |
+
### Overview of Highest and Lowest Daily Percentage Changes
|
183 |
+
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}%.
|
184 |
+
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}%.
|
185 |
+
"""),
|
186 |
+
highest_percentage
|
187 |
+
])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
return
|
189 |
|
190 |
|