InNoobWeTrust commited on
Commit
37a1056
·
1 Parent(s): b7f33b4

feat: Add date selection

Browse files
Files changed (1) hide show
  1. streamlit_app.py +75 -111
streamlit_app.py CHANGED
@@ -17,7 +17,7 @@ alt.renderers.set_embed_options(theme="dark")
17
  def fetch_asset(asset):
18
  return fetch(asset)
19
 
20
- def gen_charts(asset, chart_size={"width": 560, "height": 300}):
21
  # Gen data
22
  data = fetch_asset(asset)
23
  etf_volumes = data.etf_volumes
@@ -27,44 +27,57 @@ def gen_charts(asset, chart_size={"width": 560, "height": 300}):
27
  cum_flow_individual = data.cum_flow_individual
28
  cum_flow_total = data.cum_flow_total
29
 
30
- trading_vol_fig = (
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  alt.Chart(etf_volumes)
32
  .transform_fold(
33
  etf_volumes.drop(columns="Date").columns.to_list(), as_=["Funds", "Volume"]
34
  )
35
  .mark_line()
36
  .encode(
37
- x=alt.X("Date:T", axis=alt.Axis(tickCount="day")),
38
- y=alt.Y("Volume:Q"),
39
  color="Funds:N",
40
  )
41
  ).properties(
42
  width=chart_size["width"],
43
- height=chart_size["height"] / 2,
44
  )
45
- trading_vol_total_fig = (
46
  alt.Chart(etf_volumes)
47
  .transform_fold(
48
  etf_volumes.drop(columns="Date").columns.to_list(), as_=["Funds", "Volume"]
49
  )
50
  .mark_rule()
51
  .encode(
52
- x=alt.X("Date:T", axis=alt.Axis(tickCount="day", title="", labels=False)),
53
- y=alt.Y("sum(Volume):Q", title="Total Volume"),
54
  color=alt.value("teal"),
55
  )
56
  ).properties(
57
  width=chart_size["width"],
58
- height=chart_size["height"] / 2,
59
- )
60
- # Combine trading volume and average trading volume
61
- trading_vol_fig = trading_vol_total_fig & trading_vol_fig
62
- trading_vol_fig = trading_vol_fig.properties(
63
- title=f"{asset} ETF trading volume",
64
  )
65
 
66
  # Net flow individual
67
- net_flow_individual_fig = (
68
  alt.Chart(etf_flow_individual)
69
  .transform_fold(
70
  etf_flow_individual.drop(columns="Date").columns.to_list(),
@@ -72,20 +85,20 @@ def gen_charts(asset, chart_size={"width": 560, "height": 300}):
72
  )
73
  .mark_line()
74
  .encode(
75
- x=alt.X("Date:T", axis=alt.Axis(tickCount="day")),
76
- y=alt.Y("Net Flow:Q"),
77
  color="Funds:N",
78
  )
79
  ).properties(
80
  width=chart_size["width"],
81
- height=chart_size["height"] / 2,
82
  )
