feat: configurable simulation duration and periodic signal saving

Frontend:
- Added duration selector (1min, 5min, 10min, 30min)
- Added check interval selector (10s, 30s, 60s)

Backend:
- Signals are now saved to database every 30 seconds during simulation
- Can stop simulation early to see partial signals
This commit is contained in:
shokollm
2026-04-11 17:56:27 +00:00
parent 726e579f5f
commit 1b1358353f
3 changed files with 57 additions and 7 deletions

View File

@@ -22,6 +22,7 @@ def run_simulation_sync(
simulation_id: str, db_url: str, bot_id: str, config: Dict[str, Any] simulation_id: str, db_url: str, bot_id: str, config: Dict[str, Any]
): ):
import asyncio import asyncio
import time
from ..services.simulate.engine import SimulateEngine from ..services.simulate.engine import SimulateEngine
from ..core.database import SessionLocal from ..core.database import SessionLocal
@@ -29,8 +30,44 @@ def run_simulation_sync(
engine = SimulateEngine(config) engine = SimulateEngine(config)
engine.run_id = simulation_id engine.run_id = simulation_id
running_simulations[simulation_id] = engine running_simulations[simulation_id] = engine
def save_signals_to_db():
"""Save current signals to database."""
db = SessionLocal()
try: try:
results = await engine.run() simulation = (
db.query(Simulation).filter(Simulation.id == simulation_id).first()
)
if simulation:
simulation.signals = engine.signals
db.commit()
finally:
db.close()
try:
# Run engine in background with periodic signal saving
check_interval = config.get("check_interval", 60)
save_interval = min(check_interval, 30) # Save at least every 30 seconds
async def run_with_periodic_save():
last_save_time = time.time()
while engine.running and engine.status == "running":
await asyncio.sleep(1) # Check every second
current_time = time.time()
if current_time - last_save_time >= save_interval:
save_signals_to_db()
last_save_time = current_time
# Final save when done
save_signals_to_db()
# Run both the engine and periodic save concurrently
await asyncio.gather(
engine.run(),
run_with_periodic_save()
)
db = SessionLocal() db = SessionLocal()
try: try:
simulation = ( simulation = (

View File

@@ -189,7 +189,7 @@ export const api = {
}, },
simulate: { simulate: {
async start(botId: string, config: { token: string; chain?: string; check_interval: number; auto_execute: boolean }): Promise<Simulation> { async start(botId: string, config: { token: string; chain?: string; check_interval: number; duration_seconds: number; auto_execute: boolean }): Promise<Simulation> {
const response = await fetch(`${API_URL}/bots/${botId}/simulate`, { const response = await fetch(`${API_URL}/bots/${botId}/simulate`, {
method: 'POST', method: 'POST',
headers: getAuthHeaders(), headers: getAuthHeaders(),

View File

@@ -10,6 +10,7 @@
let tokenName = $state(''); let tokenName = $state('');
let tokenAddress = $state(''); let tokenAddress = $state('');
let intervalSeconds = $state(60); let intervalSeconds = $state(60);
let durationSeconds = $state(300); // 5 minutes default
let autoExecute = $state(false); let autoExecute = $state(false);
let isRunning = $state(false); let isRunning = $state(false);
@@ -70,6 +71,7 @@
token: tokenAddress, token: tokenAddress,
chain: 'bsc', chain: 'bsc',
check_interval: intervalSeconds, check_interval: intervalSeconds,
duration_seconds: durationSeconds,
auto_execute: autoExecute auto_execute: autoExecute
}); });
setCurrentSimulation(simulation); setCurrentSimulation(simulation);
@@ -132,12 +134,23 @@
</div> </div>
</div> </div>
<div class="field"> <div class="field">
<label for="interval">Check Interval (seconds)</label> <label for="duration">Duration</label>
<select id="interval" bind:value={intervalSeconds} disabled={isRunning}> <select id="duration" bind:value={durationSeconds} disabled={isRunning}>
<option value={30}>30 seconds</option> <option value={60}>1 minute</option>
<option value={60}>60 seconds</option>
<option value={120}>2 minutes</option>
<option value={300}>5 minutes</option> <option value={300}>5 minutes</option>
<option value={600}>10 minutes</option>
<option value={1800}>30 minutes</option>
</select>
</div>
</div>
<div class="form-row">
<div class="field">
<label for="interval">Check Interval</label>
<select id="interval" bind:value={intervalSeconds} disabled={isRunning}>
<option value={10}>Every 10 seconds</option>
<option value={30}>Every 30 seconds</option>
<option value={60}>Every minute</option>
</select> </select>
</div> </div>
</div> </div>