diff --git a/projects/crypto-signals/data/arb-scanner/scan_log.json b/projects/crypto-signals/data/arb-scanner/scan_log.json index 091c198..f25ec1b 100644 --- a/projects/crypto-signals/data/arb-scanner/scan_log.json +++ b/projects/crypto-signals/data/arb-scanner/scan_log.json @@ -70401,5 +70401,2718 @@ "timestamp": "2026-02-10T02:16:15.489655+00:00" } ] + }, + { + "timestamp": "2026-02-10T02:18:21.521175+00:00", + "markets_scanned": 20, + "arbs_found": 0, + "opportunities": [ + { + "question": "Bitcoin Up or Down - February 9, 11PM ET", + "hours_left": 2.7, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1002.74, + "down_ask_size": 984.36, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 984.36, + "fillable_profit": -964.72, + "is_arb": false, + "timestamp": "2026-02-10T02:18:12.500200+00:00" + }, + { + "question": "Solana Up or Down - February 9, 9:45PM-10:00PM ET", + "hours_left": 0.7, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11163.02, + "down_ask_size": 10866.78, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10866.78, + "fillable_profit": -10649.97, + "is_arb": false, + "timestamp": "2026-02-10T02:18:12.964648+00:00" + }, + { + "question": "Solana Up or Down - February 9, 10:00PM-10:15PM ET", + "hours_left": 0.95, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10977.53, + "down_ask_size": 10976.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10976.15, + "fillable_profit": -10757.16, + "is_arb": false, + "timestamp": "2026-02-10T02:18:13.487801+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.7, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 17302.25, + "down_ask_size": 16714.76, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16714.76, + "fillable_profit": -16381.28, + "is_arb": false, + "timestamp": "2026-02-10T02:18:13.936741+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.2, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16650.52, + "down_ask_size": 16493.08, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16493.08, + "fillable_profit": -16164.02, + "is_arb": false, + "timestamp": "2026-02-10T02:18:14.437403+00:00" + }, + { + "question": "Solana Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.95, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11033.34, + "down_ask_size": 11018.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 11018.62, + "fillable_profit": -10798.78, + "is_arb": false, + "timestamp": "2026-02-10T02:18:14.874646+00:00" + }, + { + "question": "XRP Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.95, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 9752.18, + "down_ask_size": 9657.79, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 9657.79, + "fillable_profit": -9465.1, + "is_arb": false, + "timestamp": "2026-02-10T02:18:15.341958+00:00" + }, + { + "question": "Solana Up or Down on February 10?", + "hours_left": 14.7, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 39180.72, + "down_ask_size": 38962.68, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 38962.68, + "fillable_profit": -38185.32, + "is_arb": false, + "timestamp": "2026-02-10T02:18:15.773195+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15AM-4:30AM ET", + "hours_left": 7.2, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15448.07, + "down_ask_size": 15430.64, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15430.64, + "fillable_profit": -15122.78, + "is_arb": false, + "timestamp": "2026-02-10T02:18:16.324012+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 6:15AM-6:30AM ET", + "hours_left": 9.2, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16265.33, + "down_ask_size": 16461.31, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16265.33, + "fillable_profit": -15940.81, + "is_arb": false, + "timestamp": "2026-02-10T02:18:16.779043+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 2:15AM-2:30AM ET", + "hours_left": 5.2, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16726.16, + "down_ask_size": 17001.37, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16726.16, + "fillable_profit": -16392.45, + "is_arb": false, + "timestamp": "2026-02-10T02:18:17.304883+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:15AM-8:30AM ET", + "hours_left": 11.2, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15042.97, + "down_ask_size": 15100.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15042.97, + "fillable_profit": -14742.84, + "is_arb": false, + "timestamp": "2026-02-10T02:18:17.750757+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.7, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14958.31, + "down_ask_size": 15364.5, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14958.31, + "fillable_profit": -14659.87, + "is_arb": false, + "timestamp": "2026-02-10T02:18:18.314134+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.7, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1119.88, + "down_ask_size": 2345.0, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1119.88, + "fillable_profit": -1097.54, + "is_arb": false, + "timestamp": "2026-02-10T02:18:18.764067+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 9:45PM-10:00PM ET", + "hours_left": 0.7, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 19282.09, + "down_ask_size": 18697.1, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 18697.1, + "fillable_profit": -18324.07, + "is_arb": false, + "timestamp": "2026-02-10T02:18:19.202837+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15PM-4:30PM ET", + "hours_left": 19.2, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10517.99, + "down_ask_size": 10502.81, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10502.81, + "fillable_profit": -10293.26, + "is_arb": false, + "timestamp": "2026-02-10T02:18:19.646411+00:00" + }, + { + "question": "S&P 500 (SPX) Opens Up or Down on February 10?", + "hours_left": 18.7, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 32136.38, + "down_ask_size": 32185.96, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 32136.38, + "fillable_profit": -31495.21, + "is_arb": false, + "timestamp": "2026-02-10T02:18:20.113993+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 3:45AM-4:00AM ET", + "hours_left": 6.7, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15052.84, + "down_ask_size": 15041.55, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15041.55, + "fillable_profit": -14741.45, + "is_arb": false, + "timestamp": "2026-02-10T02:18:20.578639+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.7, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1239.8, + "down_ask_size": 2326.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1239.8, + "fillable_profit": -1215.06, + "is_arb": false, + "timestamp": "2026-02-10T02:18:21.050292+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:30AM-8:45AM ET", + "hours_left": 11.45, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14996.93, + "down_ask_size": 15092.11, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14996.93, + "fillable_profit": -14697.72, + "is_arb": false, + "timestamp": "2026-02-10T02:18:21.500067+00:00" + } + ] + }, + { + "timestamp": "2026-02-10T02:20:19.955866+00:00", + "markets_scanned": 20, + "arbs_found": 0, + "opportunities": [ + { + "question": "Bitcoin Up or Down - February 9, 11PM ET", + "hours_left": 2.66, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1002.74, + "down_ask_size": 984.36, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 984.36, + "fillable_profit": -964.72, + "is_arb": false, + "timestamp": "2026-02-10T02:20:10.685887+00:00" + }, + { + "question": "Solana Up or Down - February 9, 10:00PM-10:15PM ET", + "hours_left": 0.91, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10977.53, + "down_ask_size": 10976.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10976.15, + "fillable_profit": -10757.16, + "is_arb": false, + "timestamp": "2026-02-10T02:20:11.163080+00:00" + }, + { + "question": "Solana Up or Down - February 9, 9:45PM-10:00PM ET", + "hours_left": 0.66, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11163.02, + "down_ask_size": 10866.78, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10866.78, + "fillable_profit": -10649.97, + "is_arb": false, + "timestamp": "2026-02-10T02:20:11.610704+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.66, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 17302.25, + "down_ask_size": 16714.76, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16714.76, + "fillable_profit": -16381.28, + "is_arb": false, + "timestamp": "2026-02-10T02:20:12.136242+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.16, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16750.52, + "down_ask_size": 16593.08, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16593.08, + "fillable_profit": -16262.02, + "is_arb": false, + "timestamp": "2026-02-10T02:20:12.609159+00:00" + }, + { + "question": "Solana Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.91, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11033.34, + "down_ask_size": 11018.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 11018.62, + "fillable_profit": -10798.78, + "is_arb": false, + "timestamp": "2026-02-10T02:20:13.086854+00:00" + }, + { + "question": "XRP Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.91, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 9752.18, + "down_ask_size": 9657.79, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 9657.79, + "fillable_profit": -9465.1, + "is_arb": false, + "timestamp": "2026-02-10T02:20:13.559079+00:00" + }, + { + "question": "Solana Up or Down on February 10?", + "hours_left": 14.66, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 39180.72, + "down_ask_size": 38962.68, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 38962.68, + "fillable_profit": -38185.32, + "is_arb": false, + "timestamp": "2026-02-10T02:20:14.047150+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15AM-4:30AM ET", + "hours_left": 7.16, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15448.07, + "down_ask_size": 15430.64, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15430.64, + "fillable_profit": -15122.78, + "is_arb": false, + "timestamp": "2026-02-10T02:20:14.489850+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 6:15AM-6:30AM ET", + "hours_left": 9.16, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16265.33, + "down_ask_size": 16461.31, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16265.33, + "fillable_profit": -15940.81, + "is_arb": false, + "timestamp": "2026-02-10T02:20:14.962936+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 2:15AM-2:30AM ET", + "hours_left": 5.16, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16726.16, + "down_ask_size": 17001.37, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16726.16, + "fillable_profit": -16392.45, + "is_arb": false, + "timestamp": "2026-02-10T02:20:15.473694+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:15AM-8:30AM ET", + "hours_left": 11.16, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15042.97, + "down_ask_size": 15100.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15042.97, + "fillable_profit": -14742.84, + "is_arb": false, + "timestamp": "2026-02-10T02:20:15.931163+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.66, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14958.31, + "down_ask_size": 15364.43, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14958.31, + "fillable_profit": -14659.87, + "is_arb": false, + "timestamp": "2026-02-10T02:20:16.492794+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.66, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1119.88, + "down_ask_size": 2345.0, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1119.88, + "fillable_profit": -1097.54, + "is_arb": false, + "timestamp": "2026-02-10T02:20:17.050019+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 9:45PM-10:00PM ET", + "hours_left": 0.66, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 19382.09, + "down_ask_size": 18797.1, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 18797.1, + "fillable_profit": -18422.07, + "is_arb": false, + "timestamp": "2026-02-10T02:20:17.489901+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15PM-4:30PM ET", + "hours_left": 19.16, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10517.99, + "down_ask_size": 10502.81, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10502.81, + "fillable_profit": -10293.26, + "is_arb": false, + "timestamp": "2026-02-10T02:20:18.002691+00:00" + }, + { + "question": "S&P 500 (SPX) Opens Up or Down on February 10?", + "hours_left": 18.66, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 32136.38, + "down_ask_size": 32185.96, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 32136.38, + "fillable_profit": -31495.21, + "is_arb": false, + "timestamp": "2026-02-10T02:20:18.484539+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 3:45AM-4:00AM ET", + "hours_left": 6.66, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15052.84, + "down_ask_size": 15041.55, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15041.55, + "fillable_profit": -14741.45, + "is_arb": false, + "timestamp": "2026-02-10T02:20:19.010677+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.66, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1239.8, + "down_ask_size": 2326.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1239.8, + "fillable_profit": -1215.06, + "is_arb": false, + "timestamp": "2026-02-10T02:20:19.479711+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:30AM-8:45AM ET", + "hours_left": 11.41, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14996.93, + "down_ask_size": 15092.11, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14996.93, + "fillable_profit": -14697.72, + "is_arb": false, + "timestamp": "2026-02-10T02:20:19.935886+00:00" + } + ] + }, + { + "timestamp": "2026-02-10T02:22:18.956834+00:00", + "markets_scanned": 20, + "arbs_found": 0, + "opportunities": [ + { + "question": "Bitcoin Up or Down - February 9, 11PM ET", + "hours_left": 2.63, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1002.74, + "down_ask_size": 984.36, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 984.36, + "fillable_profit": -964.72, + "is_arb": false, + "timestamp": "2026-02-10T02:22:09.800644+00:00" + }, + { + "question": "Solana Up or Down - February 9, 10:00PM-10:15PM ET", + "hours_left": 0.88, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10990.3, + "down_ask_size": 10977.3, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10977.3, + "fillable_profit": -10758.29, + "is_arb": false, + "timestamp": "2026-02-10T02:22:10.329113+00:00" + }, + { + "question": "Solana Up or Down - February 9, 9:45PM-10:00PM ET", + "hours_left": 0.63, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11163.02, + "down_ask_size": 10866.78, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10866.78, + "fillable_profit": -10649.97, + "is_arb": false, + "timestamp": "2026-02-10T02:22:10.796578+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.63, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 17502.25, + "down_ask_size": 16914.76, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16914.76, + "fillable_profit": -16577.29, + "is_arb": false, + "timestamp": "2026-02-10T02:22:11.356202+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.13, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16950.52, + "down_ask_size": 16793.08, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16793.08, + "fillable_profit": -16458.03, + "is_arb": false, + "timestamp": "2026-02-10T02:22:11.821899+00:00" + }, + { + "question": "Solana Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.88, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11033.34, + "down_ask_size": 11018.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 11018.62, + "fillable_profit": -10798.78, + "is_arb": false, + "timestamp": "2026-02-10T02:22:12.330294+00:00" + }, + { + "question": "XRP Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.88, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 9752.18, + "down_ask_size": 9657.79, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 9657.79, + "fillable_profit": -9465.1, + "is_arb": false, + "timestamp": "2026-02-10T02:22:12.780598+00:00" + }, + { + "question": "Solana Up or Down on February 10?", + "hours_left": 14.63, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 39180.72, + "down_ask_size": 38962.68, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 38962.68, + "fillable_profit": -38185.32, + "is_arb": false, + "timestamp": "2026-02-10T02:22:13.328475+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15AM-4:30AM ET", + "hours_left": 7.13, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15448.07, + "down_ask_size": 15430.64, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15430.64, + "fillable_profit": -15122.78, + "is_arb": false, + "timestamp": "2026-02-10T02:22:13.795493+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 6:15AM-6:30AM ET", + "hours_left": 9.13, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16265.33, + "down_ask_size": 16461.31, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16265.33, + "fillable_profit": -15940.81, + "is_arb": false, + "timestamp": "2026-02-10T02:22:14.276715+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 2:15AM-2:30AM ET", + "hours_left": 5.13, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16726.16, + "down_ask_size": 17001.37, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16726.16, + "fillable_profit": -16392.45, + "is_arb": false, + "timestamp": "2026-02-10T02:22:14.734625+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:15AM-8:30AM ET", + "hours_left": 11.13, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15037.97, + "down_ask_size": 15095.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15037.97, + "fillable_profit": -14737.94, + "is_arb": false, + "timestamp": "2026-02-10T02:22:15.202971+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.63, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14958.31, + "down_ask_size": 15364.43, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14958.31, + "fillable_profit": -14659.87, + "is_arb": false, + "timestamp": "2026-02-10T02:22:15.635032+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.63, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1119.88, + "down_ask_size": 2345.0, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1119.88, + "fillable_profit": -1097.54, + "is_arb": false, + "timestamp": "2026-02-10T02:22:16.083429+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 9:45PM-10:00PM ET", + "hours_left": 0.63, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 19582.09, + "down_ask_size": 18997.1, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 18997.1, + "fillable_profit": -18618.08, + "is_arb": false, + "timestamp": "2026-02-10T02:22:16.565133+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15PM-4:30PM ET", + "hours_left": 19.13, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10517.99, + "down_ask_size": 10502.81, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10502.81, + "fillable_profit": -10293.26, + "is_arb": false, + "timestamp": "2026-02-10T02:22:17.075940+00:00" + }, + { + "question": "S&P 500 (SPX) Opens Up or Down on February 10?", + "hours_left": 18.63, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 32136.38, + "down_ask_size": 32185.96, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 32136.38, + "fillable_profit": -31495.21, + "is_arb": false, + "timestamp": "2026-02-10T02:22:17.524903+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 3:45AM-4:00AM ET", + "hours_left": 6.63, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15052.84, + "down_ask_size": 15041.55, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15041.55, + "fillable_profit": -14741.45, + "is_arb": false, + "timestamp": "2026-02-10T02:22:18.007897+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.63, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1239.8, + "down_ask_size": 2326.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1239.8, + "fillable_profit": -1215.06, + "is_arb": false, + "timestamp": "2026-02-10T02:22:18.484681+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:30AM-8:45AM ET", + "hours_left": 11.38, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14996.93, + "down_ask_size": 15092.11, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14996.93, + "fillable_profit": -14697.72, + "is_arb": false, + "timestamp": "2026-02-10T02:22:18.935563+00:00" + } + ] + }, + { + "timestamp": "2026-02-10T02:24:22.200543+00:00", + "markets_scanned": 20, + "arbs_found": 0, + "opportunities": [ + { + "question": "Bitcoin Up or Down - February 9, 11PM ET", + "hours_left": 2.6, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1002.74, + "down_ask_size": 984.36, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 984.36, + "fillable_profit": -964.72, + "is_arb": false, + "timestamp": "2026-02-10T02:24:12.961598+00:00" + }, + { + "question": "Solana Up or Down - February 9, 10:00PM-10:15PM ET", + "hours_left": 0.85, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10990.3, + "down_ask_size": 10977.34, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10977.34, + "fillable_profit": -10758.33, + "is_arb": false, + "timestamp": "2026-02-10T02:24:13.488126+00:00" + }, + { + "question": "Solana Up or Down - February 9, 9:45PM-10:00PM ET", + "hours_left": 0.6, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11163.02, + "down_ask_size": 10866.78, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10866.78, + "fillable_profit": -10649.97, + "is_arb": false, + "timestamp": "2026-02-10T02:24:13.931461+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10PM ET", + "hours_left": 1.6, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 621.73, + "down_ask_size": 595.83, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 595.83, + "fillable_profit": -583.94, + "is_arb": false, + "timestamp": "2026-02-10T02:24:14.393856+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.6, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 17502.25, + "down_ask_size": 16914.76, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16914.76, + "fillable_profit": -16577.29, + "is_arb": false, + "timestamp": "2026-02-10T02:24:14.965301+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.1, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16950.52, + "down_ask_size": 16793.08, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16793.08, + "fillable_profit": -16458.03, + "is_arb": false, + "timestamp": "2026-02-10T02:24:15.483319+00:00" + }, + { + "question": "Solana Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.85, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11033.34, + "down_ask_size": 11018.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 11018.62, + "fillable_profit": -10798.78, + "is_arb": false, + "timestamp": "2026-02-10T02:24:15.934750+00:00" + }, + { + "question": "XRP Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.85, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 9752.18, + "down_ask_size": 9657.79, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 9657.79, + "fillable_profit": -9465.1, + "is_arb": false, + "timestamp": "2026-02-10T02:24:16.395844+00:00" + }, + { + "question": "Solana Up or Down on February 10?", + "hours_left": 14.6, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 39180.72, + "down_ask_size": 38962.68, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 38962.68, + "fillable_profit": -38185.32, + "is_arb": false, + "timestamp": "2026-02-10T02:24:16.863546+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.6, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1233.0, + "down_ask_size": 2326.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1233.0, + "fillable_profit": -1208.4, + "is_arb": false, + "timestamp": "2026-02-10T02:24:17.342594+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15AM-4:30AM ET", + "hours_left": 7.1, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15448.07, + "down_ask_size": 15430.64, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15430.64, + "fillable_profit": -15122.78, + "is_arb": false, + "timestamp": "2026-02-10T02:24:17.826856+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.6, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1119.88, + "down_ask_size": 2345.0, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1119.88, + "fillable_profit": -1097.54, + "is_arb": false, + "timestamp": "2026-02-10T02:24:18.326557+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:15AM-8:30AM ET", + "hours_left": 11.1, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15037.97, + "down_ask_size": 15095.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15037.97, + "fillable_profit": -14737.94, + "is_arb": false, + "timestamp": "2026-02-10T02:24:18.792961+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 6:15AM-6:30AM ET", + "hours_left": 9.1, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16465.33, + "down_ask_size": 16661.31, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16465.33, + "fillable_profit": -16136.82, + "is_arb": false, + "timestamp": "2026-02-10T02:24:19.338102+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 2:15AM-2:30AM ET", + "hours_left": 5.1, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16926.16, + "down_ask_size": 17201.37, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16926.16, + "fillable_profit": -16588.46, + "is_arb": false, + "timestamp": "2026-02-10T02:24:19.807600+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.6, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14958.31, + "down_ask_size": 15364.43, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14958.31, + "fillable_profit": -14659.87, + "is_arb": false, + "timestamp": "2026-02-10T02:24:20.307594+00:00" + }, + { + "question": "S&P 500 (SPX) Opens Up or Down on February 10?", + "hours_left": 18.6, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 32136.38, + "down_ask_size": 32185.96, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 32136.38, + "fillable_profit": -31495.21, + "is_arb": false, + "timestamp": "2026-02-10T02:24:20.803068+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15PM-4:30PM ET", + "hours_left": 19.1, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10517.99, + "down_ask_size": 10502.81, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10502.81, + "fillable_profit": -10293.26, + "is_arb": false, + "timestamp": "2026-02-10T02:24:21.259444+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 3:45AM-4:00AM ET", + "hours_left": 6.6, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15052.84, + "down_ask_size": 15041.55, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15041.55, + "fillable_profit": -14741.45, + "is_arb": false, + "timestamp": "2026-02-10T02:24:21.711384+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:30AM-8:45AM ET", + "hours_left": 11.35, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14996.93, + "down_ask_size": 15092.11, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14996.93, + "fillable_profit": -14697.72, + "is_arb": false, + "timestamp": "2026-02-10T02:24:22.179789+00:00" + } + ] + }, + { + "timestamp": "2026-02-10T02:26:12.988755+00:00", + "markets_scanned": 20, + "arbs_found": 0, + "opportunities": [ + { + "question": "Bitcoin Up or Down - February 9, 11PM ET", + "hours_left": 2.57, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1002.74, + "down_ask_size": 984.36, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 984.36, + "fillable_profit": -964.72, + "is_arb": false, + "timestamp": "2026-02-10T02:26:03.765952+00:00" + }, + { + "question": "Solana Up or Down - February 9, 10:00PM-10:15PM ET", + "hours_left": 0.82, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10990.3, + "down_ask_size": 10975.74, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10975.74, + "fillable_profit": -10756.76, + "is_arb": false, + "timestamp": "2026-02-10T02:26:04.322842+00:00" + }, + { + "question": "Solana Up or Down - February 9, 9:45PM-10:00PM ET", + "hours_left": 0.57, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11142.89, + "down_ask_size": 10866.78, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10866.78, + "fillable_profit": -10649.97, + "is_arb": false, + "timestamp": "2026-02-10T02:26:04.785896+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10PM ET", + "hours_left": 1.57, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 621.73, + "down_ask_size": 605.26, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 605.26, + "fillable_profit": -593.18, + "is_arb": false, + "timestamp": "2026-02-10T02:26:05.262792+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.57, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 17502.25, + "down_ask_size": 16914.76, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16914.76, + "fillable_profit": -16577.29, + "is_arb": false, + "timestamp": "2026-02-10T02:26:05.712870+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.07, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16950.52, + "down_ask_size": 16793.08, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16793.08, + "fillable_profit": -16458.03, + "is_arb": false, + "timestamp": "2026-02-10T02:26:06.163653+00:00" + }, + { + "question": "Solana Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.82, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11033.34, + "down_ask_size": 11018.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 11018.62, + "fillable_profit": -10798.78, + "is_arb": false, + "timestamp": "2026-02-10T02:26:06.628913+00:00" + }, + { + "question": "XRP Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.82, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 9752.18, + "down_ask_size": 9657.79, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 9657.79, + "fillable_profit": -9465.1, + "is_arb": false, + "timestamp": "2026-02-10T02:26:07.090079+00:00" + }, + { + "question": "Solana Up or Down on February 10?", + "hours_left": 14.57, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 39180.72, + "down_ask_size": 38962.68, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 38962.68, + "fillable_profit": -38185.32, + "is_arb": false, + "timestamp": "2026-02-10T02:26:07.601767+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.57, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1233.0, + "down_ask_size": 2326.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1233.0, + "fillable_profit": -1208.4, + "is_arb": false, + "timestamp": "2026-02-10T02:26:08.055377+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15AM-4:30AM ET", + "hours_left": 7.07, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15448.07, + "down_ask_size": 15430.64, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15430.64, + "fillable_profit": -15122.78, + "is_arb": false, + "timestamp": "2026-02-10T02:26:08.537538+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.57, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1119.88, + "down_ask_size": 2245.0, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1119.88, + "fillable_profit": -1097.54, + "is_arb": false, + "timestamp": "2026-02-10T02:26:08.979150+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:15AM-8:30AM ET", + "hours_left": 11.07, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15237.97, + "down_ask_size": 15295.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15237.97, + "fillable_profit": -14933.95, + "is_arb": false, + "timestamp": "2026-02-10T02:26:09.486890+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 6:15AM-6:30AM ET", + "hours_left": 9.07, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16465.33, + "down_ask_size": 16661.31, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16465.33, + "fillable_profit": -16136.82, + "is_arb": false, + "timestamp": "2026-02-10T02:26:09.951807+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 2:15AM-2:30AM ET", + "hours_left": 5.07, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16926.16, + "down_ask_size": 17201.37, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16926.16, + "fillable_profit": -16588.46, + "is_arb": false, + "timestamp": "2026-02-10T02:26:10.486960+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.57, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14958.31, + "down_ask_size": 15364.43, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14958.31, + "fillable_profit": -14659.87, + "is_arb": false, + "timestamp": "2026-02-10T02:26:10.956880+00:00" + }, + { + "question": "S&P 500 (SPX) Opens Up or Down on February 10?", + "hours_left": 18.57, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 12136.38, + "down_ask_size": 32186.0, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 12136.38, + "fillable_profit": -11894.24, + "is_arb": false, + "timestamp": "2026-02-10T02:26:11.498733+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15PM-4:30PM ET", + "hours_left": 19.07, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10517.99, + "down_ask_size": 10502.81, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10502.81, + "fillable_profit": -10293.26, + "is_arb": false, + "timestamp": "2026-02-10T02:26:11.945601+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 3:45AM-4:00AM ET", + "hours_left": 6.57, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15052.84, + "down_ask_size": 15041.55, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15041.55, + "fillable_profit": -14741.45, + "is_arb": false, + "timestamp": "2026-02-10T02:26:12.492160+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:30AM-8:45AM ET", + "hours_left": 11.32, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15196.93, + "down_ask_size": 15292.11, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15196.93, + "fillable_profit": -14893.73, + "is_arb": false, + "timestamp": "2026-02-10T02:26:12.966837+00:00" + } + ] + }, + { + "timestamp": "2026-02-10T02:28:23.128112+00:00", + "markets_scanned": 24, + "arbs_found": 0, + "opportunities": [ + { + "question": "Bitcoin Up or Down - February 9, 11PM ET", + "hours_left": 2.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1002.74, + "down_ask_size": 984.36, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 984.36, + "fillable_profit": -964.72, + "is_arb": false, + "timestamp": "2026-02-10T02:28:11.985854+00:00" + }, + { + "question": "Solana Up or Down - February 9, 10:00PM-10:15PM ET", + "hours_left": 0.78, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10990.3, + "down_ask_size": 10975.74, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10975.74, + "fillable_profit": -10756.76, + "is_arb": false, + "timestamp": "2026-02-10T02:28:12.492031+00:00" + }, + { + "question": "Solana Up or Down - February 9, 9:45PM-10:00PM ET", + "hours_left": 0.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11163.03, + "down_ask_size": 10866.78, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10866.78, + "fillable_profit": -10649.97, + "is_arb": false, + "timestamp": "2026-02-10T02:28:12.961194+00:00" + }, + { + "question": "Solana Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.03, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10977.61, + "down_ask_size": 10961.41, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10961.41, + "fillable_profit": -10742.71, + "is_arb": false, + "timestamp": "2026-02-10T02:28:13.537101+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.03, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15118.1, + "down_ask_size": 15103.04, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15103.04, + "fillable_profit": -14801.71, + "is_arb": false, + "timestamp": "2026-02-10T02:28:14.009412+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10PM ET", + "hours_left": 1.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 621.73, + "down_ask_size": 601.82, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 601.82, + "fillable_profit": -589.81, + "is_arb": false, + "timestamp": "2026-02-10T02:28:14.476651+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 17502.25, + "down_ask_size": 16914.76, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16914.76, + "fillable_profit": -16577.29, + "is_arb": false, + "timestamp": "2026-02-10T02:28:14.939942+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.03, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 17050.52, + "down_ask_size": 16893.08, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16893.08, + "fillable_profit": -16556.04, + "is_arb": false, + "timestamp": "2026-02-10T02:28:15.464584+00:00" + }, + { + "question": "Solana Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.78, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11033.34, + "down_ask_size": 11018.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 11018.62, + "fillable_profit": -10798.78, + "is_arb": false, + "timestamp": "2026-02-10T02:28:15.951084+00:00" + }, + { + "question": "XRP Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.78, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 9752.18, + "down_ask_size": 9657.79, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 9657.79, + "fillable_profit": -9465.1, + "is_arb": false, + "timestamp": "2026-02-10T02:28:16.523419+00:00" + }, + { + "question": "Solana Up or Down on February 10?", + "hours_left": 14.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 39180.72, + "down_ask_size": 38962.68, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 38962.68, + "fillable_profit": -38185.32, + "is_arb": false, + "timestamp": "2026-02-10T02:28:16.970779+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1132.0, + "down_ask_size": 2326.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1132.0, + "fillable_profit": -1109.41, + "is_arb": false, + "timestamp": "2026-02-10T02:28:17.473517+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15AM-4:30AM ET", + "hours_left": 7.03, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15448.07, + "down_ask_size": 15430.64, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15430.64, + "fillable_profit": -15122.78, + "is_arb": false, + "timestamp": "2026-02-10T02:28:17.931527+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1119.88, + "down_ask_size": 2345.0, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1119.88, + "fillable_profit": -1097.54, + "is_arb": false, + "timestamp": "2026-02-10T02:28:18.407702+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:15AM-8:30AM ET", + "hours_left": 11.03, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15242.97, + "down_ask_size": 15300.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15242.97, + "fillable_profit": -14938.85, + "is_arb": false, + "timestamp": "2026-02-10T02:28:18.860200+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 6:15AM-6:30AM ET", + "hours_left": 9.03, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16465.33, + "down_ask_size": 16661.31, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16465.33, + "fillable_profit": -16136.82, + "is_arb": false, + "timestamp": "2026-02-10T02:28:19.344540+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 2:15AM-2:30AM ET", + "hours_left": 5.03, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16926.16, + "down_ask_size": 17200.72, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16926.16, + "fillable_profit": -16588.46, + "is_arb": false, + "timestamp": "2026-02-10T02:28:19.801134+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14958.31, + "down_ask_size": 15364.43, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14958.31, + "fillable_profit": -14659.87, + "is_arb": false, + "timestamp": "2026-02-10T02:28:20.330826+00:00" + }, + { + "question": "S&P 500 (SPX) Opens Up or Down on February 10?", + "hours_left": 18.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 32136.38, + "down_ask_size": 32186.0, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 32136.38, + "fillable_profit": -31495.21, + "is_arb": false, + "timestamp": "2026-02-10T02:28:20.789560+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15PM-4:30PM ET", + "hours_left": 19.03, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10517.99, + "down_ask_size": 10502.81, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10502.81, + "fillable_profit": -10293.26, + "is_arb": false, + "timestamp": "2026-02-10T02:28:21.262930+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 3:45AM-4:00AM ET", + "hours_left": 6.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15052.84, + "down_ask_size": 15041.55, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15041.55, + "fillable_profit": -14741.45, + "is_arb": false, + "timestamp": "2026-02-10T02:28:21.737499+00:00" + }, + { + "question": "Solana Up or Down - February 10, 2AM ET", + "hours_left": 5.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 359.98, + "down_ask_size": 499.99, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 359.98, + "fillable_profit": -352.8, + "is_arb": false, + "timestamp": "2026-02-10T02:28:22.181717+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:30AM-8:45AM ET", + "hours_left": 11.28, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15196.93, + "down_ask_size": 15292.11, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15196.93, + "fillable_profit": -14893.73, + "is_arb": false, + "timestamp": "2026-02-10T02:28:22.636324+00:00" + }, + { + "question": "XRP Up or Down - February 9, 9PM ET", + "hours_left": 0.53, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 523.52, + "down_ask_size": 487.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 487.15, + "fillable_profit": -477.43, + "is_arb": false, + "timestamp": "2026-02-10T02:28:23.103901+00:00" + } + ] + }, + { + "timestamp": "2026-02-10T02:30:19.006285+00:00", + "markets_scanned": 24, + "arbs_found": 0, + "opportunities": [ + { + "question": "Bitcoin Up or Down - February 9, 11PM ET", + "hours_left": 2.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1002.74, + "down_ask_size": 984.36, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 984.36, + "fillable_profit": -964.72, + "is_arb": false, + "timestamp": "2026-02-10T02:30:07.804197+00:00" + }, + { + "question": "Solana Up or Down - February 9, 10:00PM-10:15PM ET", + "hours_left": 0.75, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10990.3, + "down_ask_size": 10975.74, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10975.74, + "fillable_profit": -10756.76, + "is_arb": false, + "timestamp": "2026-02-10T02:30:08.314361+00:00" + }, + { + "question": "Solana Up or Down - February 9, 9:45PM-10:00PM ET", + "hours_left": 0.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 20781.02, + "down_ask_size": 20484.77, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 20484.77, + "fillable_profit": -20076.07, + "is_arb": false, + "timestamp": "2026-02-10T02:30:08.771857+00:00" + }, + { + "question": "Solana Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.0, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10977.61, + "down_ask_size": 10961.41, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10961.41, + "fillable_profit": -10742.71, + "is_arb": false, + "timestamp": "2026-02-10T02:30:09.330659+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.0, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15096.69, + "down_ask_size": 15103.04, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15096.69, + "fillable_profit": -14795.49, + "is_arb": false, + "timestamp": "2026-02-10T02:30:09.783347+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10PM ET", + "hours_left": 1.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 616.09, + "down_ask_size": 601.82, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 601.82, + "fillable_profit": -589.81, + "is_arb": false, + "timestamp": "2026-02-10T02:30:10.325973+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 17502.25, + "down_ask_size": 16914.76, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16914.76, + "fillable_profit": -16577.29, + "is_arb": false, + "timestamp": "2026-02-10T02:30:10.819436+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 10:15PM-10:30PM ET", + "hours_left": 1.0, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 17050.52, + "down_ask_size": 16893.08, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16893.08, + "fillable_profit": -16556.04, + "is_arb": false, + "timestamp": "2026-02-10T02:30:11.326769+00:00" + }, + { + "question": "Solana Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.75, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 11033.34, + "down_ask_size": 11018.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 11018.62, + "fillable_profit": -10798.78, + "is_arb": false, + "timestamp": "2026-02-10T02:30:11.802777+00:00" + }, + { + "question": "XRP Up or Down - February 10, 12:00AM-12:15AM ET", + "hours_left": 2.75, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 9752.18, + "down_ask_size": 9657.79, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 9657.79, + "fillable_profit": -9465.1, + "is_arb": false, + "timestamp": "2026-02-10T02:30:12.330613+00:00" + }, + { + "question": "Solana Up or Down on February 10?", + "hours_left": 14.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 39180.72, + "down_ask_size": 38962.68, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 38962.68, + "fillable_profit": -38185.32, + "is_arb": false, + "timestamp": "2026-02-10T02:30:12.795484+00:00" + }, + { + "question": "Bitcoin Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1138.79, + "down_ask_size": 2326.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1138.79, + "fillable_profit": -1116.07, + "is_arb": false, + "timestamp": "2026-02-10T02:30:13.278534+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15AM-4:30AM ET", + "hours_left": 7.0, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15448.07, + "down_ask_size": 15430.64, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15430.64, + "fillable_profit": -15122.78, + "is_arb": false, + "timestamp": "2026-02-10T02:30:13.738077+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 8:00PM-12:00AM ET", + "hours_left": 2.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 1119.88, + "down_ask_size": 2245.0, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 1119.88, + "fillable_profit": -1097.54, + "is_arb": false, + "timestamp": "2026-02-10T02:30:14.204527+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:15AM-8:30AM ET", + "hours_left": 11.0, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15242.97, + "down_ask_size": 15300.62, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15242.97, + "fillable_profit": -14938.85, + "is_arb": false, + "timestamp": "2026-02-10T02:30:14.676848+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 6:15AM-6:30AM ET", + "hours_left": 9.0, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16470.33, + "down_ask_size": 16666.31, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16470.33, + "fillable_profit": -16141.72, + "is_arb": false, + "timestamp": "2026-02-10T02:30:15.132661+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 2:15AM-2:30AM ET", + "hours_left": 5.0, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 16926.16, + "down_ask_size": 17200.72, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 16926.16, + "fillable_profit": -16588.46, + "is_arb": false, + "timestamp": "2026-02-10T02:30:15.586755+00:00" + }, + { + "question": "Ethereum Up or Down - February 9, 10:45PM-11:00PM ET", + "hours_left": 1.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 14958.17, + "down_ask_size": 15364.43, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 14958.17, + "fillable_profit": -14659.73, + "is_arb": false, + "timestamp": "2026-02-10T02:30:16.024745+00:00" + }, + { + "question": "S&P 500 (SPX) Opens Up or Down on February 10?", + "hours_left": 18.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 32136.38, + "down_ask_size": 32186.0, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 32136.38, + "fillable_profit": -31495.21, + "is_arb": false, + "timestamp": "2026-02-10T02:30:16.486745+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 4:15PM-4:30PM ET", + "hours_left": 19.0, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 10517.99, + "down_ask_size": 10502.81, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 10502.81, + "fillable_profit": -10293.26, + "is_arb": false, + "timestamp": "2026-02-10T02:30:16.945508+00:00" + }, + { + "question": "Ethereum Up or Down - February 10, 3:45AM-4:00AM ET", + "hours_left": 6.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15052.84, + "down_ask_size": 15041.55, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15041.55, + "fillable_profit": -14741.45, + "is_arb": false, + "timestamp": "2026-02-10T02:30:17.595066+00:00" + }, + { + "question": "Solana Up or Down - February 10, 2AM ET", + "hours_left": 5.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 359.98, + "down_ask_size": 499.99, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 359.98, + "fillable_profit": -352.8, + "is_arb": false, + "timestamp": "2026-02-10T02:30:18.039359+00:00" + }, + { + "question": "Bitcoin Up or Down - February 10, 8:30AM-8:45AM ET", + "hours_left": 11.25, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 15196.93, + "down_ask_size": 15292.11, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 15196.93, + "fillable_profit": -14893.73, + "is_arb": false, + "timestamp": "2026-02-10T02:30:18.522521+00:00" + }, + { + "question": "XRP Up or Down - February 9, 9PM ET", + "hours_left": 0.5, + "up_ask": 0.99, + "down_ask": 0.99, + "up_ask_size": 523.52, + "down_ask_size": 487.15, + "combined": 1.98, + "fee_up_per_100": 0.0024, + "fee_down_per_100": 0.0024, + "total_fees_per_100": 0.0049, + "net_profit_per_100": -98.0, + "net_profit_pct": -49.5, + "fillable_shares": 487.15, + "fillable_profit": -477.43, + "is_arb": false, + "timestamp": "2026-02-10T02:30:18.984136+00:00" + } + ] } ] \ No newline at end of file diff --git a/projects/crypto-signals/data/leverage-game/games/1ac7d29c/game.json b/projects/crypto-signals/data/leverage-game/games/1ac7d29c/game.json new file mode 100644 index 0000000..7325717 --- /dev/null +++ b/projects/crypto-signals/data/leverage-game/games/1ac7d29c/game.json @@ -0,0 +1,16 @@ +{ + "game_id": "1ac7d29c", + "name": "Leverage Challenge", + "starting_cash": 10000.0, + "max_leverage": 20, + "funding_rate_8h": 0.01, + "maker_fee": 0.02, + "taker_fee": 0.05, + "start_date": "2026-02-09", + "creator": "case", + "created_at": "2026-02-10T02:31:27.614107+00:00", + "players": [ + "case" + ], + "status": "active" +} \ No newline at end of file diff --git a/projects/crypto-signals/data/leverage-game/games/1ac7d29c/players/case/portfolio.json b/projects/crypto-signals/data/leverage-game/games/1ac7d29c/players/case/portfolio.json new file mode 100644 index 0000000..55b48eb --- /dev/null +++ b/projects/crypto-signals/data/leverage-game/games/1ac7d29c/players/case/portfolio.json @@ -0,0 +1,7 @@ +{ + "cash": 10000.0, + "positions": {}, + "total_realized_pnl": 0, + "total_fees_paid": 0, + "total_funding_paid": 0 +} \ No newline at end of file diff --git a/projects/crypto-signals/data/leverage-game/games/1ac7d29c/players/case/snapshots.json b/projects/crypto-signals/data/leverage-game/games/1ac7d29c/players/case/snapshots.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/projects/crypto-signals/data/leverage-game/games/1ac7d29c/players/case/snapshots.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/projects/crypto-signals/data/leverage-game/games/1ac7d29c/players/case/trades.json b/projects/crypto-signals/data/leverage-game/games/1ac7d29c/players/case/trades.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/projects/crypto-signals/data/leverage-game/games/1ac7d29c/players/case/trades.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/projects/crypto-signals/data/leverage-game/trader_state.json b/projects/crypto-signals/data/leverage-game/trader_state.json new file mode 100644 index 0000000..870c317 --- /dev/null +++ b/projects/crypto-signals/data/leverage-game/trader_state.json @@ -0,0 +1,4 @@ +{ + "peak_pnl": {}, + "last_alert": null +} \ No newline at end of file diff --git a/projects/crypto-signals/data/short-scanner/scan_log.json b/projects/crypto-signals/data/short-scanner/scan_log.json new file mode 100644 index 0000000..7619420 --- /dev/null +++ b/projects/crypto-signals/data/short-scanner/scan_log.json @@ -0,0 +1,487 @@ +[ + { + "timestamp": "2026-02-10T02:31:38.063585+00:00", + "coins_scanned": 29, + "strong_signals": 0, + "results": [ + { + "symbol": "FIL", + "price": 0.954, + "rsi": 61.7, + "vwap_pct": 9.0, + "macd_histogram": -0.932576, + "bb_position": 0.76, + "change_24h": 0.74, + "change_4h": 0.0, + "vol_trend": 0.05, + "score": 40, + "reasons": [ + "RSI mildly elevated (61.7)", + "Well above VWAP (+9.0%)", + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:34.839978+00:00" + }, + { + "symbol": "NEAR", + "price": 1.045, + "rsi": 60.0, + "vwap_pct": 1.62, + "macd_histogram": -1.030379, + "bb_position": 0.93, + "change_24h": -0.85, + "change_4h": 2.35, + "vol_trend": 1.02, + "score": 38, + "reasons": [ + "RSI mildly elevated (60.0)", + "Slightly above VWAP (+1.6%)", + "MACD bearish + accelerating", + "Near upper Bollinger (0.93)" + ], + "timestamp": "2026-02-10T02:31:33.678025+00:00" + }, + { + "symbol": "OP", + "price": 0.19, + "rsi": 64.2, + "vwap_pct": 3.23, + "macd_histogram": -0.187435, + "bb_position": 0.79, + "change_24h": 0.53, + "change_4h": 0.0, + "vol_trend": 1.07, + "score": 35, + "reasons": [ + "RSI mildly elevated (64.2)", + "Above VWAP (+3.2%)", + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:36.709597+00:00" + }, + { + "symbol": "ARB", + "price": 0.114, + "rsi": 52.1, + "vwap_pct": 3.09, + "macd_histogram": -0.113948, + "bb_position": 0.72, + "change_24h": -3.55, + "change_4h": 2.06, + "vol_trend": 0.11, + "score": 30, + "reasons": [ + "Above VWAP (+3.1%)", + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:36.470618+00:00" + }, + { + "symbol": "ADA", + "price": 0.2693, + "rsi": 50.2, + "vwap_pct": 1.35, + "macd_histogram": -0.269763, + "bb_position": 0.62, + "change_24h": -1.43, + "change_4h": -0.81, + "vol_trend": 0.15, + "score": 23, + "reasons": [ + "Slightly above VWAP (+1.3%)", + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:32.520420+00:00" + }, + { + "symbol": "LINK", + "price": 8.88, + "rsi": 55.1, + "vwap_pct": 1.7, + "macd_histogram": -8.839752, + "bb_position": 0.73, + "change_24h": 0.79, + "change_4h": -0.34, + "vol_trend": 0.84, + "score": 23, + "reasons": [ + "Slightly above VWAP (+1.7%)", + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:32.968544+00:00" + }, + { + "symbol": "UNI", + "price": 3.519, + "rsi": 56.2, + "vwap_pct": 2.62, + "macd_histogram": -3.494918, + "bb_position": 0.65, + "change_24h": 2.18, + "change_4h": 0.0, + "vol_trend": 0.72, + "score": 23, + "reasons": [ + "Slightly above VWAP (+2.6%)", + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:34.365690+00:00" + }, + { + "symbol": "AAVE", + "price": 113.55, + "rsi": 55.0, + "vwap_pct": 1.28, + "macd_histogram": -112.920164, + "bb_position": 0.71, + "change_24h": 0.82, + "change_4h": 2.23, + "vol_trend": 0.55, + "score": 23, + "reasons": [ + "Slightly above VWAP (+1.3%)", + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:34.599689+00:00" + }, + { + "symbol": "APT", + "price": 1.067, + "rsi": 49.4, + "vwap_pct": 1.06, + "macd_histogram": -1.076147, + "bb_position": 0.63, + "change_24h": -2.65, + "change_4h": 0.0, + "vol_trend": 0.23, + "score": 23, + "reasons": [ + "Slightly above VWAP (+1.1%)", + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:35.993067+00:00" + }, + { + "symbol": "SUI", + "price": 0.9668, + "rsi": 50.4, + "vwap_pct": 1.54, + "macd_histogram": -0.969969, + "bb_position": 0.66, + "change_24h": -2.0, + "change_4h": -0.17, + "vol_trend": 0.03, + "score": 23, + "reasons": [ + "Slightly above VWAP (+1.5%)", + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:36.231436+00:00" + }, + { + "symbol": "BTC", + "price": 70249.15, + "rsi": 51.0, + "vwap_pct": 0.34, + "macd_histogram": -70262.247326, + "bb_position": 0.63, + "change_24h": -1.38, + "change_4h": 0.18, + "vol_trend": 0.96, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:31.360741+00:00" + }, + { + "symbol": "ETH", + "price": 2109.49, + "rsi": 55.4, + "vwap_pct": 0.97, + "macd_histogram": -2104.718634, + "bb_position": 0.67, + "change_24h": 0.44, + "change_4h": 0.2, + "vol_trend": 1.27, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:31.596017+00:00" + }, + { + "symbol": "SOL", + "price": 86.88, + "rsi": 52.0, + "vwap_pct": 0.65, + "macd_histogram": -86.940038, + "bb_position": 0.65, + "change_24h": -0.98, + "change_4h": 0.17, + "vol_trend": 0.88, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:31.806936+00:00" + }, + { + "symbol": "XRP", + "price": 1.4454, + "rsi": 53.8, + "vwap_pct": 0.52, + "macd_histogram": -1.439527, + "bb_position": 0.66, + "change_24h": -0.39, + "change_4h": 0.59, + "vol_trend": 1.67, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:32.046327+00:00" + }, + { + "symbol": "DOGE", + "price": 0.09629, + "rsi": 52.4, + "vwap_pct": 0.47, + "macd_histogram": -0.096217, + "bb_position": 0.7, + "change_24h": -0.98, + "change_4h": -0.43, + "vol_trend": 2.79, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:32.284061+00:00" + }, + { + "symbol": "AVAX", + "price": 9.01, + "rsi": 47.3, + "vwap_pct": 0.43, + "macd_histogram": -9.05205, + "bb_position": 0.56, + "change_24h": -1.31, + "change_4h": -0.44, + "vol_trend": 0.29, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:32.758345+00:00" + }, + { + "symbol": "DOT", + "price": 1.316, + "rsi": 47.5, + "vwap_pct": 0.69, + "macd_histogram": -1.325125, + "bb_position": 0.57, + "change_24h": -2.52, + "change_4h": -0.9, + "vol_trend": 0.23, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:33.205989+00:00" + }, + { + "symbol": "MATIC", + "price": 0.4492, + "rsi": 41.9, + "vwap_pct": -0.77, + "macd_histogram": -0.452491, + "bb_position": 0.32, + "change_24h": -1.58, + "change_4h": 0.22, + "vol_trend": 1.07, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:33.442040+00:00" + }, + { + "symbol": "ATOM", + "price": 1.953, + "rsi": 49.3, + "vwap_pct": 0.52, + "macd_histogram": -1.965896, + "bb_position": 0.5, + "change_24h": 0.93, + "change_4h": 0.05, + "vol_trend": 1.04, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:33.888750+00:00" + }, + { + "symbol": "LTC", + "price": 54.36, + "rsi": 50.1, + "vwap_pct": 0.22, + "macd_histogram": -54.485415, + "bb_position": 0.61, + "change_24h": -1.06, + "change_4h": -0.22, + "vol_trend": 2.73, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:34.128167+00:00" + }, + { + "symbol": "ALGO", + "price": 0.0951, + "rsi": 45.3, + "vwap_pct": -1.14, + "macd_histogram": -0.095952, + "bb_position": 0.5, + "change_24h": -2.56, + "change_4h": -2.36, + "vol_trend": 1.65, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:35.076205+00:00" + }, + { + "symbol": "XLM", + "price": 0.1614, + "rsi": 52.5, + "vwap_pct": 0.89, + "macd_histogram": -0.160963, + "bb_position": 0.69, + "change_24h": -1.34, + "change_4h": 1.13, + "vol_trend": 2.74, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:35.314005+00:00" + }, + { + "symbol": "VET", + "price": 0.00791, + "rsi": 48.8, + "vwap_pct": -0.02, + "macd_histogram": -0.007928, + "bb_position": 0.55, + "change_24h": -3.06, + "change_4h": 0.89, + "vol_trend": 0.27, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:35.550100+00:00" + }, + { + "symbol": "ICP", + "price": 2.782, + "rsi": 40.1, + "vwap_pct": -1.9, + "macd_histogram": -2.843397, + "bb_position": 0.14, + "change_24h": 3.81, + "change_4h": -2.49, + "vol_trend": 10.38, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:35.759005+00:00" + }, + { + "symbol": "SEI", + "price": 0.075, + "rsi": 29.9, + "vwap_pct": -0.25, + "macd_histogram": -0.075645, + "bb_position": 0.38, + "change_24h": -4.34, + "change_4h": 0.0, + "vol_trend": 0.11, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:36.945126+00:00" + }, + { + "symbol": "HYPE", + "price": 31.49, + "rsi": 45.7, + "vwap_pct": -1.11, + "macd_histogram": -31.681649, + "bb_position": 0.39, + "change_24h": -5.29, + "change_4h": 0.41, + "vol_trend": 21.91, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:37.184127+00:00" + }, + { + "symbol": "TRUMP", + "price": 3.446, + "rsi": 50.1, + "vwap_pct": 0.08, + "macd_histogram": -3.45085, + "bb_position": 0.49, + "change_24h": 0.35, + "change_4h": 0.0, + "vol_trend": 0.81, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:37.440389+00:00" + }, + { + "symbol": "PUMP", + "price": 0.002041, + "rsi": 37.6, + "vwap_pct": -2.03, + "macd_histogram": -0.002063, + "bb_position": 0.31, + "change_24h": -4.31, + "change_4h": 0.0, + "vol_trend": 1.28, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:37.674937+00:00" + }, + { + "symbol": "ASTER", + "price": 0.612, + "rsi": 50.2, + "vwap_pct": 0.21, + "macd_histogram": -0.610803, + "bb_position": 0.58, + "change_24h": -5.85, + "change_4h": 0.33, + "vol_trend": 0.63, + "score": 15, + "reasons": [ + "MACD bearish + accelerating" + ], + "timestamp": "2026-02-10T02:31:37.912733+00:00" + } + ] + } +] \ No newline at end of file diff --git a/projects/crypto-signals/leverage_game.py b/projects/crypto-signals/leverage_game.py new file mode 100644 index 0000000..eddc3be --- /dev/null +++ b/projects/crypto-signals/leverage_game.py @@ -0,0 +1,504 @@ +#!/usr/bin/env python3 +""" +Crypto Leverage Trading Game Engine +Paper trading with longs, shorts, and configurable leverage. +Tracks liquidation prices, unrealized PnL, and funding costs. +""" + +import json +import os +import uuid +import time +import urllib.request +from datetime import datetime, date, timezone +from pathlib import Path + +DATA_DIR = Path(__file__).parent / "data" / "leverage-game" +GAMES_DIR = DATA_DIR / "games" + +BINANCE_TICKER = "https://api.binance.us/api/v3/ticker/price" + + +def _load(path, default=None): + if path.exists(): + return json.loads(path.read_text()) + return default if default is not None else {} + + +def _save(path, data): + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(data, indent=2, default=str)) + + +def _game_path(game_id): + return GAMES_DIR / game_id / "game.json" + +def _player_path(game_id, username): + return GAMES_DIR / game_id / "players" / username / "portfolio.json" + +def _trades_path(game_id, username): + return GAMES_DIR / game_id / "players" / username / "trades.json" + +def _snapshots_path(game_id, username): + return GAMES_DIR / game_id / "players" / username / "snapshots.json" + + +# ── Price Fetching ── + +def get_price(symbol): + """Get current price from Binance US.""" + if not symbol.endswith("USDT"): + symbol = f"{symbol}USDT" + url = f"{BINANCE_TICKER}?symbol={symbol}" + req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'}) + try: + resp = urllib.request.urlopen(req, timeout=10) + return float(json.loads(resp.read())['price']) + except: + return None + + +# ── Game Management ── + +def create_game(name, starting_cash=10_000.0, max_leverage=20, creator="system"): + """Create a new leverage trading game.""" + game_id = str(uuid.uuid4())[:8] + config = { + "game_id": game_id, + "name": name, + "starting_cash": starting_cash, + "max_leverage": max_leverage, + "funding_rate_8h": 0.01, # 0.01% per 8h (typical perp funding) + "maker_fee": 0.02, # 0.02% + "taker_fee": 0.05, # 0.05% + "start_date": date.today().isoformat(), + "creator": creator, + "created_at": datetime.now(timezone.utc).isoformat(), + "players": [], + "status": "active", + } + _save(_game_path(game_id), config) + return game_id + + +def list_games(active_only=True): + """List all leverage games.""" + games = [] + if not GAMES_DIR.exists(): + return games + for gid in os.listdir(GAMES_DIR): + gp = _game_path(gid) + if gp.exists(): + config = _load(gp) + if active_only and config.get("status") != "active": + continue + games.append(config) + return sorted(games, key=lambda g: g.get("created_at", ""), reverse=True) + + +def get_game(game_id): + return _load(_game_path(game_id)) + + +def join_game(game_id, username): + """Add player to game.""" + config = get_game(game_id) + if not config: + return {"error": "Game not found"} + if username in config["players"]: + return {"error": f"{username} already in game"} + + config["players"].append(username) + _save(_game_path(game_id), config) + + _save(_player_path(game_id, username), { + "cash": config["starting_cash"], + "positions": {}, + "total_realized_pnl": 0, + "total_fees_paid": 0, + "total_funding_paid": 0, + }) + _save(_trades_path(game_id, username), []) + _save(_snapshots_path(game_id, username), []) + + return {"success": True, "game_id": game_id, "username": username} + + +# ── Position Math ── + +def calc_liquidation_price(entry_price, leverage, direction): + """ + Simplified liquidation price. + Long: liq = entry * (1 - 1/leverage) + Short: liq = entry * (1 + 1/leverage) + """ + if direction == "long": + return entry_price * (1 - 1 / leverage) + else: # short + return entry_price * (1 + 1 / leverage) + + +def calc_unrealized_pnl(entry_price, current_price, size_usd, leverage, direction): + """ + Calculate unrealized PnL for a leveraged position. + size_usd = margin (collateral). Notional = size_usd * leverage. + """ + notional = size_usd * leverage + shares = notional / entry_price + + if direction == "long": + pnl = (current_price - entry_price) * shares + else: # short + pnl = (entry_price - current_price) * shares + + return pnl + + +def is_liquidated(entry_price, current_price, leverage, direction): + """Check if position would be liquidated.""" + liq_price = calc_liquidation_price(entry_price, leverage, direction) + if direction == "long": + return current_price <= liq_price + else: + return current_price >= liq_price + + +# ── Trading ── + +def open_position(game_id, username, symbol, direction, margin_usd, leverage, reason="Manual"): + """ + Open a leveraged position. + margin_usd: collateral put up + leverage: multiplier (e.g., 10x) + direction: 'long' or 'short' + """ + pf = _load(_player_path(game_id, username)) + game = get_game(game_id) + if not pf or not game: + return {"error": "Player or game not found"} + + if direction not in ("long", "short"): + return {"error": "Direction must be 'long' or 'short'"} + if leverage > game.get("max_leverage", 20): + return {"error": f"Max leverage is {game['max_leverage']}x"} + if margin_usd > pf["cash"]: + return {"error": f"Insufficient cash. Need ${margin_usd:.2f}, have ${pf['cash']:.2f}"} + + symbol = symbol.upper().replace("USDT", "") + price = get_price(symbol) + if not price: + return {"error": f"Could not fetch price for {symbol}"} + + notional = margin_usd * leverage + fee = notional * game.get("taker_fee", 0.05) / 100 + + # Deduct margin + entry fee from cash + pf["cash"] -= (margin_usd + fee) + pf["total_fees_paid"] = pf.get("total_fees_paid", 0) + fee + + pos_id = f"{symbol}_{direction}_{str(uuid.uuid4())[:4]}" + liq_price = calc_liquidation_price(price, leverage, direction) + + pf["positions"][pos_id] = { + "symbol": symbol, + "direction": direction, + "leverage": leverage, + "margin_usd": margin_usd, + "notional": round(notional, 2), + "entry_price": price, + "current_price": price, + "liquidation_price": round(liq_price, 4), + "unrealized_pnl": 0, + "entry_fee": round(fee, 4), + "opened_at": datetime.now(timezone.utc).isoformat(), + "reason": reason, + } + + _save(_player_path(game_id, username), pf) + + # Log trade + trades = _load(_trades_path(game_id, username), []) + trades.append({ + "action": "OPEN", + "pos_id": pos_id, + "symbol": symbol, + "direction": direction, + "leverage": leverage, + "margin_usd": margin_usd, + "notional": round(notional, 2), + "entry_price": price, + "liquidation_price": round(liq_price, 4), + "fee": round(fee, 4), + "reason": reason, + "timestamp": datetime.now(timezone.utc).isoformat(), + }) + _save(_trades_path(game_id, username), trades) + + return { + "success": True, + "pos_id": pos_id, + "symbol": symbol, + "direction": direction, + "leverage": leverage, + "entry_price": price, + "margin": margin_usd, + "notional": round(notional, 2), + "liquidation_price": round(liq_price, 4), + "fee": round(fee, 4), + } + + +def close_position(game_id, username, pos_id, reason="Manual"): + """Close a leveraged position.""" + pf = _load(_player_path(game_id, username)) + game = get_game(game_id) + if not pf or not game: + return {"error": "Player or game not found"} + if pos_id not in pf["positions"]: + return {"error": f"Position {pos_id} not found"} + + pos = pf["positions"][pos_id] + price = get_price(pos["symbol"]) + if not price: + return {"error": f"Could not fetch price for {pos['symbol']}"} + + # Calculate PnL + pnl = calc_unrealized_pnl( + pos["entry_price"], price, pos["margin_usd"], pos["leverage"], pos["direction"] + ) + + # Check liquidation + liquidated = is_liquidated(pos["entry_price"], price, pos["leverage"], pos["direction"]) + if liquidated: + pnl = -pos["margin_usd"] # Lose entire margin + + # Exit fee + notional = pos["margin_usd"] * pos["leverage"] + fee = notional * game.get("taker_fee", 0.05) / 100 + + # Return margin + PnL - fee to cash + returned = pos["margin_usd"] + pnl - fee + if returned < 0: + returned = 0 # Can't lose more than margin (no negative balance) + + pf["cash"] += returned + pf["total_realized_pnl"] = pf.get("total_realized_pnl", 0) + pnl + pf["total_fees_paid"] = pf.get("total_fees_paid", 0) + fee + + del pf["positions"][pos_id] + _save(_player_path(game_id, username), pf) + + # Log trade + pnl_pct = (pnl / pos["margin_usd"] * 100) if pos["margin_usd"] > 0 else 0 + trades = _load(_trades_path(game_id, username), []) + trades.append({ + "action": "LIQUIDATED" if liquidated else "CLOSE", + "pos_id": pos_id, + "symbol": pos["symbol"], + "direction": pos["direction"], + "leverage": pos["leverage"], + "entry_price": pos["entry_price"], + "exit_price": price, + "margin_usd": pos["margin_usd"], + "pnl": round(pnl, 2), + "pnl_pct": round(pnl_pct, 2), + "fee": round(fee, 4), + "liquidated": liquidated, + "reason": reason, + "timestamp": datetime.now(timezone.utc).isoformat(), + }) + _save(_trades_path(game_id, username), trades) + + return { + "success": True, + "pos_id": pos_id, + "symbol": pos["symbol"], + "direction": pos["direction"], + "entry_price": pos["entry_price"], + "exit_price": price, + "pnl": round(pnl, 2), + "pnl_pct": round(pnl_pct, 2), + "liquidated": liquidated, + "returned_to_cash": round(returned, 2), + } + + +def update_prices(game_id, username): + """Update all position prices and check for liquidations.""" + pf = _load(_player_path(game_id, username)) + if not pf: + return [] + + liquidations = [] + to_liquidate = [] + + for pos_id, pos in pf["positions"].items(): + price = get_price(pos["symbol"]) + if not price: + continue + + pos["current_price"] = price + pos["unrealized_pnl"] = round( + calc_unrealized_pnl(pos["entry_price"], price, pos["margin_usd"], pos["leverage"], pos["direction"]), + 2 + ) + + if is_liquidated(pos["entry_price"], price, pos["leverage"], pos["direction"]): + to_liquidate.append(pos_id) + + time.sleep(0.1) + + _save(_player_path(game_id, username), pf) + + # Process liquidations + for pos_id in to_liquidate: + result = close_position(game_id, username, pos_id, reason="LIQUIDATED") + liquidations.append(result) + + return liquidations + + +# ── Portfolio View ── + +def get_portfolio(game_id, username): + """Get full portfolio with live PnL.""" + pf = _load(_player_path(game_id, username)) + game = get_game(game_id) + if not pf or not game: + return None + + starting = game["starting_cash"] + total_unrealized = sum(p.get("unrealized_pnl", 0) for p in pf["positions"].values()) + total_margin_locked = sum(p["margin_usd"] for p in pf["positions"].values()) + equity = pf["cash"] + total_margin_locked + total_unrealized + total_pnl = equity - starting + + return { + "username": username, + "game_id": game_id, + "cash": round(pf["cash"], 2), + "margin_locked": round(total_margin_locked, 2), + "unrealized_pnl": round(total_unrealized, 2), + "realized_pnl": round(pf.get("total_realized_pnl", 0), 2), + "total_fees": round(pf.get("total_fees_paid", 0), 2), + "equity": round(equity, 2), + "total_pnl": round(total_pnl, 2), + "pnl_pct": round(total_pnl / starting * 100, 2), + "num_positions": len(pf["positions"]), + "positions": pf["positions"], + } + + +def get_trades(game_id, username): + return _load(_trades_path(game_id, username), []) + + +def daily_snapshot(game_id, username): + """Take daily snapshot.""" + p = get_portfolio(game_id, username) + if not p: + return None + snapshots = _load(_snapshots_path(game_id, username), []) + today = date.today().isoformat() + snapshots = [s for s in snapshots if s["date"] != today] + snapshots.append({ + "date": today, + "equity": p["equity"], + "total_pnl": p["total_pnl"], + "pnl_pct": p["pnl_pct"], + "cash": p["cash"], + "num_positions": p["num_positions"], + "realized_pnl": p["realized_pnl"], + "total_fees": p["total_fees"], + }) + _save(_snapshots_path(game_id, username), snapshots) + return snapshots[-1] + + +def get_leaderboard(game_id): + """Leaderboard sorted by equity.""" + game = get_game(game_id) + if not game: + return [] + board = [] + for username in game["players"]: + p = get_portfolio(game_id, username) + if p: + trades = get_trades(game_id, username) + closed = [t for t in trades if t.get("action") in ("CLOSE", "LIQUIDATED")] + wins = [t for t in closed if t.get("pnl", 0) > 0] + liquidations = [t for t in closed if t.get("liquidated")] + board.append({ + "username": username, + "equity": p["equity"], + "total_pnl": p["total_pnl"], + "pnl_pct": p["pnl_pct"], + "num_positions": p["num_positions"], + "trades_closed": len(closed), + "win_rate": round(len(wins) / len(closed) * 100, 1) if closed else 0, + "liquidations": len(liquidations), + "total_fees": p["total_fees"], + }) + return sorted(board, key=lambda x: x["pnl_pct"], reverse=True) + + +# ── Auto-Trader (Scanner Integration) ── + +def auto_trade_from_scanner(game_id, username, scan_results, margin_per_trade=200, leverage=10): + """ + Automatically open positions based on scanner results. + Short scanner (score >= 50) → open short + Spot scanner (score >= 40) → open long + """ + opened = [] + for r in scan_results: + symbol = r["symbol"] + score = r["score"] + + # Determine direction based on which scanner produced this + direction = r.get("direction", "short") # Default to short for short scanner + + if score < 40: + continue + + # Scale leverage with conviction + if score >= 70: + lev = min(leverage, 15) + elif score >= 50: + lev = min(leverage, 10) + else: + lev = min(leverage, 5) + + result = open_position(game_id, username, symbol, direction, margin_per_trade, lev, + reason=f"Scanner score:{score} | {', '.join(r.get('reasons', []))}") + if result.get("success"): + opened.append(result) + + return opened + + +# ── Initialize ── + +def ensure_default_game(): + """Create default Leverage Challenge game.""" + for g in list_games(): + if g["name"] == "Leverage Challenge": + return g["game_id"] + + game_id = create_game("Leverage Challenge", starting_cash=10_000.0, max_leverage=20, creator="case") + join_game(game_id, "case") + return game_id + + +if __name__ == "__main__": + game_id = ensure_default_game() + game = get_game(game_id) + print(f"Game: {game['name']} ({game_id})") + print(f"Players: {game['players']}") + print(f"Starting cash: ${game['starting_cash']:,.2f}") + print(f"Max leverage: {game['max_leverage']}x") + + board = get_leaderboard(game_id) + for entry in board: + print(f" {entry['username']}: ${entry['equity']:,.2f} ({entry['pnl_pct']:+.2f}%) " + f"| {entry['trades_closed']} trades | {entry['win_rate']}% win | {entry['liquidations']} liquidated") diff --git a/projects/crypto-signals/scripts/leverage_trader.py b/projects/crypto-signals/scripts/leverage_trader.py new file mode 100644 index 0000000..bd33898 --- /dev/null +++ b/projects/crypto-signals/scripts/leverage_trader.py @@ -0,0 +1,292 @@ +#!/usr/bin/env python3 +""" +Automated Leverage Trader +Runs short scanner + spot scanner, opens positions in the Leverage Challenge game, +manages exits (TP/SL/trailing stop), and reports via Telegram. + +Zero AI tokens — systemd timer. +""" + +import json +import os +import sys +import time +import urllib.request +from datetime import datetime, timezone +from pathlib import Path + +# Add parent to path for imports +sys.path.insert(0, str(Path(__file__).parent.parent)) + +from leverage_game import ( + ensure_default_game, get_game, get_portfolio, open_position, + close_position, update_prices, get_trades, get_leaderboard +) +from scripts.short_scanner import scan_coin, COINS as SHORT_COINS + +TELEGRAM_BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "") +TELEGRAM_CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID", "6443752046") + +DATA_DIR = Path(__file__).parent.parent / "data" / "leverage-game" +STATE_FILE = DATA_DIR / "trader_state.json" + +# Trading params +MARGIN_PER_TRADE = 200 # $200 margin per position +DEFAULT_LEVERAGE = 10 # 10x default +MAX_OPEN_POSITIONS = 10 # Max simultaneous positions +SHORT_SCORE_THRESHOLD = 50 # Min score to open short +LONG_SCORE_THRESHOLD = 45 # Min score to open long +TP_PCT = 5.0 # Take profit at 5% on margin (50% on notional at 10x) +SL_PCT = -3.0 # Stop loss at -3% on margin (30% on notional at 10x) +TRAILING_STOP_PCT = 2.0 # Trailing stop: close if drops 2% from peak + + +def load_state(): + if STATE_FILE.exists(): + return json.loads(STATE_FILE.read_text()) + return {"peak_pnl": {}, "last_alert": None} + +def save_state(state): + STATE_FILE.parent.mkdir(parents=True, exist_ok=True) + STATE_FILE.write_text(json.dumps(state, indent=2)) + + +def send_telegram(message): + if not TELEGRAM_BOT_TOKEN: + print(f"[TG] {message}") + return + url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" + data = json.dumps({ + "chat_id": TELEGRAM_CHAT_ID, + "text": message, + "parse_mode": "HTML" + }).encode() + req = urllib.request.Request(url, data=data, headers={ + "Content-Type": "application/json", "User-Agent": "Mozilla/5.0" + }) + try: + urllib.request.urlopen(req, timeout=10) + except Exception as e: + print(f"Telegram failed: {e}") + + +def run_short_scan(): + """Run short scanner on all coins.""" + results = [] + for symbol in SHORT_COINS: + r = scan_coin(symbol) + if r: + r["direction"] = "short" + results.append(r) + time.sleep(0.15) + return sorted(results, key=lambda x: x['score'], reverse=True) + + +def run_spot_scan(): + """Run spot/long scanner (inverse of short criteria — oversold = buy).""" + results = [] + for symbol in SHORT_COINS: + r = scan_coin(symbol) + if r: + # Invert: low RSI + below VWAP = long opportunity + long_score = 0 + reasons = [] + + if r['rsi'] <= 25: + long_score += 30 + reasons.append(f"RSI extremely oversold ({r['rsi']})") + elif r['rsi'] <= 30: + long_score += 25 + reasons.append(f"RSI oversold ({r['rsi']})") + elif r['rsi'] <= 35: + long_score += 15 + reasons.append(f"RSI low ({r['rsi']})") + elif r['rsi'] <= 40: + long_score += 5 + reasons.append(f"RSI mildly low ({r['rsi']})") + + if r['vwap_pct'] < -5: + long_score += 20 + reasons.append(f"Well below VWAP ({r['vwap_pct']:+.1f}%)") + elif r['vwap_pct'] < -3: + long_score += 15 + reasons.append(f"Below VWAP ({r['vwap_pct']:+.1f}%)") + elif r['vwap_pct'] < -1: + long_score += 8 + reasons.append(f"Slightly below VWAP ({r['vwap_pct']:+.1f}%)") + + if r['change_24h'] < -15: + long_score += 15 + reasons.append(f"Dumped {r['change_24h']:.1f}% 24h") + elif r['change_24h'] < -8: + long_score += 10 + reasons.append(f"Down {r['change_24h']:.1f}% 24h") + elif r['change_24h'] < -4: + long_score += 5 + reasons.append(f"Down {r['change_24h']:.1f}% 24h") + + if r['bb_position'] < 0: + long_score += 15 + reasons.append(f"Below lower Bollinger ({r['bb_position']:.2f})") + elif r['bb_position'] < 0.15: + long_score += 10 + reasons.append(f"Near lower Bollinger ({r['bb_position']:.2f})") + + results.append({ + "symbol": r["symbol"], + "price": r["price"], + "rsi": r["rsi"], + "vwap_pct": r["vwap_pct"], + "change_24h": r["change_24h"], + "bb_position": r["bb_position"], + "score": long_score, + "reasons": reasons, + "direction": "long", + }) + time.sleep(0.15) + return sorted(results, key=lambda x: x['score'], reverse=True) + + +def manage_exits(game_id, username, state): + """Check open positions for TP/SL/trailing stop exits.""" + pf = get_portfolio(game_id, username) + if not pf: + return [] + + exits = [] + for pos_id, pos in list(pf["positions"].items()): + pnl_pct = (pos.get("unrealized_pnl", 0) / pos["margin_usd"] * 100) if pos["margin_usd"] > 0 else 0 + + # Track peak PnL for trailing stop + peak_key = pos_id + if peak_key not in state.get("peak_pnl", {}): + state["peak_pnl"][peak_key] = pnl_pct + if pnl_pct > state["peak_pnl"].get(peak_key, 0): + state["peak_pnl"][peak_key] = pnl_pct + + peak = state["peak_pnl"].get(peak_key, 0) + reason = None + + # Take profit + if pnl_pct >= TP_PCT: + reason = f"TP hit ({pnl_pct:+.1f}%)" + # Stop loss + elif pnl_pct <= SL_PCT: + reason = f"SL hit ({pnl_pct:+.1f}%)" + # Trailing stop (only if we were profitable) + elif peak >= 2.0 and (peak - pnl_pct) >= TRAILING_STOP_PCT: + reason = f"Trailing stop (peak {peak:+.1f}%, now {pnl_pct:+.1f}%)" + + if reason: + result = close_position(game_id, username, pos_id, reason=reason) + if result.get("success"): + exits.append(result) + # Clean up peak tracking + state["peak_pnl"].pop(peak_key, None) + + return exits + + +def main(): + game_id = ensure_default_game() + state = load_state() + + print(f"=== Leverage Trader ===") + print(f"Time: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}") + print(f"Game: {game_id}") + + # 1. Update prices and check liquidations + liquidations = update_prices(game_id, "case") + for liq in liquidations: + msg = f"💀 LIQUIDATED: {liq['symbol']} {liq['direction']} {liq.get('leverage', '?')}x | Lost ${abs(liq.get('pnl', 0)):.2f}" + send_telegram(msg) + print(msg) + + # 2. Manage exits (TP/SL/trailing) + exits = manage_exits(game_id, "case", state) + for ex in exits: + emoji = "✅" if ex.get("pnl", 0) > 0 else "❌" + msg = (f"{emoji} Closed: {ex['symbol']} {ex['direction']} | " + f"Entry: ${ex['entry_price']:.4f} → Exit: ${ex['exit_price']:.4f} | " + f"PnL: ${ex['pnl']:+.2f} ({ex['pnl_pct']:+.1f}%)") + print(msg) + + # 3. Get current portfolio + pf = get_portfolio(game_id, "case") + num_open = pf["num_positions"] if pf else 0 + slots = MAX_OPEN_POSITIONS - num_open + + print(f"\nPortfolio: ${pf['equity']:,.2f} ({pf['pnl_pct']:+.2f}%) | {num_open} positions | {slots} slots open") + + # 4. Scan for new opportunities + if slots > 0: + # Run both scanners + shorts = run_short_scan() + longs = run_spot_scan() + + # Get existing symbols to avoid doubling up + existing_symbols = set() + if pf: + for pos in pf["positions"].values(): + existing_symbols.add(pos["symbol"]) + + opened = [] + + # Open short positions + for r in shorts: + if slots <= 0: + break + if r["score"] < SHORT_SCORE_THRESHOLD: + break + if r["symbol"] in existing_symbols: + continue + + lev = 15 if r["score"] >= 70 else 10 if r["score"] >= 60 else 7 + result = open_position(game_id, "case", r["symbol"], "short", MARGIN_PER_TRADE, lev, + reason=f"Short scanner score:{r['score']}") + if result.get("success"): + opened.append(result) + existing_symbols.add(r["symbol"]) + slots -= 1 + time.sleep(0.2) + + # Open long positions + for r in longs: + if slots <= 0: + break + if r["score"] < LONG_SCORE_THRESHOLD: + break + if r["symbol"] in existing_symbols: + continue + + lev = 15 if r["score"] >= 70 else 10 if r["score"] >= 60 else 7 + result = open_position(game_id, "case", r["symbol"], "long", MARGIN_PER_TRADE, lev, + reason=f"Long scanner score:{r['score']}") + if result.get("success"): + opened.append(result) + existing_symbols.add(r["symbol"]) + slots -= 1 + time.sleep(0.2) + + if opened: + lines = [f"📊 Opened {len(opened)} positions\n"] + for o in opened: + lines.append(f"{'🔴' if o['direction']=='short' else '🟢'} {o['symbol']} {o['direction']} {o['leverage']}x @ ${o['entry_price']:.4f} (${o['margin']:.0f} margin)") + send_telegram("\n".join(lines)) + print(f"\nOpened {len(opened)} new positions") + + # 5. Send periodic summary (every 4 hours) + if exits or liquidations: + pf = get_portfolio(game_id, "case") # Refresh + msg = (f"📈 Leverage Challenge Update\n" + f"Equity: ${pf['equity']:,.2f} ({pf['pnl_pct']:+.2f}%)\n" + f"Positions: {pf['num_positions']} | Cash: ${pf['cash']:,.2f}\n" + f"Realized PnL: ${pf['realized_pnl']:+,.2f} | Fees: ${pf['total_fees']:,.2f}") + send_telegram(msg) + + save_state(state) + print("\nDone.") + + +if __name__ == "__main__": + main() diff --git a/projects/crypto-signals/scripts/short_scanner.py b/projects/crypto-signals/scripts/short_scanner.py new file mode 100644 index 0000000..d56597a --- /dev/null +++ b/projects/crypto-signals/scripts/short_scanner.py @@ -0,0 +1,336 @@ +#!/usr/bin/env python3 +""" +Crypto Short Signal Scanner +Scans for overbought coins ripe for shorting. +Criteria: high RSI, price above VWAP, fading momentum, bearish divergence. + +Zero AI tokens — runs as pure Python via systemd timer. +""" + +import json +import os +import sys +import time +import math +import urllib.request +from datetime import datetime, timezone, timedelta +from pathlib import Path + +# Config +DATA_DIR = Path(__file__).parent.parent / "data" / "short-scanner" +DATA_DIR.mkdir(parents=True, exist_ok=True) +SCAN_LOG = DATA_DIR / "scan_log.json" + +TELEGRAM_BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "") +TELEGRAM_CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID", "6443752046") + +BINANCE_KLINES = "https://api.binance.us/api/v3/klines" +BINANCE_TICKER = "https://api.binance.us/api/v3/ticker/24hr" + +# Coins to scan (popular leveraged trading coins) +COINS = [ + "BTCUSDT", "ETHUSDT", "SOLUSDT", "XRPUSDT", "DOGEUSDT", + "ADAUSDT", "AVAXUSDT", "LINKUSDT", "DOTUSDT", "MATICUSDT", + "NEARUSDT", "ATOMUSDT", "LTCUSDT", "UNIUSDT", "AAVEUSDT", + "FILUSDT", "ALGOUSDT", "XLMUSDT", "VETUSDT", "ICPUSDT", + "APTUSDT", "SUIUSDT", "ARBUSDT", "OPUSDT", "SEIUSDT", + "HYPEUSDT", "TRUMPUSDT", "PUMPUSDT", "ASTERUSDT", +] + + +def get_klines(symbol, interval='1h', limit=100): + """Fetch klines from Binance US.""" + url = f"{BINANCE_KLINES}?symbol={symbol}&interval={interval}&limit={limit}" + req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'}) + try: + resp = urllib.request.urlopen(req, timeout=10) + raw = json.loads(resp.read()) + return [{ + 'open': float(k[1]), + 'high': float(k[2]), + 'low': float(k[3]), + 'close': float(k[4]), + 'volume': float(k[5]), + 'close_time': k[6], + } for k in raw] + except: + return [] + + +def calc_rsi(closes, period=14): + """Calculate RSI.""" + if len(closes) < period + 1: + return 50 + deltas = [closes[i] - closes[i-1] for i in range(1, len(closes))] + gains = [d if d > 0 else 0 for d in deltas] + losses = [-d if d < 0 else 0 for d in deltas] + + avg_gain = sum(gains[:period]) / period + avg_loss = sum(losses[:period]) / period + + for i in range(period, len(deltas)): + avg_gain = (avg_gain * (period - 1) + gains[i]) / period + avg_loss = (avg_loss * (period - 1) + losses[i]) / period + + if avg_loss == 0: + return 100 + rs = avg_gain / avg_loss + return round(100 - (100 / (1 + rs)), 1) + + +def calc_vwap(klines): + """Calculate VWAP from klines.""" + cum_vol = 0 + cum_tp_vol = 0 + for k in klines: + tp = (k['high'] + k['low'] + k['close']) / 3 + cum_vol += k['volume'] + cum_tp_vol += tp * k['volume'] + if cum_vol == 0: + return 0 + return cum_tp_vol / cum_vol + + +def calc_ema(values, period): + """Calculate EMA.""" + if not values: + return 0 + multiplier = 2 / (period + 1) + ema = values[0] + for v in values[1:]: + ema = (v - ema) * multiplier + ema + return ema + + +def calc_macd(closes): + """Calculate MACD (12, 26, 9).""" + if len(closes) < 26: + return 0, 0, 0 + ema12 = calc_ema(closes, 12) + ema26 = calc_ema(closes, 26) + macd_line = ema12 - ema26 + # Approximate signal line + signal = calc_ema(closes[-9:], 9) if len(closes) >= 9 else macd_line + histogram = macd_line - signal + return macd_line, signal, histogram + + +def calc_bollinger_position(closes, period=20): + """How far price is from upper Bollinger band. >1 = above upper band.""" + if len(closes) < period: + return 0.5 + recent = closes[-period:] + sma = sum(recent) / period + std = (sum((x - sma)**2 for x in recent) / period) ** 0.5 + if std == 0: + return 0.5 + upper = sma + 2 * std + lower = sma - 2 * std + band_width = upper - lower + if band_width == 0: + return 0.5 + return (closes[-1] - lower) / band_width + + +def volume_trend(klines, lookback=10): + """Compare recent volume to average. >1 means increasing volume.""" + if len(klines) < lookback * 2: + return 1.0 + recent_vol = sum(k['volume'] for k in klines[-lookback:]) / lookback + older_vol = sum(k['volume'] for k in klines[-lookback*2:-lookback]) / lookback + if older_vol == 0: + return 1.0 + return recent_vol / older_vol + + +def scan_coin(symbol): + """Analyze a single coin for short signals.""" + # Get 1h candles for RSI/VWAP/indicators + klines_1h = get_klines(symbol, '1h', 100) + if len(klines_1h) < 30: + return None + + closes = [k['close'] for k in klines_1h] + current_price = closes[-1] + + # RSI (14-period on 1h) + rsi = calc_rsi(closes) + + # VWAP (24h) + vwap_24h = calc_vwap(klines_1h[-24:]) + vwap_pct = ((current_price - vwap_24h) / vwap_24h * 100) if vwap_24h else 0 + + # MACD + macd_line, signal_line, histogram = calc_macd(closes) + macd_bearish = histogram < 0 # Below signal = bearish + + # Bollinger position + bb_pos = calc_bollinger_position(closes) + + # Volume trend + vol_trend = volume_trend(klines_1h) + + # 24h change + price_24h_ago = closes[-24] if len(closes) >= 24 else closes[0] + change_24h = ((current_price - price_24h_ago) / price_24h_ago * 100) if price_24h_ago else 0 + + # 4h change (momentum) + price_4h_ago = closes[-4] if len(closes) >= 4 else closes[0] + change_4h = ((current_price - price_4h_ago) / price_4h_ago * 100) if price_4h_ago else 0 + + # === SHORT SCORING === + score = 0 + reasons = [] + + # RSI overbought (max 30 pts) + if rsi >= 80: + score += 30 + reasons.append(f"RSI extremely overbought ({rsi})") + elif rsi >= 70: + score += 25 + reasons.append(f"RSI overbought ({rsi})") + elif rsi >= 65: + score += 15 + reasons.append(f"RSI elevated ({rsi})") + elif rsi >= 60: + score += 5 + reasons.append(f"RSI mildly elevated ({rsi})") + + # Price above VWAP (max 20 pts) + if vwap_pct > 5: + score += 20 + reasons.append(f"Well above VWAP (+{vwap_pct:.1f}%)") + elif vwap_pct > 3: + score += 15 + reasons.append(f"Above VWAP (+{vwap_pct:.1f}%)") + elif vwap_pct > 1: + score += 8 + reasons.append(f"Slightly above VWAP (+{vwap_pct:.1f}%)") + + # MACD bearish crossover (max 15 pts) + if macd_bearish and histogram < -0.001 * current_price: + score += 15 + reasons.append("MACD bearish + accelerating") + elif macd_bearish: + score += 10 + reasons.append("MACD bearish crossover") + + # Bollinger band position (max 15 pts) + if bb_pos > 1.0: + score += 15 + reasons.append(f"Above upper Bollinger ({bb_pos:.2f})") + elif bb_pos > 0.85: + score += 10 + reasons.append(f"Near upper Bollinger ({bb_pos:.2f})") + + # Big recent pump (mean reversion candidate) (max 15 pts) + if change_24h > 15: + score += 15 + reasons.append(f"Pumped +{change_24h:.1f}% 24h") + elif change_24h > 8: + score += 10 + reasons.append(f"Up +{change_24h:.1f}% 24h") + elif change_24h > 4: + score += 5 + reasons.append(f"Up +{change_24h:.1f}% 24h") + + # Volume fading on uptrend (exhaustion) (5 pts) + if change_24h > 2 and vol_trend < 0.7: + score += 5 + reasons.append("Volume fading on uptrend (exhaustion)") + + return { + "symbol": symbol.replace("USDT", ""), + "price": current_price, + "rsi": rsi, + "vwap_pct": round(vwap_pct, 2), + "macd_histogram": round(histogram, 6), + "bb_position": round(bb_pos, 2), + "change_24h": round(change_24h, 2), + "change_4h": round(change_4h, 2), + "vol_trend": round(vol_trend, 2), + "score": score, + "reasons": reasons, + "timestamp": datetime.now(timezone.utc).isoformat(), + } + + +def send_telegram_alert(message): + """Send alert via Telegram bot API.""" + if not TELEGRAM_BOT_TOKEN: + print(f"[ALERT] {message}") + return + url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" + data = json.dumps({ + "chat_id": TELEGRAM_CHAT_ID, + "text": message, + "parse_mode": "HTML" + }).encode() + req = urllib.request.Request(url, data=data, headers={ + "Content-Type": "application/json", + "User-Agent": "Mozilla/5.0" + }) + try: + urllib.request.urlopen(req, timeout=10) + except Exception as e: + print(f"Telegram alert failed: {e}") + + +def main(): + print(f"=== Crypto Short Signal Scanner ===") + print(f"Time: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}") + print() + + results = [] + for symbol in COINS: + result = scan_coin(symbol) + if result: + results.append(result) + time.sleep(0.15) # Rate limiting + + # Sort by score descending + results.sort(key=lambda x: x['score'], reverse=True) + + # Print all results + for r in results: + emoji = "🔴" if r['score'] >= 50 else "🟡" if r['score'] >= 30 else "⚪" + print(f"{emoji} {r['symbol']:8s} score:{r['score']:3d} | RSI:{r['rsi']:5.1f} | VWAP:{r['vwap_pct']:+6.1f}% | 24h:{r['change_24h']:+6.1f}% | BB:{r['bb_position']:.2f}") + if r['reasons']: + for reason in r['reasons']: + print(f" → {reason}") + + # Alert on strong short signals (score >= 50) + strong = [r for r in results if r['score'] >= 50] + if strong: + lines = ["🔴 Short Signals Detected\n"] + for r in strong: + lines.append(f"{r['symbol']} (score: {r['score']})") + lines.append(f" Price: ${r['price']:.4f} | RSI: {r['rsi']} | VWAP: {r['vwap_pct']:+.1f}%") + lines.append(f" 24h: {r['change_24h']:+.1f}% | BB: {r['bb_position']:.2f}") + for reason in r['reasons']: + lines.append(f" → {reason}") + lines.append("") + send_telegram_alert("\n".join(lines)) + + # Save scan log + log = [] + if SCAN_LOG.exists(): + try: + log = json.loads(SCAN_LOG.read_text()) + except: + pass + + log.append({ + "timestamp": datetime.now(timezone.utc).isoformat(), + "coins_scanned": len(results), + "strong_signals": len(strong), + "results": results, + }) + log = log[-500:] + SCAN_LOG.write_text(json.dumps(log, indent=2)) + + print(f"\n📊 Summary: {len(results)} scanned, {len(strong)} strong short signals") + + +if __name__ == "__main__": + main() diff --git a/projects/feed-hunter/data/kch123-tracking/stats.json b/projects/feed-hunter/data/kch123-tracking/stats.json index 5c08de6..0f28bab 100644 --- a/projects/feed-hunter/data/kch123-tracking/stats.json +++ b/projects/feed-hunter/data/kch123-tracking/stats.json @@ -1,5 +1,5 @@ { - "last_check": "2026-02-10T02:13:59.845747+00:00", + "last_check": "2026-02-10T02:31:59.875011+00:00", "total_tracked": 3100, "new_this_check": 0 } \ No newline at end of file