83
- net_flow_total_fig = (
84
  alt.Chart(etf_flow_total)
85
  .mark_rule()
86
  .encode(
87
- x=alt.X("Date:T", axis=alt.Axis(tickCount="day", title="", labels=False)),
88
- y=alt.Y("Total:Q"),
89
  color=alt.condition(
90
  alt.datum.Total > 0,
91
  alt.value("seagreen"), # The positive color
@@ -94,52 +107,11 @@ def gen_charts(asset, chart_size={"width": 560, "height": 300}):
94
  )
95
  ).properties(
96
  width=chart_size["width"],
97
- height=chart_size["height"] / 2,
98
- )
99
- net_flow_individual_fig = net_flow_total_fig & net_flow_individual_fig
100
- net_flow_individual_fig = net_flow_individual_fig.resolve_scale(
101
- x="shared"
102
- ).properties(
103
- title=f"{asset} ETF net flow of individual funds",
104
- )
105
-
106
- net_flow_total_fig = (
107
- alt.Chart(etf_flow_total)
108
- .mark_rule()
109
- .encode(
110
- x=alt.X("Date:T", axis=alt.Axis(tickCount="day", title="", labels=False)),
111
- y=alt.Y("Total:Q"),
112
- color=alt.condition(
113
- alt.datum.Total > 0,
114
- alt.value("seagreen"), # The positive color
115
- alt.value("orangered"), # The negative color
116
- ),
117
- )
118
- ).properties(
119
- width=chart_size["width"],
120
- height=chart_size["height"] / 2,
121
- )
122
- # Line chart of price
123
- price_fig = (
124
- alt.Chart(price)
125
- .mark_line()
126
- .encode(
127
- x=alt.X("Date:T", axis=alt.Axis(tickCount="day")),
128
- y=alt.Y("Price:Q").scale(zero=False),
129
- color=alt.value("crimson"),
130
- )
131
- ).properties(
132
- width=chart_size["width"],
133
- height=chart_size["height"] / 2,
134
- )
135
-
136
- net_flow_total_fig = net_flow_total_fig & price_fig
137
- net_flow_total_fig = net_flow_total_fig.resolve_scale(x="shared").properties(
138
- title=f"{asset} ETF net flow total vs asset price",
139
  )
140
 
141
  # Stacking area chart of flow from individual funds
142
- cum_flow_individual_net_fig = (
143
  alt.Chart(cum_flow_individual)
144
  .transform_fold(
145
  cum_flow_individual.drop(columns="Date").columns.to_list(),
@@ -147,72 +119,62 @@ def gen_charts(asset, chart_size={"width": 560, "height": 300}):
147
  )
148
  .mark_area()
149
  .encode(
150
- x=alt.X("Date:T", axis=alt.Axis(tickCount="day", title="", labels=False)),
151
- y=alt.Y("Net Flow:Q"),
152
  color=alt.Color("Funds:N", scale=alt.Scale(scheme="tableau20")),
153
  )
154
  ).properties(
155
  width=chart_size["width"],
156
- height=chart_size["height"] / 2,
157
- )
158
- cum_flow_individual_net_fig = cum_flow_individual_net_fig & price_fig
159
- cum_flow_individual_net_fig = cum_flow_individual_net_fig.resolve_scale(
160
- x="shared"
161
- ).properties(
162
- title=f"{asset} ETF cumulative flow of individual funds vs asset price",
163
  )
164
 
165
  # Area chart for cumulative flow
166
- cum_flow_total_fig = (
167
  alt.Chart(cum_flow_total)
168
  .transform_calculate(
169
  negative="datum.Total < 0",
170
  )
171
  .mark_area()
172
  .encode(
173
- x=alt.X("Date:T", axis=alt.Axis(tickCount="day", title="", labels=False)),
174
- y=alt.Y("Total:Q", impute={"value": 0}),
175
  color=alt.Color(
176
  "negative:N", title="Negative Flow", scale=alt.Scale(scheme="set2")
177
  ),
178
  )
179
  ).properties(
180
  width=chart_size["width"],
181
- height=chart_size["height"] / 2,
182
- )
183
- cum_flow_total_fig = cum_flow_total_fig & price_fig
184
- cum_flow_total_fig = cum_flow_total_fig.resolve_scale(x="shared").properties(
185
- title=f"{asset} ETF cumulative flow total vs asset price",
186
  )
187
 
188
  return SimpleNamespace(
189
- trading_vol_fig=trading_vol_fig,
190
- net_flow_individual_fig=net_flow_individual_fig,
191
- net_flow_total_fig=net_flow_total_fig,
192
- cum_flow_individual_net_fig=cum_flow_individual_net_fig,
193
- cum_flow_total_fig=cum_flow_total_fig,
 
 
 
 
194
  )
195
 
196
-
197
- def asset_charts(asset: str, chart_size={"width": "container", "height": 300}):
198
  charts = gen_charts(asset, chart_size)
199
  # Vertical concat the charts in each asset into single column of that asset
200
  all_charts = (
201
- charts.trading_vol_fig
202
- & charts.net_flow_individual_fig
203
- & charts.net_flow_total_fig
204
- & charts.cum_flow_individual_net_fig
205
- & charts.cum_flow_total_fig
206
- ).resolve_scale(color="independent")
207
-
208
- return all_charts
209
-
210
-
211
- def compound_chart(chart_size={"width": 560, "height": 300}):
212
- all_charts_btc = asset_charts("BTC", chart_size)
213
- all_charts_eth = asset_charts("ETH", chart_size)
214
- # Horizontal concat the charts for btc and eth
215
- all_charts = (all_charts_btc | all_charts_eth).resolve_scale(color="independent")
216
 
217
  return all_charts
218
 
@@ -236,9 +198,15 @@ if __name__ == "__main__":
236
  eth = fetch_asset("ETH")
237
 
238
  with dashboard_tab:
239
- chart = compound_chart(chart_size={"width": 560, "height": 300})
 
240
  # Display charts
241
- st.altair_chart(chart, use_container_width=True)
 
 
 
 
 
242
  btc_col, eth_col = st.columns(2)
243
  with btc_col:
244
  iframe(btc.url, height=1200, scrolling=True)
@@ -249,12 +217,8 @@ if __name__ == "__main__":
249
  "Asset to view",
250
  ("BTC", "ETH"),
251
  )
