AI / LLM Integration Research
This document surveys every realistic opportunity to integrate local LLMs (via Ollama) into the mi-casa trading platform — covering signal enhancement, entry timing, regime detection, parameter optimisation, and reporting — along with architecture options, model selection, prompt engineering guidelines, and a phased implementation plan.
Codebase Context
mi-casa is a full-stack Bun application: a React 19 frontend backed by a layered Controller → Service → Repository backend, Drizzle ORM, and PostgreSQL (TimescaleDB). Two microservices sit alongside it:
| Microservice | Responsibility |
|---|---|
ohlc-service | Harmonic & structure pattern detection, signal scoring, SL/TP calculation, backtest engine, parameter optimisation grid search |
ctrader-service | Live tick streaming from IC Markets EU via the cTrader Open API WebSocket |
Pattern coverage as of this research:
| Category | Patterns |
|---|---|
| Harmonic XABCD | Gartley, Bat, Butterfly, Crab, Shark, Cypher |
| Structure | ABCD, Three Drives, Double Top/Bottom, Head & Shoulders |
| Candlestick | 19 patterns (Doji, Hammer, Engulfing, Morning Star, etc.) |
All patterns carry Fibonacci ratio validation and a signalScore field. The auto-trade engine is fully rule-based and deterministic — there is no existing AI integration, making this a clean-slate opportunity.
Related technical references: Markets — Pattern Detection, OHLC Phase 2 — Actionability & Observability.
Integration Opportunities
Opportunities are ranked by expected impact and implementation tractability.
⭐⭐⭐⭐⭐ Highest Priority
1. Signal Score Enhancement
| Attribute | Detail |
|---|---|
| Current state | Deterministic score based on Fibonacci ratio deviation + pattern geometry |
| Opportunity | LLM re-scores each detected pattern considering: ratio quality vs ideal, recent candle action at PRZ, RSI/MACD context, multi-timeframe confluence |
| Integration point | New aiScore + compositeScore columns on ohlcPatterns; blend 60% classic / 40% AI |
| Latency | ~200 ms async — never blocks the classic score write |
| Expected benefit | 15–25% P&L improvement over baseline |
The async path means the classic score is always immediately available. The composite score updates once the LLM responds, and a WebSocket broadcast pushes the refreshed value to the frontend.
2. Entry Timing Optimisation
| Attribute | Detail |
|---|---|
| Current state | Pattern completes → auto-trade enters immediately |
| Opportunity | LLM advises whether price has arrived at the PRZ now vs will arrive in N candles, and whether confirmation candles and momentum support the trade direction |
| Integration point | New entryTimingService; recommendation field on the pattern and trade objects |
| Expected benefit | 20–30% reduction in premature entries |
The recommendation surfaces as an advisory card in the UI — the auto-trade engine can optionally gate on it before submitting an entry.
⭐⭐⭐⭐ High Priority
3. Dynamic SL/TP Adjustment
| Attribute | Detail |
|---|---|
| Current state | Fixed SL/TP multipliers from trading configuration |
| Opportunity | LLM adjusts multipliers based on ATR, Bollinger Band width, pattern quality, and detected market regime |
| Integration point | Modify SL/TP calculation in ohlc-service before submitting the auto-trade |
| Expected benefit | Better risk-reward in high-volatility conditions; tighter SL in calm conditions |
4. Parameter Optimisation — Bayesian Guidance
| Attribute | Detail |
|---|---|
| Current state | Exhaustive grid search over SL/TP multipliers, PRZ tolerance, and min confidence — O(n^k) combinations, slow on large ranges |
| Opportunity | LLM/Bayesian-guided search proposes the next parameter combination based on prior results, converging in far fewer iterations |
| Integration point | Replace or wrap the grid search in the trading-config-optimiser flow |
| Expected benefit | Same or better optimal parameters in ~10× fewer iterations |
5. Pattern Quality Classifier
| Attribute | Detail |
|---|---|
| Current state | Binary — pattern detected or not |
| Opportunity | Grade patterns as poor / fair / good / excellent based on geometric quality, candle context, and Fibonacci deviation from the ideal ratio |
| Integration point | New qualityGrade field on ohlcPatterns; displayed in the chart overlay |
6. Emerging Pattern Prediction
| Attribute | Detail |
|---|---|
| Current state | Only completed patterns (all legs confirmed) are scored |
| Opportunity | LLM predicts whether an in-progress XABC leg will complete as a valid D point — providing early alerts before the pattern finalises |
| Expected benefit | Earlier warnings, better trade preparation time |
⭐⭐⭐ Medium Priority
7. Market Regime Detection
| Attribute | Detail |
|---|---|
| Current state | Each pattern evaluated independently with no market context |
| Opportunity | Classify market state hourly, per symbol × timeframe: trending / ranging / choppy / pre-breakout / post-news |
| Integration point | New market_regimes table; regime label used to weight composite signal scores (e.g., down-weight harmonic setups during choppy) |
| Latency | ~1 s, runs hourly in background — no real-time requirement |
| Expected benefit | 30–50% reduction in losses during choppy or low-quality conditions |
8. Trade Execution Recommendations
| Attribute | Detail |
|---|---|
| Opportunity | Advisory card in the UI: “LLM recommends waiting — price has overshot PRZ by 0.3% and momentum is bearish on 15 m” |
| Integration point | executionRecommendationService; surfaced as a dismissible card before auto-trade entry |
9. Multi-Pattern Confluence
| Attribute | Detail |
|---|---|
| Opportunity | When multiple patterns complete near the same price zone (e.g., Gartley on 1 h + Bat on 4 h at the same PRZ), LLM boosts the composite score significantly |
| Integration point | Cross-timeframe query at signal time; confluence flag added to the pattern record |
⭐⭐ Medium-Low Priority
10. Automated Report Generation
| Attribute | Detail |
|---|---|
| Opportunity | Weekly P&L summaries with LLM-written narrative insights, pattern performance by type and timeframe, and optimisation recommendations |
| Integration point | reportGenerationService — best orchestrated via n8n scheduled workflow → email via Nodemailer |
11. Candlestick Pattern Enhancement
| Attribute | Detail |
|---|---|
| Current state | Binary detection (pattern present or absent) |
| Opportunity | LLM scores wick length, body size, colour sequence, and volume confirmation → continuous confidence score [0, 1] |
12. Slippage & Spread Impact Modelling
| Attribute | Detail |
|---|---|
| Opportunity | Learn time-of-day and news-event slippage patterns from closed trades; feed the model into entry timing recommendations |
⭐ Lower Priority (Interesting)
| Idea | Description |
|---|---|
| Pattern Morphing Prediction | ”Current XABC suggests a potential Butterfly or Crab at D” — helps traders prepare for alternative completions |
| Trader Psychology Helper | Streak-aware warnings — “5-candle win streak detected; review signal quality carefully before the next entry” |
| Kelly Criterion Position Sizing | LLM-assisted fractional Kelly based on backtest win rates per pattern type and timeframe |
| Correlated Pair Analysis | Multi-asset conflict/confluence detection across tracked pairs |
| Sentiment Analysis | Combine harmonic pattern signals with forex news sentiment from RSS feeds |
Implementation Architecture
Option A — Direct Ollama Integration (Recommended)
Call the Ollama HTTP API directly from the Bun backend. No new microservice is needed for initial phases.
Pros: low latency (same server), no API costs, data never leaves the server, GDPR compliant, no third-party keys required.
Cons: requires model selection and local VRAM; inference is 150–400 ms per request (acceptable for async use cases).
ohlc-service detects pattern
↓ (sync) classic signalScore written to DB
↓ (async, fire-and-forget)
backend/services/ollamaClient.ts
→ POST http://localhost:11434/api/generate
→ parse JSON response
→ write aiScore + compositeScore to ohlcPatterns
↓
WebSocket broadcast → updated composite score to frontend
Environment variables to add:
| Variable | Default | Purpose |
|---|---|---|
OLLAMA_ENDPOINT | http://localhost:11434 | Ollama HTTP base URL |
OLLAMA_MODEL | mistral | Active model name |
Option B — Hybrid (Ollama + Cloud Fallback)
Use Ollama as the primary inference path; fall back to OpenAI or Anthropic on timeout or error. Useful during high-volatility sessions when Ollama may be saturated.
Option C — Dedicated AI Microservice (Future)
Extract all AI logic into an ai-service with its own routes and prompt store. Connect from ohlc-service via HTTP. Adopt this when managing multiple models or fine-tuned variants at scale.
ai-service/
├── routes/
│ ├── signalScore.ts
│ ├── entryTiming.ts
│ ├── patternClassify.ts
│ └── regimeDetection.ts
├── services/
│ └── ollamaClient.ts
└── prompts/
├── signalScoring.md
├── entryTiming.md
└── regimeDetection.md
n8n as AI Orchestration Layer
n8n is well-suited for non-real-time AI workflows that benefit from visual orchestration, scheduling, and webhook triggers. It would run as a docker-compose service alongside mi-casa and call both the Ollama API and mi-casa REST endpoints.
n8n is not currently in the stack — it requires a new docker-compose service entry.
Suggested workflows:
| Workflow | Trigger | Description |
|---|---|---|
| Daily Trading Report | Schedule 06:00 | Query DB → Ollama for narrative → send via Nodemailer |
| Weekly Optimisation Review | Schedule | Compare AI score vs trade outcomes; flag prompt drift |
| Pattern Alert Enrichment | Webhook from mi-casa | Receive pattern event → Ollama narrative → enrich notification |
| Backtest Insight | Webhook on backtest complete | LLM interprets results and suggests parameter changes |
| News Sentiment Feed | Schedule every 15 min | Fetch forex RSS → Ollama sentiment extraction → write to DB |
Model Selection
Target hardware: 12 GB VRAM.
| Model | Size | Latency | Quality | Notes |
|---|---|---|---|---|
| Mistral 7B | 3.5 GB | ~200 ms | Good | ⭐ Recommended starting point — well-tested on structured JSON tasks |
| Orca 2 7B | 3.5 GB | ~150 ms | Excellent | Fastest at quality; strong instruction following |
| Llama 3 8B | 4.7 GB | ~250 ms | Very Good | Strong reasoning; good JSON adherence |
| Llama 2 13B | 7.3 GB | ~400 ms | Better | Use when deeper context analysis is needed |
| Mixtral 8x7B | ~13 GB | ~800 ms | Best | Tight on 12 GB — test VRAM headroom before using |
Models are loaded via ollama pull <model> and swapped at runtime via the OLLAMA_MODEL env var. Start with Mistral 7B — good balance of speed, reliability, and structured JSON output.
Prompt Engineering Strategy
Use structured, role-prefixed prompts that always request a JSON response. This avoids the need to parse free-form prose and makes response validation straightforward.
Example — Signal Scoring Prompt
You are an expert forex harmonic pattern trader.
PATTERN:
- Type: {patternType}
- Direction: {direction}
- Fibonacci Ratios: {ratios} (ideal: {idealRatios})
- Signal Score (classic): {signalScore}
- RSI at D: {rsiValue}
- Market Regime: {regime}
RECENT CANDLES (last 5):
{candleJson}
Rate the quality of this pattern and its probability of reaching TP1.
Respond ONLY with JSON:
{
"score": <0-100>,
"grade": "poor|fair|good|excellent",
"risks": ["<risk1>", "<risk2>"],
"confidence": "low|med|high"
}Key Principles
| Principle | Detail |
|---|---|
| Always request JSON | Avoids prose parsing; validate with a JSON schema or simple type check |
| Anchor on the classic score | Including signalScore (classic) lets the model calibrate relative to the deterministic baseline |
| Keep tokens under 600 | Controls per-request latency; use abbreviated candle representations |
| Never include user data | Only send pattern coordinates, Fibonacci ratios, and technical indicators — never user IDs, account balances, trade history, or strategy names |
| Version your prompts | Store prompt templates as files (e.g., prompts/signalScoring.md) and version them in git so changes are traceable |
Score Blending
function blendScores(classicScore: number, aiScore: number | null): number {
if (aiScore === null) return classicScore; // graceful fallback
return classicScore * 0.6 + aiScore * 0.4; // 60/40 — AI is experimental
}As confidence in LLM scoring grows — validated against closed-trade outcomes — shift the weighting progressively toward the AI score. Treat the weighting ratio as a configurable parameter (e.g., stored in trading config) rather than a hard-coded constant.
Performance & Resource Considerations
| Concern | Guidance |
|---|---|
| Acceptable use | Async background scoring, user-triggered analysis, hourly regime detection |
| Not suitable | Real-time every-tick processing, live candle streaming |
| Batching | Collect 5–10 patterns then score together to amortise model overhead |
| Caching | Cache scores for identical pattern + indicator fingerprints (same coordinates, same candle context) |
| Rate limiting | Cap at ~20 LLM requests/minute per model instance |
| Circuit breaker | Always fall back to the classic score if Ollama is unavailable or times out — use a 5 s hard timeout |
The circuit breaker is non-negotiable: the auto-trade engine must never block on an LLM response. The classic score is the ground truth; the AI score is an enhancement.
Monitoring & Feedback Loop
Track these metrics to validate LLM value over time and catch prompt drift:
| Metric | Description |
|---|---|
signal_score_impact | Average P&L of trades with composite score vs trades with only classic score |
entry_timing_accuracy | Percentage of AI-recommended entries that fell in the top P&L quartile |
regime_detection_accuracy | Backtest-derived regime label vs ground truth classification |
prediction_latency | P50 / P95 / P99 Ollama response times |
fallback_rate | Percentage of requests where Ollama was skipped (timeout or circuit open) |
Log Schema
Log each LLM call immediately:
{
symbol: string,
patternType: string,
classicScore: number,
aiScore: number,
latency_ms: number,
model: string,
promptVersion: string
}When the trade closes, append the outcome:
{
outcome: 'win' | 'loss' | 'breakeven',
pnlPips: number,
accuracy: number // aiScore alignment with outcome
}This produces a labelled dataset for iterative prompt improvement and, eventually, fine-tuning.
Security & Privacy
Since Ollama runs locally on the same server, the privacy posture is strong by default:
| Property | Status |
|---|---|
| Market data leaves the server | ✅ Never |
| Trading strategy exposed to third parties | ✅ Never |
| Third-party API keys required | ✅ Not required |
| GDPR / privacy compliance | ✅ Fully compliant |
| Model auditability | ✅ Open-source, runnable offline |
Prompt sanitisation rule: only send pattern coordinates, Fibonacci ratios, and technical indicators to the LLM. Never include user IDs, account balances, trade history, or strategy configuration details in any prompt.
What Ollama Won’t Cover
LLMs are not the right tool for every AI-adjacent problem in trading. The table below maps alternative approaches to the gaps:
| Need | Recommended Tool | Notes |
|---|---|---|
| Time-series price forecasting | Prophet, LSTM, Chronos | LLMs are not suited for sequence prediction over raw price data — use dedicated forecasting models, runnable on GPU via Python |
| Semantic pattern search | nomic-embed-text (via Ollama) | Embeddings for “find historically similar patterns” — medium effort, high value once the pattern history is large enough |
| Fine-tuning on own trade data | LoRA fine-tune on Colab/RunPod → export GGUF → import into Ollama | Train on closed-trade outcomes for a specialised scorer; the resulting model runs locally like any other Ollama model |
| Cloud API fallback | OpenAI / Anthropic | Easy opt-in via OLLAMA_ENDPOINT override; ensures availability when the local instance is under load |
| Scheduled & event-driven AI workflows | n8n (docker-compose) | Visual orchestration without custom glue code — see n8n as AI Orchestration Layer |
Recommended Implementation Phases
Phase 1 — Foundation
- Add
OLLAMA_ENDPOINTandOLLAMA_MODELto.env.exampleandbun-env.d.ts - Create
backend/services/ollamaClient.ts— thin wrapper with 5 s timeout, circuit breaker, and graceful fallback tonull - Write unit tests for the Ollama client using mocked responses
- Confirm Mistral 7B runs on the target server and returns valid JSON for a test prompt
Deliverable: a tested, production-safe Ollama client with no impact on existing features.
Phase 2 — Signal Score Enhancement
- Add
aiScoreandcompositeScorecolumns to theohlcPatternsschema (nullable; migration required) - Hook async LLM scoring into the pattern detection pipeline in
ohlc-service - A/B test on historical data: compare
compositeScorevsclassicScorevs actual trade outcomes - Surface
compositeScorein the pattern overlay and the analytics dashboard
Deliverable: live AI-enhanced scoring with measurable P&L comparison.
Phase 3 — Entry Timing
- Build
entryTimingServicewith its own prompt template - Add an advisory card to the pattern detail view in the UI
- Log recommendations vs actual entry outcomes for the feedback loop
Deliverable: actionable entry timing guidance for the paper auto-trader.
Phase 4 — Market Regime Detection
- Add
market_regimestable to the schema - Run hourly regime classification per symbol × timeframe
- Weight signal scores by regime in the composite score calculation
- Show the current regime badge in the UI per symbol/timeframe header
Deliverable: context-aware scoring that suppresses low-quality signals in choppy conditions.
Phase 5 — Parameter Optimisation
- Wrap the grid search with a Bayesian/LLM-guided next-step suggestion loop
- Compare convergence speed vs the current pure grid search on historical data
- Document prompt templates for parameter suggestion in
prompts/
Deliverable: faster optimisation convergence; same quality results in fewer iterations.
Phase 6 — n8n Workflows
- Add n8n to
docker-composewith persistent volume for workflow storage - Build the daily report workflow (DB query → Ollama narrative → Nodemailer)
- Build the pattern alert enrichment webhook workflow
Deliverable: automated, LLM-authored trading reports delivered by email on schedule.