CanvestAI

ETF research for Canadian retail investors, rebuilt as two systems over one SQLite database. A nightly pipeline scores 16 equity sectors through eight weighted lenses, then deliberates over the result. A LangGraph advisor answers questions by fanning out to four discipline agents per turn. Every recommendation is graded again once its horizon elapses, and each lens is graded on its own, so the weights have to earn themselves.

August 25, 2026

Overview

Canadian retail investors work from scattered data, opaque fees, and generic advice that ignores their risk tolerance and tax situation. CanvestAI started as a set of composable ETF-scoring skills run from a terminal. It is now two systems sharing one SQLite database. The split matters because the part that must run unattended does not depend on the part that talks.

The nightly pipeline uses no LLM at all. It is cron-safe Python and bash. The conversational orchestrator sits on top and reads the pipeline output through a read-only MCP surface, adding live market and web data at question time. If the orchestrator goes down, the pipeline still produces its verdicts. If a data feed goes down, the pipeline degrades that one lens and still finishes the night.

The nightly pipeline

Eight lens agents score 16 equity sectors in parallel. Each carries a fixed weight: technical (0.25), business cycle (0.20), monetary policy (0.15), astro (0.15), geopolitical (0.10), sentiment (0.08), social media (0.05), and numerology (0.02). A deliberation agent combines them into a weighted score. It also detects conflict between lenses and keeps a dissent log. That makes a verdict that looks confident only because seven lenses stayed quiet easy to tell apart from one where the lenses actually agreed.

Ephemeris data, charts, and the Vedic lens no longer live in this repo. They were extracted into a separate astro agent reached over A2A, with a single client module in CanvestAI speaking that protocol.

Verdicts go into a recommendations table and are then graded. Once a recommendation reaches its horizon, the outcome is scored against what happened. Each lens is scored separately, at its own horizon. That is what keeps the weights honest: a lens carrying 0.25 of the vote has a track record you can read.

The conversational orchestrator

  • LangGraph supervisor spine: fold memory, route the turn, then either clarify, answer directly, or run the full chain.
  • A recommendation turn fans out to four discipline agents in parallel: fundamental, technical, astro, and research. The results then join, deliberate, rank ETFs in code, produce a recommendation, and challenge it before composing a reply.
  • Ranking stays in code rather than in a prompt, so the same inputs produce the same ordering and the step is testable.
  • A dedicated challenge agent argues against the recommendation before the user sees it.
  • Narrow routes skip the deliberation chain entirely: research only, astro only, sky only, and portfolio review. None of them pays for a fan-out that has nothing to merge.
  • Agents are reached only through an A2A seam. No graph node imports an agent directly.
  • Every turn has a cost ceiling. A callback meters real token usage and prices it live. On a hard breach, nodes degrade to no-ops and record themselves, so the turn still reaches a reply built from whatever was gathered.

Status

Both systems run. The pipeline scores sectors nightly and grades its own past calls; the orchestrator answers turns end to end.

The open problem is trade construction rather than signal generation. Paper-trading results stay off the public dashboard because the engine books positions the target account cannot place. A bearish sector view was being written as a direct index short instead of an instrument the account can actually buy. Until that is fixed, the recorded P&L measures the modelling error more than the model.

Code and related repositories