252
- charts = gen_charts(asset, chart_size={"width": "container", "height": 600})
253
- st.altair_chart(charts.trading_vol_fig, use_container_width=True)
254
- st.altair_chart(charts.net_flow_individual_fig, use_container_width=True)
255
- st.altair_chart(charts.net_flow_total_fig, use_container_width=True)
256
- st.altair_chart(charts.cum_flow_individual_net_fig, use_container_width=True)
257
- st.altair_chart(charts.cum_flow_total_fig, use_container_width=True)
258
  iframe(fetch_asset(asset).url, height=1200, scrolling=True)
259
  with flow_tab:
260
  btc_flow, eth_flow = btc.etf_flow, eth.etf_flow
 
17
  def fetch_asset(asset):
18
  return fetch(asset)
19
 
20
+ def gen_charts(asset, chart_size={"width": 560, "height": 150}):
21
  # Gen data
22
  data = fetch_asset(asset)
23
  etf_volumes = data.etf_volumes
 
27
  cum_flow_individual = data.cum_flow_individual
28
  cum_flow_total = data.cum_flow_total
29
 
30
+ # Selection interval
31
+ interval = alt.selection_interval(encodings=["x"])
32
+ # Line chart of price
33
+ price = (
34
+ alt.Chart(price)
35
+ .mark_line()
36
+ .encode(
37
+ x=alt.X("Date:T", axis=alt.Axis(tickCount={"interval": "month", "step": 1}), title=""),
38
+ y=alt.Y("Price:Q").scale(zero=False),
39
+ color=alt.value("crimson"),
40
+ )
41
+ ).properties(
42
+ width=chart_size["width"],
43
+ height=chart_size["height"],
44
+ )
45
+ # View selection
46
+ view = price.add_params(interval)
47
+
48
+ trading_vol_individual = (
49
  alt.Chart(etf_volumes)
50
  .transform_fold(
51
  etf_volumes.drop(columns="Date").columns.to_list(), as_=["Funds", "Volume"]
52
  )
53
  .mark_line()
54
  .encode(
55
+ x=alt.X("Date:T", axis=alt.Axis(tickCount={"interval": "month", "step": 1}), title=""),
56
+ y=alt.Y("Volume:Q", title="Trading Volume Individual"),
57
  color="Funds:N",
58
  )
59
  ).properties(
60
  width=chart_size["width"],
61
+ height=chart_size["height"],
62
  )
63
+ trading_vol_total = (
64
  alt.Chart(etf_volumes)
65
  .transform_fold(
66
  etf_volumes.drop(columns="Date").columns.to_list(), as_=["Funds", "Volume"]
67
  )
68
  .mark_rule()
69
  .encode(
70
+ x=alt.X("Date:T", axis=alt.Axis(tickCount={"interval": "month", "step": 1}), title=""),
71
+ y=alt.Y("sum(Volume):Q", title="Trading Volume Total"),
72
  color=alt.value("teal"),
73
  )
74
  ).properties(
75
  width=chart_size["width"],
76
+ height=chart_size["height"],
 
 
 
 
 
77
  )
78
 
79
  # Net flow individual
80
+ net_flow_individual = (
81
  alt.Chart(etf_flow_individual)
82
  .transform_fold(
83
  etf_flow_individual.drop(columns="Date").columns.to_list(),
 
85
  )
86
  .mark_line()
87
  .encode(
88
+ x=alt.X("Date:T", axis=alt.Axis(tickCount={"interval": "month", "step": 1}), title=""),
89
+ y=alt.Y("Net Flow:Q", title="Net Flow Individual"),
90
  color="Funds:N",
91
  )
92
  ).properties(
93
  width=chart_size["width"],
94
+ height=chart_size["height"],
95
  )
