{ "cells": [ { "cell_type": "code", "execution_count": 2, "id": "0b5ca901", "metadata": {}, "outputs": [], "source": [ "import requests\n", "import pandas as pd\n", "import numpy as np\n", "from datetime import datetime\n", "import time\n", "import json\n", "import valkey\n", "from dataclasses import dataclass, field, asdict\n", "import modules.structs as structs\n", "import modules.aster_auth as aster_auth\n", "import modules.manual_leverage as leverage\n", "VAL_KEY = valkey.Valkey(host='localhost', port=6379, db=0, decode_responses=True)\n", "df_leverage_by_exch = pd.DataFrame(data=leverage.LEVERAGE_BY_EXCH)" ] }, { "cell_type": "code", "execution_count": 101, "id": "20665e82", "metadata": {}, "outputs": [], "source": [ "### ********** TODO: ADD IN VOLUME DATA TO FILTER MKTS ###" ] }, { "cell_type": "code", "execution_count": 102, "id": "53647b40", "metadata": {}, "outputs": [], "source": [ "# ### ASTER Historical FR ###\n", "# params = {\n", "# 'limit': 1000,\n", "# }\n", "# r = json.loads(requests.get('https://fapi.asterdex.com/fapi/v3/fundingRate', params=params).text)\n", "# df_aster_hist_fr = pd.DataFrame(r)\n", "# df_aster_hist_fr['funding_rate_ts_dt'] = pd.to_datetime(df_aster_hist_fr['fundingTime'], unit='ms')\n", "# df_aster_hist_fr = df_aster_hist_fr.sort_values(by='fundingTime', ascending=True).drop_duplicates(subset=['symbol'], keep='last')" ] }, { "cell_type": "code", "execution_count": 103, "id": "1f3b65ee", "metadata": {}, "outputs": [], "source": [ "# ### ASTER Current FR ###\n", "# r = json.loads(requests.get('https://fapi.asterdex.com/fapi/v3/fundingInfo').text)\n", "# df_aster_current_fr = pd.DataFrame(r)\n", "# df_aster_current_fr['funding_rate_ts_dt'] = pd.to_datetime(df_aster_current_fr['time'], unit='ms')\n", "# df_aster_current_fr['funding_rate'] = df_aster_current_fr['interestRate']\n" ] }, { "cell_type": "code", "execution_count": 104, "id": "5176d5b1", "metadata": {}, "outputs": [], "source": [ "### ASTER EXCHANGE INFO ###\n", "fut_acct_exchangeInfo: dict = {\n", " \"url\": \"/fapi/v3/exchangeInfo\",\n", " \"method\": \"GET\",\n", " \"params\": {}\n", "}\n", "r: dict = await aster_auth.post_authenticated_url(fut_acct_exchangeInfo) # ty:ignore[invalid-assignment]\n", "df_aster_exch_info = pd.DataFrame(r['symbols'])\n", "df_aster_exch_info['min_order_size'] = df_aster_exch_info['filters'].apply(lambda x: [f for f in x if f.get('filterType', None) == 'LOT_SIZE'][0]['minQty'] )\n", "df_aster_exch_info['min_price'] = df_aster_exch_info['filters'].apply(lambda x: [f for f in x if f.get('filterType', None) == 'PRICE_FILTER'][0]['minPrice'] )\n", "df_aster_exch_info['min_notional'] = df_aster_exch_info['filters'].apply(lambda x: [f for f in x if f.get('filterType', None) == 'MIN_NOTIONAL'][0]['notional'] )\n", "df_aster_exch_info['min_lot_size'] = df_aster_exch_info['filters'].apply(lambda x: [f for f in x if f.get('filterType', None) == 'LOT_SIZE'][0]['stepSize'] )\n", "\n", "fut_acct_ticker_stats: dict = {\n", " \"url\": \"/fapi/v3/ticker/24hr\",\n", " \"method\": \"GET\",\n", " \"params\": {}\n", "}\n", "r: dict = await aster_auth.post_authenticated_url(fut_acct_ticker_stats) # ty:ignore[invalid-assignment]\n", "df_aster_ticker_stats = pd.DataFrame(r)\n", "df_aster_ticker_stats['last_trade_ts_ast'] = df_aster_ticker_stats['closeTime']\n", "\n", "df_aster_exch_info = df_aster_exch_info.merge(df_aster_ticker_stats[['symbol','quoteVolume','last_trade_ts_ast']].rename({'quoteVolume':'daily_volume'}, axis=1), on='symbol', how='left')\n", "df_aster_exch_info['daily_volume'] = df_aster_exch_info['daily_volume'].astype(float)" ] }, { "cell_type": "code", "execution_count": 105, "id": "e33ec721", "metadata": {}, "outputs": [], "source": [ "### Extended Current FR ###\n", "r = json.loads(requests.get('https://api.starknet.extended.exchange/api/v1/info/markets').text)\n", "df_extend_current_mkt_stats = pd.DataFrame(r['data'])\n", "\n", "df_extend_current_mkt_stats['funding_rate'] = df_extend_current_mkt_stats['marketStats'].apply(lambda x: x.get('fundingRate',{}))\n", "df_extend_current_mkt_stats['funding_rate_ts'] = df_extend_current_mkt_stats['marketStats'].apply(lambda x: x.get('nextFundingRate',{}))\n", "df_extend_current_mkt_stats['daily_volume'] = df_extend_current_mkt_stats['marketStats'].apply(lambda x: x.get('dailyVolume',{})).astype(float)\n", "df_extend_current_mkt_stats['min_order_size'] = df_extend_current_mkt_stats['tradingConfig'].apply(lambda x: x.get('minOrderSize',{}))\n", "df_extend_current_mkt_stats['min_price'] = df_extend_current_mkt_stats['tradingConfig'].apply(lambda x: x.get('minPriceChange',{}))\n", "df_extend_current_mkt_stats['min_notional'] = 0\n", "df_extend_current_mkt_stats['min_lot_size'] = df_extend_current_mkt_stats['tradingConfig'].apply(lambda x: x.get('minOrderSizeChange',{}))\n", "\n", "df_extend_current_mkt_stats['max_leverage'] = df_extend_current_mkt_stats['tradingConfig'].apply(lambda x: x.get('maxLeverage',{}))\n", "\n", "\n", "# df_extend_current_fr = df_extend_current_mkt_stats[['status','name','assetName','collateralAssetName','category','min_order_size','min_price','max_leverage','funding_rate','funding_rate_ts']]\n", "# df_extend_current_fr['funding_rate_ts_dt'] = pd.to_datetime(df_extend_current_fr['funding_rate_ts'], unit='ms')\n", "# df_extend_current_fr = df_extend_current_fr.loc[df_extend_current_fr['status']=='ACTIVE',:]" ] }, { "cell_type": "code", "execution_count": 106, "id": "62815940", "metadata": {}, "outputs": [], "source": [ "### ASTER Current FR from Mark Price Req ###\n", "# r = json.loads(requests.get('https://fapi.asterdex.com/fapi/v3/exchangeInfo').text)\n", "# df_aster_current_mkt_stats = pd.DataFrame(r)\n", "# ### ASTER Current FR from Mark Price Req ###\n", "# r = json.loads(requests.get('https://fapi.asterdex.com/fapi/v3/premiumIndex').text)\n", "# df_aster_current_mkt_stats = pd.DataFrame(r)" ] }, { "cell_type": "code", "execution_count": 107, "id": "271a67c1", "metadata": {}, "outputs": [], "source": [ "### ASTER CURRENT FR - WS ###\n", "df_aster_current_fr = pd.DataFrame(json.loads(VAL_KEY.get('fund_rate_aster_all'))) # ty:ignore[invalid-argument-type]\n", "df_aster_current_fr = df_aster_current_fr[['s','E','r','T']].rename({'s':'symbol','E':'funding_rate_updated_ts_ms','r':'funding_rate','T':'next_funding_ts'}, axis=1)\n", "df_aster_current_fr['funding_rate_updated_dt'] = pd.to_datetime(df_aster_current_fr['funding_rate_updated_ts_ms'], unit='ms')\n", "df_aster_current_fr['funding_rate'] = df_aster_current_fr['funding_rate'].astype(float)\n", "df_aster_current_fr['time_delta_to_next_funding'] = pd.to_datetime(df_aster_current_fr['next_funding_ts'], unit='ms') - pd.Timestamp.now()\n", "df_aster_current_fr = df_aster_current_fr.merge(df_aster_exch_info[['symbol','daily_volume','min_order_size','min_price','min_lot_size','min_notional','last_trade_ts_ast']], on='symbol', how='left')" ] }, { "cell_type": "code", "execution_count": 108, "id": "1ce2fde4", "metadata": {}, "outputs": [], "source": [ "### EXTEND CURRENT FR - WS ###\n", "df_extended_current_fr = pd.DataFrame(json.loads(VAL_KEY.get('fund_rate_extended_all'))) # ty:ignore[invalid-argument-type]\n", "df_extended_current_fr = df_extended_current_fr[['symbol','funding_rate_updated_ts_ms','funding_rate']]\n", "df_extended_current_fr['funding_rate_updated_dt'] = pd.to_datetime(df_extended_current_fr['funding_rate_updated_ts_ms'], unit='ms')\n", "df_extended_current_fr['funding_rate'] = df_extended_current_fr['funding_rate'].astype(float)\n", "\n", "# df_extended_current_fr = df_extended_current_fr.merge(df_extend_current_mkt_stats[['name','assetName','status', 'funding_rate_ts','max_leverage']].rename({'name':'symbol','funding_rate_ts':'next_funding_ts'}, axis=1), on='symbol', how='left')\n", "df_extended_current_fr = df_extended_current_fr.merge(df_extend_current_mkt_stats[['name','assetName','status', 'funding_rate_ts','min_order_size','min_price','min_lot_size','min_notional','daily_volume']].rename({'name':'symbol','funding_rate_ts':'next_funding_ts'}, axis=1), on='symbol', how='left')\n", "df_extended_current_fr = df_extended_current_fr.loc[df_extended_current_fr['status']=='ACTIVE',:]\n", "df_extended_current_fr['USDT_Symbol'] = df_extended_current_fr['assetName'] + 'USDT'\n", "df_extended_current_fr['time_delta_to_next_funding'] = pd.to_datetime(df_extended_current_fr['next_funding_ts'], unit='ms') - pd.Timestamp.now()" ] }, { "cell_type": "code", "execution_count": 109, "id": "ff88b413", "metadata": {}, "outputs": [], "source": [ "### COMBINED CURRENT FR - WS ###\n", "df_comb_current_fr = df_extended_current_fr.merge(df_aster_current_fr, left_on='USDT_Symbol', right_on='symbol', how='inner', suffixes=('_ext', '_ast'))\n", "df_comb_current_fr['next_funding_at_same_time'] = (abs(df_comb_current_fr['time_delta_to_next_funding_ext'].dt.total_seconds() - df_comb_current_fr['time_delta_to_next_funding_ast'].dt.total_seconds()) / 60) < 1\n", "df_comb_current_fr['net_funding_rate'] = (df_comb_current_fr[['funding_rate_ext', 'funding_rate_ast']].max(axis=1) - df_comb_current_fr[['funding_rate_ext', 'funding_rate_ast']].min(axis=1)).where(df_comb_current_fr['next_funding_at_same_time'], df_comb_current_fr['funding_rate_ext'])\n", "df_comb_current_fr['net_funding_rate_abs'] = df_comb_current_fr['net_funding_rate'].abs()\n", "\n", "### NET MULT ###\n", "df_comb_current_fr_net = df_comb_current_fr.merge(df_leverage_by_exch.loc[df_leverage_by_exch['exchange']=='EXTEND'], left_on='assetName', right_on='lh_asset').merge(df_leverage_by_exch.loc[df_leverage_by_exch['exchange']=='ASTER'], left_on='assetName', right_on='lh_asset', suffixes=('_ext', '_ast'))\n", "df_comb_current_fr_net['net_mult'] = 1 / ( ( 0.5 / df_comb_current_fr_net['max_leverage_ext'] ) + ( 0.5 / df_comb_current_fr_net['max_leverage_ast'] ) )\n", "df_comb_current_fr_net['net_mult'] = df_comb_current_fr_net['net_mult'].round(2)\n", "df_comb_current_fr_net['net_mult_x_net_fr_abs'] = df_comb_current_fr_net['net_funding_rate_abs'] * df_comb_current_fr_net['net_mult']" ] }, { "cell_type": "code", "execution_count": 110, "id": "f5ade993", "metadata": {}, "outputs": [], "source": [ "df_best_fr_rate = df_comb_current_fr_net[['symbol_ext','symbol_ast','daily_volume_ext','daily_volume_ast','min_price_ext','min_price_ast','min_order_size_ext','min_order_size_ast','min_lot_size_ext','min_lot_size_ast','min_notional_ext','min_notional_ast','funding_rate_ext','funding_rate_ast','max_leverage_ext','max_leverage_ast','lh_asset_ext','lh_asset_ast','rh_asset_ext','rh_asset_ast','net_mult_x_net_fr_abs','net_funding_rate_abs','net_funding_rate','next_funding_at_same_time','last_trade_ts_ast']].sort_values(by='net_mult_x_net_fr_abs', ascending=False).reset_index(drop=True)\n", "df_best_fr_rate['hourly_dollars_per_1k'] = df_best_fr_rate['net_mult_x_net_fr_abs'] * 1000\n", "df_best_fr_rate['hourly_dollars_per_1k'] = df_best_fr_rate['hourly_dollars_per_1k'].round(2)" ] }, { "cell_type": "code", "execution_count": 111, "id": "84bbc5a8", "metadata": {}, "outputs": [], "source": [ "last_trade_max_ts = []\n", "\n", "for index, row in df_best_fr_rate.iterrows():\n", " r = json.loads(requests.get(f'https://api.starknet.extended.exchange/api/v1/info/markets/{row['symbol_ext']}/trades').text)\n", " max_ts = max([t['T'] for t in r['data']])\n", " last_trade_max_ts.append({'symbol_ext':row['symbol_ext'],'last_trade_ts_ext': max_ts})\n", " time.sleep(0.01)\n", "\n", "df_best_fr_rate = df_best_fr_rate.merge(pd.DataFrame(last_trade_max_ts), on='symbol_ext', how='left')" ] }, { "cell_type": "code", "execution_count": 112, "id": "7bd849e4", "metadata": {}, "outputs": [], "source": [ "df_best_fr_rate['last_trade_ts_dt_ast'] = pd.to_datetime(df_best_fr_rate['last_trade_ts_ast'], unit='ms')\n", "df_best_fr_rate['last_trade_ts_dt_ext'] = pd.to_datetime(df_best_fr_rate['last_trade_ts_ext'], unit='ms')\n", "df_best_fr_rate = df_best_fr_rate.loc[( (datetime.now().timestamp()*1000 )-df_best_fr_rate['last_trade_ts_ast']) < (3*60*1000) ]\n", "df_best_fr_rate = df_best_fr_rate.loc[( (datetime.now().timestamp()*1000 )-df_best_fr_rate['last_trade_ts_ext']) < (15*60*1000) ]" ] }, { "cell_type": "code", "execution_count": 113, "id": "48d093ce", "metadata": {}, "outputs": [ { "data": { "application/vnd.microsoft.datawrangler.viewer.v0+json": { "columns": [ { "name": "index", "rawType": "int64", "type": "integer" }, { "name": "symbol_ext", "rawType": "str", "type": "string" }, { "name": "symbol_ast", "rawType": "str", "type": "string" }, { "name": "daily_volume_ext", "rawType": "float64", "type": "float" }, { "name": "daily_volume_ast", "rawType": "float64", "type": "float" }, { "name": "min_price_ext", "rawType": "str", "type": "string" }, { "name": "min_price_ast", "rawType": "str", "type": "string" }, { "name": "min_order_size_ext", "rawType": "str", "type": "string" }, { "name": "min_order_size_ast", "rawType": "str", "type": "string" }, { "name": "min_lot_size_ext", "rawType": "str", "type": "string" }, { "name": "min_lot_size_ast", "rawType": "str", "type": "string" }, { "name": "min_notional_ext", "rawType": "float64", "type": "float" }, { "name": "min_notional_ast", "rawType": "str", "type": "string" }, { "name": "funding_rate_ext", "rawType": "float64", "type": "float" }, { "name": "funding_rate_ast", "rawType": "float64", "type": "float" }, { "name": "max_leverage_ext", "rawType": "int64", "type": "integer" }, { "name": "max_leverage_ast", "rawType": "int64", "type": "integer" }, { "name": "lh_asset_ext", "rawType": "str", "type": "string" }, { "name": "lh_asset_ast", "rawType": "str", "type": "string" }, { "name": "rh_asset_ext", "rawType": "str", "type": "string" }, { "name": "rh_asset_ast", "rawType": "str", "type": "string" }, { "name": "net_mult_x_net_fr_abs", "rawType": "float64", "type": "float" }, { "name": "net_funding_rate_abs", "rawType": "float64", "type": "float" }, { "name": "net_funding_rate", "rawType": "float64", "type": "float" }, { "name": "next_funding_at_same_time", "rawType": "bool", "type": "boolean" }, { "name": "last_trade_ts_ast", "rawType": "float64", "type": "float" }, { "name": "hourly_dollars_per_1k", "rawType": "float64", "type": "float" }, { "name": "last_trade_ts_ext", "rawType": "int64", "type": "integer" }, { "name": "last_trade_ts_dt_ast", "rawType": "datetime64[ms]", "type": "datetime" }, { "name": "last_trade_ts_dt_ext", "rawType": "datetime64[ms]", "type": "datetime" } ], "ref": "fb395936-194b-4884-9460-1644ab82f860", "rows": [ [ "0", "LIT-USD", "LITUSDT", "1530863.4786", "557344.16", "0.0001", "0.0001000", "10", "1", "1", "1", "0.0", "5", "1.3e-05", "7.641e-05", "25", "50", "LIT", "LIT", "USD", "USDT", "0.0021134552999999994", "6.340999999999999e-05", "6.340999999999999e-05", "True", "1777838955491.0", "2.11", "1777838893573", "2026-05-03 20:09:15.491000", "2026-05-03 20:08:13.573000" ], [ "1", "ZEC-USD", "ZECUSDT", "5395747.6736", "1986811.3", "0.001", "0.0100", "0.1", "0.001", "0.1", "0.001", "0.0", "5", "1.3e-05", "-7.232e-05", "10", "75", "ZEC", "ZEC", "USD", "USDT", "0.0015058979999999999", "8.532e-05", "8.532e-05", "True", "1777838956400.0", "1.51", "1777838958681", "2026-05-03 20:09:16.400000", "2026-05-03 20:09:18.681000" ], [ "2", "ETH-USD", "ETHUSDT", "63794900.8984", "215801150.77", "0.1", "0.01", "0.01", "0.001", "0.001", "0.001", "0.0", "5", "-1.6e-05", "5.828e-05", "50", "150", "ETH", "ETH", "USD", "USDT", "0.0012", "1.6e-05", "-1.6e-05", "False", "1777838959171.0", "1.2", "1777838943428", "2026-05-03 20:09:19.171000", "2026-05-03 20:09:03.428000" ], [ "3", "HYPE-USD", "HYPEUSDT", "25572374.04134", "3517135.54", "0.001", "0.00100", "0.1", "0.01", "0.01", "0.01", "0.0", "5", "1.3e-05", "-1.902e-05", "50", "300", "HYPE", "HYPE", "USD", "USDT", "0.00111423", "1.3e-05", "1.3e-05", "False", "1777838926707.0", "1.11", "1777838941321", "2026-05-03 20:08:46.707000", "2026-05-03 20:09:01.321000" ], [ "5", "XRP-USD", "XRPUSDT", "5624796.8796", "7717251.91", "0.0001", "0.0143", "10", "0.1", "1", "0.1", "0.0", "5", "1.3e-05", "0.0001", "50", "100", "XRP", "XRP", "USD", "USDT", "0.0008667099999999999", "1.3e-05", "1.3e-05", "False", "1777838956056.0", "0.87", "1777838873023", "2026-05-03 20:09:16.056000", "2026-05-03 20:07:53.023000" ], [ "6", "BNB-USD", "BNBUSDT", "3508321.26862", "7656349.56", "0.01", "0.010", "0.01", "0.01", "0.001", "0.01", "0.0", "5", "1.3e-05", "0.00013255", "50", "100", "BNB", "BNB", "USD", "USDT", "0.0008667099999999999", "1.3e-05", "1.3e-05", "False", "1777838957563.0", "0.87", "1777838862018", "2026-05-03 20:09:17.563000", "2026-05-03 20:07:42.018000" ], [ "7", "DOGE-USD", "DOGEUSDT", "2224083.3516", "13131913.36", "0.00001", "0.002440", "100", "1", "10", "1", "0.0", "5", "1.3e-05", "4.512e-05", "50", "75", "DOGE", "DOGE", "USD", "USDT", "0.00078", "1.3e-05", "1.3e-05", "False", "1777838958745.0", "0.78", "1777838861853", "2026-05-03 20:09:18.745000", "2026-05-03 20:07:41.853000" ], [ "9", "ASTER-USD", "ASTERUSDT", "379897.4992", "35798413.55", "0.00001", "0.00010", "10", "0.01", "1", "0.01", "0.0", "5", "1.3e-05", "5e-05", "25", "75", "ASTER", "ASTER", "USD", "USDT", "0.0004875", "1.3e-05", "1.3e-05", "False", "1777838956077.0", "0.49", "1777838861663", "2026-05-03 20:09:16.077000", "2026-05-03 20:07:41.663000" ], [ "10", "CHIP-USD", "CHIPUSDT", "601581.80858", "369037.94", "0.000001", "0.0000100", "100", "1", "10", "1", "0.0", "5", "-0.000455", "-0.00050814", "5", "50", "CHIP", "CHIP", "USD", "USDT", "0.0004830426000000002", "5.314000000000002e-05", "5.314000000000002e-05", "True", "1777838833850.0", "0.48", "1777838894261", "2026-05-03 20:07:13.850000", "2026-05-03 20:08:14.261000" ], [ "11", "SOL-USD", "SOLUSDT", "10993777.163", "28191542.03", "0.01", "0.4200", "0.1", "0.01", "0.01", "0.01", "0.0", "5", "7e-06", "0.0001", "50", "100", "SOL", "SOL", "USD", "USDT", "0.00046669", "7e-06", "7e-06", "False", "1777838959552.0", "0.47", "1777838903681", "2026-05-03 20:09:19.552000", "2026-05-03 20:08:23.681000" ], [ "12", "BTC-USD", "BTCUSDT", "190699704.69432", "331787901.64", "1", "1", "0.0001", "0.001", "0.00001", "0.001", "0.0", "5", "-6e-06", "-9.62e-06", "50", "150", "BTC", "BTC", "USD", "USDT", "0.00045", "6e-06", "-6e-06", "False", "1777838959137.0", "0.45", "1777838940017", "2026-05-03 20:09:19.137000", "2026-05-03 20:09:00.017000" ], [ "14", "WLFI-USD", "WLFIUSDT", "118516.608", "2231254.7", "0.00001", "0.0001000", "100", "1", "10", "1", "0.0", "5", "1.3e-05", "5e-05", "10", "25", "WLFI", "WLFI", "USD", "USDT", "0.00018576999999999998", "1.3e-05", "1.3e-05", "False", "1777838920826.0", "0.19", "1777838640653", "2026-05-03 20:08:40.826000", "2026-05-03 20:04:00.653000" ] ], "shape": { "columns": 29, "rows": 12 } }, "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
symbol_extsymbol_astdaily_volume_extdaily_volume_astmin_price_extmin_price_astmin_order_size_extmin_order_size_astmin_lot_size_extmin_lot_size_ast...rh_asset_astnet_mult_x_net_fr_absnet_funding_rate_absnet_funding_ratenext_funding_at_same_timelast_trade_ts_asthourly_dollars_per_1klast_trade_ts_extlast_trade_ts_dt_astlast_trade_ts_dt_ext
0LIT-USDLITUSDT1.530863e+065.573442e+050.00010.000100010111...USDT0.0021130.0000630.000063True1.777839e+122.1117778388935732026-05-03 20:09:15.4912026-05-03 20:08:13.573
1ZEC-USDZECUSDT5.395748e+061.986811e+060.0010.01000.10.0010.10.001...USDT0.0015060.0000850.000085True1.777839e+121.5117778389586812026-05-03 20:09:16.4002026-05-03 20:09:18.681
2ETH-USDETHUSDT6.379490e+072.158012e+080.10.010.010.0010.0010.001...USDT0.0012000.000016-0.000016False1.777839e+121.2017778389434282026-05-03 20:09:19.1712026-05-03 20:09:03.428
3HYPE-USDHYPEUSDT2.557237e+073.517136e+060.0010.001000.10.010.010.01...USDT0.0011140.0000130.000013False1.777839e+121.1117778389413212026-05-03 20:08:46.7072026-05-03 20:09:01.321
5XRP-USDXRPUSDT5.624797e+067.717252e+060.00010.0143100.110.1...USDT0.0008670.0000130.000013False1.777839e+120.8717778388730232026-05-03 20:09:16.0562026-05-03 20:07:53.023
6BNB-USDBNBUSDT3.508321e+067.656350e+060.010.0100.010.010.0010.01...USDT0.0008670.0000130.000013False1.777839e+120.8717778388620182026-05-03 20:09:17.5632026-05-03 20:07:42.018
7DOGE-USDDOGEUSDT2.224083e+061.313191e+070.000010.0024401001101...USDT0.0007800.0000130.000013False1.777839e+120.7817778388618532026-05-03 20:09:18.7452026-05-03 20:07:41.853
9ASTER-USDASTERUSDT3.798975e+053.579841e+070.000010.00010100.0110.01...USDT0.0004870.0000130.000013False1.777839e+120.4917778388616632026-05-03 20:09:16.0772026-05-03 20:07:41.663
10CHIP-USDCHIPUSDT6.015818e+053.690379e+050.0000010.00001001001101...USDT0.0004830.0000530.000053True1.777839e+120.4817778388942612026-05-03 20:07:13.8502026-05-03 20:08:14.261
11SOL-USDSOLUSDT1.099378e+072.819154e+070.010.42000.10.010.010.01...USDT0.0004670.0000070.000007False1.777839e+120.4717778389036812026-05-03 20:09:19.5522026-05-03 20:08:23.681
12BTC-USDBTCUSDT1.906997e+083.317879e+08110.00010.0010.000010.001...USDT0.0004500.000006-0.000006False1.777839e+120.4517778389400172026-05-03 20:09:19.1372026-05-03 20:09:00.017
14WLFI-USDWLFIUSDT1.185166e+052.231255e+060.000010.00010001001101...USDT0.0001860.0000130.000013False1.777839e+120.1917778386406532026-05-03 20:08:40.8262026-05-03 20:04:00.653
\n", "

12 rows × 29 columns

\n", "
" ], "text/plain": [ " symbol_ext symbol_ast daily_volume_ext daily_volume_ast min_price_ext \\\n", "0 LIT-USD LITUSDT 1.530863e+06 5.573442e+05 0.0001 \n", "1 ZEC-USD ZECUSDT 5.395748e+06 1.986811e+06 0.001 \n", "2 ETH-USD ETHUSDT 6.379490e+07 2.158012e+08 0.1 \n", "3 HYPE-USD HYPEUSDT 2.557237e+07 3.517136e+06 0.001 \n", "5 XRP-USD XRPUSDT 5.624797e+06 7.717252e+06 0.0001 \n", "6 BNB-USD BNBUSDT 3.508321e+06 7.656350e+06 0.01 \n", "7 DOGE-USD DOGEUSDT 2.224083e+06 1.313191e+07 0.00001 \n", "9 ASTER-USD ASTERUSDT 3.798975e+05 3.579841e+07 0.00001 \n", "10 CHIP-USD CHIPUSDT 6.015818e+05 3.690379e+05 0.000001 \n", "11 SOL-USD SOLUSDT 1.099378e+07 2.819154e+07 0.01 \n", "12 BTC-USD BTCUSDT 1.906997e+08 3.317879e+08 1 \n", "14 WLFI-USD WLFIUSDT 1.185166e+05 2.231255e+06 0.00001 \n", "\n", " min_price_ast min_order_size_ext min_order_size_ast min_lot_size_ext \\\n", "0 0.0001000 10 1 1 \n", "1 0.0100 0.1 0.001 0.1 \n", "2 0.01 0.01 0.001 0.001 \n", "3 0.00100 0.1 0.01 0.01 \n", "5 0.0143 10 0.1 1 \n", "6 0.010 0.01 0.01 0.001 \n", "7 0.002440 100 1 10 \n", "9 0.00010 10 0.01 1 \n", "10 0.0000100 100 1 10 \n", "11 0.4200 0.1 0.01 0.01 \n", "12 1 0.0001 0.001 0.00001 \n", "14 0.0001000 100 1 10 \n", "\n", " min_lot_size_ast ... rh_asset_ast net_mult_x_net_fr_abs \\\n", "0 1 ... USDT 0.002113 \n", "1 0.001 ... USDT 0.001506 \n", "2 0.001 ... USDT 0.001200 \n", "3 0.01 ... USDT 0.001114 \n", "5 0.1 ... USDT 0.000867 \n", "6 0.01 ... USDT 0.000867 \n", "7 1 ... USDT 0.000780 \n", "9 0.01 ... USDT 0.000487 \n", "10 1 ... USDT 0.000483 \n", "11 0.01 ... USDT 0.000467 \n", "12 0.001 ... USDT 0.000450 \n", "14 1 ... USDT 0.000186 \n", "\n", " net_funding_rate_abs net_funding_rate next_funding_at_same_time \\\n", "0 0.000063 0.000063 True \n", "1 0.000085 0.000085 True \n", "2 0.000016 -0.000016 False \n", "3 0.000013 0.000013 False \n", "5 0.000013 0.000013 False \n", "6 0.000013 0.000013 False \n", "7 0.000013 0.000013 False \n", "9 0.000013 0.000013 False \n", "10 0.000053 0.000053 True \n", "11 0.000007 0.000007 False \n", "12 0.000006 -0.000006 False \n", "14 0.000013 0.000013 False \n", "\n", " last_trade_ts_ast hourly_dollars_per_1k last_trade_ts_ext \\\n", "0 1.777839e+12 2.11 1777838893573 \n", "1 1.777839e+12 1.51 1777838958681 \n", "2 1.777839e+12 1.20 1777838943428 \n", "3 1.777839e+12 1.11 1777838941321 \n", "5 1.777839e+12 0.87 1777838873023 \n", "6 1.777839e+12 0.87 1777838862018 \n", "7 1.777839e+12 0.78 1777838861853 \n", "9 1.777839e+12 0.49 1777838861663 \n", "10 1.777839e+12 0.48 1777838894261 \n", "11 1.777839e+12 0.47 1777838903681 \n", "12 1.777839e+12 0.45 1777838940017 \n", "14 1.777839e+12 0.19 1777838640653 \n", "\n", " last_trade_ts_dt_ast last_trade_ts_dt_ext \n", "0 2026-05-03 20:09:15.491 2026-05-03 20:08:13.573 \n", "1 2026-05-03 20:09:16.400 2026-05-03 20:09:18.681 \n", "2 2026-05-03 20:09:19.171 2026-05-03 20:09:03.428 \n", "3 2026-05-03 20:08:46.707 2026-05-03 20:09:01.321 \n", "5 2026-05-03 20:09:16.056 2026-05-03 20:07:53.023 \n", "6 2026-05-03 20:09:17.563 2026-05-03 20:07:42.018 \n", "7 2026-05-03 20:09:18.745 2026-05-03 20:07:41.853 \n", "9 2026-05-03 20:09:16.077 2026-05-03 20:07:41.663 \n", "10 2026-05-03 20:07:13.850 2026-05-03 20:08:14.261 \n", "11 2026-05-03 20:09:19.552 2026-05-03 20:08:23.681 \n", "12 2026-05-03 20:09:19.137 2026-05-03 20:09:00.017 \n", "14 2026-05-03 20:08:40.826 2026-05-03 20:04:00.653 \n", "\n", "[12 rows x 29 columns]" ] }, "execution_count": 113, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_best_fr_rate" ] }, { "cell_type": "code", "execution_count": null, "id": "bbad7d21", "metadata": {}, "outputs": [], "source": [ "### Candles for Midpoint Dispersion ###\n", "# Aster\n", "import modules.aster_auth as aster_auth\n", "symbol = 'BTCUSDT'\n", "candles = {\n", " \"url\": \"/fapi/v3/klines\",\n", " \"method\": \"GET\",\n", " \"params\": {\n", " 'symbol': symbol,\n", " 'interval': '1m',\n", " 'limit':'1440'\n", " }\n", "}\n", "j = await aster_auth.post_authenticated_url(candles)\n", "df_candles_aster = pd.DataFrame(j, columns=['open_ts','open_px','high_px','low_px','close_px','volume','close_ts','quote_asset_volume','count_trades','taker_buy_base_asset_volume','taker_buy_quote_asset_volume','_drop'])\n", "df_candles_aster" ] }, { "cell_type": "code", "execution_count": null, "id": "421577f1", "metadata": {}, "outputs": [], "source": [ "# Extend\n", "symbol_ext = 'BTC-USD'\n", "params = {\n", " 'interval':'1m',\n", " 'limit':1440,\n", "}\n", "r = json.loads(requests.get(f'https://api.starknet.extended.exchange/api/v1/info/candles/{symbol}/trades', params=params).text)\n", "df_candles_extended = pd.DataFrame(r)\n" ] }, { "cell_type": "code", "execution_count": 14, "id": "f83feeda", "metadata": {}, "outputs": [ { "data": { "application/vnd.microsoft.datawrangler.viewer.v0+json": { "columns": [ { "name": "index", "rawType": "str", "type": "string" }, { "name": "status", "rawType": "str", "type": "string" }, { "name": "error", "rawType": "object", "type": "unknown" } ], "ref": "53323547-ff3c-492b-9d00-eb33883ef6b5", "rows": [ [ "code", "ERROR", "1001" ], [ "message", "ERROR", "Market not found" ] ], "shape": { "columns": 2, "rows": 2 } }, "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
statuserror
codeERROR1001
messageERRORMarket not found
\n", "
" ], "text/plain": [ " status error\n", "code ERROR 1001\n", "message ERROR Market not found" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_candles_extended" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'symbol_ast': 'CHIPUSDT', 'symbol_extended': 'CHIP-USD'}" ] }, "execution_count": 98, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# min_daily_volume = 100_000\n", "# df_best_fr_rate = df_best_fr_rate.loc[ (df_best_fr_rate['daily_volume_ast']>=min_daily_volume) & (df_best_fr_rate['daily_volume_ext']>min_daily_volume) ,:].reset_index(drop=True)\n", "\n", "\n", "best_next_funding_pair = {'symbol_ast':df_best_fr_rate['symbol_ast'][0],'symbol_extended':df_best_fr_rate['symbol_ext'][0]}\n", "best_next_funding_pair" ] }, { "cell_type": "code", "execution_count": 82, "id": "125ee5ed", "metadata": {}, "outputs": [], "source": [ "ASTER = structs.Perpetual_Exchange(\n", " mult = int(df_best_fr_rate['max_leverage_ast'][0]),\n", " lh_asset = df_best_fr_rate['lh_asset_ast'][0],\n", " rh_asset = df_best_fr_rate['rh_asset_ast'][0],\n", " symbol_asset_separator = '',\n", " initial_funding_rate=float(df_best_fr_rate['funding_rate_ast'][0]),\n", " min_price=float(df_best_fr_rate['min_price_ast'][0]),\n", " min_order_size=float(df_best_fr_rate['min_order_size_ast'][0]),\n", " min_lot_size=float(df_best_fr_rate['min_lot_size_ast'][0]),\n", " min_notional=float(df_best_fr_rate['min_notional_ast'][0]),\n", ")\n", " \n", "EXTEND = structs.Perpetual_Exchange(\n", " mult = int(df_best_fr_rate['max_leverage_ext'][0]),\n", " lh_asset = df_best_fr_rate['lh_asset_ext'][0],\n", " rh_asset = df_best_fr_rate['rh_asset_ext'][0],\n", " symbol_asset_separator = '-',\n", " initial_funding_rate=float(df_best_fr_rate['funding_rate_ext'][0]),\n", " min_price=float(df_best_fr_rate['min_price_ext'][0]),\n", " min_order_size=float(df_best_fr_rate['min_order_size_ext'][0]),\n", " min_lot_size=float(df_best_fr_rate['min_lot_size_ext'][0]),\n", " min_notional=float(df_best_fr_rate['min_notional_ext'][0]),\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "185c04e9", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "b7a08468", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "ca6b3810", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "id": "cdcda9a8", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "py_313", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.13" } }, "nbformat": 4, "nbformat_minor": 5 }