From 245a15666e8842c31b5d46a1813962877c0841d9 Mon Sep 17 00:00:00 2001 From: Senofy <63175905+Senofy@users.noreply.github.com> Date: Thu, 12 Mar 2026 03:42:54 -0500 Subject: [PATCH] Add configurable tick interval (time between trades) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Seed tick_interval_seconds setting (default 60s) - Expose tick_interval_seconds via GET/PATCH /api/settings - startScheduler reads the setting at start time; enforces 5s minimum - getSchedulerStatus returns intervalSeconds for the UI - Main page: "Every [__] s" input in idle bar — saves on blur, persists across restarts; running state displays "every Ns" next to symbol/action Co-Authored-By: Claude Sonnet 4.6 --- app/api/settings/route.ts | 2 +- app/page.tsx | 35 +++++++++++++++++++++++++++++++++-- lib/auto-trade.ts | 6 ++++-- lib/db.ts | 1 + 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/app/api/settings/route.ts b/app/api/settings/route.ts index 6ff3d54..fbd69a9 100644 --- a/app/api/settings/route.ts +++ b/app/api/settings/route.ts @@ -1,7 +1,7 @@ import { NextRequest, NextResponse } from 'next/server'; import { getSetting, setSetting } from '@/lib/db'; -const VALID_KEYS = ['max_concurrent_accounts'] as const; +const VALID_KEYS = ['max_concurrent_accounts', 'tick_interval_seconds'] as const; type SettingKey = typeof VALID_KEYS[number]; export async function GET() { diff --git a/app/page.tsx b/app/page.tsx index 656328b..d64d707 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -256,6 +256,7 @@ interface SchedulerStatus { action: 'Buy' | 'Sell' | 'Random'; symbol: string; lastRun: string | null; + intervalSeconds: number; } export default function Home() { @@ -270,10 +271,11 @@ export default function Home() { const [sortDir, setSortDir] = useState('asc'); // Trade controls - const [scheduler, setScheduler] = useState({ running: false, action: 'Buy', symbol: 'NQ', lastRun: null }); + const [scheduler, setScheduler] = useState({ running: false, action: 'Buy', symbol: 'NQ', lastRun: null, intervalSeconds: 60 }); const [enabledSymbols, setEnabledSymbols] = useState([]); const [tradeSymbol, setTradeSymbol] = useState(''); const [tradeAction, setTradeAction] = useState<'Buy' | 'Sell' | 'Random'>('Buy'); + const [tickInterval, setTickInterval] = useState('60'); const [tradeLoading, setTradeLoading] = useState(false); const handleSort = (col: SortKey) => { @@ -314,6 +316,13 @@ export default function Home() { }) .catch(() => {}); + fetch('/api/settings') + .then((r) => r.json()) + .then((s: { tick_interval_seconds?: string | null }) => { + if (s.tick_interval_seconds != null) setTickInterval(s.tick_interval_seconds); + }) + .catch(() => {}); + fetchConfig(); fetchScheduler(); @@ -456,9 +465,10 @@ export default function Home() { {scheduler.symbol} · {scheduler.action} + every {scheduler.intervalSeconds}s {scheduler.lastRun && ( - last run {new Date(scheduler.lastRun).toLocaleTimeString()} + · last run {new Date(scheduler.lastRun).toLocaleTimeString()} )}