v1.3 infra integration: Qdrant memory RAG, Trilium journaling, n8n emit hooks

This commit is contained in:
2026-02-26 08:29:59 -08:00
parent cb5edf694d
commit ddc42254fa
5 changed files with 171 additions and 163 deletions

54
bot.py
View File

@@ -13,6 +13,10 @@ from services import (
place_order,
market_open,
positions_snapshot,
qdrant_similar,
qdrant_add_memory,
trilium_log,
n8n_emit,
)
scheduler = BackgroundScheduler(timezone=settings.timezone)
@@ -55,14 +59,15 @@ def run_cycle():
news = searx_news(symbol)
strat = strategy_signals(symbol, news)
decision = llm_final_decision(symbol, news, strat)
memory_hits = qdrant_similar(symbol, json.dumps(news)[:2000], limit=5)
decision = llm_final_decision(symbol, news, strat, memory_hits)
# Escalate to deeper research when model asks or confidence weak
if decision.get("needs_more_research") or decision.get("confidence", 0) < settings.min_confidence:
more = extra_research(symbol, decision.get("research_topics", []))
if more:
news = news + more
decision = llm_final_decision(symbol, news, strat)
memory_hits = qdrant_similar(symbol, json.dumps(news)[:2000], limit=5)
decision = llm_final_decision(symbol, news, strat, memory_hits)
drow = BotDecision(
symbol=symbol,
@@ -77,19 +82,11 @@ def run_cycle():
db.commit()
db.refresh(drow)
should_trade = (
decision["action"] in {"buy", "sell"}
and decision["confidence"] >= settings.min_confidence
)
should_trade = decision["action"] in {"buy", "sell"} and decision["confidence"] >= settings.min_confidence
if should_trade:
# Fee/slippage-aware cap for tiny bankroll
effective_cost = settings.fee_per_trade_usd + (settings.slippage_bps / 10000.0) * decision["order_usd"]
notional = min(
settings.max_order_usd,
decision["order_usd"],
settings.max_daily_notional - spent,
)
notional = min(settings.max_order_usd, decision["order_usd"], settings.max_daily_notional - spent)
if notional <= effective_cost:
drow.status = "risk_blocked"
db.add(drow)
@@ -100,21 +97,46 @@ def run_cycle():
ok = bool(res and res.get("ok"))
drow.status = "executed" if ok else "failed"
db.add(drow)
db.add(TradeExecution(
trade = TradeExecution(
symbol=symbol,
side=decision["action"],
qty=float((res or {}).get("json", {}).get("qty", 0) or 0),
notional=notional,
alpaca_order_id=(res or {}).get("json", {}).get("id", ""),
raw=json.dumps({"decision": decision, "strategy": strat, "broker": res})[:60000],
))
raw=json.dumps({"decision": decision, "strategy": strat, "memory": memory_hits, "broker": res})[:60000],
)
db.add(trade)
db.commit()
# learning memory + notes + orchestration signal
qdrant_add_memory(symbol, f"{symbol} {decision['action']} conf={decision['confidence']} reason={decision['reason']}", {
"status": drow.status,
"action": decision["action"],
"confidence": decision["confidence"],
"ts": datetime.utcnow().isoformat(),
})
trilium_log(
f"Trade {symbol} {decision['action']} {drow.status}",
f"## Decision\n- symbol: {symbol}\n- action: {decision['action']}\n- confidence: {decision['confidence']:.2f}\n- status: {drow.status}\n- notional: ${notional:.2f}\n\n## Reason\n{decision['reason']}\n\n## Strategy\n{json.dumps(strat, indent=2)}\n"
)
n8n_emit({"event": "trade", "symbol": symbol, "status": drow.status, "decision": decision, "notional": notional})
if ok:
spent += notional
else:
drow.status = "skipped"
db.add(drow)
db.commit()
# store non-trade decisions too for memory
qdrant_add_memory(symbol, f"{symbol} decision={decision['action']} conf={decision['confidence']} status={drow.status}", {
"status": drow.status,
"action": decision["action"],
"confidence": decision["confidence"],
"ts": datetime.utcnow().isoformat(),
})
finally:
db.close()