From c14bb98f7fa4411bb28bfee1f52ff7b4e5905206 Mon Sep 17 00:00:00 2001 From: drjones Date: Sun, 2 Aug 2026 19:10:27 -0700 Subject: [PATCH] =?UTF-8?q?K4LSH1=5FOPS:=20multi-coin=20LLM=20bot=20?= =?UTF-8?q?=E2=80=94=20DOGE/SOL/ETH,=20two-tier=20qwen+ornith,=20self-adap?= =?UTF-8?q?ting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/bot.cpython-311.pyc | Bin 0 -> 45103 bytes __pycache__/bot.cpython-314.pyc | Bin 0 -> 41634 bytes __pycache__/dashboard.cpython-311.pyc | Bin 0 -> 28521 bytes bot.lock | 0 bot.log | 1716 +++++++++++++++++++++++++ bot.py | 617 +++++++++ bot_console.log | 211 +++ config.json | 16 + dash_console.log | 75 ++ dashboard.py | 384 ++++++ doge.db | Bin 0 -> 57344 bytes doge.json | 28 + doge.lock | 0 eth.db | Bin 0 -> 61440 bytes eth.json | 28 + eth.lock | 0 kalshi_private_key.pem | 27 + launch_all.sh | 9 + sol.db | Bin 0 -> 57344 bytes sol.json | 28 + sol.lock | 0 state.db | Bin 0 -> 126976 bytes test_bot.py | 279 ++++ 23 files changed, 3418 insertions(+) create mode 100644 __pycache__/bot.cpython-311.pyc create mode 100644 __pycache__/bot.cpython-314.pyc create mode 100644 __pycache__/dashboard.cpython-311.pyc create mode 100644 bot.lock create mode 100644 bot.log create mode 100644 bot.py create mode 100644 bot_console.log create mode 100644 config.json create mode 100644 dash_console.log create mode 100644 dashboard.py create mode 100644 doge.db create mode 100644 doge.json create mode 100644 doge.lock create mode 100644 eth.db create mode 100644 eth.json create mode 100644 eth.lock create mode 100644 kalshi_private_key.pem create mode 100755 launch_all.sh create mode 100644 sol.db create mode 100644 sol.json create mode 100644 sol.lock create mode 100644 state.db create mode 100644 test_bot.py diff --git a/__pycache__/bot.cpython-311.pyc b/__pycache__/bot.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..00cfc5957ae83937fe08d6d37196c963005ee6da GIT binary patch literal 45103 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 c8=`Eo){u{VGV0iq?&sQ>@~ literal 0 HcmV?d00001 diff --git a/__pycache__/bot.cpython-314.pyc b/__pycache__/bot.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..855208523ce9b326ef266f65b3f79014125fda0e GIT binary patch literal 41634 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 A>;M1& literal 0 HcmV?d00001 diff --git a/__pycache__/dashboard.cpython-311.pyc b/__pycache__/dashboard.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3aeae02a3d774575e80f0191255ad36f5210db13 GIT binary patch literal 28521 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 # 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 LtOipxQ!f7>we0OP literal 0 HcmV?d00001 diff --git a/bot.lock b/bot.lock new file mode 100644 index 0000000..e69de29 diff --git a/bot.log b/bot.log new file mode 100644 index 0000000..85d036c --- /dev/null +++ b/bot.log @@ -0,0 +1,1716 @@ +2026-08-01 21:28:28,778 K4LSH1_OPS online — mode=AUTO dry_run=True stake=50¢ +2026-08-01 21:28:43,182 ollama vote failed: Expecting value: line 1 column 1 (char 0) +2026-08-01 21:28:43,289 skip KXBTC15M-26AUG020030-30: mom=FLAT llm=SKIP +2026-08-01 21:31:06,263 ollama vote failed: Expecting value: line 1 column 1 (char 0) +2026-08-01 21:31:06,365 skip KXBTC15M-26AUG020045-45: mom=FLAT llm=SKIP +2026-08-01 21:32:22,951 K4LSH1_OPS online — mode=AUTO dry_run=True stake=50¢ +2026-08-01 21:32:27,370 skip KXBTC15M-26AUG020045-45: mom=FLAT llm=SKIP +2026-08-01 21:32:48,554 127.0.0.1 - - [01/Aug/2026 21:32:48] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:35:07,483 K4LSH1_OPS online — mode=AUTO dry_run=True stake=50¢ +2026-08-01 21:35:11,460 skip KXBTC15M-26AUG020045-45: mom=FLAT llm=SKIP +2026-08-01 21:35:45,702 127.0.0.1 - - [01/Aug/2026 21:35:45] "POST /api/control HTTP/1.1" 200 - +2026-08-01 21:35:46,925 K4LSH1_OPS online — mode=DOWN_SPAM dry_run=True stake=45¢ +2026-08-01 21:35:50,882 [SIM] MAKER-POST NO KXBTC15M-26AUG020045-45 @ 45¢ — spam-mode short +2026-08-01 21:36:35,412 127.0.0.1 - - [01/Aug/2026 21:36:35] "POST /api/control HTTP/1.1" 200 - +2026-08-01 21:36:36,636 K4LSH1_OPS online — mode=AUTO dry_run=True stake=50¢ +2026-08-01 21:36:39,490 skip KXBTC15M-26AUG020045-45: mom=FLAT llm=SKIP +2026-08-01 21:36:51,971 127.0.0.1 - - [01/Aug/2026 21:36:51] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:37:51,322 127.0.0.1 - - [01/Aug/2026 21:37:51] "GET / HTTP/1.1" 200 - +2026-08-01 21:37:51,475 127.0.0.1 - - [01/Aug/2026 21:37:51] "GET /favicon.ico HTTP/1.1" 404 - +2026-08-01 21:37:51,931 127.0.0.1 - - [01/Aug/2026 21:37:51] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:37:56,802 127.0.0.1 - - [01/Aug/2026 21:37:56] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:01,781 127.0.0.1 - - [01/Aug/2026 21:38:01] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:06,979 127.0.0.1 - - [01/Aug/2026 21:38:06] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:11,858 127.0.0.1 - - [01/Aug/2026 21:38:11] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:16,859 127.0.0.1 - - [01/Aug/2026 21:38:16] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:21,861 127.0.0.1 - - [01/Aug/2026 21:38:21] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:26,861 127.0.0.1 - - [01/Aug/2026 21:38:26] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:31,775 127.0.0.1 - - [01/Aug/2026 21:38:31] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:36,887 127.0.0.1 - - [01/Aug/2026 21:38:36] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:41,957 127.0.0.1 - - [01/Aug/2026 21:38:41] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:46,751 127.0.0.1 - - [01/Aug/2026 21:38:46] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:51,850 127.0.0.1 - - [01/Aug/2026 21:38:51] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:56,742 127.0.0.1 - - [01/Aug/2026 21:38:56] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:01,740 127.0.0.1 - - [01/Aug/2026 21:39:01] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:06,809 127.0.0.1 - - [01/Aug/2026 21:39:06] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:11,751 127.0.0.1 - - [01/Aug/2026 21:39:11] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:17,389 127.0.0.1 - - [01/Aug/2026 21:39:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:21,827 127.0.0.1 - - [01/Aug/2026 21:39:21] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:27,040 127.0.0.1 - - [01/Aug/2026 21:39:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:31,777 127.0.0.1 - - [01/Aug/2026 21:39:31] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:37,052 127.0.0.1 - - [01/Aug/2026 21:39:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:41,781 127.0.0.1 - - [01/Aug/2026 21:39:41] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:46,761 127.0.0.1 - - [01/Aug/2026 21:39:46] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:51,853 127.0.0.1 - - [01/Aug/2026 21:39:51] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:56,761 127.0.0.1 - - [01/Aug/2026 21:39:56] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:02,240 K4LSH1_OPS online — mode=AUTO dry_run=True stake=50¢ +2026-08-01 21:41:06,530 skip KXBTC15M-26AUG020045-45: mom=FLAT llm=SKIP +2026-08-01 21:41:07,056 127.0.0.1 - - [01/Aug/2026 21:41:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:11,883 127.0.0.1 - - [01/Aug/2026 21:41:11] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:16,773 127.0.0.1 - - [01/Aug/2026 21:41:16] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:21,925 127.0.0.1 - - [01/Aug/2026 21:41:21] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:26,934 127.0.0.1 - - [01/Aug/2026 21:41:26] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:31,967 127.0.0.1 - - [01/Aug/2026 21:41:31] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:36,896 127.0.0.1 - - [01/Aug/2026 21:41:36] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:41,793 127.0.0.1 - - [01/Aug/2026 21:41:41] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:46,760 127.0.0.1 - - [01/Aug/2026 21:41:46] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:51,826 127.0.0.1 - - [01/Aug/2026 21:41:51] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:41:56,747 127.0.0.1 - - [01/Aug/2026 21:41:56] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:42:17,349 127.0.0.1 - - [01/Aug/2026 21:42:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:42:30,045 127.0.0.1 - - [01/Aug/2026 21:42:30] "GET / HTTP/1.1" 200 - +2026-08-01 21:43:03,948 127.0.0.1 - - [01/Aug/2026 21:43:03] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:43:08,987 127.0.0.1 - - [01/Aug/2026 21:43:08] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:43:14,528 127.0.0.1 - - [01/Aug/2026 21:43:14] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:43:43,420 127.0.0.1 - - [01/Aug/2026 21:43:43] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:43:48,349 127.0.0.1 - - [01/Aug/2026 21:43:48] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:43:53,497 127.0.0.1 - - [01/Aug/2026 21:43:53] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:43:58,528 127.0.0.1 - - [01/Aug/2026 21:43:58] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:03,341 127.0.0.1 - - [01/Aug/2026 21:44:03] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:06,563 127.0.0.1 - - [01/Aug/2026 21:44:06] "GET / HTTP/1.1" 200 - +2026-08-01 21:44:07,047 127.0.0.1 - - [01/Aug/2026 21:44:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:12,082 127.0.0.1 - - [01/Aug/2026 21:44:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:17,085 127.0.0.1 - - [01/Aug/2026 21:44:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:22,041 127.0.0.1 - - [01/Aug/2026 21:44:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:27,089 127.0.0.1 - - [01/Aug/2026 21:44:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:29,743 127.0.0.1 - - [01/Aug/2026 21:44:29] "POST /api/control HTTP/1.1" 200 - +2026-08-01 21:44:30,399 127.0.0.1 - - [01/Aug/2026 21:44:30] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:30,590 127.0.0.1 - - [01/Aug/2026 21:44:30] "POST /api/toggle-dry HTTP/1.1" 200 - +2026-08-01 21:44:31,004 127.0.0.1 - - [01/Aug/2026 21:44:31] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:32,058 127.0.0.1 - - [01/Aug/2026 21:44:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:36,984 127.0.0.1 - - [01/Aug/2026 21:44:36] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:42,006 127.0.0.1 - - [01/Aug/2026 21:44:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:47,063 127.0.0.1 - - [01/Aug/2026 21:44:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:52,003 127.0.0.1 - - [01/Aug/2026 21:44:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:44:57,086 127.0.0.1 - - [01/Aug/2026 21:44:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:02,147 127.0.0.1 - - [01/Aug/2026 21:45:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:06,982 127.0.0.1 - - [01/Aug/2026 21:45:06] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:11,984 127.0.0.1 - - [01/Aug/2026 21:45:11] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:17,097 127.0.0.1 - - [01/Aug/2026 21:45:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:21,970 127.0.0.1 - - [01/Aug/2026 21:45:21] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:27,128 127.0.0.1 - - [01/Aug/2026 21:45:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:32,133 127.0.0.1 - - [01/Aug/2026 21:45:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:37,426 127.0.0.1 - - [01/Aug/2026 21:45:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:38,730 skip KXBTC15M-26AUG020100-00: mom=FLAT llm=SKIP +2026-08-01 21:45:40,622 skip KXBTC15M-26AUG020100-00: mom=FLAT llm=SKIP +2026-08-01 21:45:42,061 127.0.0.1 - - [01/Aug/2026 21:45:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:42,761 skip KXBTC15M-26AUG020100-00: mom=FLAT llm=SKIP +2026-08-01 21:45:45,645 skip KXBTC15M-26AUG020100-00: mom=FLAT llm=SKIP +2026-08-01 21:45:47,190 127.0.0.1 - - [01/Aug/2026 21:45:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:50,253 skip KXBTC15M-26AUG020100-00: mom=FLAT llm=SKIP +2026-08-01 21:45:52,028 127.0.0.1 - - [01/Aug/2026 21:45:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:45:57,021 127.0.0.1 - - [01/Aug/2026 21:45:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:02,080 127.0.0.1 - - [01/Aug/2026 21:46:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:07,005 127.0.0.1 - - [01/Aug/2026 21:46:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:12,100 127.0.0.1 - - [01/Aug/2026 21:46:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:17,248 127.0.0.1 - - [01/Aug/2026 21:46:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:21,988 127.0.0.1 - - [01/Aug/2026 21:46:21] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:27,004 127.0.0.1 - - [01/Aug/2026 21:46:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:32,064 127.0.0.1 - - [01/Aug/2026 21:46:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:37,131 127.0.0.1 - - [01/Aug/2026 21:46:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:42,007 127.0.0.1 - - [01/Aug/2026 21:46:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:47,120 127.0.0.1 - - [01/Aug/2026 21:46:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:52,231 127.0.0.1 - - [01/Aug/2026 21:46:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:46:57,149 127.0.0.1 - - [01/Aug/2026 21:46:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:02,105 127.0.0.1 - - [01/Aug/2026 21:47:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:07,010 127.0.0.1 - - [01/Aug/2026 21:47:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:12,002 127.0.0.1 - - [01/Aug/2026 21:47:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:17,094 127.0.0.1 - - [01/Aug/2026 21:47:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:21,980 127.0.0.1 - - [01/Aug/2026 21:47:21] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:26,997 127.0.0.1 - - [01/Aug/2026 21:47:26] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:32,078 127.0.0.1 - - [01/Aug/2026 21:47:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:37,006 127.0.0.1 - - [01/Aug/2026 21:47:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:41,989 127.0.0.1 - - [01/Aug/2026 21:47:41] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:47,120 127.0.0.1 - - [01/Aug/2026 21:47:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:52,010 127.0.0.1 - - [01/Aug/2026 21:47:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:47:57,043 127.0.0.1 - - [01/Aug/2026 21:47:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:02,135 127.0.0.1 - - [01/Aug/2026 21:48:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:07,106 127.0.0.1 - - [01/Aug/2026 21:48:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:12,002 127.0.0.1 - - [01/Aug/2026 21:48:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:17,190 127.0.0.1 - - [01/Aug/2026 21:48:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:22,032 127.0.0.1 - - [01/Aug/2026 21:48:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:27,013 127.0.0.1 - - [01/Aug/2026 21:48:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:32,126 127.0.0.1 - - [01/Aug/2026 21:48:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:37,012 127.0.0.1 - - [01/Aug/2026 21:48:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:42,046 127.0.0.1 - - [01/Aug/2026 21:48:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:47,074 127.0.0.1 - - [01/Aug/2026 21:48:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:52,120 127.0.0.1 - - [01/Aug/2026 21:48:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:48:57,029 127.0.0.1 - - [01/Aug/2026 21:48:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:02,098 127.0.0.1 - - [01/Aug/2026 21:49:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:06,994 127.0.0.1 - - [01/Aug/2026 21:49:06] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:12,056 127.0.0.1 - - [01/Aug/2026 21:49:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:17,081 127.0.0.1 - - [01/Aug/2026 21:49:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:22,102 127.0.0.1 - - [01/Aug/2026 21:49:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:27,027 127.0.0.1 - - [01/Aug/2026 21:49:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:32,107 127.0.0.1 - - [01/Aug/2026 21:49:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:37,249 127.0.0.1 - - [01/Aug/2026 21:49:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:42,117 127.0.0.1 - - [01/Aug/2026 21:49:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:47,160 127.0.0.1 - - [01/Aug/2026 21:49:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:52,084 127.0.0.1 - - [01/Aug/2026 21:49:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:49:57,097 127.0.0.1 - - [01/Aug/2026 21:49:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:02,094 127.0.0.1 - - [01/Aug/2026 21:50:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:07,054 127.0.0.1 - - [01/Aug/2026 21:50:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:12,035 127.0.0.1 - - [01/Aug/2026 21:50:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:17,102 127.0.0.1 - - [01/Aug/2026 21:50:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:22,031 127.0.0.1 - - [01/Aug/2026 21:50:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:27,117 127.0.0.1 - - [01/Aug/2026 21:50:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:32,191 127.0.0.1 - - [01/Aug/2026 21:50:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:37,024 127.0.0.1 - - [01/Aug/2026 21:50:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:42,051 127.0.0.1 - - [01/Aug/2026 21:50:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:47,303 127.0.0.1 - - [01/Aug/2026 21:50:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:52,096 127.0.0.1 - - [01/Aug/2026 21:50:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:50:57,029 127.0.0.1 - - [01/Aug/2026 21:50:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:02,703 127.0.0.1 - - [01/Aug/2026 21:51:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:07,022 127.0.0.1 - - [01/Aug/2026 21:51:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:12,019 127.0.0.1 - - [01/Aug/2026 21:51:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:17,212 127.0.0.1 - - [01/Aug/2026 21:51:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:22,027 127.0.0.1 - - [01/Aug/2026 21:51:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:27,020 127.0.0.1 - - [01/Aug/2026 21:51:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:32,080 127.0.0.1 - - [01/Aug/2026 21:51:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:37,028 127.0.0.1 - - [01/Aug/2026 21:51:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:42,116 127.0.0.1 - - [01/Aug/2026 21:51:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:47,085 127.0.0.1 - - [01/Aug/2026 21:51:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:52,071 127.0.0.1 - - [01/Aug/2026 21:51:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:51:57,245 127.0.0.1 - - [01/Aug/2026 21:51:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:02,107 127.0.0.1 - - [01/Aug/2026 21:52:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:07,014 127.0.0.1 - - [01/Aug/2026 21:52:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:12,192 127.0.0.1 - - [01/Aug/2026 21:52:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:17,127 127.0.0.1 - - [01/Aug/2026 21:52:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:22,061 127.0.0.1 - - [01/Aug/2026 21:52:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:27,134 127.0.0.1 - - [01/Aug/2026 21:52:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:32,146 127.0.0.1 - - [01/Aug/2026 21:52:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:37,025 127.0.0.1 - - [01/Aug/2026 21:52:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:42,128 127.0.0.1 - - [01/Aug/2026 21:52:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:47,389 127.0.0.1 - - [01/Aug/2026 21:52:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:52,030 127.0.0.1 - - [01/Aug/2026 21:52:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:52:57,026 127.0.0.1 - - [01/Aug/2026 21:52:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:02,148 127.0.0.1 - - [01/Aug/2026 21:53:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:07,010 127.0.0.1 - - [01/Aug/2026 21:53:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:12,044 127.0.0.1 - - [01/Aug/2026 21:53:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:17,118 127.0.0.1 - - [01/Aug/2026 21:53:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:22,218 127.0.0.1 - - [01/Aug/2026 21:53:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:27,046 127.0.0.1 - - [01/Aug/2026 21:53:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:32,265 127.0.0.1 - - [01/Aug/2026 21:53:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:37,191 127.0.0.1 - - [01/Aug/2026 21:53:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:42,031 127.0.0.1 - - [01/Aug/2026 21:53:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:47,089 127.0.0.1 - - [01/Aug/2026 21:53:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:52,360 127.0.0.1 - - [01/Aug/2026 21:53:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:53:57,042 127.0.0.1 - - [01/Aug/2026 21:53:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:02,416 127.0.0.1 - - [01/Aug/2026 21:54:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:07,052 127.0.0.1 - - [01/Aug/2026 21:54:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:12,047 127.0.0.1 - - [01/Aug/2026 21:54:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:17,120 127.0.0.1 - - [01/Aug/2026 21:54:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:22,054 127.0.0.1 - - [01/Aug/2026 21:54:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:27,053 127.0.0.1 - - [01/Aug/2026 21:54:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:32,222 127.0.0.1 - - [01/Aug/2026 21:54:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:38,048 127.0.0.1 - - [01/Aug/2026 21:54:38] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:42,080 127.0.0.1 - - [01/Aug/2026 21:54:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:47,161 127.0.0.1 - - [01/Aug/2026 21:54:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:52,057 127.0.0.1 - - [01/Aug/2026 21:54:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:54:57,060 127.0.0.1 - - [01/Aug/2026 21:54:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:02,238 127.0.0.1 - - [01/Aug/2026 21:55:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:07,161 127.0.0.1 - - [01/Aug/2026 21:55:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:12,081 127.0.0.1 - - [01/Aug/2026 21:55:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:17,122 127.0.0.1 - - [01/Aug/2026 21:55:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:22,061 127.0.0.1 - - [01/Aug/2026 21:55:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:27,083 127.0.0.1 - - [01/Aug/2026 21:55:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:32,271 127.0.0.1 - - [01/Aug/2026 21:55:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:37,057 127.0.0.1 - - [01/Aug/2026 21:55:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:42,208 127.0.0.1 - - [01/Aug/2026 21:55:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:47,452 127.0.0.1 - - [01/Aug/2026 21:55:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:52,059 127.0.0.1 - - [01/Aug/2026 21:55:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:55:57,064 127.0.0.1 - - [01/Aug/2026 21:55:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:02,098 127.0.0.1 - - [01/Aug/2026 21:56:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:07,364 127.0.0.1 - - [01/Aug/2026 21:56:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:12,089 127.0.0.1 - - [01/Aug/2026 21:56:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:17,432 127.0.0.1 - - [01/Aug/2026 21:56:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:22,190 127.0.0.1 - - [01/Aug/2026 21:56:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:27,200 127.0.0.1 - - [01/Aug/2026 21:56:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:32,935 127.0.0.1 - - [01/Aug/2026 21:56:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:38,162 127.0.0.1 - - [01/Aug/2026 21:56:38] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:42,108 127.0.0.1 - - [01/Aug/2026 21:56:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:47,188 127.0.0.1 - - [01/Aug/2026 21:56:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:52,181 127.0.0.1 - - [01/Aug/2026 21:56:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:56:57,249 127.0.0.1 - - [01/Aug/2026 21:56:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:02,224 127.0.0.1 - - [01/Aug/2026 21:57:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:07,122 127.0.0.1 - - [01/Aug/2026 21:57:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:12,190 127.0.0.1 - - [01/Aug/2026 21:57:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:17,102 127.0.0.1 - - [01/Aug/2026 21:57:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:22,617 127.0.0.1 - - [01/Aug/2026 21:57:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:27,363 127.0.0.1 - - [01/Aug/2026 21:57:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:32,098 127.0.0.1 - - [01/Aug/2026 21:57:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:37,218 127.0.0.1 - - [01/Aug/2026 21:57:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:42,413 127.0.0.1 - - [01/Aug/2026 21:57:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:47,222 127.0.0.1 - - [01/Aug/2026 21:57:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:53,188 127.0.0.1 - - [01/Aug/2026 21:57:53] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:57:57,391 127.0.0.1 - - [01/Aug/2026 21:57:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:02,415 127.0.0.1 - - [01/Aug/2026 21:58:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:07,235 127.0.0.1 - - [01/Aug/2026 21:58:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:12,802 127.0.0.1 - - [01/Aug/2026 21:58:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:17,245 127.0.0.1 - - [01/Aug/2026 21:58:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:22,459 127.0.0.1 - - [01/Aug/2026 21:58:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:27,124 127.0.0.1 - - [01/Aug/2026 21:58:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:32,229 127.0.0.1 - - [01/Aug/2026 21:58:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:37,255 127.0.0.1 - - [01/Aug/2026 21:58:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:42,163 127.0.0.1 - - [01/Aug/2026 21:58:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:47,533 127.0.0.1 - - [01/Aug/2026 21:58:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:52,229 127.0.0.1 - - [01/Aug/2026 21:58:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:58:57,211 127.0.0.1 - - [01/Aug/2026 21:58:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:02,219 127.0.0.1 - - [01/Aug/2026 21:59:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:07,226 127.0.0.1 - - [01/Aug/2026 21:59:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:12,194 127.0.0.1 - - [01/Aug/2026 21:59:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:17,331 127.0.0.1 - - [01/Aug/2026 21:59:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:22,207 127.0.0.1 - - [01/Aug/2026 21:59:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:28,127 127.0.0.1 - - [01/Aug/2026 21:59:28] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:32,135 127.0.0.1 - - [01/Aug/2026 21:59:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:37,330 127.0.0.1 - - [01/Aug/2026 21:59:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:42,147 127.0.0.1 - - [01/Aug/2026 21:59:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:47,153 127.0.0.1 - - [01/Aug/2026 21:59:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:52,236 127.0.0.1 - - [01/Aug/2026 21:59:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:59:57,175 127.0.0.1 - - [01/Aug/2026 21:59:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:02,267 127.0.0.1 - - [01/Aug/2026 22:00:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:07,619 127.0.0.1 - - [01/Aug/2026 22:00:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:13,290 127.0.0.1 - - [01/Aug/2026 22:00:13] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:18,114 127.0.0.1 - - [01/Aug/2026 22:00:18] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:22,255 127.0.0.1 - - [01/Aug/2026 22:00:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:27,931 127.0.0.1 - - [01/Aug/2026 22:00:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:32,311 127.0.0.1 - - [01/Aug/2026 22:00:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:37,571 127.0.0.1 - - [01/Aug/2026 22:00:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:42,884 127.0.0.1 - - [01/Aug/2026 22:00:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:43,621 skip KXBTC15M-26AUG020115-15: mom=UP llm=SKIP +2026-08-01 22:00:46,431 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:00:47,155 127.0.0.1 - - [01/Aug/2026 22:00:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:48,836 skip KXBTC15M-26AUG020115-15: ask None¢ > stake cap 20¢ +2026-08-01 22:00:52,276 127.0.0.1 - - [01/Aug/2026 22:00:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:56,705 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:00:57,201 127.0.0.1 - - [01/Aug/2026 22:00:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:00:58,206 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:01:02,418 127.0.0.1 - - [01/Aug/2026 22:01:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:07,469 127.0.0.1 - - [01/Aug/2026 22:01:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:07,999 skip KXBTC15M-26AUG020115-15: mom=UP llm=SKIP +2026-08-01 22:01:11,843 skip KXBTC15M-26AUG020115-15: ask None¢ > stake cap 20¢ +2026-08-01 22:01:13,189 127.0.0.1 - - [01/Aug/2026 22:01:13] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:17,228 127.0.0.1 - - [01/Aug/2026 22:01:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:22,283 127.0.0.1 - - [01/Aug/2026 22:01:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:24,692 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:01:26,687 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:01:27,272 127.0.0.1 - - [01/Aug/2026 22:01:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:32,527 127.0.0.1 - - [01/Aug/2026 22:01:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:35,077 skip KXBTC15M-26AUG020115-15: mom=UP llm=SKIP +2026-08-01 22:01:37,360 127.0.0.1 - - [01/Aug/2026 22:01:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:42,730 127.0.0.1 - - [01/Aug/2026 22:01:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:47,298 127.0.0.1 - - [01/Aug/2026 22:01:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:52,285 127.0.0.1 - - [01/Aug/2026 22:01:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:01:52,938 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:01:54,595 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:01:57,419 127.0.0.1 - - [01/Aug/2026 22:01:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:02,182 127.0.0.1 - - [01/Aug/2026 22:02:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:07,471 127.0.0.1 - - [01/Aug/2026 22:02:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:12,264 127.0.0.1 - - [01/Aug/2026 22:02:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:16,143 skip KXBTC15M-26AUG020115-15: mom=UP llm=SKIP +2026-08-01 22:02:17,440 127.0.0.1 - - [01/Aug/2026 22:02:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:22,365 127.0.0.1 - - [01/Aug/2026 22:02:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:23,023 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:02:27,318 127.0.0.1 - - [01/Aug/2026 22:02:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:32,209 127.0.0.1 - - [01/Aug/2026 22:02:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:37,238 127.0.0.1 - - [01/Aug/2026 22:02:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:42,723 127.0.0.1 - - [01/Aug/2026 22:02:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:46,485 skip KXBTC15M-26AUG020115-15: mom=FLAT llm=SKIP +2026-08-01 22:02:47,284 127.0.0.1 - - [01/Aug/2026 22:02:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:52,281 127.0.0.1 - - [01/Aug/2026 22:02:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:02:57,262 127.0.0.1 - - [01/Aug/2026 22:02:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:02,332 127.0.0.1 - - [01/Aug/2026 22:03:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:07,200 127.0.0.1 - - [01/Aug/2026 22:03:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:12,310 127.0.0.1 - - [01/Aug/2026 22:03:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:17,297 127.0.0.1 - - [01/Aug/2026 22:03:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:22,417 127.0.0.1 - - [01/Aug/2026 22:03:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:27,193 127.0.0.1 - - [01/Aug/2026 22:03:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:32,264 127.0.0.1 - - [01/Aug/2026 22:03:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:38,982 127.0.0.1 - - [01/Aug/2026 22:03:38] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:42,306 127.0.0.1 - - [01/Aug/2026 22:03:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:47,200 127.0.0.1 - - [01/Aug/2026 22:03:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:52,294 127.0.0.1 - - [01/Aug/2026 22:03:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:03:57,638 127.0.0.1 - - [01/Aug/2026 22:03:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:02,264 127.0.0.1 - - [01/Aug/2026 22:04:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:07,228 127.0.0.1 - - [01/Aug/2026 22:04:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:12,497 127.0.0.1 - - [01/Aug/2026 22:04:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:17,226 127.0.0.1 - - [01/Aug/2026 22:04:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:22,624 127.0.0.1 - - [01/Aug/2026 22:04:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:27,227 127.0.0.1 - - [01/Aug/2026 22:04:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:32,335 127.0.0.1 - - [01/Aug/2026 22:04:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:37,237 127.0.0.1 - - [01/Aug/2026 22:04:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:42,723 127.0.0.1 - - [01/Aug/2026 22:04:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:47,247 127.0.0.1 - - [01/Aug/2026 22:04:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:52,600 127.0.0.1 - - [01/Aug/2026 22:04:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:04:57,240 127.0.0.1 - - [01/Aug/2026 22:04:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:02,321 127.0.0.1 - - [01/Aug/2026 22:05:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:08,296 127.0.0.1 - - [01/Aug/2026 22:05:08] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:12,289 127.0.0.1 - - [01/Aug/2026 22:05:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:17,659 127.0.0.1 - - [01/Aug/2026 22:05:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:23,121 127.0.0.1 - - [01/Aug/2026 22:05:23] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:27,592 127.0.0.1 - - [01/Aug/2026 22:05:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:32,395 127.0.0.1 - - [01/Aug/2026 22:05:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:37,348 127.0.0.1 - - [01/Aug/2026 22:05:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:42,608 127.0.0.1 - - [01/Aug/2026 22:05:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:47,316 127.0.0.1 - - [01/Aug/2026 22:05:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:53,106 127.0.0.1 - - [01/Aug/2026 22:05:53] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:05:57,601 127.0.0.1 - - [01/Aug/2026 22:05:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:02,731 127.0.0.1 - - [01/Aug/2026 22:06:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:07,353 127.0.0.1 - - [01/Aug/2026 22:06:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:12,293 127.0.0.1 - - [01/Aug/2026 22:06:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:17,345 127.0.0.1 - - [01/Aug/2026 22:06:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:22,415 127.0.0.1 - - [01/Aug/2026 22:06:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:27,349 127.0.0.1 - - [01/Aug/2026 22:06:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:32,362 127.0.0.1 - - [01/Aug/2026 22:06:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:37,513 127.0.0.1 - - [01/Aug/2026 22:06:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:42,240 127.0.0.1 - - [01/Aug/2026 22:06:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:47,275 127.0.0.1 - - [01/Aug/2026 22:06:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:52,416 127.0.0.1 - - [01/Aug/2026 22:06:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:06:57,396 127.0.0.1 - - [01/Aug/2026 22:06:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:02,298 127.0.0.1 - - [01/Aug/2026 22:07:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:07,315 127.0.0.1 - - [01/Aug/2026 22:07:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:12,413 127.0.0.1 - - [01/Aug/2026 22:07:12] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:18,012 127.0.0.1 - - [01/Aug/2026 22:07:18] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:22,449 127.0.0.1 - - [01/Aug/2026 22:07:22] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:27,404 127.0.0.1 - - [01/Aug/2026 22:07:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:32,572 127.0.0.1 - - [01/Aug/2026 22:07:32] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:37,438 127.0.0.1 - - [01/Aug/2026 22:07:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:42,333 127.0.0.1 - - [01/Aug/2026 22:07:42] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:47,337 127.0.0.1 - - [01/Aug/2026 22:07:47] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:52,358 127.0.0.1 - - [01/Aug/2026 22:07:52] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:07:57,307 127.0.0.1 - - [01/Aug/2026 22:07:57] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:08:02,507 127.0.0.1 - - [01/Aug/2026 22:08:02] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:08:07,487 127.0.0.1 - - [01/Aug/2026 22:08:07] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:08:13,413 127.0.0.1 - - [01/Aug/2026 22:08:13] "GET /api/state HTTP/1.1" 200 - +2026-08-01 22:15:51,326 skip KXBTC15M-26AUG020130-30: mom=DOWN llm=SKIP +2026-08-01 22:15:53,252 skip KXBTC15M-26AUG020130-30: mom=DOWN llm=SKIP +2026-08-01 22:15:57,991 skip KXBTC15M-26AUG020130-30: mom=DOWN llm=SKIP +2026-08-01 22:16:00,178 skip KXBTC15M-26AUG020130-30: mom=DOWN llm=SKIP +2026-08-01 22:16:01,241 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:16:24,681 skip KXBTC15M-26AUG020130-30: mom=DOWN llm=SKIP +2026-08-01 22:30:28,534 skip KXBTC15M-26AUG020145-45: mom=FLAT llm=SKIP +2026-08-01 22:30:30,798 skip KXBTC15M-26AUG020145-45: mom=FLAT llm=SKIP +2026-08-01 22:30:33,469 skip KXBTC15M-26AUG020145-45: mom=FLAT llm=SKIP +2026-08-01 22:30:35,447 skip KXBTC15M-26AUG020145-45: mom=FLAT llm=SKIP +2026-08-01 22:30:38,119 skip KXBTC15M-26AUG020145-45: mom=FLAT llm=SKIP +2026-08-01 22:45:45,108 skip KXBTC15M-26AUG020200-00: mom=DOWN llm=SKIP +2026-08-01 22:45:46,902 skip KXBTC15M-26AUG020200-00: mom=DOWN llm=SKIP +2026-08-01 22:45:49,008 skip KXBTC15M-26AUG020200-00: mom=DOWN llm=SKIP +2026-08-01 22:45:50,847 skip KXBTC15M-26AUG020200-00: mom=DOWN llm=SKIP +2026-08-01 22:45:52,769 skip KXBTC15M-26AUG020200-00: mom=DOWN llm=SKIP +2026-08-01 23:00:42,225 skip KXBTC15M-26AUG020215-15: mom=FLAT llm=SKIP +2026-08-01 23:00:44,082 skip KXBTC15M-26AUG020215-15: mom=FLAT llm=SKIP +2026-08-01 23:00:46,004 skip KXBTC15M-26AUG020215-15: mom=FLAT llm=SKIP +2026-08-01 23:00:47,853 skip KXBTC15M-26AUG020215-15: mom=FLAT llm=SKIP +2026-08-01 23:00:55,206 skip KXBTC15M-26AUG020215-15: mom=FLAT llm=SKIP +2026-08-01 23:15:39,537 skip KXBTC15M-26AUG020230-30: mom=FLAT llm=SKIP +2026-08-01 23:15:41,592 skip KXBTC15M-26AUG020230-30: mom=FLAT llm=SKIP +2026-08-01 23:15:43,457 skip KXBTC15M-26AUG020230-30: mom=FLAT llm=SKIP +2026-08-01 23:15:45,267 skip KXBTC15M-26AUG020230-30: mom=FLAT llm=SKIP +2026-08-01 23:15:47,287 skip KXBTC15M-26AUG020230-30: mom=FLAT llm=SKIP +2026-08-01 23:30:39,844 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 23:30:41,094 skip KXBTC15M-26AUG020245-45: mom=UP llm=SKIP +2026-08-01 23:30:42,247 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 23:30:43,887 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 23:30:47,443 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 23:31:02,912 skip KXBTC15M-26AUG020245-45: mom=UP llm=SKIP +2026-08-01 23:31:04,856 skip KXBTC15M-26AUG020245-45: mom=UP llm=SKIP +2026-08-01 23:31:06,956 skip KXBTC15M-26AUG020245-45: mom=UP llm=SKIP +2026-08-01 23:31:15,212 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 23:31:38,420 skip KXBTC15M-26AUG020245-45: mom=UP llm=SKIP +2026-08-01 23:45:33,888 skip KXBTC15M-26AUG020300-00: mom=FLAT llm=SKIP +2026-08-01 23:45:35,575 skip KXBTC15M-26AUG020300-00: mom=FLAT llm=SKIP +2026-08-01 23:45:37,428 skip KXBTC15M-26AUG020300-00: mom=FLAT llm=SKIP +2026-08-01 23:45:40,129 skip KXBTC15M-26AUG020300-00: mom=FLAT llm=SKIP +2026-08-01 23:45:42,154 skip KXBTC15M-26AUG020300-00: mom=FLAT llm=SKIP +2026-08-02 00:00:28,526 skip KXBTC15M-26AUG020315-15: mom=FLAT llm=SKIP +2026-08-02 00:00:30,216 skip KXBTC15M-26AUG020315-15: mom=FLAT llm=SKIP +2026-08-02 00:00:32,066 skip KXBTC15M-26AUG020315-15: mom=FLAT llm=SKIP +2026-08-02 00:00:33,784 skip KXBTC15M-26AUG020315-15: mom=FLAT llm=SKIP +2026-08-02 00:00:35,709 skip KXBTC15M-26AUG020315-15: mom=FLAT llm=SKIP +2026-08-02 00:15:24,448 skip KXBTC15M-26AUG020330-30: mom=FLAT llm=SKIP +2026-08-02 00:15:26,330 skip KXBTC15M-26AUG020330-30: mom=FLAT llm=SKIP +2026-08-02 00:15:28,171 skip KXBTC15M-26AUG020330-30: mom=FLAT llm=SKIP +2026-08-02 00:15:30,051 skip KXBTC15M-26AUG020330-30: mom=FLAT llm=SKIP +2026-08-02 00:15:31,894 skip KXBTC15M-26AUG020330-30: mom=FLAT llm=SKIP +2026-08-02 00:30:40,080 skip KXBTC15M-26AUG020345-45: mom=FLAT llm=SKIP +2026-08-02 00:30:41,938 skip KXBTC15M-26AUG020345-45: mom=FLAT llm=SKIP +2026-08-02 00:30:43,537 skip KXBTC15M-26AUG020345-45: mom=FLAT llm=SKIP +2026-08-02 00:30:45,416 skip KXBTC15M-26AUG020345-45: mom=FLAT llm=SKIP +2026-08-02 00:30:47,247 skip KXBTC15M-26AUG020345-45: mom=FLAT llm=SKIP +2026-08-02 00:45:35,241 skip KXBTC15M-26AUG020400-00: mom=UP llm=SKIP +2026-08-02 00:45:37,097 skip KXBTC15M-26AUG020400-00: mom=UP llm=SKIP +2026-08-02 00:45:38,670 skip KXBTC15M-26AUG020400-00: mom=UP llm=SKIP +2026-08-02 00:45:45,948 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 00:45:47,847 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 00:46:08,932 skip KXBTC15M-26AUG020400-00: mom=FLAT llm=SKIP +2026-08-02 00:46:11,559 skip KXBTC15M-26AUG020400-00: mom=FLAT llm=SKIP +2026-08-02 01:00:42,618 skip KXBTC15M-26AUG020415-15: mom=FLAT llm=SKIP +2026-08-02 01:00:44,309 skip KXBTC15M-26AUG020415-15: mom=FLAT llm=SKIP +2026-08-02 01:00:45,798 skip KXBTC15M-26AUG020415-15: mom=FLAT llm=SKIP +2026-08-02 01:00:47,209 skip KXBTC15M-26AUG020415-15: mom=FLAT llm=SKIP +2026-08-02 01:00:49,527 skip KXBTC15M-26AUG020415-15: mom=FLAT llm=SKIP +2026-08-02 01:15:57,060 skip KXBTC15M-26AUG020430-30: mom=FLAT llm=SKIP +2026-08-02 01:15:58,723 skip KXBTC15M-26AUG020430-30: mom=FLAT llm=SKIP +2026-08-02 01:16:00,301 skip KXBTC15M-26AUG020430-30: mom=FLAT llm=SKIP +2026-08-02 01:16:01,867 skip KXBTC15M-26AUG020430-30: mom=FLAT llm=SKIP +2026-08-02 01:16:03,992 skip KXBTC15M-26AUG020430-30: mom=FLAT llm=SKIP +2026-08-02 01:30:09,358 skip KXBTC15M-26AUG020445-45: mom=DOWN llm=SKIP +2026-08-02 01:30:10,600 skip KXBTC15M-26AUG020445-45: mom=DOWN llm=SKIP +2026-08-02 01:30:12,000 skip KXBTC15M-26AUG020445-45: mom=DOWN llm=SKIP +2026-08-02 01:30:13,246 skip KXBTC15M-26AUG020445-45: mom=DOWN llm=SKIP +2026-08-02 01:30:14,406 skip KXBTC15M-26AUG020445-45: ask None¢ > stake cap 20¢ +2026-08-02 01:30:36,032 skip KXBTC15M-26AUG020445-45: mom=DOWN llm=SKIP +2026-08-02 01:45:43,435 skip KXBTC15M-26AUG020500-00: mom=DOWN llm=SKIP +2026-08-02 01:45:44,342 skip KXBTC15M-26AUG020500-00: mom=DOWN llm=SKIP +2026-08-02 01:45:45,100 skip KXBTC15M-26AUG020500-00: mom=DOWN llm=SKIP +2026-08-02 01:45:45,943 skip KXBTC15M-26AUG020500-00: mom=DOWN llm=SKIP +2026-08-02 01:45:46,896 skip KXBTC15M-26AUG020500-00: mom=DOWN llm=SKIP +2026-08-02 02:00:37,677 skip KXBTC15M-26AUG020515-15: mom=FLAT llm=SKIP +2026-08-02 02:00:38,705 skip KXBTC15M-26AUG020515-15: mom=FLAT llm=SKIP +2026-08-02 02:00:39,938 skip KXBTC15M-26AUG020515-15: mom=FLAT llm=SKIP +2026-08-02 02:00:40,906 skip KXBTC15M-26AUG020515-15: mom=FLAT llm=SKIP +2026-08-02 02:00:41,808 skip KXBTC15M-26AUG020515-15: mom=FLAT llm=SKIP +2026-08-02 02:15:30,670 skip KXBTC15M-26AUG020530-30: mom=UP llm=SKIP +2026-08-02 02:15:31,451 skip KXBTC15M-26AUG020530-30: mom=UP llm=SKIP +2026-08-02 02:15:32,257 skip KXBTC15M-26AUG020530-30: mom=UP llm=SKIP +2026-08-02 02:15:33,869 skip KXBTC15M-26AUG020530-30: ask None¢ > stake cap 20¢ +2026-08-02 02:15:37,988 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 02:15:55,453 skip KXBTC15M-26AUG020530-30: mom=UP llm=SKIP +2026-08-02 02:16:04,159 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 02:16:25,744 skip KXBTC15M-26AUG020530-30: mom=FLAT llm=SKIP +2026-08-02 02:30:17,817 skip KXBTC15M-26AUG020545-45: mom=DOWN llm=SKIP +2026-08-02 02:30:18,871 skip KXBTC15M-26AUG020545-45: mom=DOWN llm=SKIP +2026-08-02 02:30:19,876 skip KXBTC15M-26AUG020545-45: mom=DOWN llm=SKIP +2026-08-02 02:30:20,815 skip KXBTC15M-26AUG020545-45: mom=DOWN llm=SKIP +2026-08-02 02:30:22,225 skip KXBTC15M-26AUG020545-45: mom=DOWN llm=SKIP +2026-08-02 02:45:51,515 skip KXBTC15M-26AUG020600-00: mom=FLAT llm=SKIP +2026-08-02 02:45:52,336 skip KXBTC15M-26AUG020600-00: mom=FLAT llm=SKIP +2026-08-02 02:45:53,166 skip KXBTC15M-26AUG020600-00: mom=FLAT llm=SKIP +2026-08-02 02:45:53,865 skip KXBTC15M-26AUG020600-00: mom=FLAT llm=SKIP +2026-08-02 02:45:54,729 skip KXBTC15M-26AUG020600-00: mom=FLAT llm=SKIP +2026-08-02 02:58:32,788 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Read timed out. (read timeout=15) +2026-08-02 02:58:32,790 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Read timed out. (read timeout=15) +2026-08-02 02:58:33,719 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Read timed out. (read timeout=15) +2026-08-02 02:58:34,346 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Read timed out. (read timeout=15) +2026-08-02 02:58:35,283 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Read timed out. (read timeout=15) +2026-08-02 02:59:04,972 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:04,974 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:05,856 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:06,478 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:07,417 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:37,142 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:37,144 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:38,018 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:38,626 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:39,575 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 03:00:43,157 skip KXBTC15M-26AUG020615-15: mom=FLAT llm=SKIP +2026-08-02 03:00:44,235 skip KXBTC15M-26AUG020615-15: mom=FLAT llm=SKIP +2026-08-02 03:00:45,057 skip KXBTC15M-26AUG020615-15: mom=FLAT llm=SKIP +2026-08-02 03:00:45,891 skip KXBTC15M-26AUG020615-15: mom=FLAT llm=SKIP +2026-08-02 03:00:46,736 skip KXBTC15M-26AUG020615-15: mom=FLAT llm=SKIP +2026-08-02 03:15:15,539 skip KXBTC15M-26AUG020630-30: mom=DOWN llm=SKIP +2026-08-02 03:15:16,790 skip KXBTC15M-26AUG020630-30: mom=DOWN llm=SKIP +2026-08-02 03:15:18,273 skip KXBTC15M-26AUG020630-30: mom=DOWN llm=SKIP +2026-08-02 03:15:18,602 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 03:15:19,599 skip KXBTC15M-26AUG020630-30: mom=DOWN llm=SKIP +2026-08-02 03:16:12,711 skip KXBTC15M-26AUG020630-30: mom=DOWN llm=SKIP +2026-08-02 03:31:24,240 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 03:31:24,365 skip KXBTC15M-26AUG020645-45: mom=FLAT llm=SKIP +2026-08-02 03:31:25,838 skip KXBTC15M-26AUG020645-45: mom=FLAT llm=SKIP +2026-08-02 03:31:27,291 skip KXBTC15M-26AUG020645-45: mom=FLAT llm=SKIP +2026-08-02 03:31:29,474 skip KXBTC15M-26AUG020645-45: mom=FLAT llm=SKIP +2026-08-02 03:31:30,958 skip KXBTC15M-26AUG020645-45: mom=FLAT llm=SKIP +2026-08-02 03:45:56,982 skip KXBTC15M-26AUG020700-00: mom=UP llm=SKIP +2026-08-02 03:45:58,591 skip KXBTC15M-26AUG020700-00: mom=UP llm=SKIP +2026-08-02 03:45:59,371 skip KXBTC15M-26AUG020700-00: mom=UP llm=SKIP +2026-08-02 03:46:02,520 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 03:46:04,909 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 03:46:23,849 skip KXBTC15M-26AUG020700-00: mom=UP llm=SKIP +2026-08-02 03:46:26,271 skip KXBTC15M-26AUG020700-00: mom=UP llm=SKIP +2026-08-02 04:00:19,304 skip KXBTC15M-26AUG020715-15: mom=FLAT llm=SKIP +2026-08-02 04:00:26,091 skip KXBTC15M-26AUG020715-15: mom=FLAT llm=SKIP +2026-08-02 04:00:26,894 skip KXBTC15M-26AUG020715-15: mom=FLAT llm=SKIP +2026-08-02 04:00:28,049 skip KXBTC15M-26AUG020715-15: mom=FLAT llm=SKIP +2026-08-02 04:00:31,611 skip KXBTC15M-26AUG020715-15: mom=FLAT llm=SKIP +2026-08-02 04:15:31,974 skip KXBTC15M-26AUG020730-30: mom=FLAT llm=SKIP +2026-08-02 04:15:34,753 skip KXBTC15M-26AUG020730-30: mom=FLAT llm=SKIP +2026-08-02 04:15:35,639 skip KXBTC15M-26AUG020730-30: mom=FLAT llm=SKIP +2026-08-02 04:15:36,597 skip KXBTC15M-26AUG020730-30: mom=FLAT llm=SKIP +2026-08-02 04:15:39,965 skip KXBTC15M-26AUG020730-30: mom=FLAT llm=SKIP +2026-08-02 04:30:24,112 skip KXBTC15M-26AUG020745-45: mom=FLAT llm=SKIP +2026-08-02 04:30:24,927 skip KXBTC15M-26AUG020745-45: mom=FLAT llm=SKIP +2026-08-02 04:30:25,736 skip KXBTC15M-26AUG020745-45: mom=FLAT llm=SKIP +2026-08-02 04:30:26,838 skip KXBTC15M-26AUG020745-45: mom=FLAT llm=SKIP +2026-08-02 04:30:27,694 skip KXBTC15M-26AUG020745-45: mom=FLAT llm=SKIP +2026-08-02 04:45:36,785 skip KXBTC15M-26AUG020800-00: mom=DOWN llm=SKIP +2026-08-02 04:45:37,654 skip KXBTC15M-26AUG020800-00: mom=DOWN llm=SKIP +2026-08-02 04:45:38,559 skip KXBTC15M-26AUG020800-00: mom=DOWN llm=SKIP +2026-08-02 04:45:39,458 skip KXBTC15M-26AUG020800-00: mom=DOWN llm=SKIP +2026-08-02 04:45:40,349 skip KXBTC15M-26AUG020800-00: mom=DOWN llm=SKIP +2026-08-02 05:00:49,635 skip KXBTC15M-26AUG020815-15: mom=FLAT llm=SKIP +2026-08-02 05:00:50,833 skip KXBTC15M-26AUG020815-15: mom=FLAT llm=SKIP +2026-08-02 05:00:51,695 skip KXBTC15M-26AUG020815-15: mom=FLAT llm=SKIP +2026-08-02 05:00:52,855 skip KXBTC15M-26AUG020815-15: mom=FLAT llm=SKIP +2026-08-02 05:00:53,719 skip KXBTC15M-26AUG020815-15: mom=FLAT llm=SKIP +2026-08-02 05:15:22,437 skip KXBTC15M-26AUG020830-30: mom=UP llm=SKIP +2026-08-02 05:15:26,120 skip KXBTC15M-26AUG020830-30: ask None¢ > stake cap 20¢ +2026-08-02 05:15:28,115 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:15:28,866 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:15:30,023 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:15:47,650 skip KXBTC15M-26AUG020830-30: mom=UP llm=SKIP +2026-08-02 05:15:49,350 skip KXBTC15M-26AUG020830-30: mom=UP llm=SKIP +2026-08-02 05:15:50,158 skip KXBTC15M-26AUG020830-30: mom=UP llm=SKIP +2026-08-02 05:15:56,001 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:16:22,405 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:16:48,860 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:17:10,408 skip KXBTC15M-26AUG020830-30: mom=UP llm=SKIP +2026-08-02 05:30:34,554 skip KXBTC15M-26AUG020845-45: mom=FLAT llm=SKIP +2026-08-02 05:30:35,693 skip KXBTC15M-26AUG020845-45: mom=FLAT llm=SKIP +2026-08-02 05:30:36,662 skip KXBTC15M-26AUG020845-45: mom=FLAT llm=SKIP +2026-08-02 05:30:37,971 skip KXBTC15M-26AUG020845-45: mom=FLAT llm=SKIP +2026-08-02 05:30:38,801 skip KXBTC15M-26AUG020845-45: mom=FLAT llm=SKIP +2026-08-02 05:45:26,802 skip KXBTC15M-26AUG020900-00: mom=FLAT llm=SKIP +2026-08-02 05:45:27,631 skip KXBTC15M-26AUG020900-00: mom=FLAT llm=SKIP +2026-08-02 05:45:28,427 skip KXBTC15M-26AUG020900-00: mom=FLAT llm=SKIP +2026-08-02 05:45:29,223 skip KXBTC15M-26AUG020900-00: mom=FLAT llm=SKIP +2026-08-02 05:45:30,046 skip KXBTC15M-26AUG020900-00: mom=FLAT llm=SKIP +2026-08-02 06:01:18,133 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 06:01:18,224 skip KXBTC15M-26AUG020915-15: mom=DOWN llm=SKIP +2026-08-02 06:01:19,219 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 06:01:19,298 skip KXBTC15M-26AUG020915-15: mom=DOWN llm=SKIP +2026-08-02 06:01:19,397 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 06:01:19,526 skip KXBTC15M-26AUG020915-15: mom=DOWN llm=SKIP +2026-08-02 06:01:21,261 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 06:01:21,343 skip KXBTC15M-26AUG020915-15: mom=DOWN llm=SKIP +2026-08-02 06:01:21,685 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 06:01:21,767 skip KXBTC15M-26AUG020915-15: mom=DOWN llm=SKIP +2026-08-02 06:15:47,149 skip KXBTC15M-26AUG020930-30: mom=FLAT llm=SKIP +2026-08-02 06:15:48,039 skip KXBTC15M-26AUG020930-30: mom=FLAT llm=SKIP +2026-08-02 06:15:49,804 skip KXBTC15M-26AUG020930-30: mom=FLAT llm=SKIP +2026-08-02 06:15:51,210 skip KXBTC15M-26AUG020930-30: mom=FLAT llm=SKIP +2026-08-02 06:15:52,398 skip KXBTC15M-26AUG020930-30: mom=FLAT llm=SKIP +2026-08-02 06:30:39,593 skip KXBTC15M-26AUG020945-45: mom=FLAT llm=SKIP +2026-08-02 06:30:40,731 skip KXBTC15M-26AUG020945-45: mom=FLAT llm=SKIP +2026-08-02 06:30:41,544 skip KXBTC15M-26AUG020945-45: mom=FLAT llm=SKIP +2026-08-02 06:30:42,342 skip KXBTC15M-26AUG020945-45: mom=FLAT llm=SKIP +2026-08-02 06:30:43,148 skip KXBTC15M-26AUG020945-45: mom=FLAT llm=SKIP +2026-08-02 06:45:31,886 skip KXBTC15M-26AUG021000-00: mom=UP llm=SKIP +2026-08-02 06:45:32,885 skip KXBTC15M-26AUG021000-00: mom=UP llm=SKIP +2026-08-02 06:45:33,761 skip KXBTC15M-26AUG021000-00: ask None¢ > stake cap 20¢ +2026-08-02 06:45:39,485 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 06:45:40,288 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 06:45:55,288 skip KXBTC15M-26AUG021000-00: mom=UP llm=SKIP +2026-08-02 06:46:01,062 skip KXBTC15M-26AUG021000-00: mom=FLAT llm=SKIP +2026-08-02 06:46:01,890 skip KXBTC15M-26AUG021000-00: mom=FLAT llm=SKIP +2026-08-02 07:00:24,822 skip KXBTC15M-26AUG021015-15: mom=FLAT llm=SKIP +2026-08-02 07:00:25,531 skip KXBTC15M-26AUG021015-15: mom=FLAT llm=SKIP +2026-08-02 07:00:26,365 skip KXBTC15M-26AUG021015-15: mom=FLAT llm=SKIP +2026-08-02 07:00:28,922 skip KXBTC15M-26AUG021015-15: mom=FLAT llm=SKIP +2026-08-02 07:00:29,759 skip KXBTC15M-26AUG021015-15: mom=FLAT llm=SKIP +2026-08-02 07:06:48,604 127.0.0.1 - - [02/Aug/2026 07:06:48] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:06:53,342 127.0.0.1 - - [02/Aug/2026 07:06:53] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:06:58,350 127.0.0.1 - - [02/Aug/2026 07:06:58] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:07:03,435 127.0.0.1 - - [02/Aug/2026 07:07:03] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:07:08,298 127.0.0.1 - - [02/Aug/2026 07:07:08] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:07:13,339 127.0.0.1 - - [02/Aug/2026 07:07:13] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:07:19,049 127.0.0.1 - - [02/Aug/2026 07:07:19] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:11:33,971 K4LSH1_OPS online — mode=AUTO dry_run=False stake=20¢ +2026-08-02 07:11:45,153 skip KXBTC15M-26AUG021015-15: no swing (0.025% < 0.12%) +2026-08-02 07:12:11,125 127.0.0.1 - - [02/Aug/2026 07:12:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:12:59,130 K4LSH1_OPS online — mode=AUTO dry_run=False stake=20¢ +2026-08-02 07:13:02,716 skip KXBTC15M-26AUG021015-15: no swing (0.007% < 0.12%) +2026-08-02 07:13:34,229 127.0.0.1 - - [02/Aug/2026 07:13:34] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:14:49,474 K4LSH1_OPS online — mode=AUTO dry_run=False stake=20¢ +2026-08-02 07:15:27,634 127.0.0.1 - - [02/Aug/2026 07:15:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:15:29,763 skip KXBTC15M-26AUG021030-30: no swing (0.011% < 0.12%) +2026-08-02 07:15:33,488 skip KXBTC15M-26AUG021030-30: no swing (0.011% < 0.12%) +2026-08-02 07:15:34,740 skip KXBTC15M-26AUG021030-30: mom=FLAT llm=SKIP +2026-08-02 07:15:35,872 skip KXBTC15M-26AUG021030-30: mom=FLAT llm=SKIP +2026-08-02 07:15:36,714 skip KXBTC15M-26AUG021030-30: mom=FLAT llm=SKIP +2026-08-02 07:15:37,565 skip KXBTC15M-26AUG021030-30: mom=FLAT llm=SKIP +2026-08-02 07:15:38,394 skip KXBTC15M-26AUG021030-30: mom=FLAT llm=SKIP +2026-08-02 07:15:46,537 skip KXBTC15M-26AUG021030-30: no swing (0.018% < 0.12%) +2026-08-02 07:16:34,256 127.0.0.1 - - [02/Aug/2026 07:16:34] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:17:14,679 127.0.0.1 - - [02/Aug/2026 07:17:14] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:18:21,009 127.0.0.1 - - [02/Aug/2026 07:18:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 07:19:51,722 K4LSH1_OPS online — mode=AUTO dry_run=False stake=20¢ +2026-08-02 07:19:55,357 skip KXBTC15M-26AUG021030-30: no swing (0.097% < 0.12%) +2026-08-02 07:30:50,138 skip KXBTC15M-26AUG021045-45: no swing (0.029% < 0.12%) +2026-08-02 07:45:48,276 skip KXBTC15M-26AUG021100-00: no swing (0.012% < 0.12%) +2026-08-02 08:01:27,905 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 08:01:27,988 skip KXBTC15M-26AUG021115-15: no swing (0.038% < 0.12%) +2026-08-02 08:16:03,064 skip KXBTC15M-26AUG021130-30: no swing (0.030% < 0.12%) +2026-08-02 08:30:49,265 skip KXBTC15M-26AUG021145-45: no swing (0.019% < 0.12%) +2026-08-02 08:46:26,721 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 08:46:26,816 skip KXBTC15M-26AUG021200-00: no swing (0.026% < 0.12%) +2026-08-02 09:00:28,604 skip KXBTC15M-26AUG021215-15: no swing (0.021% < 0.12%) +2026-08-02 09:15:38,371 skip KXBTC15M-26AUG021230-30: no swing (0.031% < 0.12%) +2026-08-02 09:31:36,148 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 09:31:36,234 skip KXBTC15M-26AUG021245-45: no swing (0.005% < 0.12%) +2026-08-02 09:46:04,717 skip KXBTC15M-26AUG021300-00: no swing (0.100% < 0.12%) +2026-08-02 10:00:25,295 skip KXBTC15M-26AUG021315-15: no swing (0.024% < 0.12%) +2026-08-02 10:16:08,456 skip KXBTC15M-26AUG021330-30: no swing (0.046% < 0.12%) +2026-08-02 10:30:57,828 skip KXBTC15M-26AUG021345-45: no swing (0.087% < 0.12%) +2026-08-02 10:45:19,917 skip KXBTC15M-26AUG021400-00: no swing (0.048% < 0.12%) +2026-08-02 11:00:42,483 skip KXBTC15M-26AUG021415-15: no swing (0.027% < 0.12%) +2026-08-02 11:15:44,592 skip KXBTC15M-26AUG021430-30: no swing (0.022% < 0.12%) +2026-08-02 11:30:25,791 skip KXBTC15M-26AUG021445-45: no swing (0.039% < 0.12%) +2026-08-02 11:45:55,497 skip KXBTC15M-26AUG021500-00: no swing (0.111% < 0.12%) +2026-08-02 12:00:58,673 skip KXBTC15M-26AUG021515-15: no swing (0.081% < 0.12%) +2026-08-02 12:15:45,811 skip KXBTC15M-26AUG021530-30: no swing (0.019% < 0.12%) +2026-08-02 12:30:27,553 skip KXBTC15M-26AUG021545-45: no swing (0.025% < 0.12%) +2026-08-02 12:45:49,696 skip KXBTC15M-26AUG021600-00: no swing (0.090% < 0.12%) +2026-08-02 13:00:54,053 skip KXBTC15M-26AUG021615-15: no swing (0.018% < 0.12%) +2026-08-02 13:16:04,172 skip KXBTC15M-26AUG021630-30: no swing (0.006% < 0.12%) +2026-08-02 13:30:45,953 skip KXBTC15M-26AUG021645-45: no swing (0.026% < 0.12%) +2026-08-02 13:45:47,102 skip KXBTC15M-26AUG021700-00: no swing (0.003% < 0.12%) +2026-08-02 13:56:39,174 127.0.0.1 - - [02/Aug/2026 13:56:39] "GET /api/status HTTP/1.1" 404 - +2026-08-02 13:56:39,184 127.0.0.1 - - [02/Aug/2026 13:56:39] "GET / HTTP/1.1" 200 - +2026-08-02 13:57:09,922 127.0.0.1 - - [02/Aug/2026 13:57:09] "GET /api/state HTTP/1.1" 200 - +2026-08-02 13:59:52,580 127.0.0.1 - - [02/Aug/2026 13:59:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:01:09,818 127.0.0.1 - - [02/Aug/2026 14:01:09] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:01:44,301 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 14:01:44,433 skip KXBTC15M-26AUG021715-15: no swing (0.032% < 0.12%) +2026-08-02 14:12:21,902 127.0.0.1 - - [02/Aug/2026 14:12:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:14:06,217 127.0.0.1 - - [02/Aug/2026 14:14:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:14:39,030 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 14:14:48,793 127.0.0.1 - - [02/Aug/2026 14:14:48] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:15:30,283 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 14:15:32,813 skip KXBTC15M-26AUG021730-30: no swing (0.019% < 0.08%) +2026-08-02 14:16:34,622 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 14:16:43,150 skip KXBTC15M-26AUG021730-30: no swing (0.045% < 0.08%) +2026-08-02 14:16:45,510 127.0.0.1 - - [02/Aug/2026 14:16:45] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:17:01,124 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 14:17:03,853 skip KXBTC15M-26AUG021730-30: no swing (0.029% < 0.06%) +2026-08-02 14:17:11,401 127.0.0.1 - - [02/Aug/2026 14:17:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:19:09,095 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 14:19:11,849 skip KXDOGE15M-26AUG021730-30: no swing (0.017% < 0.06%) +2026-08-02 14:19:24,512 127.0.0.1 - - [02/Aug/2026 14:19:24] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:20:25,027 127.0.0.1 - - [02/Aug/2026 14:20:25] "GET / HTTP/1.1" 200 - +2026-08-02 14:20:31,448 127.0.0.1 - - [02/Aug/2026 14:20:31] "GET / HTTP/1.1" 200 - +2026-08-02 14:20:32,014 127.0.0.1 - - [02/Aug/2026 14:20:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:20:36,892 127.0.0.1 - - [02/Aug/2026 14:20:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:20:41,864 127.0.0.1 - - [02/Aug/2026 14:20:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:20:46,953 127.0.0.1 - - [02/Aug/2026 14:20:46] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:20:51,983 127.0.0.1 - - [02/Aug/2026 14:20:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:20:56,920 127.0.0.1 - - [02/Aug/2026 14:20:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:01,939 127.0.0.1 - - [02/Aug/2026 14:21:01] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:06,898 127.0.0.1 - - [02/Aug/2026 14:21:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:11,990 127.0.0.1 - - [02/Aug/2026 14:21:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:17,009 127.0.0.1 - - [02/Aug/2026 14:21:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:21,860 127.0.0.1 - - [02/Aug/2026 14:21:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:26,876 127.0.0.1 - - [02/Aug/2026 14:21:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:31,948 127.0.0.1 - - [02/Aug/2026 14:21:31] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:36,876 127.0.0.1 - - [02/Aug/2026 14:21:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:41,885 127.0.0.1 - - [02/Aug/2026 14:21:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:46,963 127.0.0.1 - - [02/Aug/2026 14:21:46] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:51,864 127.0.0.1 - - [02/Aug/2026 14:21:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:21:56,890 127.0.0.1 - - [02/Aug/2026 14:21:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:01,934 127.0.0.1 - - [02/Aug/2026 14:22:01] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:08,011 127.0.0.1 - - [02/Aug/2026 14:22:08] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:11,910 127.0.0.1 - - [02/Aug/2026 14:22:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:12,487 127.0.0.1 - - [02/Aug/2026 14:22:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:16,933 127.0.0.1 - - [02/Aug/2026 14:22:16] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:21,971 127.0.0.1 - - [02/Aug/2026 14:22:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:26,995 127.0.0.1 - - [02/Aug/2026 14:22:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:31,959 127.0.0.1 - - [02/Aug/2026 14:22:31] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:36,886 127.0.0.1 - - [02/Aug/2026 14:22:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:41,889 127.0.0.1 - - [02/Aug/2026 14:22:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:46,951 127.0.0.1 - - [02/Aug/2026 14:22:46] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:51,888 127.0.0.1 - - [02/Aug/2026 14:22:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:22:56,886 127.0.0.1 - - [02/Aug/2026 14:22:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:01,959 127.0.0.1 - - [02/Aug/2026 14:23:01] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:06,882 127.0.0.1 - - [02/Aug/2026 14:23:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:11,897 127.0.0.1 - - [02/Aug/2026 14:23:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:16,973 127.0.0.1 - - [02/Aug/2026 14:23:16] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:21,878 127.0.0.1 - - [02/Aug/2026 14:23:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:26,923 127.0.0.1 - - [02/Aug/2026 14:23:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:31,965 127.0.0.1 - - [02/Aug/2026 14:23:31] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:36,984 127.0.0.1 - - [02/Aug/2026 14:23:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:41,873 127.0.0.1 - - [02/Aug/2026 14:23:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:46,947 127.0.0.1 - - [02/Aug/2026 14:23:46] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:51,892 127.0.0.1 - - [02/Aug/2026 14:23:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:23:56,879 127.0.0.1 - - [02/Aug/2026 14:23:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:01,990 127.0.0.1 - - [02/Aug/2026 14:24:01] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:06,890 127.0.0.1 - - [02/Aug/2026 14:24:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:11,884 127.0.0.1 - - [02/Aug/2026 14:24:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:16,949 127.0.0.1 - - [02/Aug/2026 14:24:16] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:21,873 127.0.0.1 - - [02/Aug/2026 14:24:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:26,891 127.0.0.1 - - [02/Aug/2026 14:24:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:31,989 127.0.0.1 - - [02/Aug/2026 14:24:31] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:36,890 127.0.0.1 - - [02/Aug/2026 14:24:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:42,016 127.0.0.1 - - [02/Aug/2026 14:24:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:46,960 127.0.0.1 - - [02/Aug/2026 14:24:46] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:51,875 127.0.0.1 - - [02/Aug/2026 14:24:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:24:56,899 127.0.0.1 - - [02/Aug/2026 14:24:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:01,964 127.0.0.1 - - [02/Aug/2026 14:25:01] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:06,913 127.0.0.1 - - [02/Aug/2026 14:25:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:11,907 127.0.0.1 - - [02/Aug/2026 14:25:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:16,946 127.0.0.1 - - [02/Aug/2026 14:25:16] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:21,900 127.0.0.1 - - [02/Aug/2026 14:25:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:26,872 127.0.0.1 - - [02/Aug/2026 14:25:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:32,069 127.0.0.1 - - [02/Aug/2026 14:25:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:36,900 127.0.0.1 - - [02/Aug/2026 14:25:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:41,891 127.0.0.1 - - [02/Aug/2026 14:25:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:46,971 127.0.0.1 - - [02/Aug/2026 14:25:46] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:51,936 127.0.0.1 - - [02/Aug/2026 14:25:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:25:56,905 127.0.0.1 - - [02/Aug/2026 14:25:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:01,962 127.0.0.1 - - [02/Aug/2026 14:26:01] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:06,891 127.0.0.1 - - [02/Aug/2026 14:26:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:11,991 127.0.0.1 - - [02/Aug/2026 14:26:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:16,984 127.0.0.1 - - [02/Aug/2026 14:26:16] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:21,920 127.0.0.1 - - [02/Aug/2026 14:26:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:27,009 127.0.0.1 - - [02/Aug/2026 14:26:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:31,995 127.0.0.1 - - [02/Aug/2026 14:26:31] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:36,900 127.0.0.1 - - [02/Aug/2026 14:26:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:41,893 127.0.0.1 - - [02/Aug/2026 14:26:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:46,992 127.0.0.1 - - [02/Aug/2026 14:26:46] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:51,897 127.0.0.1 - - [02/Aug/2026 14:26:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:26:56,888 127.0.0.1 - - [02/Aug/2026 14:26:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:01,980 127.0.0.1 - - [02/Aug/2026 14:27:01] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:06,887 127.0.0.1 - - [02/Aug/2026 14:27:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:13,070 127.0.0.1 - - [02/Aug/2026 14:27:13] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:17,081 127.0.0.1 - - [02/Aug/2026 14:27:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:21,993 127.0.0.1 - - [02/Aug/2026 14:27:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:26,944 127.0.0.1 - - [02/Aug/2026 14:27:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:31,974 127.0.0.1 - - [02/Aug/2026 14:27:31] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:36,993 127.0.0.1 - - [02/Aug/2026 14:27:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:41,892 127.0.0.1 - - [02/Aug/2026 14:27:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:46,981 127.0.0.1 - - [02/Aug/2026 14:27:46] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:51,911 127.0.0.1 - - [02/Aug/2026 14:27:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:27:56,916 127.0.0.1 - - [02/Aug/2026 14:27:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:01,979 127.0.0.1 - - [02/Aug/2026 14:28:01] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:06,908 127.0.0.1 - - [02/Aug/2026 14:28:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:12,011 127.0.0.1 - - [02/Aug/2026 14:28:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:16,981 127.0.0.1 - - [02/Aug/2026 14:28:16] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:21,913 127.0.0.1 - - [02/Aug/2026 14:28:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:26,896 127.0.0.1 - - [02/Aug/2026 14:28:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:32,003 127.0.0.1 - - [02/Aug/2026 14:28:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:36,907 127.0.0.1 - - [02/Aug/2026 14:28:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:41,930 127.0.0.1 - - [02/Aug/2026 14:28:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:46,967 127.0.0.1 - - [02/Aug/2026 14:28:46] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:51,904 127.0.0.1 - - [02/Aug/2026 14:28:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:28:56,920 127.0.0.1 - - [02/Aug/2026 14:28:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:01,976 127.0.0.1 - - [02/Aug/2026 14:29:01] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:06,921 127.0.0.1 - - [02/Aug/2026 14:29:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:11,932 127.0.0.1 - - [02/Aug/2026 14:29:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:16,985 127.0.0.1 - - [02/Aug/2026 14:29:16] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:22,009 127.0.0.1 - - [02/Aug/2026 14:29:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:26,901 127.0.0.1 - - [02/Aug/2026 14:29:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:31,980 127.0.0.1 - - [02/Aug/2026 14:29:31] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:37,005 127.0.0.1 - - [02/Aug/2026 14:29:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:42,011 127.0.0.1 - - [02/Aug/2026 14:29:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:47,068 127.0.0.1 - - [02/Aug/2026 14:29:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:51,913 127.0.0.1 - - [02/Aug/2026 14:29:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:29:56,911 127.0.0.1 - - [02/Aug/2026 14:29:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:02,027 127.0.0.1 - - [02/Aug/2026 14:30:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:06,903 127.0.0.1 - - [02/Aug/2026 14:30:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:11,910 127.0.0.1 - - [02/Aug/2026 14:30:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:17,010 127.0.0.1 - - [02/Aug/2026 14:30:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:21,931 127.0.0.1 - - [02/Aug/2026 14:30:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:26,905 127.0.0.1 - - [02/Aug/2026 14:30:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:31,984 127.0.0.1 - - [02/Aug/2026 14:30:31] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:37,010 127.0.0.1 - - [02/Aug/2026 14:30:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:41,903 127.0.0.1 - - [02/Aug/2026 14:30:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:46,683 skip KXDOGE15M-26AUG021745-45: no swing (0.044% < 0.06%) +2026-08-02 14:30:46,986 127.0.0.1 - - [02/Aug/2026 14:30:46] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:52,023 127.0.0.1 - - [02/Aug/2026 14:30:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:30:56,926 127.0.0.1 - - [02/Aug/2026 14:30:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:02,005 127.0.0.1 - - [02/Aug/2026 14:31:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:06,939 127.0.0.1 - - [02/Aug/2026 14:31:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:11,936 127.0.0.1 - - [02/Aug/2026 14:31:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:17,035 127.0.0.1 - - [02/Aug/2026 14:31:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:21,976 127.0.0.1 - - [02/Aug/2026 14:31:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:26,934 127.0.0.1 - - [02/Aug/2026 14:31:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:32,009 127.0.0.1 - - [02/Aug/2026 14:31:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:36,938 127.0.0.1 - - [02/Aug/2026 14:31:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:41,934 127.0.0.1 - - [02/Aug/2026 14:31:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:47,090 127.0.0.1 - - [02/Aug/2026 14:31:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:51,925 127.0.0.1 - - [02/Aug/2026 14:31:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:31:56,991 127.0.0.1 - - [02/Aug/2026 14:31:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:02,071 127.0.0.1 - - [02/Aug/2026 14:32:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:07,027 127.0.0.1 - - [02/Aug/2026 14:32:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:11,950 127.0.0.1 - - [02/Aug/2026 14:32:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:18,061 127.0.0.1 - - [02/Aug/2026 14:32:18] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:21,942 127.0.0.1 - - [02/Aug/2026 14:32:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:27,040 127.0.0.1 - - [02/Aug/2026 14:32:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:32,045 127.0.0.1 - - [02/Aug/2026 14:32:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:36,942 127.0.0.1 - - [02/Aug/2026 14:32:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:41,949 127.0.0.1 - - [02/Aug/2026 14:32:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:47,046 127.0.0.1 - - [02/Aug/2026 14:32:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:51,982 127.0.0.1 - - [02/Aug/2026 14:32:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:32:56,990 127.0.0.1 - - [02/Aug/2026 14:32:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:02,120 127.0.0.1 - - [02/Aug/2026 14:33:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:07,058 127.0.0.1 - - [02/Aug/2026 14:33:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:11,957 127.0.0.1 - - [02/Aug/2026 14:33:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:17,036 127.0.0.1 - - [02/Aug/2026 14:33:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:21,988 127.0.0.1 - - [02/Aug/2026 14:33:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:26,961 127.0.0.1 - - [02/Aug/2026 14:33:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:32,006 127.0.0.1 - - [02/Aug/2026 14:33:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:36,970 127.0.0.1 - - [02/Aug/2026 14:33:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:41,958 127.0.0.1 - - [02/Aug/2026 14:33:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:47,044 127.0.0.1 - - [02/Aug/2026 14:33:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:51,991 127.0.0.1 - - [02/Aug/2026 14:33:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:33:56,954 127.0.0.1 - - [02/Aug/2026 14:33:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:02,103 127.0.0.1 - - [02/Aug/2026 14:34:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:06,970 127.0.0.1 - - [02/Aug/2026 14:34:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:12,023 127.0.0.1 - - [02/Aug/2026 14:34:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:17,038 127.0.0.1 - - [02/Aug/2026 14:34:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:21,971 127.0.0.1 - - [02/Aug/2026 14:34:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:26,973 127.0.0.1 - - [02/Aug/2026 14:34:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:32,055 127.0.0.1 - - [02/Aug/2026 14:34:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:36,967 127.0.0.1 - - [02/Aug/2026 14:34:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:41,992 127.0.0.1 - - [02/Aug/2026 14:34:41] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:47,061 127.0.0.1 - - [02/Aug/2026 14:34:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:51,970 127.0.0.1 - - [02/Aug/2026 14:34:51] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:34:56,978 127.0.0.1 - - [02/Aug/2026 14:34:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:02,187 127.0.0.1 - - [02/Aug/2026 14:35:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:06,985 127.0.0.1 - - [02/Aug/2026 14:35:06] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:12,013 127.0.0.1 - - [02/Aug/2026 14:35:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:17,159 127.0.0.1 - - [02/Aug/2026 14:35:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:21,990 127.0.0.1 - - [02/Aug/2026 14:35:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:27,001 127.0.0.1 - - [02/Aug/2026 14:35:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:32,069 127.0.0.1 - - [02/Aug/2026 14:35:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:36,989 127.0.0.1 - - [02/Aug/2026 14:35:36] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:42,010 127.0.0.1 - - [02/Aug/2026 14:35:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:47,131 127.0.0.1 - - [02/Aug/2026 14:35:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:52,096 127.0.0.1 - - [02/Aug/2026 14:35:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:35:57,016 127.0.0.1 - - [02/Aug/2026 14:35:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:02,074 127.0.0.1 - - [02/Aug/2026 14:36:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:07,008 127.0.0.1 - - [02/Aug/2026 14:36:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:12,013 127.0.0.1 - - [02/Aug/2026 14:36:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:17,066 127.0.0.1 - - [02/Aug/2026 14:36:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:22,097 127.0.0.1 - - [02/Aug/2026 14:36:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:27,044 127.0.0.1 - - [02/Aug/2026 14:36:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:32,098 127.0.0.1 - - [02/Aug/2026 14:36:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:37,004 127.0.0.1 - - [02/Aug/2026 14:36:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:42,110 127.0.0.1 - - [02/Aug/2026 14:36:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:47,093 127.0.0.1 - - [02/Aug/2026 14:36:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:52,144 127.0.0.1 - - [02/Aug/2026 14:36:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:36:57,057 127.0.0.1 - - [02/Aug/2026 14:36:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:02,090 127.0.0.1 - - [02/Aug/2026 14:37:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:07,048 127.0.0.1 - - [02/Aug/2026 14:37:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:12,058 127.0.0.1 - - [02/Aug/2026 14:37:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:17,081 127.0.0.1 - - [02/Aug/2026 14:37:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:26,203 127.0.0.1 - - [02/Aug/2026 14:37:26] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:27,120 127.0.0.1 - - [02/Aug/2026 14:37:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:32,213 127.0.0.1 - - [02/Aug/2026 14:37:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:37,130 127.0.0.1 - - [02/Aug/2026 14:37:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:42,029 127.0.0.1 - - [02/Aug/2026 14:37:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:47,097 127.0.0.1 - - [02/Aug/2026 14:37:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:52,037 127.0.0.1 - - [02/Aug/2026 14:37:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:37:57,036 127.0.0.1 - - [02/Aug/2026 14:37:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:02,125 127.0.0.1 - - [02/Aug/2026 14:38:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:07,069 127.0.0.1 - - [02/Aug/2026 14:38:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:12,027 127.0.0.1 - - [02/Aug/2026 14:38:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:17,116 127.0.0.1 - - [02/Aug/2026 14:38:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:22,071 127.0.0.1 - - [02/Aug/2026 14:38:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:27,036 127.0.0.1 - - [02/Aug/2026 14:38:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:32,209 127.0.0.1 - - [02/Aug/2026 14:38:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:37,029 127.0.0.1 - - [02/Aug/2026 14:38:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:42,042 127.0.0.1 - - [02/Aug/2026 14:38:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:47,100 127.0.0.1 - - [02/Aug/2026 14:38:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:52,040 127.0.0.1 - - [02/Aug/2026 14:38:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:38:57,039 127.0.0.1 - - [02/Aug/2026 14:38:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:02,140 127.0.0.1 - - [02/Aug/2026 14:39:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:07,032 127.0.0.1 - - [02/Aug/2026 14:39:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:12,141 127.0.0.1 - - [02/Aug/2026 14:39:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:17,111 127.0.0.1 - - [02/Aug/2026 14:39:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:22,048 127.0.0.1 - - [02/Aug/2026 14:39:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:27,052 127.0.0.1 - - [02/Aug/2026 14:39:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:32,233 127.0.0.1 - - [02/Aug/2026 14:39:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:37,045 127.0.0.1 - - [02/Aug/2026 14:39:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:42,035 127.0.0.1 - - [02/Aug/2026 14:39:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:47,119 127.0.0.1 - - [02/Aug/2026 14:39:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:52,034 127.0.0.1 - - [02/Aug/2026 14:39:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:39:57,050 127.0.0.1 - - [02/Aug/2026 14:39:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:02,149 127.0.0.1 - - [02/Aug/2026 14:40:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:07,022 127.0.0.1 - - [02/Aug/2026 14:40:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:12,161 127.0.0.1 - - [02/Aug/2026 14:40:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:17,239 127.0.0.1 - - [02/Aug/2026 14:40:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:22,095 127.0.0.1 - - [02/Aug/2026 14:40:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:27,052 127.0.0.1 - - [02/Aug/2026 14:40:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:32,116 127.0.0.1 - - [02/Aug/2026 14:40:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:37,037 127.0.0.1 - - [02/Aug/2026 14:40:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:42,058 127.0.0.1 - - [02/Aug/2026 14:40:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:47,114 127.0.0.1 - - [02/Aug/2026 14:40:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:52,043 127.0.0.1 - - [02/Aug/2026 14:40:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:40:57,086 127.0.0.1 - - [02/Aug/2026 14:40:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:02,139 127.0.0.1 - - [02/Aug/2026 14:41:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:07,040 127.0.0.1 - - [02/Aug/2026 14:41:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:12,059 127.0.0.1 - - [02/Aug/2026 14:41:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:17,124 127.0.0.1 - - [02/Aug/2026 14:41:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:22,054 127.0.0.1 - - [02/Aug/2026 14:41:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:27,065 127.0.0.1 - - [02/Aug/2026 14:41:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:32,157 127.0.0.1 - - [02/Aug/2026 14:41:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:37,062 127.0.0.1 - - [02/Aug/2026 14:41:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:42,067 127.0.0.1 - - [02/Aug/2026 14:41:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:47,126 127.0.0.1 - - [02/Aug/2026 14:41:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:52,053 127.0.0.1 - - [02/Aug/2026 14:41:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:41:57,163 127.0.0.1 - - [02/Aug/2026 14:41:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:02,161 127.0.0.1 - - [02/Aug/2026 14:42:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:07,060 127.0.0.1 - - [02/Aug/2026 14:42:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:12,076 127.0.0.1 - - [02/Aug/2026 14:42:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:17,233 127.0.0.1 - - [02/Aug/2026 14:42:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:22,077 127.0.0.1 - - [02/Aug/2026 14:42:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:33,225 127.0.0.1 - - [02/Aug/2026 14:42:33] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:34,495 127.0.0.1 - - [02/Aug/2026 14:42:34] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:37,182 127.0.0.1 - - [02/Aug/2026 14:42:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:42,096 127.0.0.1 - - [02/Aug/2026 14:42:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:47,231 127.0.0.1 - - [02/Aug/2026 14:42:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:52,167 127.0.0.1 - - [02/Aug/2026 14:42:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:42:57,181 127.0.0.1 - - [02/Aug/2026 14:42:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:02,148 127.0.0.1 - - [02/Aug/2026 14:43:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:07,084 127.0.0.1 - - [02/Aug/2026 14:43:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:12,097 127.0.0.1 - - [02/Aug/2026 14:43:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:17,160 127.0.0.1 - - [02/Aug/2026 14:43:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:22,104 127.0.0.1 - - [02/Aug/2026 14:43:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:27,086 127.0.0.1 - - [02/Aug/2026 14:43:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:32,255 127.0.0.1 - - [02/Aug/2026 14:43:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:37,081 127.0.0.1 - - [02/Aug/2026 14:43:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:42,104 127.0.0.1 - - [02/Aug/2026 14:43:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:47,152 127.0.0.1 - - [02/Aug/2026 14:43:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:52,090 127.0.0.1 - - [02/Aug/2026 14:43:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:43:57,083 127.0.0.1 - - [02/Aug/2026 14:43:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:02,185 127.0.0.1 - - [02/Aug/2026 14:44:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:07,090 127.0.0.1 - - [02/Aug/2026 14:44:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:12,152 127.0.0.1 - - [02/Aug/2026 14:44:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:17,166 127.0.0.1 - - [02/Aug/2026 14:44:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:22,118 127.0.0.1 - - [02/Aug/2026 14:44:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:27,145 127.0.0.1 - - [02/Aug/2026 14:44:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:32,298 127.0.0.1 - - [02/Aug/2026 14:44:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:37,190 127.0.0.1 - - [02/Aug/2026 14:44:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:42,120 127.0.0.1 - - [02/Aug/2026 14:44:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:47,178 127.0.0.1 - - [02/Aug/2026 14:44:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:52,123 127.0.0.1 - - [02/Aug/2026 14:44:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:44:57,120 127.0.0.1 - - [02/Aug/2026 14:44:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:02,195 127.0.0.1 - - [02/Aug/2026 14:45:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:07,211 127.0.0.1 - - [02/Aug/2026 14:45:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:12,228 127.0.0.1 - - [02/Aug/2026 14:45:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:17,190 127.0.0.1 - - [02/Aug/2026 14:45:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:22,112 127.0.0.1 - - [02/Aug/2026 14:45:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:27,129 127.0.0.1 - - [02/Aug/2026 14:45:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:32,213 127.0.0.1 - - [02/Aug/2026 14:45:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:37,126 127.0.0.1 - - [02/Aug/2026 14:45:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:42,245 127.0.0.1 - - [02/Aug/2026 14:45:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:47,197 127.0.0.1 - - [02/Aug/2026 14:45:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:48,851 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 14:45:52,139 127.0.0.1 - - [02/Aug/2026 14:45:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:45:57,133 127.0.0.1 - - [02/Aug/2026 14:45:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:02,309 127.0.0.1 - - [02/Aug/2026 14:46:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:07,141 127.0.0.1 - - [02/Aug/2026 14:46:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:12,159 127.0.0.1 - - [02/Aug/2026 14:46:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:15,201 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 14:46:17,211 127.0.0.1 - - [02/Aug/2026 14:46:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:22,245 127.0.0.1 - - [02/Aug/2026 14:46:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:27,132 127.0.0.1 - - [02/Aug/2026 14:46:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:32,213 127.0.0.1 - - [02/Aug/2026 14:46:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:36,897 skip KXDOGE15M-26AUG021800-00: llm vetoes fade: wants SKIP +2026-08-02 14:46:37,156 127.0.0.1 - - [02/Aug/2026 14:46:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:42,143 127.0.0.1 - - [02/Aug/2026 14:46:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:47,221 127.0.0.1 - - [02/Aug/2026 14:46:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:52,133 127.0.0.1 - - [02/Aug/2026 14:46:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:46:57,148 127.0.0.1 - - [02/Aug/2026 14:46:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:02,229 127.0.0.1 - - [02/Aug/2026 14:47:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:07,147 127.0.0.1 - - [02/Aug/2026 14:47:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:12,178 127.0.0.1 - - [02/Aug/2026 14:47:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:17,214 127.0.0.1 - - [02/Aug/2026 14:47:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:22,258 127.0.0.1 - - [02/Aug/2026 14:47:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:27,274 127.0.0.1 - - [02/Aug/2026 14:47:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:32,268 127.0.0.1 - - [02/Aug/2026 14:47:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:38,210 127.0.0.1 - - [02/Aug/2026 14:47:38] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:42,156 127.0.0.1 - - [02/Aug/2026 14:47:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:47,393 127.0.0.1 - - [02/Aug/2026 14:47:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:52,173 127.0.0.1 - - [02/Aug/2026 14:47:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:47:57,174 127.0.0.1 - - [02/Aug/2026 14:47:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:02,249 127.0.0.1 - - [02/Aug/2026 14:48:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:07,261 127.0.0.1 - - [02/Aug/2026 14:48:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:12,278 127.0.0.1 - - [02/Aug/2026 14:48:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:17,298 127.0.0.1 - - [02/Aug/2026 14:48:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:22,342 127.0.0.1 - - [02/Aug/2026 14:48:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:27,180 127.0.0.1 - - [02/Aug/2026 14:48:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:32,181 127.0.0.1 - - [02/Aug/2026 14:48:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:37,281 127.0.0.1 - - [02/Aug/2026 14:48:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:42,193 127.0.0.1 - - [02/Aug/2026 14:48:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:47,215 127.0.0.1 - - [02/Aug/2026 14:48:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:52,185 127.0.0.1 - - [02/Aug/2026 14:48:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:48:57,359 127.0.0.1 - - [02/Aug/2026 14:48:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:02,195 127.0.0.1 - - [02/Aug/2026 14:49:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:07,193 127.0.0.1 - - [02/Aug/2026 14:49:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:12,206 127.0.0.1 - - [02/Aug/2026 14:49:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:17,261 127.0.0.1 - - [02/Aug/2026 14:49:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:22,394 127.0.0.1 - - [02/Aug/2026 14:49:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:27,206 127.0.0.1 - - [02/Aug/2026 14:49:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:32,204 127.0.0.1 - - [02/Aug/2026 14:49:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:37,268 127.0.0.1 - - [02/Aug/2026 14:49:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:42,213 127.0.0.1 - - [02/Aug/2026 14:49:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:47,195 127.0.0.1 - - [02/Aug/2026 14:49:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:52,209 127.0.0.1 - - [02/Aug/2026 14:49:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:49:57,316 127.0.0.1 - - [02/Aug/2026 14:49:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:02,207 127.0.0.1 - - [02/Aug/2026 14:50:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:07,205 127.0.0.1 - - [02/Aug/2026 14:50:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:12,223 127.0.0.1 - - [02/Aug/2026 14:50:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:17,278 127.0.0.1 - - [02/Aug/2026 14:50:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:22,217 127.0.0.1 - - [02/Aug/2026 14:50:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:27,207 127.0.0.1 - - [02/Aug/2026 14:50:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:32,212 127.0.0.1 - - [02/Aug/2026 14:50:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:37,420 127.0.0.1 - - [02/Aug/2026 14:50:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:42,211 127.0.0.1 - - [02/Aug/2026 14:50:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:47,224 127.0.0.1 - - [02/Aug/2026 14:50:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:52,437 127.0.0.1 - - [02/Aug/2026 14:50:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:50:57,235 127.0.0.1 - - [02/Aug/2026 14:50:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:02,232 127.0.0.1 - - [02/Aug/2026 14:51:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:07,232 127.0.0.1 - - [02/Aug/2026 14:51:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:12,303 127.0.0.1 - - [02/Aug/2026 14:51:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:17,231 127.0.0.1 - - [02/Aug/2026 14:51:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:22,243 127.0.0.1 - - [02/Aug/2026 14:51:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:27,232 127.0.0.1 - - [02/Aug/2026 14:51:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:32,395 127.0.0.1 - - [02/Aug/2026 14:51:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:37,244 127.0.0.1 - - [02/Aug/2026 14:51:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:42,254 127.0.0.1 - - [02/Aug/2026 14:51:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:47,321 127.0.0.1 - - [02/Aug/2026 14:51:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:52,248 127.0.0.1 - - [02/Aug/2026 14:51:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:51:57,234 127.0.0.1 - - [02/Aug/2026 14:51:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:02,504 127.0.0.1 - - [02/Aug/2026 14:52:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:07,270 127.0.0.1 - - [02/Aug/2026 14:52:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:12,287 127.0.0.1 - - [02/Aug/2026 14:52:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:17,232 127.0.0.1 - - [02/Aug/2026 14:52:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:22,300 127.0.0.1 - - [02/Aug/2026 14:52:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:27,239 127.0.0.1 - - [02/Aug/2026 14:52:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:32,246 127.0.0.1 - - [02/Aug/2026 14:52:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:37,413 127.0.0.1 - - [02/Aug/2026 14:52:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:43,351 127.0.0.1 - - [02/Aug/2026 14:52:43] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:47,276 127.0.0.1 - - [02/Aug/2026 14:52:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:52,399 127.0.0.1 - - [02/Aug/2026 14:52:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:52:57,269 127.0.0.1 - - [02/Aug/2026 14:52:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:02,271 127.0.0.1 - - [02/Aug/2026 14:53:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:07,341 127.0.0.1 - - [02/Aug/2026 14:53:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:12,333 127.0.0.1 - - [02/Aug/2026 14:53:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:17,286 127.0.0.1 - - [02/Aug/2026 14:53:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:22,346 127.0.0.1 - - [02/Aug/2026 14:53:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:27,262 127.0.0.1 - - [02/Aug/2026 14:53:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:32,361 127.0.0.1 - - [02/Aug/2026 14:53:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:37,464 127.0.0.1 - - [02/Aug/2026 14:53:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:42,394 127.0.0.1 - - [02/Aug/2026 14:53:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:47,265 127.0.0.1 - - [02/Aug/2026 14:53:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:52,477 127.0.0.1 - - [02/Aug/2026 14:53:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:53:57,295 127.0.0.1 - - [02/Aug/2026 14:53:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:02,394 127.0.0.1 - - [02/Aug/2026 14:54:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:07,357 127.0.0.1 - - [02/Aug/2026 14:54:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:12,290 127.0.0.1 - - [02/Aug/2026 14:54:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:17,279 127.0.0.1 - - [02/Aug/2026 14:54:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:22,489 127.0.0.1 - - [02/Aug/2026 14:54:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:27,285 127.0.0.1 - - [02/Aug/2026 14:54:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:32,298 127.0.0.1 - - [02/Aug/2026 14:54:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:37,369 127.0.0.1 - - [02/Aug/2026 14:54:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:42,472 127.0.0.1 - - [02/Aug/2026 14:54:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:47,411 127.0.0.1 - - [02/Aug/2026 14:54:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:52,373 127.0.0.1 - - [02/Aug/2026 14:54:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:54:57,291 127.0.0.1 - - [02/Aug/2026 14:54:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:02,484 127.0.0.1 - - [02/Aug/2026 14:55:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:07,391 127.0.0.1 - - [02/Aug/2026 14:55:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:12,489 127.0.0.1 - - [02/Aug/2026 14:55:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:17,298 127.0.0.1 - - [02/Aug/2026 14:55:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:22,371 127.0.0.1 - - [02/Aug/2026 14:55:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:27,302 127.0.0.1 - - [02/Aug/2026 14:55:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:32,397 127.0.0.1 - - [02/Aug/2026 14:55:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:37,457 127.0.0.1 - - [02/Aug/2026 14:55:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:42,398 127.0.0.1 - - [02/Aug/2026 14:55:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:47,314 127.0.0.1 - - [02/Aug/2026 14:55:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:52,480 127.0.0.1 - - [02/Aug/2026 14:55:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:55:57,305 127.0.0.1 - - [02/Aug/2026 14:55:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:56:02,401 127.0.0.1 - - [02/Aug/2026 14:56:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:56:07,463 127.0.0.1 - - [02/Aug/2026 14:56:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:56:12,351 127.0.0.1 - - [02/Aug/2026 14:56:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:56:17,374 127.0.0.1 - - [02/Aug/2026 14:56:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:56:22,492 127.0.0.1 - - [02/Aug/2026 14:56:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:56:27,344 127.0.0.1 - - [02/Aug/2026 14:56:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:56:32,400 127.0.0.1 - - [02/Aug/2026 14:56:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:56:38,913 127.0.0.1 - - [02/Aug/2026 14:56:38] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:56:43,974 127.0.0.1 - - [02/Aug/2026 14:56:43] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:56:57,612 127.0.0.1 - - [02/Aug/2026 14:56:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:57:11,345 127.0.0.1 - - [02/Aug/2026 14:57:11] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:57:39,386 127.0.0.1 - - [02/Aug/2026 14:57:39] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:58:24,437 127.0.0.1 - - [02/Aug/2026 14:58:24] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:58:33,194 127.0.0.1 - - [02/Aug/2026 14:58:33] "GET /api/state HTTP/1.1" 200 - +2026-08-02 14:59:49,701 127.0.0.1 - - [02/Aug/2026 14:59:49] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:00:00,323 127.0.0.1 - - [02/Aug/2026 15:00:00] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:00:41,194 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 15:01:02,733 skip KXDOGE15M-26AUG021815-15: no swing (0.038% < 0.06%) +2026-08-02 15:02:33,255 127.0.0.1 - - [02/Aug/2026 15:02:33] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:05:04,179 127.0.0.1 - - [02/Aug/2026 15:05:04] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:10:10,305 127.0.0.1 - - [02/Aug/2026 15:10:10] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:14:56,954 127.0.0.1 - - [02/Aug/2026 15:14:56] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:16:01,078 skip KXDOGE15M-26AUG021830-30: no swing (0.023% < 0.06%) +2026-08-02 15:17:54,566 127.0.0.1 - - [02/Aug/2026 15:17:54] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:17:58,222 127.0.0.1 - - [02/Aug/2026 15:17:58] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:03,233 127.0.0.1 - - [02/Aug/2026 15:18:03] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:08,216 127.0.0.1 - - [02/Aug/2026 15:18:08] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:13,285 127.0.0.1 - - [02/Aug/2026 15:18:13] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:18,201 127.0.0.1 - - [02/Aug/2026 15:18:18] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:21,258 127.0.0.1 - - [02/Aug/2026 15:18:21] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:23,204 127.0.0.1 - - [02/Aug/2026 15:18:23] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:28,206 127.0.0.1 - - [02/Aug/2026 15:18:28] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:33,417 127.0.0.1 - - [02/Aug/2026 15:18:33] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:38,226 127.0.0.1 - - [02/Aug/2026 15:18:38] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:43,229 127.0.0.1 - - [02/Aug/2026 15:18:43] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:48,418 127.0.0.1 - - [02/Aug/2026 15:18:48] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:53,224 127.0.0.1 - - [02/Aug/2026 15:18:53] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:18:58,218 127.0.0.1 - - [02/Aug/2026 15:18:58] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:03,242 127.0.0.1 - - [02/Aug/2026 15:19:03] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:08,286 127.0.0.1 - - [02/Aug/2026 15:19:08] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:13,205 127.0.0.1 - - [02/Aug/2026 15:19:13] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:17,969 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:19:18,271 127.0.0.1 - - [02/Aug/2026 15:19:18] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:23,214 127.0.0.1 - - [02/Aug/2026 15:19:23] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:28,438 skip KXDOGE15M-26AUG021830-30: llm vetoes fade: wants DOWN +2026-08-02 15:19:28,443 127.0.0.1 - - [02/Aug/2026 15:19:28] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:33,219 127.0.0.1 - - [02/Aug/2026 15:19:33] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:38,219 127.0.0.1 - - [02/Aug/2026 15:19:38] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:43,244 127.0.0.1 - - [02/Aug/2026 15:19:43] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:48,314 127.0.0.1 - - [02/Aug/2026 15:19:48] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:53,201 127.0.0.1 - - [02/Aug/2026 15:19:53] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:19:58,212 127.0.0.1 - - [02/Aug/2026 15:19:58] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:03,212 127.0.0.1 - - [02/Aug/2026 15:20:03] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:08,385 127.0.0.1 - - [02/Aug/2026 15:20:08] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:13,308 127.0.0.1 - - [02/Aug/2026 15:20:13] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:18,237 127.0.0.1 - - [02/Aug/2026 15:20:18] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:23,224 127.0.0.1 - - [02/Aug/2026 15:20:23] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:28,274 127.0.0.1 - - [02/Aug/2026 15:20:28] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:33,238 127.0.0.1 - - [02/Aug/2026 15:20:33] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:38,232 127.0.0.1 - - [02/Aug/2026 15:20:38] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:43,236 127.0.0.1 - - [02/Aug/2026 15:20:43] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:48,305 127.0.0.1 - - [02/Aug/2026 15:20:48] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:53,232 127.0.0.1 - - [02/Aug/2026 15:20:53] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:20:58,233 127.0.0.1 - - [02/Aug/2026 15:20:58] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:03,344 127.0.0.1 - - [02/Aug/2026 15:21:03] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:08,393 127.0.0.1 - - [02/Aug/2026 15:21:08] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:13,238 127.0.0.1 - - [02/Aug/2026 15:21:13] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:18,352 127.0.0.1 - - [02/Aug/2026 15:21:18] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:23,243 127.0.0.1 - - [02/Aug/2026 15:21:23] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:28,324 127.0.0.1 - - [02/Aug/2026 15:21:28] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:33,247 127.0.0.1 - - [02/Aug/2026 15:21:33] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:38,314 127.0.0.1 - - [02/Aug/2026 15:21:38] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:43,240 127.0.0.1 - - [02/Aug/2026 15:21:43] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:48,320 127.0.0.1 - - [02/Aug/2026 15:21:48] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:53,266 127.0.0.1 - - [02/Aug/2026 15:21:53] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:21:58,342 127.0.0.1 - - [02/Aug/2026 15:21:58] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:03,366 127.0.0.1 - - [02/Aug/2026 15:22:03] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:08,279 127.0.0.1 - - [02/Aug/2026 15:22:08] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:09,915 127.0.0.1 - - [02/Aug/2026 15:22:09] "GET / HTTP/1.1" 200 - +2026-08-02 15:22:10,619 127.0.0.1 - - [02/Aug/2026 15:22:10] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:15,593 127.0.0.1 - - [02/Aug/2026 15:22:15] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:20,680 127.0.0.1 - - [02/Aug/2026 15:22:20] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:25,629 127.0.0.1 - - [02/Aug/2026 15:22:25] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:30,645 127.0.0.1 - - [02/Aug/2026 15:22:30] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:35,674 127.0.0.1 - - [02/Aug/2026 15:22:35] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:40,669 127.0.0.1 - - [02/Aug/2026 15:22:40] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:45,621 127.0.0.1 - - [02/Aug/2026 15:22:45] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:22:50,671 127.0.0.1 - - [02/Aug/2026 15:22:50] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:04,096 127.0.0.1 - - [02/Aug/2026 15:23:04] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:05,773 127.0.0.1 - - [02/Aug/2026 15:23:05] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:09,040 127.0.0.1 - - [02/Aug/2026 15:23:09] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:10,613 127.0.0.1 - - [02/Aug/2026 15:23:10] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:15,623 127.0.0.1 - - [02/Aug/2026 15:23:15] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:20,651 127.0.0.1 - - [02/Aug/2026 15:23:20] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:25,625 127.0.0.1 - - [02/Aug/2026 15:23:25] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:30,601 127.0.0.1 - - [02/Aug/2026 15:23:30] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:35,658 127.0.0.1 - - [02/Aug/2026 15:23:35] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:40,614 127.0.0.1 - - [02/Aug/2026 15:23:40] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:45,610 127.0.0.1 - - [02/Aug/2026 15:23:45] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:50,764 127.0.0.1 - - [02/Aug/2026 15:23:50] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:23:55,615 127.0.0.1 - - [02/Aug/2026 15:23:55] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:00,716 127.0.0.1 - - [02/Aug/2026 15:24:00] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:05,770 127.0.0.1 - - [02/Aug/2026 15:24:05] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:10,604 127.0.0.1 - - [02/Aug/2026 15:24:10] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:15,709 127.0.0.1 - - [02/Aug/2026 15:24:15] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:20,684 127.0.0.1 - - [02/Aug/2026 15:24:20] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:25,598 127.0.0.1 - - [02/Aug/2026 15:24:25] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:30,631 127.0.0.1 - - [02/Aug/2026 15:24:30] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:35,674 127.0.0.1 - - [02/Aug/2026 15:24:35] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:40,609 127.0.0.1 - - [02/Aug/2026 15:24:40] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:45,607 127.0.0.1 - - [02/Aug/2026 15:24:45] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:50,753 127.0.0.1 - - [02/Aug/2026 15:24:50] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:24:55,701 127.0.0.1 - - [02/Aug/2026 15:24:55] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:00,703 127.0.0.1 - - [02/Aug/2026 15:25:00] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:05,652 127.0.0.1 - - [02/Aug/2026 15:25:05] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:10,602 127.0.0.1 - - [02/Aug/2026 15:25:10] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:15,603 127.0.0.1 - - [02/Aug/2026 15:25:15] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:20,661 127.0.0.1 - - [02/Aug/2026 15:25:20] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:25,601 127.0.0.1 - - [02/Aug/2026 15:25:25] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:30,720 127.0.0.1 - - [02/Aug/2026 15:25:30] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:35,777 127.0.0.1 - - [02/Aug/2026 15:25:35] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:40,629 127.0.0.1 - - [02/Aug/2026 15:25:40] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:45,605 127.0.0.1 - - [02/Aug/2026 15:25:45] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:50,796 127.0.0.1 - - [02/Aug/2026 15:25:50] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:25:55,717 127.0.0.1 - - [02/Aug/2026 15:25:55] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:00,665 127.0.0.1 - - [02/Aug/2026 15:26:00] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:05,679 127.0.0.1 - - [02/Aug/2026 15:26:05] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:10,644 127.0.0.1 - - [02/Aug/2026 15:26:10] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:15,614 127.0.0.1 - - [02/Aug/2026 15:26:15] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:20,731 127.0.0.1 - - [02/Aug/2026 15:26:20] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:25,041 127.0.0.1 - - [02/Aug/2026 15:26:25] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:25,616 127.0.0.1 - - [02/Aug/2026 15:26:25] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:26,932 127.0.0.1 - - [02/Aug/2026 15:26:26] "GET / HTTP/1.1" 200 - +2026-08-02 15:26:27,347 127.0.0.1 - - [02/Aug/2026 15:26:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:32,402 127.0.0.1 - - [02/Aug/2026 15:26:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:37,412 127.0.0.1 - - [02/Aug/2026 15:26:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:42,361 127.0.0.1 - - [02/Aug/2026 15:26:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:47,353 127.0.0.1 - - [02/Aug/2026 15:26:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:52,485 127.0.0.1 - - [02/Aug/2026 15:26:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:26:57,353 127.0.0.1 - - [02/Aug/2026 15:26:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:02,527 127.0.0.1 - - [02/Aug/2026 15:27:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:07,533 127.0.0.1 - - [02/Aug/2026 15:27:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:12,487 127.0.0.1 - - [02/Aug/2026 15:27:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:17,346 127.0.0.1 - - [02/Aug/2026 15:27:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:22,412 127.0.0.1 - - [02/Aug/2026 15:27:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:27,441 127.0.0.1 - - [02/Aug/2026 15:27:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:32,405 127.0.0.1 - - [02/Aug/2026 15:27:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:37,514 127.0.0.1 - - [02/Aug/2026 15:27:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:42,341 127.0.0.1 - - [02/Aug/2026 15:27:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:47,366 127.0.0.1 - - [02/Aug/2026 15:27:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:52,487 127.0.0.1 - - [02/Aug/2026 15:27:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:27:57,358 127.0.0.1 - - [02/Aug/2026 15:27:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:02,347 127.0.0.1 - - [02/Aug/2026 15:28:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:07,435 127.0.0.1 - - [02/Aug/2026 15:28:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:13,496 127.0.0.1 - - [02/Aug/2026 15:28:13] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:17,376 127.0.0.1 - - [02/Aug/2026 15:28:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:22,536 127.0.0.1 - - [02/Aug/2026 15:28:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:27,348 127.0.0.1 - - [02/Aug/2026 15:28:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:32,340 127.0.0.1 - - [02/Aug/2026 15:28:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:37,428 127.0.0.1 - - [02/Aug/2026 15:28:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:42,402 127.0.0.1 - - [02/Aug/2026 15:28:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:47,380 127.0.0.1 - - [02/Aug/2026 15:28:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:52,435 127.0.0.1 - - [02/Aug/2026 15:28:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:28:57,382 127.0.0.1 - - [02/Aug/2026 15:28:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:02,402 127.0.0.1 - - [02/Aug/2026 15:29:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:07,428 127.0.0.1 - - [02/Aug/2026 15:29:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:12,359 127.0.0.1 - - [02/Aug/2026 15:29:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:17,363 127.0.0.1 - - [02/Aug/2026 15:29:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:22,492 127.0.0.1 - - [02/Aug/2026 15:29:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:27,365 127.0.0.1 - - [02/Aug/2026 15:29:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:32,475 127.0.0.1 - - [02/Aug/2026 15:29:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:37,444 127.0.0.1 - - [02/Aug/2026 15:29:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:42,405 127.0.0.1 - - [02/Aug/2026 15:29:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:47,405 127.0.0.1 - - [02/Aug/2026 15:29:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:52,446 127.0.0.1 - - [02/Aug/2026 15:29:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:29:57,412 127.0.0.1 - - [02/Aug/2026 15:29:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:02,357 127.0.0.1 - - [02/Aug/2026 15:30:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:07,498 127.0.0.1 - - [02/Aug/2026 15:30:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:12,502 127.0.0.1 - - [02/Aug/2026 15:30:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:17,363 127.0.0.1 - - [02/Aug/2026 15:30:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:22,610 127.0.0.1 - - [02/Aug/2026 15:30:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:27,411 127.0.0.1 - - [02/Aug/2026 15:30:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:32,505 127.0.0.1 - - [02/Aug/2026 15:30:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:37,466 127.0.0.1 - - [02/Aug/2026 15:30:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:42,357 127.0.0.1 - - [02/Aug/2026 15:30:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:47,382 127.0.0.1 - - [02/Aug/2026 15:30:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:52,520 127.0.0.1 - - [02/Aug/2026 15:30:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:30:57,362 127.0.0.1 - - [02/Aug/2026 15:30:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:02,363 127.0.0.1 - - [02/Aug/2026 15:31:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:03,357 skip KXDOGE15M-26AUG021845-45: llm vetoes fade: wants DOWN +2026-08-02 15:31:07,447 127.0.0.1 - - [02/Aug/2026 15:31:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:12,493 127.0.0.1 - - [02/Aug/2026 15:31:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:17,474 127.0.0.1 - - [02/Aug/2026 15:31:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:22,678 127.0.0.1 - - [02/Aug/2026 15:31:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:27,366 127.0.0.1 - - [02/Aug/2026 15:31:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:32,369 127.0.0.1 - - [02/Aug/2026 15:31:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:37,543 127.0.0.1 - - [02/Aug/2026 15:31:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:42,505 127.0.0.1 - - [02/Aug/2026 15:31:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:47,397 127.0.0.1 - - [02/Aug/2026 15:31:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:52,427 127.0.0.1 - - [02/Aug/2026 15:31:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:31:57,375 127.0.0.1 - - [02/Aug/2026 15:31:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:02,497 127.0.0.1 - - [02/Aug/2026 15:32:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:07,476 127.0.0.1 - - [02/Aug/2026 15:32:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:12,423 127.0.0.1 - - [02/Aug/2026 15:32:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:17,371 127.0.0.1 - - [02/Aug/2026 15:32:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:22,442 127.0.0.1 - - [02/Aug/2026 15:32:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:27,542 127.0.0.1 - - [02/Aug/2026 15:32:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:32,376 127.0.0.1 - - [02/Aug/2026 15:32:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:37,597 127.0.0.1 - - [02/Aug/2026 15:32:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:42,491 127.0.0.1 - - [02/Aug/2026 15:32:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:47,388 127.0.0.1 - - [02/Aug/2026 15:32:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:52,588 127.0.0.1 - - [02/Aug/2026 15:32:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:32:57,486 127.0.0.1 - - [02/Aug/2026 15:32:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:02,503 127.0.0.1 - - [02/Aug/2026 15:33:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:07,441 127.0.0.1 - - [02/Aug/2026 15:33:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:12,381 127.0.0.1 - - [02/Aug/2026 15:33:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:18,443 127.0.0.1 - - [02/Aug/2026 15:33:18] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:22,587 127.0.0.1 - - [02/Aug/2026 15:33:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:27,382 127.0.0.1 - - [02/Aug/2026 15:33:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:32,424 127.0.0.1 - - [02/Aug/2026 15:33:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:37,476 127.0.0.1 - - [02/Aug/2026 15:33:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:42,491 127.0.0.1 - - [02/Aug/2026 15:33:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:47,380 127.0.0.1 - - [02/Aug/2026 15:33:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:52,460 127.0.0.1 - - [02/Aug/2026 15:33:52] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:33:57,385 127.0.0.1 - - [02/Aug/2026 15:33:57] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:02,488 127.0.0.1 - - [02/Aug/2026 15:34:02] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:07,453 127.0.0.1 - - [02/Aug/2026 15:34:07] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:12,500 127.0.0.1 - - [02/Aug/2026 15:34:12] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:17,392 127.0.0.1 - - [02/Aug/2026 15:34:17] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:22,451 127.0.0.1 - - [02/Aug/2026 15:34:22] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:27,381 127.0.0.1 - - [02/Aug/2026 15:34:27] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:32,401 127.0.0.1 - - [02/Aug/2026 15:34:32] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:37,443 127.0.0.1 - - [02/Aug/2026 15:34:37] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:42,384 127.0.0.1 - - [02/Aug/2026 15:34:42] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:47,399 127.0.0.1 - - [02/Aug/2026 15:34:47] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:47,821 127.0.0.1 - - [02/Aug/2026 15:34:47] "GET / HTTP/1.1" 200 - +2026-08-02 15:34:48,553 127.0.0.1 - - [02/Aug/2026 15:34:48] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:53,619 127.0.0.1 - - [02/Aug/2026 15:34:53] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:34:58,531 127.0.0.1 - - [02/Aug/2026 15:34:58] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:35:03,527 127.0.0.1 - - [02/Aug/2026 15:35:03] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:35:08,611 127.0.0.1 - - [02/Aug/2026 15:35:08] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:35:13,543 127.0.0.1 - - [02/Aug/2026 15:35:13] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:35:18,536 127.0.0.1 - - [02/Aug/2026 15:35:18] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:36:13,693 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:36:20,128 skip KXDOGE15M-26AUG021845-45: llm vetoes fade: wants DOWN +2026-08-02 15:36:26,462 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:36:30,475 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:36:33,349 skip KXSOL15M-26AUG021845-45: llm vetoes fade: wants DOWN +2026-08-02 15:36:34,582 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:36:36,572 skip KXDOGE15M-26AUG021845-45: llm vetoes fade: wants DOWN +2026-08-02 15:36:40,198 skip KXETH15M-26AUG021845-45: llm vetoes fade: wants DOWN +2026-08-02 15:40:19,510 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:40:22,279 skip KXDOGE15M-26AUG021845-45: llm vetoes fade: wants SKIP +2026-08-02 15:40:24,531 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:40:27,143 skip KXSOL15M-26AUG021845-45: llm vetoes fade: wants DOWN +2026-08-02 15:40:29,552 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:40:32,174 skip KXETH15M-26AUG021845-45: llm vetoes fade: wants DOWN +2026-08-02 15:41:55,913 Exception on /api/fleet [GET] +Traceback (most recent call last): + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 1511, in wsgi_app + response = self.full_dispatch_request() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 919, in full_dispatch_request + rv = self.handle_user_exception(e) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 917, in full_dispatch_request + rv = self.dispatch_request() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 902, in dispatch_request + return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/dashboard.py", line 320, in fleet_api + evts = [dict(r) for r in conn.execute("SELECT * FROM events ORDER BY id DESC LIMIT 40")] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +sqlite3.OperationalError: no such column: id +2026-08-02 15:41:55,915 127.0.0.1 - - [02/Aug/2026 15:41:55] "GET /api/fleet HTTP/1.1" 500 - +2026-08-02 15:41:59,998 Exception on /api/fleet [GET] +Traceback (most recent call last): + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 1511, in wsgi_app + response = self.full_dispatch_request() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 919, in full_dispatch_request + rv = self.handle_user_exception(e) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 917, in full_dispatch_request + rv = self.dispatch_request() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 902, in dispatch_request + return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/dashboard.py", line 320, in fleet_api + evts = [dict(r) for r in conn.execute("SELECT * FROM events ORDER BY id DESC LIMIT 40")] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +sqlite3.OperationalError: no such column: id +2026-08-02 15:41:59,998 127.0.0.1 - - [02/Aug/2026 15:41:59] "GET /api/fleet HTTP/1.1" 500 - +2026-08-02 15:42:04,978 Exception on /api/fleet [GET] +Traceback (most recent call last): + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 1511, in wsgi_app + response = self.full_dispatch_request() + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 919, in full_dispatch_request + rv = self.handle_user_exception(e) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 917, in full_dispatch_request + rv = self.dispatch_request() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/.venv/lib/python3.11/site-packages/flask/app.py", line 902, in dispatch_request + return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "/Users/drjones/kalshi-bot/dashboard.py", line 320, in fleet_api + evts = [dict(r) for r in conn.execute("SELECT * FROM events ORDER BY id DESC LIMIT 40")] + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +sqlite3.OperationalError: no such column: id +2026-08-02 15:42:14,186 127.0.0.1 - - [02/Aug/2026 15:42:14] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:42:26,168 127.0.0.1 - - [02/Aug/2026 15:42:26] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:42:41,329 127.0.0.1 - - [02/Aug/2026 15:42:41] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:42:45,499 127.0.0.1 - - [02/Aug/2026 15:42:45] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:43:19,872 127.0.0.1 - - [02/Aug/2026 15:43:19] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:43:49,817 127.0.0.1 - - [02/Aug/2026 15:43:49] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:44:05,051 127.0.0.1 - - [02/Aug/2026 15:44:05] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:44:09,558 127.0.0.1 - - [02/Aug/2026 15:44:09] "GET / HTTP/1.1" 200 - +2026-08-02 15:44:09,937 127.0.0.1 - - [02/Aug/2026 15:44:09] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:44:10,279 127.0.0.1 - - [02/Aug/2026 15:44:10] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:44:15,266 127.0.0.1 - - [02/Aug/2026 15:44:15] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:44:17,748 127.0.0.1 - - [02/Aug/2026 15:44:17] "GET / HTTP/1.1" 200 - +2026-08-02 15:44:18,181 127.0.0.1 - - [02/Aug/2026 15:44:18] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:44:19,504 127.0.0.1 - - [02/Aug/2026 15:44:19] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:44:19,999 127.0.0.1 - - [02/Aug/2026 15:44:19] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:44:20,523 127.0.0.1 - - [02/Aug/2026 15:44:20] "GET /api/state HTTP/1.1" 200 - +2026-08-02 15:44:34,846 127.0.0.1 - - [02/Aug/2026 15:44:34] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:44:34,935 127.0.0.1 - - [02/Aug/2026 15:44:34] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:44:49,861 127.0.0.1 - - [02/Aug/2026 15:44:49] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:44:49,946 127.0.0.1 - - [02/Aug/2026 15:44:49] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:45:04,937 127.0.0.1 - - [02/Aug/2026 15:45:04] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:45:05,100 127.0.0.1 - - [02/Aug/2026 15:45:05] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:45:17,020 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:45:19,977 127.0.0.1 - - [02/Aug/2026 15:45:19] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:45:20,057 127.0.0.1 - - [02/Aug/2026 15:45:20] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:45:22,013 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:45:27,049 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:45:30,063 skip KXETH15M-26AUG021900-00: market closed (status=?) +2026-08-02 15:45:34,995 127.0.0.1 - - [02/Aug/2026 15:45:34] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:45:35,078 127.0.0.1 - - [02/Aug/2026 15:45:35] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:45:44,817 skip KXSOL15M-26AUG021900-00: ornith passes: RSI neutral + narrow range = no exhaustion +2026-08-02 15:45:50,011 127.0.0.1 - - [02/Aug/2026 15:45:50] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:45:50,090 127.0.0.1 - - [02/Aug/2026 15:45:50] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:46:00,488 skip KXDOGE15M-26AUG021900-00: market closed (status=?) +2026-08-02 15:46:05,028 127.0.0.1 - - [02/Aug/2026 15:46:05] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:46:05,108 127.0.0.1 - - [02/Aug/2026 15:46:05] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:46:20,045 127.0.0.1 - - [02/Aug/2026 15:46:20] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:46:20,126 127.0.0.1 - - [02/Aug/2026 15:46:20] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:46:35,058 127.0.0.1 - - [02/Aug/2026 15:46:35] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:46:35,141 127.0.0.1 - - [02/Aug/2026 15:46:35] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:46:50,074 127.0.0.1 - - [02/Aug/2026 15:46:50] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:46:50,155 127.0.0.1 - - [02/Aug/2026 15:46:50] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:47:05,091 127.0.0.1 - - [02/Aug/2026 15:47:05] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:47:05,176 127.0.0.1 - - [02/Aug/2026 15:47:05] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:47:20,109 127.0.0.1 - - [02/Aug/2026 15:47:20] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:47:20,191 127.0.0.1 - - [02/Aug/2026 15:47:20] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:47:35,129 127.0.0.1 - - [02/Aug/2026 15:47:35] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:47:35,210 127.0.0.1 - - [02/Aug/2026 15:47:35] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:47:41,626 127.0.0.1 - - [02/Aug/2026 15:47:41] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:47:50,147 127.0.0.1 - - [02/Aug/2026 15:47:50] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:47:50,233 127.0.0.1 - - [02/Aug/2026 15:47:50] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:47:54,751 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:47:57,862 MAKER-POST NO KXDOGE15M-26AUG021900-00 @ 45¢ — ornith: DOWN spike 100.00% → DOWN conf=0.72 +2026-08-02 15:48:00,735 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:48:05,165 127.0.0.1 - - [02/Aug/2026 15:48:05] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:48:05,251 127.0.0.1 - - [02/Aug/2026 15:48:05] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:48:06,771 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:48:09,436 skip KXETH15M-26AUG021900-00: ornith passes: RSI neutral + Fear&Greed low = no clear exhaustion +2026-08-02 15:48:12,064 MAKER-POST NO KXSOL15M-26AUG021900-00 @ 45¢ — ornith: UP spike 62392.45% → DOWN conf=0.72 +2026-08-02 15:48:20,184 127.0.0.1 - - [02/Aug/2026 15:48:20] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:48:20,272 127.0.0.1 - - [02/Aug/2026 15:48:20] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:48:35,203 127.0.0.1 - - [02/Aug/2026 15:48:35] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:48:35,296 127.0.0.1 - - [02/Aug/2026 15:48:35] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:48:50,226 127.0.0.1 - - [02/Aug/2026 15:48:50] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:48:50,306 127.0.0.1 - - [02/Aug/2026 15:48:50] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:49:05,244 127.0.0.1 - - [02/Aug/2026 15:49:05] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:49:05,331 127.0.0.1 - - [02/Aug/2026 15:49:05] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:49:20,262 127.0.0.1 - - [02/Aug/2026 15:49:20] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:49:20,636 127.0.0.1 - - [02/Aug/2026 15:49:20] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:49:34,601 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:49:35,558 127.0.0.1 - - [02/Aug/2026 15:49:35] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:49:35,644 127.0.0.1 - - [02/Aug/2026 15:49:35] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:49:40,588 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:49:40,959 MAKER-POST NO KXDOGE15M-26AUG021900-00 @ 45¢ — ornith: DOWN spike 100.00% → DOWN conf=0.75 +2026-08-02 15:49:43,544 skip KXSOL15M-26AUG021900-00: ornith passes: RSI neutral, 24h range tight—no spike to fade +2026-08-02 15:49:46,623 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:49:50,578 127.0.0.1 - - [02/Aug/2026 15:49:50] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:49:50,672 127.0.0.1 - - [02/Aug/2026 15:49:50] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:49:57,612 MAKER-POST NO KXETH15M-26AUG021900-00 @ 45¢ — ornith: UP spike 1594287.58% → DOWN conf=0.72 +2026-08-02 15:50:05,598 127.0.0.1 - - [02/Aug/2026 15:50:05] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:50:05,692 127.0.0.1 - - [02/Aug/2026 15:50:05] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:50:20,617 127.0.0.1 - - [02/Aug/2026 15:50:20] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:50:20,704 127.0.0.1 - - [02/Aug/2026 15:50:20] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:50:35,637 127.0.0.1 - - [02/Aug/2026 15:50:35] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:50:35,723 127.0.0.1 - - [02/Aug/2026 15:50:35] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:50:50,659 127.0.0.1 - - [02/Aug/2026 15:50:50] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:50:50,746 127.0.0.1 - - [02/Aug/2026 15:50:50] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:51:05,679 127.0.0.1 - - [02/Aug/2026 15:51:05] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:51:05,766 127.0.0.1 - - [02/Aug/2026 15:51:05] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:51:20,699 127.0.0.1 - - [02/Aug/2026 15:51:20] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:51:20,787 127.0.0.1 - - [02/Aug/2026 15:51:20] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:51:35,720 127.0.0.1 - - [02/Aug/2026 15:51:35] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:51:35,807 127.0.0.1 - - [02/Aug/2026 15:51:35] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:51:50,743 127.0.0.1 - - [02/Aug/2026 15:51:50] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:51:50,831 127.0.0.1 - - [02/Aug/2026 15:51:50] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:52:05,764 127.0.0.1 - - [02/Aug/2026 15:52:05] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:52:05,861 127.0.0.1 - - [02/Aug/2026 15:52:05] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:52:20,785 127.0.0.1 - - [02/Aug/2026 15:52:20] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:52:20,874 127.0.0.1 - - [02/Aug/2026 15:52:20] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:52:34,539 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:52:35,808 127.0.0.1 - - [02/Aug/2026 15:52:35] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:52:35,897 127.0.0.1 - - [02/Aug/2026 15:52:35] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:52:37,218 skip KXDOGE15M-26AUG021900-00: no swing (0.000% < 0.04%) +2026-08-02 15:52:45,716 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:52:48,082 skip KXDOGE15M-26AUG021900-00: no swing (0.000% < 0.04%) +2026-08-02 15:52:50,831 127.0.0.1 - - [02/Aug/2026 15:52:50] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:52:50,916 127.0.0.1 - - [02/Aug/2026 15:52:50] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:52:51,768 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:52:54,734 skip KXSOL15M-26AUG021900-00: no swing (0.000% < 0.04%) +2026-08-02 15:52:57,817 K4LSH1_OPS online — mode=AUTO dry_run=False stake=15¢ +2026-08-02 15:53:05,852 127.0.0.1 - - [02/Aug/2026 15:53:05] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:53:05,952 127.0.0.1 - - [02/Aug/2026 15:53:05] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:53:07,667 skip KXETH15M-26AUG021900-00: no swing (0.000% < 0.04%) +2026-08-02 15:53:20,878 127.0.0.1 - - [02/Aug/2026 15:53:20] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:53:20,968 127.0.0.1 - - [02/Aug/2026 15:53:20] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:53:35,900 127.0.0.1 - - [02/Aug/2026 15:53:35] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:53:35,992 127.0.0.1 - - [02/Aug/2026 15:53:35] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:53:50,922 127.0.0.1 - - [02/Aug/2026 15:53:50] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:53:51,014 127.0.0.1 - - [02/Aug/2026 15:53:51] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:54:05,944 127.0.0.1 - - [02/Aug/2026 15:54:05] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:54:06,038 127.0.0.1 - - [02/Aug/2026 15:54:06] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:54:20,967 127.0.0.1 - - [02/Aug/2026 15:54:20] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:54:21,344 127.0.0.1 - - [02/Aug/2026 15:54:21] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:54:36,271 127.0.0.1 - - [02/Aug/2026 15:54:36] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:54:36,365 127.0.0.1 - - [02/Aug/2026 15:54:36] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:54:51,297 127.0.0.1 - - [02/Aug/2026 15:54:51] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:54:51,385 127.0.0.1 - - [02/Aug/2026 15:54:51] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:55:06,320 127.0.0.1 - - [02/Aug/2026 15:55:06] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:55:06,414 127.0.0.1 - - [02/Aug/2026 15:55:06] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:55:21,343 127.0.0.1 - - [02/Aug/2026 15:55:21] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:55:21,440 127.0.0.1 - - [02/Aug/2026 15:55:21] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:55:36,368 127.0.0.1 - - [02/Aug/2026 15:55:36] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:55:36,455 127.0.0.1 - - [02/Aug/2026 15:55:36] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:55:51,392 127.0.0.1 - - [02/Aug/2026 15:55:51] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:55:51,480 127.0.0.1 - - [02/Aug/2026 15:55:51] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:56:06,416 127.0.0.1 - - [02/Aug/2026 15:56:06] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:56:06,514 127.0.0.1 - - [02/Aug/2026 15:56:06] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:56:21,441 127.0.0.1 - - [02/Aug/2026 15:56:21] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:56:21,533 127.0.0.1 - - [02/Aug/2026 15:56:21] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:56:36,465 127.0.0.1 - - [02/Aug/2026 15:56:36] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:56:36,555 127.0.0.1 - - [02/Aug/2026 15:56:36] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:56:51,488 127.0.0.1 - - [02/Aug/2026 15:56:51] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:56:51,577 127.0.0.1 - - [02/Aug/2026 15:56:51] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:57:06,512 127.0.0.1 - - [02/Aug/2026 15:57:06] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:57:06,605 127.0.0.1 - - [02/Aug/2026 15:57:06] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:57:21,535 127.0.0.1 - - [02/Aug/2026 15:57:21] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:57:21,632 127.0.0.1 - - [02/Aug/2026 15:57:21] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:57:36,560 127.0.0.1 - - [02/Aug/2026 15:57:36] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:57:36,661 127.0.0.1 - - [02/Aug/2026 15:57:36] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:57:51,588 127.0.0.1 - - [02/Aug/2026 15:57:51] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:57:51,679 127.0.0.1 - - [02/Aug/2026 15:57:51] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:58:06,613 127.0.0.1 - - [02/Aug/2026 15:58:06] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:58:06,710 127.0.0.1 - - [02/Aug/2026 15:58:06] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:58:21,638 127.0.0.1 - - [02/Aug/2026 15:58:21] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:58:21,729 127.0.0.1 - - [02/Aug/2026 15:58:21] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:58:36,666 127.0.0.1 - - [02/Aug/2026 15:58:36] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:58:36,754 127.0.0.1 - - [02/Aug/2026 15:58:36] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:58:51,690 127.0.0.1 - - [02/Aug/2026 15:58:51] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:58:51,786 127.0.0.1 - - [02/Aug/2026 15:58:51] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:59:06,721 127.0.0.1 - - [02/Aug/2026 15:59:06] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:59:06,849 127.0.0.1 - - [02/Aug/2026 15:59:06] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 15:59:21,749 127.0.0.1 - - [02/Aug/2026 15:59:21] "GET /fleet HTTP/1.1" 200 - +2026-08-02 15:59:22,164 127.0.0.1 - - [02/Aug/2026 15:59:22] "GET /api/fleet HTTP/1.1" 200 - +2026-08-02 16:00:46,169 skip KXETH15M-26AUG021915-15: no swing (0.005% < 0.04%) +2026-08-02 16:00:46,792 skip KXDOGE15M-26AUG021915-15: no swing (0.039% < 0.04%) +2026-08-02 16:00:50,587 MAKER-POST NO KXSOL15M-26AUG021915-15 @ 45¢ — ornith: DOWN spike 0.05% → DOWN conf=0.72 +2026-08-02 16:04:35,227 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:04:41,274 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:04:44,285 MAKER-POST NO KXDOGE15M-26AUG021915-15 @ 5¢ — ornith: DOWN spike 0.05% → DOWN conf=0.65 +2026-08-02 16:04:47,230 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:04:49,730 skip KXETH15M-26AUG021915-15: no swing (0.011% < 0.005%) +2026-08-02 16:06:49,958 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:06:55,895 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:07:01,928 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:07:04,838 MAKER-POST NO KXETH15M-26AUG021915-15 @ 5¢ — ornith: DOWN spike 0.12% → DOWN conf=0.65 +2026-08-02 16:14:08,061 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:14:14,080 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:14:20,046 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:15:29,455 MAKER-POST NO KXSOL15M-26AUG021930-30 @ 5¢ — ornith: DOWN spike 0.11% → DOWN conf=0.62 +2026-08-02 16:15:42,620 MAKER-POST NO KXDOGE15M-26AUG021930-30 @ 5¢ — ornith: DOWN spike 0.19% → DOWN conf=0.65 +2026-08-02 16:16:06,181 MAKER-POST NO KXETH15M-26AUG021930-30 @ 5¢ — ornith: DOWN spike 0.12% → DOWN conf=0.65 +2026-08-02 16:18:28,645 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:18:34,647 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:18:40,632 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:22:43,485 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:23:15,210 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:23:21,226 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:23:27,279 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:28:55,974 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:29:00,991 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:29:06,033 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ +2026-08-02 16:30:19,789 skip KXSOL15M-26AUG021945-45: ornith passes: RSI neutral, no exhaustion signal +2026-08-02 16:30:55,893 MAKER-POST NO KXDOGE15M-26AUG021945-45 @ 50¢ — ornith: UP spike 0.14% → DOWN conf=0.72 +2026-08-02 16:30:57,528 MAKER-POST NO KXETH15M-26AUG021945-45 @ 50¢ — ornith: UP spike 0.11% → DOWN conf=0.62 +2026-08-02 16:45:41,471 skip KXETH15M-26AUG022000-00: ornith passes: RSI neutral, no exhaustion signal +2026-08-02 16:45:41,512 MAKER-POST NO KXSOL15M-26AUG022000-00 @ 50¢ — ornith: DOWN spike 0.05% → DOWN conf=0.65 +2026-08-02 16:45:50,785 skip KXDOGE15M-26AUG022000-00: ornith passes: RSI oversold + 24h range $0-$0 = dead market, no fade signal +2026-08-02 17:00:31,843 MAKER-POST NO KXDOGE15M-26AUG022015-15 @ 50¢ — ornith: UP spike 0.07% → DOWN conf=0.65 +2026-08-02 17:00:32,629 MAKER-POST NO KXSOL15M-26AUG022015-15 @ 50¢ — ornith: UP spike 0.17% → DOWN conf=0.72 +2026-08-02 17:00:51,056 skip KXETH15M-26AUG022015-15: ornith passes: RSI neutral, no exhaustion signal +2026-08-02 17:15:31,474 MAKER-POST NO KXSOL15M-26AUG022030-30 @ 50¢ — ornith: DOWN spike 0.10% → DOWN conf=0.62 +2026-08-02 17:15:36,471 MAKER-POST NO KXETH15M-26AUG022030-30 @ 50¢ — ornith: DOWN spike 0.14% → DOWN conf=0.62 +2026-08-02 17:15:36,896 MAKER-POST NO KXDOGE15M-26AUG022030-30 @ 50¢ — ornith: DOWN spike 0.11% → DOWN conf=0.65 +2026-08-02 17:30:40,931 MAKER-POST NO KXSOL15M-26AUG022045-45 @ 50¢ — ornith: DOWN spike 0.22% → DOWN conf=0.65 +2026-08-02 17:30:42,121 MAKER-POST NO KXETH15M-26AUG022045-45 @ 50¢ — ornith: DOWN spike 0.22% → DOWN conf=0.65 +2026-08-02 17:30:56,054 skip KXDOGE15M-26AUG022045-45: ornith passes: No price data to assess trend +2026-08-02 17:45:35,718 MAKER-POST NO KXDOGE15M-26AUG022100-00 @ 50¢ — ornith: DOWN spike 0.10% → DOWN conf=0.72 +2026-08-02 17:45:36,474 MAKER-POST NO KXSOL15M-26AUG022100-00 @ 50¢ — ornith: DOWN spike 0.11% → DOWN conf=0.72 +2026-08-02 17:45:58,340 skip KXETH15M-26AUG022100-00: ornith passes: RSI oversold + Fear&Greed low = bottoming, not fading +2026-08-02 17:48:03,830 HEDGE KXBTC15M-TEST: no@45¢ + yes@42¢ → locked 13¢ +2026-08-02 17:48:04,314 ollama vote failed: Expecting value: line 1 column 1 (char 0) +2026-08-02 17:48:04,315 ollama vote failed: Expecting value: line 1 column 1 (char 0) +2026-08-02 17:48:04,315 ollama vote failed: Expecting value: line 1 column 1 (char 0) +2026-08-02 17:49:52,453 HEDGE KXBTC15M-TEST: no@45¢ + yes@42¢ → locked 13¢ +2026-08-02 17:49:54,007 ollama vote failed: the JSON object must be str, bytes or bytearray, not MagicMock +2026-08-02 17:49:54,007 ollama vote failed: the JSON object must be str, bytes or bytearray, not MagicMock +2026-08-02 17:49:54,008 ollama vote failed: the JSON object must be str, bytes or bytearray, not MagicMock +2026-08-02 18:00:41,758 MAKER-POST NO KXSOL15M-26AUG022115-15 @ 50¢ — ornith: DOWN spike 0.11% → DOWN conf=0.72 +2026-08-02 18:00:45,615 skip KXDOGE15M-26AUG022115-15: ornith passes: RSI=0 oversold + 24h range $0-$0 = no real move to fade +2026-08-02 18:00:51,663 MAKER-POST NO KXETH15M-26AUG022115-15 @ 50¢ — ornith: DOWN spike 0.10% → DOWN conf=0.72 +2026-08-02 18:15:16,621 skip KXSOL15M-26AUG022130-30: ornith passes: RSI neutral, no exhaustion signal +2026-08-02 18:16:00,588 skip KXDOGE15M-26AUG022130-30: ornith passes: No price data provided for BTC +2026-08-02 18:16:08,336 MAKER-POST NO KXETH15M-26AUG022130-30 @ 50¢ — ornith: DOWN spike 0.14% → DOWN conf=0.62 +2026-08-02 18:18:13,638 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ max_spend=100¢ +2026-08-02 18:18:20,615 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ max_spend=100¢ +2026-08-02 18:18:20,615 staggering start by 20s +2026-08-02 18:18:23,872 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ max_spend=100¢ +2026-08-02 18:18:23,872 staggering start by 40s +2026-08-02 18:18:24,609 POST NO x1 KXDOGE15M-26AUG022130-30 @ 50¢ — ornith: DOWN spike 0.13% → DOWN conf=0.72 +2026-08-02 18:18:50,177 POST NO x1 KXSOL15M-26AUG022130-30 @ 50¢ — ornith: DOWN spike 0.12% → DOWN conf=0.62 +2026-08-02 18:19:24,020 POST NO x1 KXETH15M-26AUG022130-30 @ 50¢ — ornith: DOWN spike 0.08% → DOWN conf=0.52 +2026-08-02 18:23:20,655 skip KXDOGE15M-26AUG022130-30: ornith passes: RSI neutral, no spike detected +2026-08-02 18:23:49,313 skip KXSOL15M-26AUG022130-30: ornith passes: RSI neutral at 50, no exhaustion signal +2026-08-02 18:24:14,604 POST NO x1 KXETH15M-26AUG022130-30 @ 50¢ — ornith: DOWN spike 0.03% → DOWN conf=0.72 +2026-08-02 18:28:26,185 skip KXDOGE15M-26AUG022130-30: ornith passes: RSI 98 overbought but no price data to confirm trend vs spike +2026-08-02 18:28:53,977 POST NO x1 KXSOL15M-26AUG022130-30 @ 50¢ — ornith: DOWN spike 0.07% → DOWN conf=0.65 +2026-08-02 18:29:26,169 skip KXETH15M-26AUG022130-30: ornith passes: RSI neutral, no exhaustion signal +2026-08-02 18:33:30,453 POST NO x1 KXDOGE15M-26AUG022145-45 @ 50¢ — ornith: UP spike 0.05% → DOWN conf=0.72 +2026-08-02 18:33:51,482 POST NO x1 KXSOL15M-26AUG022145-45 @ 50¢ — ornith: DOWN spike 0.03% → DOWN conf=0.65 +2026-08-02 18:34:15,865 skip KXETH15M-26AUG022145-45: ornith passes: RSI neutral, no exhaustion signal +2026-08-02 18:38:33,367 skip KXDOGE15M-26AUG022145-45: ornith passes: RSI=0 oversold + 24h flat = no trend to fade +2026-08-02 18:38:58,086 POST NO x1 KXSOL15M-26AUG022145-45 @ 50¢ — ornith: DOWN spike 0.08% → DOWN conf=0.65 +2026-08-02 18:39:31,032 skip KXETH15M-26AUG022145-45: ornith passes: RSI 63 not stretched; no spike data +2026-08-02 18:43:32,402 skip KXDOGE15M-26AUG022145-45: ornith passes: RSI=0 oversold + 24h range $0-$0 = no real move +2026-08-02 18:43:57,637 POST NO x1 KXSOL15M-26AUG022145-45 @ 50¢ — ornith: UP spike 0.08% → DOWN conf=0.65 +2026-08-02 18:44:21,425 skip KXETH15M-26AUG022145-45: ornith passes: RSI 61 not stretched; range wide suggests trend, not chop +2026-08-02 18:47:01,043 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ max_spend=100¢ +2026-08-02 18:47:04,138 HEDGE KXBTC15M-TEST: no@45¢ + yes@42¢ → locked 13¢ +2026-08-02 18:47:04,648 deep llm failed: '>=' not supported between instances of 'MagicMock' and 'int' +2026-08-02 18:47:04,649 deep llm failed: '>=' not supported between instances of 'MagicMock' and 'int' +2026-08-02 18:47:04,650 deep llm failed: '>=' not supported between instances of 'MagicMock' and 'int' +2026-08-02 18:47:06,182 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ max_spend=100¢ +2026-08-02 18:47:06,183 staggering start by 20s +2026-08-02 18:47:11,233 POST YES x1 KXDOGE15M-26AUG022200-00 @ 50¢ — ⚠ RSI 0 extreme oversold → fade UP +2026-08-02 18:47:11,548 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ max_spend=100¢ +2026-08-02 18:47:11,548 staggering start by 40s +2026-08-02 18:47:36,491 skip KXSOL15M-26AUG022200-00: BTC +0.5% 24h — no counter-trend shorts (conf 0.65<0.78) +2026-08-02 18:48:11,162 skip KXETH15M-26AUG022200-00: BTC +0.6% 24h — no counter-trend shorts (conf 0.72<0.78) +2026-08-02 18:50:30,184 HEDGE KXBTC15M-TEST: no@45¢ + yes@42¢ → locked 13¢ +2026-08-02 18:50:30,587 deep llm failed: '>=' not supported between instances of 'MagicMock' and 'int' +2026-08-02 18:50:30,588 deep llm failed: '>=' not supported between instances of 'MagicMock' and 'int' +2026-08-02 18:50:30,589 deep llm failed: '>=' not supported between instances of 'MagicMock' and 'int' +2026-08-02 18:52:15,246 POST YES x1 KXDOGE15M-26AUG022200-00 @ 50¢ — ⚠ RSI 0 extreme oversold → fade UP +2026-08-02 18:52:41,123 POST YES x1 KXSOL15M-26AUG022200-00 @ 50¢ — ⚠ RSI 0 extreme oversold → fade UP +2026-08-02 18:53:05,662 POST NO x1 KXETH15M-26AUG022200-00 @ 50¢ — ⚠ RSI 100 extreme overbought → fade DOWN +2026-08-02 18:57:19,234 POST NO x1 KXDOGE15M-26AUG022200-00 @ 50¢ — ⚠ RSI 100 extreme overbought → fade DOWN +2026-08-02 18:57:40,738 POST NO x1 KXSOL15M-26AUG022200-00 @ 50¢ — ⚠ RSI 86 extreme overbought → fade DOWN +2026-08-02 18:58:16,098 skip KXETH15M-26AUG022200-00: BTC +0.5% 24h — no counter-trend shorts (conf 0.65<0.78) +2026-08-02 19:02:20,989 skip KXDOGE15M-26AUG022215-15: passes: RSI 63 not stretched, no spike data +2026-08-02 19:02:46,568 POST YES x1 KXSOL15M-26AUG022215-15 @ 50¢ — ⚠ RSI 0 extreme oversold → fade UP +2026-08-02 19:03:11,001 POST NO x1 KXETH15M-26AUG022215-15 @ 50¢ — ⚠ RSI 98 extreme overbought → fade DOWN +2026-08-02 19:07:21,813 POST NO x1 KXDOGE15M-26AUG022215-15 @ 50¢ — ⚠ RSI 100 extreme overbought → fade DOWN +2026-08-02 19:07:46,317 POST YES x1 KXSOL15M-26AUG022215-15 @ 50¢ — ⚠ RSI 0 extreme oversold → fade UP +2026-08-02 19:08:14,797 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ max_spend=100¢ +2026-08-02 19:08:19,711 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ max_spend=100¢ +2026-08-02 19:08:19,711 staggering start by 20s +2026-08-02 19:08:21,175 loop error: name 'llm_vote' is not defined +2026-08-02 19:08:24,773 K4LSH1_OPS online — mode=AUTO dry_run=False stake=10¢ max_spend=100¢ +2026-08-02 19:08:24,774 staggering start by 40s +2026-08-02 19:08:26,747 POST NO x1 KXETH15M-26AUG022215-15 @ 50¢ — DOWN: DOWN spike 0.06% conf=0.65 [RSI oversold + Fear, but 15m momentum DOWN suggests fading t] +2026-08-02 19:08:45,920 loop error: name 'llm_vote' is not defined +2026-08-02 19:09:12,858 loop error: name 'llm_vote' is not defined diff --git a/bot.py b/bot.py new file mode 100644 index 0000000..2dcc9f7 --- /dev/null +++ b/bot.py @@ -0,0 +1,617 @@ +#!/usr/bin/env python3 +""" +K4LSH1_OPS — autonomous 15-minute BTC up/down trading bot. +Momentum + local-Ollama ensemble, tiny stakes, full sqlite audit trail. +Modes: AUTO | DOWN_SPAM | UP_SPAM | OFF (persisted in config.json, hot-reloaded) +DRY_RUN=true simulates orders (still logs + tracks hypothetical P&L). +""" +import base64, json, logging, os, sqlite3, sys, time +from datetime import datetime, timezone +from pathlib import Path +from uuid import uuid4 + +import requests +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import padding + +HOME = Path(__file__).parent +CFG_PATH = HOME / "config.json" +DB_PATH = HOME / "state.db" +# per-coin Kraken pairs +KRAKEN_PAIRS = {"BTC": "XBTUSD", "ETH": "ETHUSD", "DOGE": "XDGUSD", "SOL": "SOLUSD", "XRP": "XRPUSD"} +LOG = logging.getLogger("bot") +logging.basicConfig(level=logging.INFO, format="%(asctime)s %(message)s", + handlers=[logging.FileHandler(HOME/"bot.log"), logging.StreamHandler()]) + +DEFAULT_CFG = { + "api_key_id": "28d5876b-2ece-4aa3-aa17-ec96e1e706eb", + "key_path": str(HOME / "kalshi_private_key.pem"), + "mode": "AUTO", # AUTO | DOWN_SPAM | UP_SPAM | OFF + "dry_run": True, # simulated until flipped from dashboard + "stake_cents": 50, # taker: max ask we'll pay; maker: price we post + "post_price_cents": 45, # maker mode: resting bid price when book is empty + "max_contracts": 1, + "daily_loss_cap_cents": 500, + "min_conf": 0.55, # AUTO mode: min ensemble confidence to fire + "swing_threshold_pct": 0.12, # fade triggers when |weighted 15m move| >= this + "learning": True, + "ollama_url": "http://localhost:11434", + "ollama_model": "qwen3.5:4b", + "series": "KXBTC15M", + "kill": False, +} + +def load_cfg(): + cfg = dict(DEFAULT_CFG) + if CFG_PATH.exists(): + try: cfg.update(json.loads(CFG_PATH.read_text())) + except Exception: pass + else: + CFG_PATH.write_text(json.dumps(cfg, indent=1)) + return cfg + +# ───────── kalshi client ───────── +class Kalshi: + BASE = "https://api.elections.kalshi.com" + PRE = "/trade-api/v2" + def __init__(self, key_id, key_path): + self.key_id = key_id + self.pk = serialization.load_pem_private_key(open(key_path, "rb").read(), password=None) + self.s = requests.Session() + def _h(self, method, path): + ts = str(int(time.time()*1000)) + msg = ts + method.upper() + path.split("?")[0] + sig = self.pk.sign(msg.encode(), padding.PSS(mgf=padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.DIGEST_LENGTH), hashes.SHA256()) + return {"KALSHI-ACCESS-KEY": self.key_id, + "KALSHI-ACCESS-SIGNATURE": base64.b64encode(sig).decode(), + "KALSHI-ACCESS-TIMESTAMP": ts} + def req(self, method, path, **kw): + full = self.PRE + path + for attempt in range(3): + try: + r = self.s.request(method, self.BASE+full, headers=self._h(method, full), timeout=15, **kw) + r.raise_for_status() + return r.json() + except requests.HTTPError as e: + if r.status_code in (401, 403): raise + if attempt == 2: raise + time.sleep(1.5*(attempt+1)) + def markets(self, series, status="open", limit=5): + return self.req("GET", f"/markets?series_ticker={series}&status={status}&limit={limit}").get("markets", []) + def orderbook(self, ticker, depth=5): + return self.req("GET", f"/markets/{ticker}/orderbook?depth={depth}").get("orderbook", {}) + def balance(self): + return self.req("GET", "/portfolio/balance") + def positions(self): + return self.req("GET", "/portfolio/positions?limit=50").get("market_positions", []) + def order(self, ticker, side, count, price_cents, dry): + """side='yes'|'no'. price_cents = limit price in cents. + V2 endpoint: /portfolio/events/orders with bid/ask side + dollar prices.""" + side_v2 = "bid" if side == "yes" else "ask" + price_dollars = f"{price_cents / 100:.4f}" + body = {"ticker": ticker, "client_order_id": str(uuid4()), + "side": side_v2, "count": f"{count:.2f}", + "price": price_dollars, "time_in_force": "good_till_canceled", + "self_trade_prevention_type": "taker_at_cross", + "post_only": False, "reduce_only": False} + if dry: return {"simulated": True, "order": body} + return self.req("POST", "/portfolio/events/orders", json=body) + +# ───────── btc price feed ───────── +def btc_price(coin="BTC"): + pair = KRAKEN_PAIRS.get(coin, "XBTUSD") + try: + r = requests.get(f"https://api.kraken.com/0/public/Ticker?pair={pair}", timeout=8).json() + key = list(r["result"].keys())[0] + t = r["result"][key] + _intel_cache.setdefault("kraken", {})["open24"] = float(t["o"][1] if isinstance(t["o"], list) else t["o"]) + return float(t["c"][0]) + except Exception: + try: + cb = "BTC" if coin == "BTC" else coin + r = requests.get(f"https://api.coinbase.com/v2/prices/{cb}-USD/spot", timeout=8) + return float(r.json()["data"]["amount"]) + except Exception: + return None + +# ───────── db ───────── +def db(): + conn = sqlite3.connect(DB_PATH) + conn.execute("""CREATE TABLE IF NOT EXISTS ticks (ts REAL, price REAL)""") + conn.execute("""CREATE TABLE IF NOT EXISTS decisions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, ts REAL, ticker TEXT, mode TEXT, + momentum TEXT, llm_vote TEXT, llm_conf REAL, llm_why TEXT, + final TEXT, price REAL, reason TEXT)""") + conn.execute("""CREATE TABLE IF NOT EXISTS orders ( + id INTEGER PRIMARY KEY AUTOINCREMENT, ts REAL, ticker TEXT, side TEXT, + count INT, price_cents INT, dry INT, order_id TEXT, status TEXT, + settle_ts REAL, pnl_cents INT)""") + conn.execute("""CREATE TABLE IF NOT EXISTS events (ts REAL, level TEXT, msg TEXT)""") + conn.execute("""CREATE TABLE IF NOT EXISTS kv (k TEXT PRIMARY KEY, v REAL)""") + return conn + +def log_event(conn, level, msg): + conn.execute("INSERT INTO events VALUES (?,?,?)", (time.time(), level, msg)) + conn.commit() + getattr(LOG, level if level in ("info","warning","error") else "info")(msg) + +# ───────── brain ───────── +def momentum(conn): + rows = conn.execute("SELECT ts, price FROM ticks WHERE ts > ? ORDER BY ts", + (time.time()-1800,)).fetchall() + if len(rows) < 4: return "FLAT", 0.0 + now = rows[-1][1] + def ret(minutes): + ref = min(rows, key=lambda r: abs(r[0]-(time.time()-minutes*60)))[1] + return (now-ref)/ref*100 if ref else 0 + r5, r15 = ret(5), ret(15) + score = r5*0.6 + r15*0.4 + if score > 0.008: return "UP", abs(score) + if score < -0.008: return "DOWN", abs(score) + return "FLAT", abs(score) + +# ───────── multi-source intel ───────── +_intel_cache = {"ts": 0, "data": {}} +def intel(coin="BTC"): + """Slow external context, cached 5 min: Binance 24h stats, Fear&Greed, mempool fees.""" + if time.time() - _intel_cache["ts"] < 300 and _intel_cache["data"] and coin in _intel_cache.get("coins", {}): + return _intel_cache["data"] + d = {} + # per-coin binance 24h + BINANCE_SYMBOLS = {"BTC": "BTCUSDT", "ETH": "ETHUSDT", "DOGE": "DOGEUSDT", "SOL": "SOLUSDT", "XRP": "XRPUSDT"} + bs = BINANCE_SYMBOLS.get(coin, "BTCUSDT") + try: + j = requests.get(f"https://api.binance.com/api/v3/ticker/24hr?symbol={bs}", timeout=8).json() + d["chg24"] = float(j["priceChangePercent"]); d["vol24"] = float(j["volume"]) + d["high24"] = float(j["highPrice"]); d["low24"] = float(j["lowPrice"]) + except Exception: + pass + if "chg24" not in d: + # kraken-derived 24h change (works everywhere, no geo block) + k = _intel_cache.get("kraken", {}).get("open24") + try: + cur = requests.get("https://api.kraken.com/0/public/Ticker?pair=XBTUSD", timeout=8).json()["result"]["XXBTZUSD"] + op = float(cur["o"][1] if isinstance(cur["o"], list) else cur["o"]) + cl = float(cur["c"][0]) + d["chg24"] = (cl - op) / op * 100 + d["high24"] = float(cur["h"][1]); d["low24"] = float(cur["l"][1]) + d["vol24"] = float(cur["v"][1]) + except Exception: + pass + try: + j = requests.get("https://api.alternative.me/fng/?limit=1", timeout=8).json() + d["fng"] = int(j["data"][0]["value"]); d["fng_class"] = j["data"][0]["value_classification"] + except Exception: pass + try: + j = requests.get("https://mempool.space/api/v1/fees/recommended", timeout=8).json() + d["fee_fast"] = j.get("fastestFee") + except Exception: pass + _intel_cache.update({"ts": time.time(), "data": d, "coins": {coin: True}}) + return d + +def rsi(conn, period=14): + rows = conn.execute("SELECT price FROM ticks WHERE ts > ? ORDER BY ts", (time.time()-1200,)).fetchall() + px = [r[0] for r in rows] + if len(px) < period+2: return None + gains, losses = [], [] + for a, b in zip(px[-period-1:-1], px[-period:]): + ch = b - a + (gains if ch >= 0 else losses).append(abs(ch)) + ag = sum(gains)/period; al = sum(losses)/period if losses else 1e-9 + return 100 - 100/(1 + ag/al) + +def enriched_context(cfg, price, mom, mom_score, conn): + """Build rich trading context: multi-TF trends, RSI, orderbook, BTC corr, WR history, regime.""" + coin = cfg.get("coin","BTC") + ix = intel(coin) + r1 = rsi(conn, 14); r5 = rsi(conn, 14*5) # 1min and 5min RSI + + lines = [f"=== {coin} MARKET SNAPSHOT ==="] + lines.append(f"spot: ${price:,.4f}") + lines.append(f"15m momentum: {mom} ({mom_score:.3f}%)") + if r1 is not None: lines.append(f"RSI(14,1m): {r1:.0f} {'OVERBOUGHT' if r1>70 else 'OVERSOLD' if r1<30 else 'neutral'}") + if r5 is not None: lines.append(f"RSI(14,5m): {r5:.0f} {'OVERBOUGHT' if r5>70 else 'OVERSOLD' if r5<30 else 'neutral'}") + + # Multi-timeframe trend + rows = conn.execute("SELECT ts, price FROM ticks WHERE ts > ? ORDER BY ts", + (time.time()-7200,)).fetchall() + if len(rows) >= 8: + def ret_at(minutes): + ref = min(rows, key=lambda r: abs(r[0]-(time.time()-minutes*60)))[1] + return (price-ref)/ref*100 if ref else 0 + lines.append(f"trend 1m: {ret_at(1):+.3f}% | 5m: {ret_at(5):+.3f}% | 15m: {ret_at(15):+.3f}% | 1h: {ret_at(60):+.2f}% | 2h: {ret_at(120):+.2f}%") + + # 24h stats + if "chg24" in ix: + lines.append(f"24h change: {ix['chg24']:+.2f}% | range: ${ix.get('low24',0):,.2f}-${ix.get('high24',0):,.2f} | vol24: {ix.get('vol24',0):,.0f}") + + # BTC correlation + btc_chg = ix.get("chg24", 0) + if abs(btc_chg) > 0.3: + lines.append(f"BTC 24h: {btc_chg:+.1f}% ({'bullish' if btc_chg>0 else 'bearish'}) — {'coin follows' if coin=='BTC' else 'alt follows macro'}") + + # Orderbook depth (if ticker available) + ticker = getattr(cfg, '_current_ticker', None) + if ticker: + try: + kx = Kalshi(cfg["api_key_id"], cfg["key_path"]) + book = kx.orderbook(ticker) + yes = book.get("yes",[]); no = book.get("no",[]) + if yes and no: + y_ask = yes[0][0]; n_ask = no[0][0] + spread = abs(y_ask - n_ask) + lines.append(f"orderbook: YES ask={y_ask}¢ NO ask={n_ask}¢ spread={spread}¢") + # imbalance + y_depth = sum(o[1] for o in yes[:3]) if len(yes)>=3 else 0 + n_depth = sum(o[1] for o in no[:3]) if len(no)>=3 else 0 + if y_depth+n_depth > 0: + imb = (y_depth - n_depth) / (y_depth + n_depth) + lines.append(f"orderbook imbalance: {'YES-heavy' if imb>0.15 else 'NO-heavy' if imb<-0.15 else 'balanced'} ({imb:+.2f})") + except Exception: + pass + + # Fear&Greed + if "fng" in ix: + lines.append(f"Fear&Greed: {ix['fng']} ({ix.get('fng_class','')})") + + # Per-coin recent performance + perf = conn.execute("SELECT COUNT(*), SUM(CASE WHEN pnl_cents>0 THEN 1 ELSE 0 END) FROM orders WHERE dry=0 AND status IN ('won','lost') AND ts > ?", + (time.time()-86400,)).fetchone() + total, wins = perf[0] or 0, perf[1] or 0 + if total >= 3: + wr = wins / total + lines.append(f"{coin} 24h record: {wins}W/{total-wins}L ({wr:.0%})") + + # Market regime + if len(rows) >= 20: + prices = [r[1] for r in rows[-20:]] + mean = sum(prices)/len(prices) + std = (sum((p-mean)**2 for p in prices)/len(prices))**0.5 + vol = std/mean*100 if mean else 0 + regime = "choppy" if vol < 0.01 else "trending" if vol > 0.05 else "normal" + lines.append(f"market regime: {regime} (vol={vol:.3f}%)") + + # On-chain + if "fee_fast" in ix: + lines.append(f"mempool fast fee: {ix['fee_fast']} sat/vB") + + lines.append("") + lines.append("You trade 15-minute crypto up/down binary contracts by FADING spikes:") + lines.append("- Sharp UP move → bet DOWN (mean reversion)") + lines.append("- Sharp DOWN move → bet UP (mean reversion)") + lines.append("- SKIP when: strong trend continuation, thin orderbook, BTC-fighting trade, or no clear edge") + lines.append("- Consider: RSI extremes (>80 or <20 = high-prob fade), 24h range position, BTC macro direction") + lines.append("Reply with ONLY JSON: {\"vote\":\"UP\"|\"DOWN\"|\"SKIP\",\"conf\":0.0-1.0,\"why\":\"<10 words>\"}") + return "\n".join(lines) + """Two-tier: qwen3.5 (fast gate, 0.4s on MacBook) → ornith (deep verify on RTX 3070). + Gate handles clear signals; borderline calls escalate to ornith for final verdict.""" + coin = cfg.get("coin","BTC") + ix = intel(coin); r = rsi(conn) + prompt = enriched_context(cfg, price, mom, mom_score, conn) + try: + fast_url = cfg.get("fast_llm_url", cfg.get("ollama_url","http://localhost:11434")) + fast_model = cfg.get("fast_llm_model", "qwen3.5:4b") + r1 = requests.post(fast_url+"/api/generate", + json={"model": fast_model, "prompt": prompt, "stream": False, "think": False, + "options": {"temperature": 0.3, "num_predict": 60}}, timeout=8) + txt = r1.json().get("response","") + s, e = txt.find("{"), txt.rfind("}")+1 + d1 = json.loads(txt[s:e]) if s >= 0 else {} + fast_v, fast_c, fast_w = str(d1.get("vote","BORDERLINE")).upper(), float(d1.get("conf",0.5)), str(d1.get("why",""))[:120] + except Exception as ex: + fast_v, fast_c, fast_w = "BORDERLINE", 0.50, f"gate: {str(ex)[:40]}" + + if fast_v == "BORDERLINE" or (fast_v in ("UP","DOWN") and fast_c < 0.70): + try: + deep_url = cfg.get("deep_llm_url", cfg.get("ollama_url","http://10.30.20.186:11434")) + deep_model = cfg.get("deep_llm_model", cfg.get("ollama_model","ornith:latest")) + r2 = requests.post(deep_url+"/api/generate", + json={"model": deep_model, "prompt": prompt, "stream": False, "think": False, + "options": {"temperature": 0.2, "num_predict": 90}}, timeout=60) + txt2 = r2.json().get("response","") + s2, e2 = txt2.find("{"), txt2.rfind("}")+1 + d2 = json.loads(txt2[s2:e2]) if s2 >= 0 else {} + v = str(d2.get("vote","SKIP")).upper() + if v not in ("UP","DOWN","SKIP"): v = "SKIP" + return v, float(d2.get("conf",0)), str(d2.get("why",""))[:120] + except Exception as ex2: + LOG.warning(f"deep llm failed: {ex2}") + if fast_v in ("UP","DOWN","SKIP"): return fast_v, fast_c, fast_w + return "SKIP", 0.0, "llm offline" + if fast_v not in ("UP","DOWN","SKIP"): fast_v = "SKIP" + return fast_v, fast_c, fast_w + +def decide(cfg, conn, price): + """Two-tier decision: qwen fast-gate → ornith deep-verify. + RSI extremes → force mean-reversion. BTC macro trend → gate counter-trend bets. + Self-adapting thresholds from resolved bet performance.""" + mom, mom_score = momentum(conn) + lv, lc, lw = llm_vote(cfg, price, mom, mom_score, conn) + mode = cfg["mode"] + if mode == "DOWN_SPAM": return mom, lv, lc, lw, "DOWN", "spam-mode short" + if mode == "UP_SPAM": return mom, lv, lc, lw, "UP", "spam-mode long" + + # ── RSI contrarian: extreme readings → auto-fade ── + r = rsi(conn) + if r is not None: + if r > 85: + return mom, lv, lc, lw, "DOWN", f"⚠ RSI {r:.0f} extreme overbought → fade DOWN" + if r < 15: + return mom, lv, lc, lw, "UP", f"⚠ RSI {r:.0f} extreme oversold → fade UP" + + # ── swing threshold gate ── + thr = cfg.get("swing_threshold_pct", 0.005) + if mom == "FLAT" or mom_score < thr: + return mom, lv, lc, lw, "SKIP", f"no swing ({mom_score:.3f}% < {thr}%)" + if lv not in ("UP", "DOWN"): + return mom, lv, lc, lw, "SKIP", f"passes: {lw}" + + # ── BTC macro correlation: don't fight the trend ── + coin = cfg.get("coin","BTC") + ix = intel(coin) + btc_chg = ix.get("chg24", 0) + if lv == "DOWN" and btc_chg > 0.5: + if lc < 0.78: + return mom, lv, lc, lw, "SKIP", f"BTC +{btc_chg:.1f}% 24h — no counter-trend shorts (conf {lc:.2f}<0.78)" + if lv == "UP" and btc_chg < -0.5: + if lc < 0.78: + return mom, lv, lc, lw, "SKIP", f"BTC {btc_chg:.1f}% 24h — no counter-trend longs (conf {lc:.2f}<0.78)" + + # ── adaptive confidence (self-tunes from resolved bets) ── + min_conf = learned_min_conf(conn, cfg) + + # ── self-adapting overrides (LLM-written after bet resolution) ── + override = conn.execute("SELECT v FROM kv WHERE k='control_override'").fetchone() + if override: + try: + ov = json.loads(override[0]) + if ov.get("force_min_conf"): min_conf = float(ov["force_min_conf"]) + thr = ov.get("force_swing_threshold", thr) + except Exception: pass + + if lc < min_conf: + return mom, lv, lc, lw, "SKIP", f"conf {lc:.2f}<{min_conf:.2f} (adaptive)" + + return mom, lv, lc, lw, lv, f"{lv}: {mom} spike {mom_score:.2f}% conf={lc:.2f} [{lw[:60]}]" + +# ───────── learning: resolve + adapt ───────── +def learned_min_conf(conn, cfg): + """Adaptive confidence: rises after losses, relaxes after wins. Persisted in kv table.""" + if not cfg.get("learning", True): + return cfg.get("min_conf", 0.55) + row = conn.execute("SELECT v FROM kv WHERE k='min_conf'").fetchone() + stored = row[0] if row else cfg.get("min_conf", 0.55) + res = conn.execute("SELECT pnl_cents FROM orders WHERE status IN ('won','lost') ORDER BY id DESC LIMIT 20").fetchall() + if len(res) < 8: + return stored + wr = sum(1 for r in res if r[0] and r[0] > 0) / len(res) + new = stored + if wr < 0.45: new = min(0.80, stored + 0.05) + elif wr > 0.60: new = max(0.50, stored - 0.05) + if new != stored: + conn.execute("INSERT OR REPLACE INTO kv VALUES ('min_conf', ?)", (new,)) + conn.commit() + return new + +def resolve_bets(kx, conn): + """Settle finished markets against real outcomes (sim AND live).""" + open_orders = conn.execute( + "SELECT id, ticker, side, count, price_cents, dry FROM orders WHERE status IN ('placed','posted')").fetchall() + for oid, ticker, side, count, px, dry in open_orders: + try: + m = kx.req("GET", f"/markets/{ticker}") + status = m.get("status") + if status not in ("settled", "finalized", "determined"): + # also catch expired-untraded: close_time passed + no result → mark dead + ct = m.get("close_time") + if ct: + from datetime import datetime, timezone + if datetime.fromisoformat(ct.replace("Z","+00:00")).timestamp() < time.time() - 120: + conn.execute("UPDATE orders SET status='expired', settle_ts=? WHERE id=?", (time.time(), oid)) + conn.commit() + continue + result = (m.get("result") or "").lower() # 'yes' | 'no' + if not result: + continue + won = (result == side) + pnl = (100 - px) * count if won else -px * count + conn.execute("UPDATE orders SET status=?, settle_ts=?, pnl_cents=? WHERE id=?", + ("won" if won else "lost", time.time(), pnl, oid)) + conn.commit() + log_event(conn, "info", f"{'[SIM] ' if dry else ''}{'WIN' if won else 'LOSS'} {ticker} {side}@{px}¢ → {result} ({'+' if won else ''}{pnl}¢)") + except Exception: + continue + +# ───────── counter-hedge: lock in profit on open positions ───────── +def hedge_positions(conn, kx, ticker, cfg, book): + """Scan open positions. If opposite side is cheap enough, buy it to lock profit. + Returns 'hedged' if a counter-order was placed, else None.""" + open_orders = conn.execute( + "SELECT id,side,price_cents FROM orders WHERE ticker=? AND status IN ('placed','posted')", + (ticker,)).fetchall() + if not open_orders: + return None + min_profit = cfg.get("min_profit_cents", 8) + for oid, side, entry_px in open_orders: + opp_side = "yes" if side == "no" else "no" + opp_ask_list = book.get("yes" if opp_side == "yes" else "no") + opp_ask = (opp_ask_list or [[None]])[0][0] + if opp_ask is None: + continue + profit = 100 - entry_px - opp_ask + if profit >= min_profit: + res = kx.order(ticker, opp_side, 1, opp_ask, cfg["dry_run"]) + oid2 = res.get("order_id", res.get("order", {}).get("order_id", "hedge")) + conn.execute("INSERT INTO orders (ts,ticker,side,count,price_cents,dry,order_id,status) VALUES (?,?,?,?,?,?,?,?)", + (time.time(), ticker, opp_side, 1, opp_ask, 1 if cfg["dry_run"] else 0, str(oid2), "placed")) + conn.execute("UPDATE orders SET status='hedged' WHERE id=?", (oid,)) + conn.commit() + log_event(conn, "info", f"HEDGE {ticker}: {side}@{entry_px}¢ + {opp_side}@{opp_ask}¢ → locked {profit}¢") + return "hedged" + return None + + +# ───────── main loop ───────── +def daily_pnl(conn): + return conn.execute("SELECT COALESCE(SUM(pnl_cents),0) FROM orders WHERE date(ts,'unixepoch','localtime')=date('now','localtime') AND dry=0").fetchone()[0] + +_last_adapt_ts = 0 +def adapt_controls(conn, cfg): + """After bets resolve, ask qwen to self-tune: adjust thresholds, confidence, sizing.""" + global _last_adapt_ts + if time.time() - _last_adapt_ts < 600: # max every 10 min + return + resolved = conn.execute( + "SELECT side, pnl_cents, price_cents FROM orders WHERE status IN ('won','lost') ORDER BY id DESC LIMIT 20" + ).fetchall() + if len(resolved) < 5: + return + wins = sum(1 for r in resolved if r[1] and r[1] > 0) + wr = wins / len(resolved) + summary = {"recent_bets": len(resolved), "win_rate": round(wr, 2), + "wins": wins, "losses": len(resolved)-wins, + "avg_pnl": round(sum(r[1] for r in resolved if r[1])/len(resolved)) if resolved else 0} + prompt = ( + f"Bot trading performance: {json.dumps(summary)}. " + "Current settings: swing_threshold={cfg.get('swing_threshold_pct',0.005)}% " + "min_conf={cfg.get('min_conf',0.50)}. " + "Suggest adjustments to maximize net profit. Reply with ONLY JSON: " + '{"force_min_conf":0.50,"force_swing_threshold":0.005,"reason":"<10 words>"} ' + "or empty JSON {} if no changes needed." + ) + try: + fast_url = cfg.get("fast_llm_url", "http://localhost:11434") + r = requests.post(fast_url+"/api/generate", + json={"model": cfg.get("fast_llm_model","qwen3.5:4b"), "prompt": prompt, + "stream": False, "think": False, "options": {"temperature": 0.1, "num_predict": 80}}, + timeout=10) + txt = r.json().get("response","") + s, e = txt.find("{"), txt.rfind("}")+1 + ov = json.loads(txt[s:e]) if s >= 0 else {} + if ov and ov.get("reason"): + conn.execute("INSERT OR REPLACE INTO kv(k,v) VALUES ('control_override',?)", + (json.dumps(ov),)) + conn.commit() + LOG.info(f"🔧 self-adapt: {ov.get('reason')} — override={json.dumps({k:v for k,v in ov.items() if k!='reason'})}") + _last_adapt_ts = time.time() + except Exception: + pass # silently skip on failure + +# ───────── main loop ───────── + return conn.execute("SELECT COALESCE(SUM(pnl_cents),0) FROM orders WHERE date(ts,'unixepoch','localtime')=date('now','localtime') AND dry=0").fetchone()[0] + +def run(): + global HOME, CFG_PATH, DB_PATH + import argparse, fcntl + ap = argparse.ArgumentParser() + ap.add_argument("--config", default=str(HOME/"config.json"), help="config path") + ap.add_argument("--lock", default="bot", help="lock file name stem") + ap.add_argument("--db", default=None, help="db path (overrides config)") + args, _ = ap.parse_known_args() + CFG_PATH = Path(args.config) + HOME = CFG_PATH.parent + DB_PATH = Path(args.db) if args.db else (HOME / "state.db") + lock_fd = open(HOME / f"{args.lock}.lock", "w") + try: + fcntl.flock(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + except OSError: + print("another bot instance is already running — exiting") + sys.exit(0) + cfg = load_cfg() + if cfg.get("proxy"): + os.environ["HTTP_PROXY"] = os.environ["HTTPS_PROXY"] = cfg["proxy"] + if cfg.get("db_path"): + DB_PATH = HOME / cfg["db_path"] + kx = Kalshi(cfg["api_key_id"], cfg["key_path"]) + conn = db() + log_event(conn, "info", f"K4LSH1_OPS online — mode={cfg['mode']} dry_run={cfg['dry_run']} stake={cfg['stake_cents']}¢ max_spend={cfg.get('max_spend_cents',100)}¢") + last_bet_market = None + last_decision_ts = None + # stagger startup to avoid simultaneous LLM calls + stagger = cfg.get("start_delay_sec", 0) + if stagger: + LOG.info(f"staggering start by {stagger}s") + time.sleep(stagger) + while True: + cfg = load_cfg() # hot reload (dashboard edits) + if cfg.get("kill"): + log_event(conn, "warning", "KILL switch engaged — bot halted") + break + try: + resolve_bets(kx, conn) + adapt_controls(conn, cfg) + p = btc_price(cfg.get("coin", "BTC")) + if p: + conn.execute("INSERT INTO ticks VALUES (?,?)", (time.time(), p)) + conn.execute("DELETE FROM ticks WHERE ts < ?", (time.time()-7200,)) + conn.commit() + coin = cfg.get("coin", "BTC") + if cfg["mode"] != "OFF" and p: + mkts = kx.markets(cfg["series"], "open", 3) + if mkts: + m = sorted(mkts, key=lambda x: x["close_time"])[-1] + ticker = m["ticker"] + close_ts = datetime.fromisoformat(m["close_time"].replace("Z","+00:00")).timestamp() + mins_left = (close_ts - time.time())/60 + if mins_left > 0.5: + # 5-min re-evaluation window + cycle_sec = cfg.get("decision_interval_sec", 300) + now_ts = time.time() + if last_decision_ts and (now_ts - last_decision_ts) < cycle_sec: + continue # wait for next decision window + last_decision_ts = now_ts + book = kx.orderbook(ticker) + # hedge check: close profitable positions + if hedge_positions(conn, kx, ticker, cfg, book) == "hedged": + continue + mom, lv, lc, lw, final, why = decide(cfg, conn, p) + yes_ask = (book.get("yes") or [[None]])[0][0] + no_ask = (book.get("no") or [[None]])[0][0] + ask = yes_ask if final == "UP" else (no_ask if final == "DOWN" else None) + side = "yes" if final == "UP" else "no" + conn.execute("INSERT INTO decisions (ts,ticker,mode,momentum,llm_vote,llm_conf,llm_why,final,price,reason) VALUES (?,?,?,?,?,?,?,?,?,?)", + (time.time(), ticker, cfg["mode"], mom, lv, lc, lw, final, p, why)) + conn.commit() + if final in ("UP","DOWN"): + if daily_pnl(conn) <= -cfg["daily_loss_cap_cents"]: + log_event(conn, "warning", "daily loss cap hit — sitting out") + continue + try: + verify = kx.req("GET", f"/markets/{ticker}") + st = verify.get("status", "open") + if st and st not in ("open", "active"): + log_event(conn, "info", f"skip {ticker}: market closed (status={st})") + continue + except Exception: + pass + # confidence-scaled contracts: max $1.00 total spend + max_spend = cfg.get("max_spend_cents", 100) + if ask and ask <= max_spend: + n = 1 if lc < 0.70 else (2 if lc < 0.80 else (3 if lc < 0.90 else 4)) + while n * ask > max_spend and n > 1: + n -= 1 + px = ask + maker = False + else: + n = 1 + px = min(cfg.get("post_price_cents", 50), max_spend) + maker = True + try: + res = kx.order(ticker, side, n, px, cfg["dry_run"]) + oid = res.get("order_id", res.get("order", {}).get("order_id", "sim")) + conn.execute("INSERT INTO orders (ts,ticker,side,count,price_cents,dry,order_id,status) VALUES (?,?,?,?,?,?,?,?)", + (time.time(), ticker, side, n, px, 1 if cfg["dry_run"] else 0, str(oid), "placed")) + conn.commit() + tag = "SIM" if cfg["dry_run"] else ("TAKER" if not maker else "POST") + log_event(conn, "info", f"{tag} {side.upper()} x{n} {ticker} @ {px}¢ — {why}") + except Exception as e: + log_event(conn, "warning", f"order failed: {e}") + else: + LOG.info(f"skip {ticker}: {why}") + except Exception as e: + log_event(conn, "error", f"loop error: {e}") + time.sleep(20) + +if __name__ == "__main__": + run() diff --git a/bot_console.log b/bot_console.log new file mode 100644 index 0000000..154d6fd --- /dev/null +++ b/bot_console.log @@ -0,0 +1,211 @@ +2026-08-01 21:32:22,951 K4LSH1_OPS online — mode=AUTO dry_run=True stake=50¢ +2026-08-01 21:32:27,370 skip KXBTC15M-26AUG020045-45: mom=FLAT llm=SKIP +2026-08-01 21:35:07,483 K4LSH1_OPS online — mode=AUTO dry_run=True stake=50¢ +2026-08-01 21:35:11,460 skip KXBTC15M-26AUG020045-45: mom=FLAT llm=SKIP +2026-08-01 21:35:46,925 K4LSH1_OPS online — mode=DOWN_SPAM dry_run=True stake=45¢ +2026-08-01 21:35:50,882 [SIM] MAKER-POST NO KXBTC15M-26AUG020045-45 @ 45¢ — spam-mode short +2026-08-01 21:36:36,636 K4LSH1_OPS online — mode=AUTO dry_run=True stake=50¢ +2026-08-01 21:36:39,490 skip KXBTC15M-26AUG020045-45: mom=FLAT llm=SKIP +2026-08-01 21:45:38,730 skip KXBTC15M-26AUG020100-00: mom=FLAT llm=SKIP +2026-08-01 21:45:40,622 skip KXBTC15M-26AUG020100-00: mom=FLAT llm=SKIP +2026-08-01 21:45:42,761 skip KXBTC15M-26AUG020100-00: mom=FLAT llm=SKIP +2026-08-01 21:45:45,645 skip KXBTC15M-26AUG020100-00: mom=FLAT llm=SKIP +2026-08-01 22:00:46,431 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:00:48,836 skip KXBTC15M-26AUG020115-15: ask None¢ > stake cap 20¢ +2026-08-01 22:00:56,705 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:00:58,206 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:01:07,999 skip KXBTC15M-26AUG020115-15: mom=UP llm=SKIP +2026-08-01 22:01:11,843 skip KXBTC15M-26AUG020115-15: ask None¢ > stake cap 20¢ +2026-08-01 22:01:24,692 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:01:26,687 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:01:35,077 skip KXBTC15M-26AUG020115-15: mom=UP llm=SKIP +2026-08-01 22:01:52,938 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:01:54,595 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:02:16,143 skip KXBTC15M-26AUG020115-15: mom=UP llm=SKIP +2026-08-01 22:02:23,023 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 22:02:46,485 skip KXBTC15M-26AUG020115-15: mom=FLAT llm=SKIP +2026-08-01 22:15:51,326 skip KXBTC15M-26AUG020130-30: mom=DOWN llm=SKIP +2026-08-01 22:15:53,252 skip KXBTC15M-26AUG020130-30: mom=DOWN llm=SKIP +2026-08-01 22:15:57,991 skip KXBTC15M-26AUG020130-30: mom=DOWN llm=SKIP +2026-08-01 22:16:00,178 skip KXBTC15M-26AUG020130-30: mom=DOWN llm=SKIP +2026-08-01 22:30:28,534 skip KXBTC15M-26AUG020145-45: mom=FLAT llm=SKIP +2026-08-01 22:30:30,798 skip KXBTC15M-26AUG020145-45: mom=FLAT llm=SKIP +2026-08-01 22:30:33,469 skip KXBTC15M-26AUG020145-45: mom=FLAT llm=SKIP +2026-08-01 22:30:35,447 skip KXBTC15M-26AUG020145-45: mom=FLAT llm=SKIP +2026-08-01 22:45:45,108 skip KXBTC15M-26AUG020200-00: mom=DOWN llm=SKIP +2026-08-01 22:45:46,902 skip KXBTC15M-26AUG020200-00: mom=DOWN llm=SKIP +2026-08-01 22:45:49,008 skip KXBTC15M-26AUG020200-00: mom=DOWN llm=SKIP +2026-08-01 22:45:50,847 skip KXBTC15M-26AUG020200-00: mom=DOWN llm=SKIP +2026-08-01 23:00:42,225 skip KXBTC15M-26AUG020215-15: mom=FLAT llm=SKIP +2026-08-01 23:00:44,082 skip KXBTC15M-26AUG020215-15: mom=FLAT llm=SKIP +2026-08-01 23:00:46,004 skip KXBTC15M-26AUG020215-15: mom=FLAT llm=SKIP +2026-08-01 23:00:55,206 skip KXBTC15M-26AUG020215-15: mom=FLAT llm=SKIP +2026-08-01 23:15:39,537 skip KXBTC15M-26AUG020230-30: mom=FLAT llm=SKIP +2026-08-01 23:15:41,592 skip KXBTC15M-26AUG020230-30: mom=FLAT llm=SKIP +2026-08-01 23:15:43,457 skip KXBTC15M-26AUG020230-30: mom=FLAT llm=SKIP +2026-08-01 23:15:47,287 skip KXBTC15M-26AUG020230-30: mom=FLAT llm=SKIP +2026-08-01 23:30:39,844 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 23:30:41,094 skip KXBTC15M-26AUG020245-45: mom=UP llm=SKIP +2026-08-01 23:30:43,887 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 23:30:47,443 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 23:31:02,912 skip KXBTC15M-26AUG020245-45: mom=UP llm=SKIP +2026-08-01 23:31:06,956 skip KXBTC15M-26AUG020245-45: mom=UP llm=SKIP +2026-08-01 23:31:15,212 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-01 23:31:38,420 skip KXBTC15M-26AUG020245-45: mom=UP llm=SKIP +2026-08-01 23:45:33,888 skip KXBTC15M-26AUG020300-00: mom=FLAT llm=SKIP +2026-08-01 23:45:35,575 skip KXBTC15M-26AUG020300-00: mom=FLAT llm=SKIP +2026-08-01 23:45:37,428 skip KXBTC15M-26AUG020300-00: mom=FLAT llm=SKIP +2026-08-01 23:45:42,154 skip KXBTC15M-26AUG020300-00: mom=FLAT llm=SKIP +2026-08-02 00:00:28,526 skip KXBTC15M-26AUG020315-15: mom=FLAT llm=SKIP +2026-08-02 00:00:30,216 skip KXBTC15M-26AUG020315-15: mom=FLAT llm=SKIP +2026-08-02 00:00:32,066 skip KXBTC15M-26AUG020315-15: mom=FLAT llm=SKIP +2026-08-02 00:00:35,709 skip KXBTC15M-26AUG020315-15: mom=FLAT llm=SKIP +2026-08-02 00:15:26,330 skip KXBTC15M-26AUG020330-30: mom=FLAT llm=SKIP +2026-08-02 00:15:28,171 skip KXBTC15M-26AUG020330-30: mom=FLAT llm=SKIP +2026-08-02 00:15:30,051 skip KXBTC15M-26AUG020330-30: mom=FLAT llm=SKIP +2026-08-02 00:15:31,894 skip KXBTC15M-26AUG020330-30: mom=FLAT llm=SKIP +2026-08-02 00:30:41,938 skip KXBTC15M-26AUG020345-45: mom=FLAT llm=SKIP +2026-08-02 00:30:43,537 skip KXBTC15M-26AUG020345-45: mom=FLAT llm=SKIP +2026-08-02 00:30:45,416 skip KXBTC15M-26AUG020345-45: mom=FLAT llm=SKIP +2026-08-02 00:30:47,247 skip KXBTC15M-26AUG020345-45: mom=FLAT llm=SKIP +2026-08-02 00:45:35,241 skip KXBTC15M-26AUG020400-00: mom=UP llm=SKIP +2026-08-02 00:45:38,670 skip KXBTC15M-26AUG020400-00: mom=UP llm=SKIP +2026-08-02 00:45:45,948 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 00:45:47,847 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 00:46:08,932 skip KXBTC15M-26AUG020400-00: mom=FLAT llm=SKIP +2026-08-02 00:46:11,559 skip KXBTC15M-26AUG020400-00: mom=FLAT llm=SKIP +2026-08-02 01:00:42,618 skip KXBTC15M-26AUG020415-15: mom=FLAT llm=SKIP +2026-08-02 01:00:44,309 skip KXBTC15M-26AUG020415-15: mom=FLAT llm=SKIP +2026-08-02 01:00:45,798 skip KXBTC15M-26AUG020415-15: mom=FLAT llm=SKIP +2026-08-02 01:00:49,527 skip KXBTC15M-26AUG020415-15: mom=FLAT llm=SKIP +2026-08-02 01:15:57,060 skip KXBTC15M-26AUG020430-30: mom=FLAT llm=SKIP +2026-08-02 01:15:58,723 skip KXBTC15M-26AUG020430-30: mom=FLAT llm=SKIP +2026-08-02 01:16:01,867 skip KXBTC15M-26AUG020430-30: mom=FLAT llm=SKIP +2026-08-02 01:16:03,992 skip KXBTC15M-26AUG020430-30: mom=FLAT llm=SKIP +2026-08-02 01:30:09,358 skip KXBTC15M-26AUG020445-45: mom=DOWN llm=SKIP +2026-08-02 01:30:12,000 skip KXBTC15M-26AUG020445-45: mom=DOWN llm=SKIP +2026-08-02 01:30:13,246 skip KXBTC15M-26AUG020445-45: mom=DOWN llm=SKIP +2026-08-02 01:30:14,406 skip KXBTC15M-26AUG020445-45: ask None¢ > stake cap 20¢ +2026-08-02 01:30:36,032 skip KXBTC15M-26AUG020445-45: mom=DOWN llm=SKIP +2026-08-02 01:45:43,435 skip KXBTC15M-26AUG020500-00: mom=DOWN llm=SKIP +2026-08-02 01:45:44,342 skip KXBTC15M-26AUG020500-00: mom=DOWN llm=SKIP +2026-08-02 01:45:45,943 skip KXBTC15M-26AUG020500-00: mom=DOWN llm=SKIP +2026-08-02 01:45:46,896 skip KXBTC15M-26AUG020500-00: mom=DOWN llm=SKIP +2026-08-02 02:00:37,677 skip KXBTC15M-26AUG020515-15: mom=FLAT llm=SKIP +2026-08-02 02:00:39,938 skip KXBTC15M-26AUG020515-15: mom=FLAT llm=SKIP +2026-08-02 02:00:40,906 skip KXBTC15M-26AUG020515-15: mom=FLAT llm=SKIP +2026-08-02 02:00:41,808 skip KXBTC15M-26AUG020515-15: mom=FLAT llm=SKIP +2026-08-02 02:15:30,670 skip KXBTC15M-26AUG020530-30: mom=UP llm=SKIP +2026-08-02 02:15:31,451 skip KXBTC15M-26AUG020530-30: mom=UP llm=SKIP +2026-08-02 02:15:32,257 skip KXBTC15M-26AUG020530-30: mom=UP llm=SKIP +2026-08-02 02:15:33,869 skip KXBTC15M-26AUG020530-30: ask None¢ > stake cap 20¢ +2026-08-02 02:15:55,453 skip KXBTC15M-26AUG020530-30: mom=UP llm=SKIP +2026-08-02 02:30:18,871 skip KXBTC15M-26AUG020545-45: mom=DOWN llm=SKIP +2026-08-02 02:30:19,876 skip KXBTC15M-26AUG020545-45: mom=DOWN llm=SKIP +2026-08-02 02:30:20,815 skip KXBTC15M-26AUG020545-45: mom=DOWN llm=SKIP +2026-08-02 02:30:22,225 skip KXBTC15M-26AUG020545-45: mom=DOWN llm=SKIP +2026-08-02 02:45:52,336 skip KXBTC15M-26AUG020600-00: mom=FLAT llm=SKIP +2026-08-02 02:45:53,166 skip KXBTC15M-26AUG020600-00: mom=FLAT llm=SKIP +2026-08-02 02:45:53,865 skip KXBTC15M-26AUG020600-00: mom=FLAT llm=SKIP +2026-08-02 02:45:54,729 skip KXBTC15M-26AUG020600-00: mom=FLAT llm=SKIP +2026-08-02 02:58:32,790 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Read timed out. (read timeout=15) +2026-08-02 02:58:33,719 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Read timed out. (read timeout=15) +2026-08-02 02:58:34,346 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Read timed out. (read timeout=15) +2026-08-02 02:58:35,283 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Read timed out. (read timeout=15) +2026-08-02 02:59:04,974 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:05,856 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:06,478 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:07,417 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:37,144 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:38,018 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:38,626 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 02:59:39,575 loop error: HTTPSConnectionPool(host='api.elections.kalshi.com', port=443): Max retries exceeded with url: /trade-api/v2/markets?series_ticker=KXBTC15M&status=open&limit=3 (Caused by SSLError(SSLEOFError(8, '[SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1016)'))) +2026-08-02 03:00:43,157 skip KXBTC15M-26AUG020615-15: mom=FLAT llm=SKIP +2026-08-02 03:00:45,057 skip KXBTC15M-26AUG020615-15: mom=FLAT llm=SKIP +2026-08-02 03:00:45,891 skip KXBTC15M-26AUG020615-15: mom=FLAT llm=SKIP +2026-08-02 03:00:46,736 skip KXBTC15M-26AUG020615-15: mom=FLAT llm=SKIP +2026-08-02 03:15:16,790 skip KXBTC15M-26AUG020630-30: mom=DOWN llm=SKIP +2026-08-02 03:15:18,273 skip KXBTC15M-26AUG020630-30: mom=DOWN llm=SKIP +2026-08-02 03:15:18,602 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 03:15:19,599 skip KXBTC15M-26AUG020630-30: mom=DOWN llm=SKIP +2026-08-02 03:16:12,711 skip KXBTC15M-26AUG020630-30: mom=DOWN llm=SKIP +2026-08-02 03:31:24,240 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 03:31:24,365 skip KXBTC15M-26AUG020645-45: mom=FLAT llm=SKIP +2026-08-02 03:31:25,838 skip KXBTC15M-26AUG020645-45: mom=FLAT llm=SKIP +2026-08-02 03:31:29,474 skip KXBTC15M-26AUG020645-45: mom=FLAT llm=SKIP +2026-08-02 03:31:30,958 skip KXBTC15M-26AUG020645-45: mom=FLAT llm=SKIP +2026-08-02 03:45:56,982 skip KXBTC15M-26AUG020700-00: mom=UP llm=SKIP +2026-08-02 03:45:59,371 skip KXBTC15M-26AUG020700-00: mom=UP llm=SKIP +2026-08-02 03:46:02,520 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 03:46:04,909 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 03:46:23,849 skip KXBTC15M-26AUG020700-00: mom=UP llm=SKIP +2026-08-02 03:46:26,271 skip KXBTC15M-26AUG020700-00: mom=UP llm=SKIP +2026-08-02 04:00:19,304 skip KXBTC15M-26AUG020715-15: mom=FLAT llm=SKIP +2026-08-02 04:00:26,091 skip KXBTC15M-26AUG020715-15: mom=FLAT llm=SKIP +2026-08-02 04:00:28,049 skip KXBTC15M-26AUG020715-15: mom=FLAT llm=SKIP +2026-08-02 04:00:31,611 skip KXBTC15M-26AUG020715-15: mom=FLAT llm=SKIP +2026-08-02 04:15:31,974 skip KXBTC15M-26AUG020730-30: mom=FLAT llm=SKIP +2026-08-02 04:15:34,753 skip KXBTC15M-26AUG020730-30: mom=FLAT llm=SKIP +2026-08-02 04:15:36,597 skip KXBTC15M-26AUG020730-30: mom=FLAT llm=SKIP +2026-08-02 04:15:39,965 skip KXBTC15M-26AUG020730-30: mom=FLAT llm=SKIP +2026-08-02 04:30:24,112 skip KXBTC15M-26AUG020745-45: mom=FLAT llm=SKIP +2026-08-02 04:30:25,736 skip KXBTC15M-26AUG020745-45: mom=FLAT llm=SKIP +2026-08-02 04:30:26,838 skip KXBTC15M-26AUG020745-45: mom=FLAT llm=SKIP +2026-08-02 04:30:27,694 skip KXBTC15M-26AUG020745-45: mom=FLAT llm=SKIP +2026-08-02 04:45:36,785 skip KXBTC15M-26AUG020800-00: mom=DOWN llm=SKIP +2026-08-02 04:45:37,654 skip KXBTC15M-26AUG020800-00: mom=DOWN llm=SKIP +2026-08-02 04:45:38,559 skip KXBTC15M-26AUG020800-00: mom=DOWN llm=SKIP +2026-08-02 04:45:40,349 skip KXBTC15M-26AUG020800-00: mom=DOWN llm=SKIP +2026-08-02 05:00:49,635 skip KXBTC15M-26AUG020815-15: mom=FLAT llm=SKIP +2026-08-02 05:00:50,833 skip KXBTC15M-26AUG020815-15: mom=FLAT llm=SKIP +2026-08-02 05:00:52,855 skip KXBTC15M-26AUG020815-15: mom=FLAT llm=SKIP +2026-08-02 05:00:53,719 skip KXBTC15M-26AUG020815-15: mom=FLAT llm=SKIP +2026-08-02 05:15:26,120 skip KXBTC15M-26AUG020830-30: ask None¢ > stake cap 20¢ +2026-08-02 05:15:28,115 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:15:28,866 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:15:30,023 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:15:47,650 skip KXBTC15M-26AUG020830-30: mom=UP llm=SKIP +2026-08-02 05:15:49,350 skip KXBTC15M-26AUG020830-30: mom=UP llm=SKIP +2026-08-02 05:15:50,158 skip KXBTC15M-26AUG020830-30: mom=UP llm=SKIP +2026-08-02 05:15:56,001 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:16:22,405 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:16:48,860 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 05:17:10,408 skip KXBTC15M-26AUG020830-30: mom=UP llm=SKIP +2026-08-02 05:30:35,693 skip KXBTC15M-26AUG020845-45: mom=FLAT llm=SKIP +2026-08-02 05:30:36,662 skip KXBTC15M-26AUG020845-45: mom=FLAT llm=SKIP +2026-08-02 05:30:37,971 skip KXBTC15M-26AUG020845-45: mom=FLAT llm=SKIP +2026-08-02 05:30:38,801 skip KXBTC15M-26AUG020845-45: mom=FLAT llm=SKIP +2026-08-02 05:45:26,802 skip KXBTC15M-26AUG020900-00: mom=FLAT llm=SKIP +2026-08-02 05:45:27,631 skip KXBTC15M-26AUG020900-00: mom=FLAT llm=SKIP +2026-08-02 05:45:28,427 skip KXBTC15M-26AUG020900-00: mom=FLAT llm=SKIP +2026-08-02 05:45:30,046 skip KXBTC15M-26AUG020900-00: mom=FLAT llm=SKIP +2026-08-02 06:01:18,133 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 06:01:18,224 skip KXBTC15M-26AUG020915-15: mom=DOWN llm=SKIP +2026-08-02 06:01:19,219 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 06:01:19,298 skip KXBTC15M-26AUG020915-15: mom=DOWN llm=SKIP +2026-08-02 06:01:19,397 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 06:01:19,526 skip KXBTC15M-26AUG020915-15: mom=DOWN llm=SKIP +2026-08-02 06:01:21,685 ollama vote failed: HTTPConnectionPool(host='localhost', port=11434): Read timed out. (read timeout=45) +2026-08-02 06:01:21,767 skip KXBTC15M-26AUG020915-15: mom=DOWN llm=SKIP +2026-08-02 06:15:47,149 skip KXBTC15M-26AUG020930-30: mom=FLAT llm=SKIP +2026-08-02 06:15:48,039 skip KXBTC15M-26AUG020930-30: mom=FLAT llm=SKIP +2026-08-02 06:15:49,804 skip KXBTC15M-26AUG020930-30: mom=FLAT llm=SKIP +2026-08-02 06:15:51,210 skip KXBTC15M-26AUG020930-30: mom=FLAT llm=SKIP +2026-08-02 06:30:39,593 skip KXBTC15M-26AUG020945-45: mom=FLAT llm=SKIP +2026-08-02 06:30:40,731 skip KXBTC15M-26AUG020945-45: mom=FLAT llm=SKIP +2026-08-02 06:30:41,544 skip KXBTC15M-26AUG020945-45: mom=FLAT llm=SKIP +2026-08-02 06:30:43,148 skip KXBTC15M-26AUG020945-45: mom=FLAT llm=SKIP +2026-08-02 06:45:31,886 skip KXBTC15M-26AUG021000-00: mom=UP llm=SKIP +2026-08-02 06:45:32,885 skip KXBTC15M-26AUG021000-00: mom=UP llm=SKIP +2026-08-02 06:45:33,761 skip KXBTC15M-26AUG021000-00: ask None¢ > stake cap 20¢ +2026-08-02 06:45:40,288 order failed: 410 Client Error: Gone for url: https://api.elections.kalshi.com/trade-api/v2/portfolio/orders +2026-08-02 06:45:55,288 skip KXBTC15M-26AUG021000-00: mom=UP llm=SKIP +2026-08-02 06:46:01,890 skip KXBTC15M-26AUG021000-00: mom=FLAT llm=SKIP +2026-08-02 07:00:24,822 skip KXBTC15M-26AUG021015-15: mom=FLAT llm=SKIP +2026-08-02 07:00:25,531 skip KXBTC15M-26AUG021015-15: mom=FLAT llm=SKIP +2026-08-02 07:00:26,365 skip KXBTC15M-26AUG021015-15: mom=FLAT llm=SKIP +2026-08-02 07:00:29,759 skip KXBTC15M-26AUG021015-15: mom=FLAT llm=SKIP +2026-08-02 07:15:34,740 skip KXBTC15M-26AUG021030-30: mom=FLAT llm=SKIP +2026-08-02 07:15:35,872 skip KXBTC15M-26AUG021030-30: mom=FLAT llm=SKIP +2026-08-02 07:15:36,714 skip KXBTC15M-26AUG021030-30: mom=FLAT llm=SKIP +2026-08-02 07:15:38,394 skip KXBTC15M-26AUG021030-30: mom=FLAT llm=SKIP diff --git a/config.json b/config.json new file mode 100644 index 0000000..c03e073 --- /dev/null +++ b/config.json @@ -0,0 +1,16 @@ +{ + "api_key_id": "28d5876b-2ece-4aa3-aa17-ec96e1e706eb", + "key_path": "/Users/drjones/kalshi-bot/kalshi_private_key.pem", + "mode": "AUTO", + "dry_run": false, + "stake_cents": 15, + "max_contracts": 1, + "daily_loss_cap_cents": 500, + "min_conf": 0.55, + "ollama_url": "http://10.30.20.186:11434", + "ollama_model": "ornith:latest", + "series": "KXDOGE15M", + "kill": false, + "swing_threshold_pct": 0.06, + "learning": true +} diff --git a/dash_console.log b/dash_console.log new file mode 100644 index 0000000..28bb8b3 --- /dev/null +++ b/dash_console.log @@ -0,0 +1,75 @@ + * Serving Flask app 'dashboard' + * Debug mode: off +WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on all addresses (0.0.0.0) + * Running on http://127.0.0.1:5053 + * Running on http://10.5.0.2:5053 +Press CTRL+C to quit +127.0.0.1 - - [01/Aug/2026 21:32:48] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:32:48,554 127.0.0.1 - - [01/Aug/2026 21:32:48] "GET /api/state HTTP/1.1" 200 - + * Serving Flask app 'dashboard' + * Debug mode: off +Address already in use +Port 5053 is in use by another program. Either identify and stop that program, or start the server with a different port. +127.0.0.1 - - [01/Aug/2026 21:35:45] "POST /api/control HTTP/1.1" 200 - +2026-08-01 21:35:45,702 127.0.0.1 - - [01/Aug/2026 21:35:45] "POST /api/control HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:36:35] "POST /api/control HTTP/1.1" 200 - +2026-08-01 21:36:35,412 127.0.0.1 - - [01/Aug/2026 21:36:35] "POST /api/control HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:36:51] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:36:51,971 127.0.0.1 - - [01/Aug/2026 21:36:51] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:37:51] "GET / HTTP/1.1" 200 - +2026-08-01 21:37:51,322 127.0.0.1 - - [01/Aug/2026 21:37:51] "GET / HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:37:51] "GET /favicon.ico HTTP/1.1" 404 - +2026-08-01 21:37:51,475 127.0.0.1 - - [01/Aug/2026 21:37:51] "GET /favicon.ico HTTP/1.1" 404 - +127.0.0.1 - - [01/Aug/2026 21:37:51] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:37:51,931 127.0.0.1 - - [01/Aug/2026 21:37:51] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:37:56] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:37:56,802 127.0.0.1 - - [01/Aug/2026 21:37:56] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:01] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:01,781 127.0.0.1 - - [01/Aug/2026 21:38:01] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:06] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:06,979 127.0.0.1 - - [01/Aug/2026 21:38:06] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:11] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:11,858 127.0.0.1 - - [01/Aug/2026 21:38:11] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:16] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:16,859 127.0.0.1 - - [01/Aug/2026 21:38:16] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:21] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:21,861 127.0.0.1 - - [01/Aug/2026 21:38:21] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:26] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:26,861 127.0.0.1 - - [01/Aug/2026 21:38:26] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:31] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:31,775 127.0.0.1 - - [01/Aug/2026 21:38:31] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:36] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:36,887 127.0.0.1 - - [01/Aug/2026 21:38:36] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:41] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:41,957 127.0.0.1 - - [01/Aug/2026 21:38:41] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:46] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:46,751 127.0.0.1 - - [01/Aug/2026 21:38:46] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:51] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:51,850 127.0.0.1 - - [01/Aug/2026 21:38:51] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:38:56] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:38:56,742 127.0.0.1 - - [01/Aug/2026 21:38:56] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:01] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:01,740 127.0.0.1 - - [01/Aug/2026 21:39:01] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:06] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:06,809 127.0.0.1 - - [01/Aug/2026 21:39:06] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:11] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:11,751 127.0.0.1 - - [01/Aug/2026 21:39:11] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:17] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:17,389 127.0.0.1 - - [01/Aug/2026 21:39:17] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:21] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:21,827 127.0.0.1 - - [01/Aug/2026 21:39:21] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:27] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:27,040 127.0.0.1 - - [01/Aug/2026 21:39:27] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:31] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:31,777 127.0.0.1 - - [01/Aug/2026 21:39:31] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:37] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:37,052 127.0.0.1 - - [01/Aug/2026 21:39:37] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:41] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:41,781 127.0.0.1 - - [01/Aug/2026 21:39:41] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:46] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:46,761 127.0.0.1 - - [01/Aug/2026 21:39:46] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:51] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:51,853 127.0.0.1 - - [01/Aug/2026 21:39:51] "GET /api/state HTTP/1.1" 200 - +127.0.0.1 - - [01/Aug/2026 21:39:56] "GET /api/state HTTP/1.1" 200 - +2026-08-01 21:39:56,761 127.0.0.1 - - [01/Aug/2026 21:39:56] "GET /api/state HTTP/1.1" 200 - diff --git a/dashboard.py b/dashboard.py new file mode 100644 index 0000000..08afe8d --- /dev/null +++ b/dashboard.py @@ -0,0 +1,384 @@ +#!/usr/bin/env python3 +"""K4LSH1_OPS — dashboard. Hacker console on :5053. Controls write config.json (bot hot-reloads).""" +import json, sqlite3, time, threading +from pathlib import Path +from flask import Flask, jsonify, request + +HOME = Path(__file__).parent +CFG_PATH = HOME / "config.json" +DB_PATH = HOME / "state.db" +app = Flask(__name__) + +HTML = r"""K4LSH1_OPS + +
+

K4LSH1_OPS

+
+
+
+
+
+

BTC/USD — kraken

+
$—
+
+ +
+

active market

+
ticker
+
question
+
closes in
+
YES —¢NO —¢
+
+

account

+
balance
+
open positions
+
bets placed (session)
+
+
+
+

AI decision stream — ollama local

+

system events

+
+
+

controls

+
STRATEGY MODE
+ +
MAX STAKE / BET: 50¢
+ + + +
+

order blotter

+
+
+
+
+
MODE
+
BTC
+
24H
+
FEAR/GREED
+
OPEN BETS
+
RESOLVED P&L
+
WIN RATE
+
AI CONF GATE
+
NEXT MARKET
+
+""" + +FLEET_HTML = r"""K4LSH1 FLEET + + +

K4LSH1_FLEET

+
+
+""" + + +def cfg(): + return json.loads(CFG_PATH.read_text()) + +@app.route("/") +def index(): + return HTML + +@app.route("/api/state") +def state(): + c = cfg() + conn = sqlite3.connect(DB_PATH) + conn.row_factory = sqlite3.Row + now = time.time() + ticks = [r[0] for r in conn.execute("SELECT price FROM ticks WHERE ts > ? ORDER BY ts", (now-1800,)).fetchall()] + last_price = ticks[-1] if ticks else None + age = None + row = conn.execute("SELECT MAX(ts) FROM ticks").fetchone() + if row and row[0]: age = int(now - row[0]) + dec = [{"t": time.strftime("%H:%M:%S", time.localtime(r["ts"])), "ticker": r["ticker"], + "momentum": r["momentum"], "llm_vote": r["llm_vote"], "llm_conf": r["llm_conf"], + "llm_why": r["llm_why"], "final": r["final"], "reason": r["reason"]} + for r in conn.execute("SELECT * FROM decisions ORDER BY id DESC LIMIT 30")] + orders = [{"t": time.strftime("%H:%M:%S", time.localtime(r["ts"])), "ticker": r["ticker"], + "side": r["side"], "count": r["count"], "price_cents": r["price_cents"], "dry": r["dry"]} + for r in conn.execute("SELECT * FROM orders ORDER BY id DESC LIMIT 20")] + events = [{"t": time.strftime("%H:%M:%S", time.localtime(r[0])), "level": r[1], "msg": r[2]} + for r in conn.execute("SELECT * FROM events ORDER BY ts DESC LIMIT 12")] + bets = conn.execute("SELECT COUNT(*) FROM orders").fetchone()[0] + perf_rows = conn.execute("SELECT status, COALESCE(pnl_cents,0) FROM orders WHERE status IN ('won','lost')").fetchall() + won = sum(1 for s,p in perf_rows if s == 'won') + pnl = sum(p for s,p in perf_rows) + open_bets = conn.execute("SELECT COUNT(*) FROM orders WHERE status IN ('placed','posted')").fetchone()[0] + kv = {r[0]: r[1] for r in conn.execute("SELECT k, v FROM kv")} + conn.close() + # live market + balance (proxy through bot's client without importing heavy code) + market, balance, positions = {}, None, 0 + try: + import sys + sys.path.insert(0, str(HOME)) + from bot import Kalshi, btc_price, DEFAULT_CFG + kx = Kalshi(c["api_key_id"], c["key_path"]) + mkts = kx.markets(c.get("series", "KXBTC15M"), "open", 2) + if mkts: + m = sorted(mkts, key=lambda x: x["close_time"])[-1] + from datetime import datetime + close_ts = datetime.fromisoformat(m["close_time"].replace("Z","+00:00")).timestamp() + book = kx.orderbook(m["ticker"]) + market = {"ticker": m["ticker"], "title": m.get("title",""), + "mins_left": (close_ts-time.time())/60, + "yes_ask": (book.get("yes") or [[None]])[0][0], + "no_ask": (book.get("no") or [[None]])[0][0]} + b = kx.balance() + balance = b.get("balance", 0) # available cash (cents) + positions = len(kx.positions()) + except Exception as e: + market = {"error": str(e)[:80]} + if last_price is None: + try: + from bot import btc_price + last_price = btc_price() + except Exception: pass + try: + from bot import intel as bot_intel + ix = bot_intel() + except Exception: + ix = {} + # momentum label + mom = "FLAT" + if len(ticks) > 10: + r = (ticks[-1]-ticks[0])/ticks[0]*100 + mom = f"{'UP' if r>0 else 'DOWN'} {abs(r):.3f}%/30m" + return jsonify({"cfg": c, "btc": last_price, "price_age": age, "spark": ticks[-120:], + "momentum": mom, "market": market, "balance": balance, + "positions": positions, "bets_session": bets, + "decisions": dec, "orders": orders, "events": events, + "intel": ix, + "perf": {"open": open_bets, "resolved": len(perf_rows), "won": won, + "pnl": pnl, "min_conf": kv.get("min_conf", c.get("min_conf", 0.55))}}) + +@app.route("/api/control", methods=["POST"]) +def control(): + c = cfg() + d = request.get_json(force=True) + if d.get("mode") in ("AUTO","DOWN_SPAM","UP_SPAM","OFF"): c["mode"] = d["mode"] + if isinstance(d.get("stake_cents"), int): c["stake_cents"] = max(1, min(99, d["stake_cents"])) + c["kill"] = False + CFG_PATH.write_text(json.dumps(c, indent=1)) + return jsonify({"ok": True}) + +@app.route("/api/toggle-dry", methods=["POST"]) +def toggle_dry(): + c = cfg(); c["dry_run"] = not c["dry_run"]; c["kill"] = False + CFG_PATH.write_text(json.dumps(c, indent=1)) + return jsonify({"ok": True, "dry_run": c["dry_run"]}) + +@app.route("/api/fleet") +def fleet_api(): + """All active coins in one call — reads each coin's own DB.""" + COINS = {"🐶DOGE": "#c2a633", "🔮SOL": "#9945FF", "💎ETH": "#627EEA"} + result = {} + for label, color in COINS.items(): + coin = label[1:] # strip leading emoji + fpath = HOME / f"{coin.lower()}.json" + if not fpath.exists(): continue + c = json.loads(fpath.read_text()) + if c.get("mode","OFF") == "OFF": continue + db_path = HOME / c.get("db_path", f"{coin.lower()}.db") + if not db_path.exists(): continue + conn = sqlite3.connect(str(db_path)) + conn.row_factory = sqlite3.Row + now = time.time() + ticks = [r[0] for r in conn.execute("SELECT price FROM ticks WHERE ts > ? ORDER BY ts", (now-1800,)).fetchall()] + last_price = ticks[-1] if ticks else None + # enriched per-coin data + decs = [dict(r) for r in conn.execute("SELECT * FROM decisions ORDER BY id DESC LIMIT 3")] + ords = [dict(r) for r in conn.execute("SELECT * FROM orders ORDER BY id DESC LIMIT 5")] + live_bets = conn.execute("SELECT COUNT(*) FROM orders WHERE status IN ('placed','posted') AND dry=0").fetchone()[0] + total_bets = conn.execute("SELECT COUNT(*) FROM orders WHERE dry=0").fetchone()[0] + pnl = conn.execute("SELECT COALESCE(SUM(pnl_cents),0) FROM orders WHERE dry=0").fetchone()[0] + won = conn.execute("SELECT COUNT(*) FROM orders WHERE status='won' AND dry=0").fetchone()[0] + import sys; sys.path.insert(0, str(HOME)) + from bot import rsi as _rsi, momentum as _mom + c_rsi = _rsi(conn); c_mom, c_score = _mom(conn) + chg24 = c.get("chg24_cache", 0) + result[coin] = {"label": label, "color": color, "series": c["series"], + "price": last_price, "mode": c["mode"], + "live_bets": live_bets, "total_bets": total_bets, + "pnl": pnl, "won": won, "stake": c.get("stake_cents", 10), + "swing": c.get("swing_threshold_pct", 0.005), + "rsi": c_rsi, "mom": f"{c_mom} {c_score:.3f}%" if c_mom != "FLAT" else c_mom, + "chg24": chg24, "decisions": decs, "orders": ords} + conn.close() + return jsonify(result) + + +@app.route("/fleet") +def fleet_page(): + return FLEET_HTML +def kill(): + c = cfg(); c["kill"] = True + CFG_PATH.write_text(json.dumps(c, indent=1)) + return jsonify({"ok": True}) + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5053, debug=False) diff --git a/doge.db b/doge.db new file mode 100644 index 0000000000000000000000000000000000000000..3508b6896972599235ce55d0258a6d39c7acc23d GIT binary patch literal 57344 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 E1LsKdi~s-t literal 0 HcmV?d00001 diff --git a/doge.json b/doge.json new file mode 100644 index 0000000..5f7fe7f --- /dev/null +++ b/doge.json @@ -0,0 +1,28 @@ +{ + "api_key_id": "28d5876b-2ece-4aa3-aa17-ec96e1e706eb", + "key_path": "/Users/drjones/kalshi-bot/kalshi_private_key.pem", + "mode": "AUTO", + "dry_run": false, + "stake_cents": 10, + "max_contracts": 1, + "daily_loss_cap_cents": 500, + "min_conf": 0.5, + "ollama_url": "http://10.30.20.186:11434", + "ollama_model": "ornith:latest", + "swing_threshold_pct": 0.005, + "learning": true, + "kill": false, + "coin": "DOGE", + "series": "KXDOGE15M", + "start_delay": 0, + "db_path": "doge.db", + "post_price_cents": 50, + "proxy": "http://10.30.20.154:3128", + "max_spend_cents": 100, + "decision_interval_sec": 300, + "start_delay_sec": 0, + "fast_llm_url": "http://localhost:11434", + "fast_llm_model": "qwen3.5:4b", + "deep_llm_url": "http://10.30.20.186:11434", + "deep_llm_model": "ornith:latest" +} \ No newline at end of file diff --git a/doge.lock b/doge.lock new file mode 100644 index 0000000..e69de29 diff --git a/eth.db b/eth.db new file mode 100644 index 0000000000000000000000000000000000000000..2679cefad4777c03e54fb2c1aeb2710a18cd38f8 GIT binary patch literal 61440 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 literal 0 HcmV?d00001 diff --git a/eth.json b/eth.json new file mode 100644 index 0000000..f7271f7 --- /dev/null +++ b/eth.json @@ -0,0 +1,28 @@ +{ + "api_key_id": "28d5876b-2ece-4aa3-aa17-ec96e1e706eb", + "key_path": "/Users/drjones/kalshi-bot/kalshi_private_key.pem", + "mode": "AUTO", + "dry_run": false, + "stake_cents": 10, + "max_contracts": 1, + "daily_loss_cap_cents": 500, + "min_conf": 0.5, + "ollama_url": "http://10.30.20.186:11434", + "ollama_model": "ornith:latest", + "swing_threshold_pct": 0.005, + "learning": true, + "kill": false, + "coin": "ETH", + "series": "KXETH15M", + "start_delay": 14, + "db_path": "eth.db", + "post_price_cents": 50, + "proxy": "http://10.30.20.189:3128", + "max_spend_cents": 100, + "decision_interval_sec": 300, + "start_delay_sec": 40, + "fast_llm_url": "http://localhost:11434", + "fast_llm_model": "qwen3.5:4b", + "deep_llm_url": "http://10.30.20.186:11434", + "deep_llm_model": "ornith:latest" +} \ No newline at end of file diff --git a/eth.lock b/eth.lock new file mode 100644 index 0000000..e69de29 diff --git a/kalshi_private_key.pem b/kalshi_private_key.pem new file mode 100644 index 0000000..8be54b7 --- /dev/null +++ b/kalshi_private_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAsiT6Qipbe9ntO7PScWfRdcSiZAuVie6RHJiO033kuinl34pj +L2kjnUSdUDez5DsVGgVfRH34lT8wnhLW/PhPScKJd1lmV5evxsPv1PZroNyOiS0j +vy5pFKgWG/hXmGoiQysufgsNOhANouxIoI7ubyKUVesUq6CEHDwTPNuC5gPliUnw +gXyB/1j6I21ghsIjifICm8UBYv1J5W3gQ1GYD5vF0Nc47Ugn3tq4mDFjvgIzulxF +HtcCdewVPH+BG3lNoTAlLK+WS3JXzrxq0rKYFIIoKyCjY4Aan2bUPfu7e74ODkX4 +EQCHKOVTgzyk3HfKkwgVmVGyavlh2zSrxlKUaQIDAQABAoIBACv6xAvcsCwx34cL +PGuB8WytKFghof/k9U9FfJFK9dJd8KHQ5O65+rBjVaENt2wjh/CeHehnXxzddk+4 +H/phBRYVIGHmIMWELcGY8tc1JNoYSVolWjtjJk8Sti6ej2WR4jaJ7Rbx/Ih2mR89 +TSrSTpwCQfO6Lya14Jel3yv5l2XYa/dlWDaiHNfbeymXEYVDTI4NEKMnzByZnour +jCsEhPIS3YEa0yLtS6FIhNftTya0q8AbghDtkXN1Pwm89XKLzRpkLZuE0v79mojB +miAifetImm6bZOwxr2C4vCmUvroIp0sCS40VTn7GHyCi6XYohGm/rk9difhVURzC +Q+AhpxkCgYEA0eaQXICA9qycos9es92rvvYgojumF9wFP5Hl+qNZv4g/KppoZGRq +7iICubJhoBSGZvHiZ34Lf8jH9v7I5JHaznqZmh60VCMm3GKUDtSWzkZcBI/FmlrM +QTrfkmiMQabWNXVw9RMgUEqnc8vHYu18Xaul1nOtXP7tuVvHxD4S7+UCgYEA2UT0 +toVdPZZ3dyuENcfnlb2CHFfawrFKWLzsSQtiUugGOubPFya35DdCjuQhyW/gcIiY +t4NCmbCSSkqHk4C7GfR3QxtMFFinm7HWdsjE4eYIXZvZTmP3B8UXWru7uDkmo+/q +7MVcMrirWezr7r7j10In6ocSQVBN3kb2/DS4ojUCgYBwUX08UnMwDEvA/1BA1UR6 +6f+qcFq/d7fDPZIf3VtAF2sdpARqfCWQCdkFf0OoQnNtENBC6vrCRTFjpRDg5n98 +b7RT+UwrnafE1Gc/zFhqRtIkir6Fi0KzQQqzsIgk9V64uoBYVAS9kkUqvIeUE1qy +URBrwfipw6x3vHoYM9M0VQKBgQDU/vzIUkXuMqw7b7XU43ztFzOOhbI4W4X/KHab +xUVG8Z/p7ovmrlZorKPbYVqeF8d3ivHsNgn8kVVY72ep+vFxqG+ioggbii4GPHl7 +Sad5rgFVg4utheKPA3C5yoFlQOHYpUMxiumv78pMBi/lhc3nITvwdyo2TXuJBRjs +duLqYQKBgDZ/a+mzI3SrA6iFYU8DuI0e5IgW92B4NHuav31ffyD5ah0gGTZ+o+H4 +Sp7xuVbg4Qr6DVY27Ky8kPL3eYDFPDPqpGFD9aNTzRxYdxqHi0jEph/MGiel4fKn +AzPZ6T8pf7rAxVhbcdChe9mvLWrb7Q1SOkVA9aXg9QuNW7zUd7Ip +-----END RSA PRIVATE KEY----- diff --git a/launch_all.sh b/launch_all.sh new file mode 100755 index 0000000..a71ce77 --- /dev/null +++ b/launch_all.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# K4LSH1_OPS multi-coin launcher +cd /Users/drjones/kalshi-bot +for coin in doge sol eth; do + echo "=== launching bot: $coin ===" + nohup .venv/bin/python bot.py --config /Users/drjones/kalshi-bot/$coin.json --lock $coin > /dev/null 2>&1 & + sleep 1 +done +echo "all 3 bots launched" diff --git a/sol.db b/sol.db new file mode 100644 index 0000000000000000000000000000000000000000..315ed0ea9940760ec25133cd51f089e2fd215da0 GIT binary patch literal 57344 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 E0l?IkZU6uP literal 0 HcmV?d00001 diff --git a/sol.json b/sol.json new file mode 100644 index 0000000..e876ab3 --- /dev/null +++ b/sol.json @@ -0,0 +1,28 @@ +{ + "api_key_id": "28d5876b-2ece-4aa3-aa17-ec96e1e706eb", + "key_path": "/Users/drjones/kalshi-bot/kalshi_private_key.pem", + "mode": "AUTO", + "dry_run": false, + "stake_cents": 10, + "max_contracts": 1, + "daily_loss_cap_cents": 500, + "min_conf": 0.5, + "ollama_url": "http://10.30.20.186:11434", + "ollama_model": "ornith:latest", + "swing_threshold_pct": 0.005, + "learning": true, + "kill": false, + "coin": "SOL", + "series": "KXSOL15M", + "start_delay": 7, + "db_path": "sol.db", + "post_price_cents": 50, + "proxy": "http://10.30.20.71:3128", + "max_spend_cents": 100, + "decision_interval_sec": 300, + "start_delay_sec": 20, + "fast_llm_url": "http://localhost:11434", + "fast_llm_model": "qwen3.5:4b", + "deep_llm_url": "http://10.30.20.186:11434", + "deep_llm_model": "ornith:latest" +} \ No newline at end of file diff --git a/sol.lock b/sol.lock new file mode 100644 index 0000000..e69de29 diff --git a/state.db b/state.db new file mode 100644 index 0000000000000000000000000000000000000000..05fc30e1fb11cd080abebd82e1eae9a8456fb6df GIT binary patch literal 126976 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 )QMgHpyv-u$7lY- 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 E0ZwcyOaK4? literal 0 HcmV?d00001 diff --git a/test_bot.py b/test_bot.py new file mode 100644 index 0000000..7fad9c3 --- /dev/null +++ b/test_bot.py @@ -0,0 +1,279 @@ +#!/usr/bin/env python3 +"""K4LSH1_OPS unit tests — verify every decision-making component.""" +import json, sqlite3, sys, time, tempfile +from pathlib import Path +from unittest.mock import patch, MagicMock + +sys.path.insert(0, str(Path(__file__).parent)) +from bot import (momentum, decide, rsi, hedge_positions, llm_vote, + Kalshi, load_cfg, learned_min_conf, KRAKEN_PAIRS, + btc_price, intel) + +PASS = 0 +FAIL = 0 + +def check(name, condition, detail=""): + global PASS, FAIL + if condition: + PASS += 1 + print(f" ✓ {name}") + else: + FAIL += 1 + print(f" ✗ {name} — {detail}") + +def test_momentum(): + print("\n═══ MOMENTUM ═══") + conn = sqlite3.connect(":memory:") + conn.execute("CREATE TABLE ticks (ts REAL, price REAL)") + now = time.time() + # flat market + for i in range(20): + conn.execute("INSERT INTO ticks VALUES (?, 100.0)", (now - 300 + i*15,)) + mom, score = momentum(conn) + check("flat market → FLAT", mom == "FLAT", f"got {mom}/{score:.4f}") + check("flat score near 0", score < 0.01, f"score={score:.4f}") + + # up market + conn.execute("DELETE FROM ticks") + for i in range(20): + p = 100.0 + i * 0.5 + conn.execute("INSERT INTO ticks VALUES (?,?)", (now - 300 + i*15, p)) + mom, score = momentum(conn) + check("rising market → UP", mom == "UP", f"got {mom}/{score:.3f}%") + check("up score positive", score > 0.05, f"score={score:.3f}%") + + # down market + conn.execute("DELETE FROM ticks") + for i in range(20): + p = 200.0 - i * 0.3 + conn.execute("INSERT INTO ticks VALUES (?,?)", (now - 300 + i*15, p)) + mom, score = momentum(conn) + check("falling market → DOWN", mom == "DOWN", f"got {mom}/{score:.3f}%") + check("down score positive", score > 0.01, f"score={score:.3f}%") + + # too few ticks + conn.execute("DELETE FROM ticks") + conn.execute("INSERT INTO ticks VALUES (?, 100)", (now,)) + mom, score = momentum(conn) + check("1 tick → FLAT", mom == "FLAT", f"got {mom}") + check("1 tick score 0", score == 0.0, f"score={score}") + conn.close() + + +def test_rsi(): + print("\n═══ RSI ═══") + conn = sqlite3.connect(":memory:") + conn.execute("CREATE TABLE ticks (ts REAL, price REAL)") + now = time.time() + # oversold: steady decline + for i in range(30): + p = 100.0 - i * 0.5 + conn.execute("INSERT INTO ticks VALUES (?,?)", (now - 1800 + i*60, p)) + val = rsi(conn) + check("decline → RSI < 30", val is not None and val < 30, f"RSI={val}") + # overbought: steady climb + conn.execute("DELETE FROM ticks") + for i in range(30): + p = 100.0 + i * 0.8 + conn.execute("INSERT INTO ticks VALUES (?,?)", (now - 1800 + i*60, p)) + val = rsi(conn) + check("climb → RSI > 70", val is not None and val > 70, f"RSI={val}") + conn.close() + + +def test_learned_min_conf(): + print("\n═══ ADAPTIVE CONFIDENCE ═══") + conn = sqlite3.connect(":memory:") + conn.execute("CREATE TABLE orders (id INTEGER PRIMARY KEY, pnl_cents INT, status TEXT)") + conn.execute("CREATE TABLE IF NOT EXISTS kv (k TEXT PRIMARY KEY, v REAL)") + cfg = {"learning": True, "min_conf": 0.55} + # < 8 resolved bets → use default + for i in range(5): + conn.execute("INSERT INTO orders(pnl_cents,status) VALUES (?,?)", (10, "won")) + lc = learned_min_conf(conn, cfg) + check("<8 bets → default", lc == 0.55, f"got {lc}") + + # majority wins → relax confidence + for i in range(15): + conn.execute("INSERT INTO orders(pnl_cents,status) VALUES (?,?)", (15 if i < 10 else -10, "won" if i < 10 else "lost")) + lc = learned_min_conf(conn, cfg) + check("high WR → relax", lc < 0.55, f"got {lc}") + + # majority losses → tighten (need fresh conn, kv starts empty) + conn.execute("DELETE FROM orders") + conn.execute("DELETE FROM kv") + for i in range(15): + conn.execute("INSERT INTO orders(pnl_cents,status) VALUES (?,?)", + (-10 if i < 10 else 15, "lost" if i < 10 else "won")) + lc = learned_min_conf(conn, {"learning": True, "min_conf": 0.55}) + check("low WR → tighten", lc > 0.55, f"got {lc}") + conn.close() + + +def test_hedge(): + print("\n═══ HEDGE LOGIC ═══") + conn = sqlite3.connect(":memory:") + conn.execute("CREATE TABLE orders (id INTEGER PRIMARY KEY, ts REAL, ticker TEXT, " + "side TEXT, count INT, price_cents INT, dry INT, order_id TEXT, status TEXT, " + "settle_ts REAL, pnl_cents INT)") + conn.execute("CREATE TABLE events (ts REAL, level TEXT, msg TEXT)") + cfg = {"dry_run": True, "min_profit_cents": 8} + ticker = "KXBTC15M-TEST" + book = {"yes": [[42]], "no": [[48]]} + + # scenario: we bought NO at 45¢, YES ask is 42¢ → profit = 100-45-42=13¢ > 8¢ min + conn.execute("INSERT INTO orders VALUES (1,0,?,?,?,?,0,'sim','posted',NULL,NULL)", + (ticker, "no", 1, 45)) + result = hedge_positions(conn, MagicMock(), ticker, cfg, book) + check("NO@45 YES@42 → hedge fires", result == "hedged", f"got {result}") + hedged = conn.execute("SELECT status FROM orders WHERE id=1").fetchone()[0] + check("original marked hedged", hedged == "hedged", f"got {hedged}") + new_orders = conn.execute("SELECT COUNT(*) FROM orders WHERE side='yes'").fetchone()[0] + check("counter-order placed", new_orders == 1) + + # scenario: profit too small + conn.execute("DELETE FROM orders") + conn.execute("INSERT INTO orders VALUES (2,0,?,?,?,?,0,'sim','posted',NULL,NULL)", + (ticker, "no", 1, 48)) + book2 = {"yes": [[49]], "no": [[50]]} + result2 = hedge_positions(conn, MagicMock(), ticker, cfg, book2) + check("NO@48 YES@49 → no hedge (1¢ profit)", result2 is None) + conn.close() + + +def test_decision_logic(): + print("\n═══ DECISION LOGIC ═══") + conn = sqlite3.connect(":memory:") + conn.execute("CREATE TABLE ticks (ts REAL, price REAL)") + conn.execute("CREATE TABLE decisions (id INTEGER PRIMARY KEY, ts REAL, ticker TEXT, " + "mode TEXT, momentum TEXT, llm_vote TEXT, llm_conf REAL, llm_why TEXT, " + "final TEXT, price REAL, reason TEXT)") + conn.execute("CREATE TABLE orders (id INTEGER PRIMARY KEY, pnl_cents INT, status TEXT)") + conn.execute("CREATE TABLE events (ts REAL, level TEXT, msg TEXT)") + conn.execute("CREATE TABLE IF NOT EXISTS kv (k TEXT PRIMARY KEY, v REAL)") + now = time.time() + for i in range(20): + p = 100.0 + i * 0.3 + conn.execute("INSERT INTO ticks VALUES (?,?)", (now - 300 + i*15, p)) + + cfg = {"swing_threshold_pct": 0.005, "min_conf": 0.50, "learning": False, + "mode": "AUTO", "coin": "BTC", "ollama_url": "http://x", "ollama_model": "x"} + + # LLM confirms: UP spike, LLM votes DOWN (fade confirmed) + with patch("bot.intel", return_value={"chg24": 0.85, "fng": 45, "fee_fast": 8}), \ + patch("bot.llm_vote", return_value=("DOWN", 0.72, "strong fade signal")): + mom, lv, lc, lw, final, why = decide(cfg, conn, 63400) + check("LLM fade confirm → DOWN", final == "DOWN", f"got {final}") + check("confidence preserved", lc == 0.72, f"got {lc}") + + # LLM passes (not enough signal) + with patch("bot.intel", return_value={"chg24": 0.1}), \ + patch("bot.llm_vote", return_value=("SKIP", 0.30, "no clear signal")): + mom, lv, lc, lw, final, why = decide(cfg, conn, 63400) + check("LLM skip → SKIP", final == "SKIP", f"got {final}") + + # LLM goes against fade but high conf — should follow LLM + with patch("bot.intel", return_value={"chg24": 0.5}), \ + patch("bot.llm_vote", return_value=("UP", 0.82, "continuation strong")): + mom, lv, lc, lw, final, why = decide(cfg, conn, 63400) + check("LLM continuation with high conf → trust LLM", final == "UP", f"got {final}/{why}") + + # Low confidence → skip + with patch("bot.intel", return_value={"chg24": 0.3}), \ + patch("bot.llm_vote", return_value=("DOWN", 0.35, "weak")): + mom, lv, lc, lw, final, why = decide(cfg, conn, 63400) + check("low conf → SKIP", final == "SKIP", f"got {final}") + + conn.close() + + +def test_price_sources(): + print("\n═══ PRICE SOURCES ═══") + for coin, pair in [("BTC","XBTUSD"), ("DOGE","XDGUSD"), ("SOL","SOLUSD"), ("ETH","ETHUSD")]: + p = btc_price(coin) + check(f"{coin} price from Kraken", p is not None and p > 0, f"${p}" if p else "None") + # coinbase fallback + with patch("bot.requests.get") as mock_get: + mock_kraken = MagicMock() + mock_kraken.json.side_effect = Exception("kraken down") + mock_cb = MagicMock() + mock_cb.json.return_value = {"data": {"amount": "99999"}} + mock_get.side_effect = [mock_kraken, mock_cb] + p = btc_price("BTC") + check("coinbase fallback works", p == 99999.0, f"got {p}") + + +def test_llm_vote_parsing(): + print("\n═══ LLM VOTE PARSING ═══") + cfg = {"ollama_url": "http://x", "ollama_model": "x", "coin": "BTC"} + # ornith says DOWN with confidence + mock_resp = MagicMock() + mock_resp.text = json.dumps({"response": "DOWN|0.72|RSI oversold, fading up spike"}) + with patch("bot.requests.post", return_value=mock_resp): + with patch("bot.intel", return_value={"chg24": 0.5}): + with patch("bot.rsi", return_value=28): + lv, lc, lw = llm_vote(cfg, 63400, "UP", 0.12, sqlite3.connect(":memory:")) + check("parses DOWN", lv == "DOWN", f"got {lv}") + check("parses confidence", lc == 0.72, f"got {lc}") + check("parses why", len(lw) > 5, f"'{lw}'") + + # ornith says SKIP + mock_resp.text = json.dumps({"response": "SKIP|0.40|no clear direction"}) + with patch("bot.requests.post", return_value=mock_resp): + with patch("bot.intel", return_value={"chg24": 0.1}): + with patch("bot.rsi", return_value=55): + lv, lc, lw = llm_vote(cfg, 63400, "FLAT", 0.001, sqlite3.connect(":memory:")) + check("parses SKIP", lv == "SKIP", f"got {lv}") + + # malformed response + mock_resp.text = json.dumps({"response": "garbage noise no pipe"}) + with patch("bot.requests.post", return_value=mock_resp): + with patch("bot.intel", return_value={}): + with patch("bot.rsi", return_value=None): + lv, lc, lw = llm_vote(cfg, 63400, "UP", 0.10, sqlite3.connect(":memory:")) + check("malformed → SKIP", lv == "SKIP", f"got {lv}") + check("malformed → 0 conf", lc == 0.0, f"got {lc}") + + +def test_config(): + print("\n═══ CONFIG ═══") + with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: + json.dump({"mode": "AUTO", "stake_cents": 15, "coin": "TEST"}, f) + fpath = f.name + try: + from bot import HOME, CFG_PATH, load_cfg + old = str(CFG_PATH) + import bot + bot.CFG_PATH = Path(fpath) + c = load_cfg() + check("loads mode", c["mode"] == "AUTO") + check("loads stake", c["stake_cents"] == 15) + bot.CFG_PATH = Path(old) + finally: + Path(fpath).unlink(missing_ok=True) + + +def test_kraken_pairs(): + print("\n═══ KRAKEN PAIRS ═══") + check("BTC → XBTUSD", KRAKEN_PAIRS["BTC"] == "XBTUSD") + check("DOGE → XDGUSD", KRAKEN_PAIRS["DOGE"] == "XDGUSD") + check("SOL → SOLUSD", KRAKEN_PAIRS["SOL"] == "SOLUSD") + check("ETH → ETHUSD", KRAKEN_PAIRS["ETH"] == "ETHUSD") + check("XRP → XRPUSD", KRAKEN_PAIRS["XRP"] == "XRPUSD") + + +if __name__ == "__main__": + print("K4LSH1_OPS UNIT TESTS") + print("=" * 50) + tests = [test_momentum, test_rsi, test_learned_min_conf, test_hedge, + test_decision_logic, test_price_sources, test_llm_vote_parsing, + test_config, test_kraken_pairs] + for t in tests: + try: + t() + except Exception as e: + print(f" ✗ CRASH: {e}") + FAIL += 1 + print(f"\n{'='*50}") + print(f"PASS: {PASS} FAIL: {FAIL}") + sys.exit(0 if FAIL == 0 else 1)