@@ -16,24 +16,48 @@ def has_error(result):
16
16
# Check if result is None or a dictionary with an error message
17
17
return result is None or (isinstance (result , dict ) and result .get ("result" ) == "error" )
18
18
19
+ @st .cache_data (ttl = 3600 ) # Cache for 1 hour
20
+ def get_market_list ():
21
+ """Fetches the list of available markets for the dropdown."""
22
+ return fetch_api_data (section = "open-interest" , path = "markets" , params = {"bypass_cache" : "true" })
23
+
19
24
def open_interest_page ():
20
25
st .title ("Open Interest on Drift" )
21
26
27
+ market_list = get_market_list ()
28
+ if not isinstance (market_list , list ) or not market_list :
29
+ st .error ("Could not fetch the list of markets. Defaulting to 'All'." )
30
+ market_list = ["All" ]
31
+
32
+ selected_market = st .selectbox (
33
+ "Select Market" ,
34
+ options = market_list ,
35
+ index = 0 , # Default to "All"
36
+ key = 'oi_market'
37
+ )
38
+
22
39
try :
23
40
# --- 1. Fetch all data ---
41
+ api_params = {}
42
+ if selected_market and selected_market != "All" :
43
+ api_params ['market_name' ] = selected_market
44
+
24
45
result_authority = fetch_api_data (
25
46
section = "open-interest" ,
26
47
path = "per-authority" ,
48
+ params = api_params ,
27
49
retry = False # Let the page handle retries via rerun
28
50
)
29
51
result_account = fetch_api_data (
30
52
section = "open-interest" ,
31
53
path = "per-account" ,
54
+ params = api_params ,
32
55
retry = False
33
56
)
34
57
result_detailed = fetch_api_data (
35
58
section = "open-interest" ,
36
59
path = "detailed-positions" ,
60
+ params = api_params ,
37
61
retry = False
38
62
)
39
63
@@ -96,8 +120,8 @@ def open_interest_page():
96
120
'authority' : 'User Authority' ,
97
121
'total_open_interest_usd' : 'Total Open Interest (USD)'
98
122
}, inplace = True )
99
- df_authority = df_authority [[ "User Authority" , "Total Open Interest (USD)" ]]
100
- df_authority ["Total Open Interest (USD)" ] = df_authority ["Total Open Interest (USD)" ].apply (lambda x : f"${ x :,.2f} " )
123
+ # Keep original numeric column for calculation, create a new one for display
124
+ df_authority ["Total Open Interest (USD) Display " ] = df_authority ["Total Open Interest (USD)" ].apply (lambda x : f"${ x :,.2f} " )
101
125
102
126
df_account = pd .DataFrame ()
103
127
if data_account :
@@ -108,8 +132,8 @@ def open_interest_page():
108
132
'authority' : 'Authority' ,
109
133
'total_open_interest_usd' : 'Total Open Interest (USD)'
110
134
}, inplace = True )
111
- df_account = df_account [[ 'User Account' , 'Authority' , 'Total Open Interest (USD)' ]]
112
- df_account ["Total Open Interest (USD)" ] = df_account ["Total Open Interest (USD)" ].apply (lambda x : f"${ x :,.2f} " )
135
+ # Create a new column for display
136
+ df_account ["Total Open Interest (USD) Display " ] = df_account ["Total Open Interest (USD)" ].apply (lambda x : f"${ x :,.2f} " )
113
137
114
138
df_detailed = pd .DataFrame ()
115
139
if data_detailed :
@@ -123,46 +147,66 @@ def open_interest_page():
123
147
'user_public_key' : 'User Account' ,
124
148
'authority' : 'Authority'
125
149
}, inplace = True )
126
- df_detailed = df_detailed [[
127
- 'Market Index' , 'Market Symbol' , 'Base Asset Amount' , 'Notional Value (USD)' ,
128
- 'User Account' , 'Authority'
129
- ]]
130
- df_detailed ['Base Asset Amount' ] = df_detailed ['Base Asset Amount' ].apply (lambda x : f"{ x :,.4f} " )
131
- df_detailed ['Notional Value (USD)' ] = df_detailed ['Notional Value (USD)' ].apply (lambda x : f"${ x :,.2f} " )
150
+ # Create new columns for display
151
+ df_detailed ['Base Asset Amount Display' ] = df_detailed ['Base Asset Amount' ].apply (lambda x : f"{ x :,.4f} " )
152
+ df_detailed ['Notional Value (USD) Display' ] = df_detailed ['Notional Value (USD)' ].apply (lambda x : f"${ x :,.2f} " )
132
153
133
154
# --- 7. Display Layout (Metrics and DataFrames) ---
134
155
total_oi_usd = 0.0
156
+ total_long_oi_usd = 0.0
157
+ total_short_oi_usd = 0.0
135
158
if not df_authority .empty :
136
159
try :
137
- # Calculate metric only if df_authority is valid and processed
138
- total_oi_usd = df_authority ['Total Open Interest (USD)' ].str .replace ('[$,]' ,'' , regex = True ).astype (float ).sum ()
160
+ # Calculate metric from the original numeric column
161
+ total_oi_usd = df_authority ['Total Open Interest (USD)' ].sum ()
162
+ total_long_oi_usd = df_authority ['long_oi_usd' ].sum ()
163
+ total_short_oi_usd = df_authority ['short_oi_usd' ].sum ()
139
164
except Exception as calc_e :
140
165
st .warning (f"Could not calculate Total OI metric: { calc_e } " )
141
166
142
- col1 , col2 = st .columns (2 )
167
+ col1 , col2 , col3 , col4 = st .columns (4 )
143
168
with col1 :
144
169
st .metric ("Total Authorities with Open Interest" , len (df_authority ) if not df_authority .empty else 0 )
145
170
with col2 :
146
171
st .metric ("Total Open Interest (USD)" , f"${ total_oi_usd :,.2f} " )
172
+ with col3 :
173
+ st .metric ("Total Long OI (USD)" , f"${ total_long_oi_usd :,.2f} " )
174
+ with col4 :
175
+ st .metric ("Total Short OI (USD)" , f"${ total_short_oi_usd :,.2f} " )
147
176
148
177
col3 , col4 = st .columns (2 )
149
178
with col3 :
150
179
st .subheader ("OI by Authority" )
151
180
if not df_authority .empty :
152
- st .dataframe (df_authority , hide_index = True )
181
+ # Display only the relevant columns
182
+ df_authority_display = df_authority [["User Authority" , "Total Open Interest (USD) Display" ]]
183
+ df_authority_display .columns = ["User Authority" , "Total Open Interest (USD)" ]
184
+ st .dataframe (df_authority_display , hide_index = True )
153
185
else :
154
186
st .info ("Authority data not available or empty." )
155
187
156
188
with col4 :
157
189
st .subheader ("OI by Account" )
158
190
if not df_account .empty :
159
- st .dataframe (df_account , hide_index = True )
191
+ # Display only the relevant columns
192
+ df_account_display = df_account [['User Account' , 'Authority' , 'Total Open Interest (USD) Display' ]]
193
+ df_account_display .columns = ['User Account' , 'Authority' , 'Total Open Interest (USD)' ]
194
+ st .dataframe (df_account_display , hide_index = True )
160
195
else :
161
196
st .info ("Account data not available or empty." )
162
197
163
198
st .subheader ("Detailed Open Positions" )
164
199
if not df_detailed .empty :
165
- st .dataframe (df_detailed , hide_index = True , use_container_width = True )
200
+ # Display only the relevant columns
201
+ df_detailed_display = df_detailed [[
202
+ 'Market Index' , 'Market Symbol' , 'Base Asset Amount Display' , 'Notional Value (USD) Display' ,
203
+ 'User Account' , 'Authority'
204
+ ]]
205
+ df_detailed_display .columns = [
206
+ 'Market Index' , 'Market Symbol' , 'Base Asset Amount' , 'Notional Value (USD)' ,
207
+ 'User Account' , 'Authority'
208
+ ]
209
+ st .dataframe (df_detailed_display , hide_index = True , use_container_width = True )
166
210
else :
167
211
st .info ("Detailed position data not available or empty." )
168
212
0 commit comments