96
+ net_flow_total = (
97
  alt.Chart(etf_flow_total)
98
  .mark_rule()
99
  .encode(
100
+ x=alt.X("Date:T", axis=alt.Axis(tickCount={"interval": "month", "step": 1}), title=""),
101
+ y=alt.Y("Total:Q", title="Net Flow Total"),
102
  color=alt.condition(
103
  alt.datum.Total > 0,
104
  alt.value("seagreen"), # The positive color
 
107
  )
108
  ).properties(
109
  width=chart_size["width"],
110
+ height=chart_size["height"],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  )
112
 
113
  # Stacking area chart of flow from individual funds
114
+ cum_flow_individual = (
115
  alt.Chart(cum_flow_individual)
116
  .transform_fold(
117
  cum_flow_individual.drop(columns="Date").columns.to_list(),
 
119
  )
120
  .mark_area()
121
  .encode(
122
+ x=alt.X("Date:T", axis=alt.Axis(tickCount={"interval": "month", "step": 1}), title=""),
123
+ y=alt.Y("Net Flow:Q", title="Cumulative Flow Individual"),
124
  color=alt.Color("Funds:N", scale=alt.Scale(scheme="tableau20")),
125
  )
126
  ).properties(
127
  width=chart_size["width"],
128
+ height=chart_size["height"],
 
 
 
 
 
 
129
  )
130
 
131
  # Area chart for cumulative flow
132
+ cum_flow_total = (
133
  alt.Chart(cum_flow_total)
134
  .transform_calculate(
135
  negative="datum.Total < 0",
136
  )
137
  .mark_area()
138
  .encode(
139
+ x=alt.X("Date:T", axis=alt.Axis(tickCount={"interval": "month", "step": 1}), title=""),
140
+ y=alt.Y("Total:Q", title="Cumulative Flow Total", impute={"value": 0}),
141
  color=alt.Color(
142
  "negative:N", title="Negative Flow", scale=alt.Scale(scheme="set2")
143
  ),
144
  )
145
  ).properties(
146
  width=chart_size["width"],
147
+ height=chart_size["height"],
 
 
 
 
148
  )
149
 
150
  return SimpleNamespace(
151
+ interval=interval,
152
+ view=view,
153
+ price=price,
154
+ trading_vol_individual=trading_vol_individual,
155
+ trading_vol_total=trading_vol_total,
156
+ net_flow_individual=net_flow_individual,
157
+ net_flow_total=net_flow_total,
158
+ cum_flow_individual=cum_flow_individual,
159
+ cum_flow_total=cum_flow_total,
160
  )
161
 
162
+ def asset_charts(asset: str, chart_size={"width": "container", "height": 150}):
 
163
  charts = gen_charts(asset, chart_size)
164
  # Vertical concat the charts in each asset into single column of that asset
165
  all_charts = (
166
+ charts.view
167
+ & charts.trading_vol_individual.encode(x=alt.X("Date:T", axis=alt.Axis(tickCount="day"), title="",scale=alt.Scale(domain=charts.interval)))
168
+ & charts.trading_vol_total.encode(x=alt.X("Date:T", axis=alt.Axis(tickCount="day"), title="",scale=alt.Scale(domain=charts.interval)))
169
+ & charts.net_flow_individual.encode(x=alt.X("Date:T", axis=alt.Axis(tickCount="day"), title="",scale=alt.Scale(domain=charts.interval)))
170
+ & charts.net_flow_total.encode(x=alt.X("Date:T", axis=alt.Axis(tickCount="day"), title="",scale=alt.Scale(domain=charts.interval)))
171
+ & charts.cum_flow_individual.encode(x=alt.X("Date:T", axis=alt.Axis(tickCount="day"), title="",scale=alt.Scale(domain=charts.interval)))
172
+ & charts.cum_flow_total.encode(x=alt.X("Date:T", axis=alt.Axis(tickCount="day"), title="",scale=alt.Scale(domain=charts.interval)))
173
+ ).resolve_scale(
174
+ color="independent",
175
+ ).properties(
176
+ title=f"{asset} ETF",
177
+ )
 
 
 
178
 
179
  return all_charts
180
 
 
198
  eth = fetch_asset("ETH")
199
 
200
  with dashboard_tab:
201
+ btc_charts = asset_charts("BTC", chart_size={"width": "container", "height": 150})
202
+ eth_charts = asset_charts("ETH", chart_size={"width": "container", "height": 150})
203
  # Display charts
204
+ btc_chart_col, eth_chart_col = st.columns(2)
205
+ with btc_chart_col:
206
+ st.altair_chart(btc_charts, use_container_width=True)
207
+ with eth_chart_col:
208
+ st.altair_chart(eth_charts, use_container_width=True)
209
+ # Display iframes
210
  btc_col, eth_col = st.columns(2)
211
  with btc_col:
212
  iframe(btc.url, height=1200, scrolling=True)
 
217
  "Asset to view",
218
  ("BTC", "ETH"),
219
  )
220
+ charts = asset_charts(asset, chart_size={"width": "container", "height": 300})
221
+ st.altair_chart(charts, use_container_width=True)
 
 
 
 
222
  iframe(fetch_asset(asset).url, height=1200, scrolling=True)
223
  with flow_tab:
224
  btc_flow, eth_flow = btc.etf_flow, eth.etf_flow