
By Yuvraj Singh Hajari
This article is provided for educational and informational purposes only and does not constitute investment advice, a recommendation, or an offer to buy or sell any security. The securities, trading signals, strategies, and AI-generated outputs shown are illustrative only. Alpaca does not recommend any security or investment strategy.
AlphaDesk is an independent educational project created by the author. All orders, positions, account information, trading activity, and results shown were generated in Alpaca’s paper-trading environment. They do not reflect actual trading or actual customer results. Paper trading is a simulation and may not account for market impact, liquidity, slippage, order priority, price availability, latency, regulatory restrictions, or other conditions affecting live trading. Automated and AI-assisted trading systems involve risks, including inaccurate or incomplete data, model errors, software failures, cybersecurity events, and unintended orders. AI-generated outputs should not be relied upon as investment recommendations.
This article reflects the author’s personal experience and opinions, which do not necessarily reflect the views of Alpaca. The author’s experience may not be representative of other customers and is not a guarantee of future performance or success. The author did not receive monetary compensation for this article but received promotional items of nominal value from Alpaca.
Personal Statement: Why I Built AlphaDesk
If you've ever watched The Big Short or The Wolf of Wall Street and come away thinking, “I need to understand how this massive, chaotic financial machine actually works under the hood,” you're not alone. I'm a fairly serious film buff, and while the arrogant brokers, the shouting on the trading floor, and the dramatic phone calls make for great cinema, what actually hooked me wasn't the drama. It was the sheer scale and technical complexity of the money moving around underneath it.
I'll be honest: I'm more drawn to the mechanics of finance than to software engineering for its own sake, even though I don't come from a quantitative or economics background. I'm a Computer Science student. But I knew that if I wanted a shot at a firm like J.P. Morgan, Barclays, or a serious quant fund, I couldn't just walk into an interview and talk about my interest in fintech or quote Michael Burry. I had to build something that proved I actually understood the ecosystem.
That's what led me to design and build AlphaDesk, an automated, multi-agent AI trading platform that monitors the market, processes information about current events, applies predefined risk controls, and is designed to generate simulated trade outputs programmatically. Rather than requiring manual order entry for each simulated transaction, the system uses an orchestrated set of agents running on a server to generate simulated trading decisions and submit simulated orders through Alpaca’s paper-trading environment.
In this piece, I'll walk through the whole build: how I went from standard classroom assignments to designing a multi-agent trading pipeline, a challenging 48-hour deployment stretch, the architecture underneath the system, and how Alpaca's developer APIs were integrated into the project’s simulated trading workflow.
The Genesis: A Computer Science Student Looking for the Ultimate Test
I'm Yuvraj. I'm a final-year Computer Science and Engineering student at the Vellore Institute of Technology (VIT) in India.
My approach to learning has always been project-based: find a stack or domain I know nothing about, panic a little, and then force myself to build something around it until I actually understand it. That's led to a fairly unconventional portfolio over the years. For a global-warming class, I trained ML models on climate datasets to build a real-time deforestation visualizer. For another project, I built AWS-based RAG pipelines to tackle language barriers in classrooms, so students could query localized educational content instantly.
But looking at the broader tech landscape, fintech stood out to me as an interesting technical challenge. The engineering problems associated with algorithmic trading (algorithmic trading fault tolerance, strict state management, time-series data at scale) can differ significantly from what you run into building a typical web app or social platform.
So I knew my capstone project had to live in this space. But I didn't want to write a Python script that computes a 50-day moving average and buys when one line crosses another. That's been done a million times. I wanted a system that could process multiple market inputs programmatically and use them to generate hypothetical trading decisions. I wanted to build the actual plumbing of a modern, AI-driven trading system.
The system I had in mind would read the news, gauge macro sentiment, run the technical numbers, check the portfolio's risk budget, and then generate a hypothetical BUY, SELL, or HOLD output, all within seconds.
Discovering the Missing Piece: Why Alpaca?
I had the architecture mapped out in my head. I knew the pieces I needed:
- A source for historical and real-time market data.
- A vector database to store and query news sentiment.
- A fast LLM to act as the decision-making “brain.”
- An API that could submit simulated orders in a paper-trading environment.
I knew how to handle the AI and the databases, but I had no idea where to get the financial plumbing. I didn't know which brokerages offered developer APIs and a paper-trading environment suitable for an educational project.
So I opened Claude and Gemini and just asked: "I'm building an automated AI trading system, where do I get the API services for this? I need market data and execution."
Both gave me a handful of traditional brokerages and data aggregators to look at. But going through the documentation for each one, Alpaca stood out to me.
From my perspective as a developer comparing the available options, Alpaca's documentation and API design stood out. Alpaca felt like it was built by engineers, for engineers. I found the documentation clear, and the paper-trading environment allowed me to test the project without using real money or submitting orders to the live securities market.
I was able to sign up, generate API keys, and pull historical data into my terminal as part of my initial setup. For my use case, I could work with predictable REST endpoints and WebSocket streams. Alpaca was a good fit for the project I wanted to build.
Architecting AlphaDesk: The Multi-Agent Pipeline
When I sat down to design the core logic, it became obvious fast that a single monolithic script would be difficult to manage. Hand an LLM a giant prompt and tell it to “trade stocks” and it can generate inaccurate or unreliable outputs that could result in unintended trading decisions.
What I needed was a strict separation of concerns. The system had to separate different functions, where quants compute the math, risk managers check the budget, researchers read the news, and a portfolio manager makes the final call. And it had to happen in the same deterministic order, every 5 minutes, without exception.
To orchestrate this, I used LangChain's LangGraph. It let me build the trading pipeline as a state machine: every 5 minutes, a cron job fires and initializes a state dictionary, which then moves down an assembly line of specialized Python nodes, each one a distinct agent.
Here's how a single cycle flows:
1. The Signal Node (The Quant)
First stop on the line, and it's pure, emotionless math. This node pulls the latest 5-minute OHLCV bars from Alpaca's Market Data API for my configured universe (AAPL, NVDA, TSLA, MSFT, AMZN), then computes a suite of technical indicators: RSI, SMA, EMA, Bollinger Bands.
The securities and technical indicators identified in this example were selected solely to illustrate the operation of the author’s simulated system. They are not recommendations by the author or Alpaca to buy, sell, or hold any security.
The goal isn't to make a final call, just to flag potential technical conditions within the simulation such as whether the system identifies an asset as oversold or detects a potential moving-average crossover. Those signals are packaged into the state dictionary and passed forward.
2. The Risk Node (The Bouncer)
Before the AI gets to do anything interesting, the state passes through the Risk Node, arguably the most important node in the whole system, since it is designed to reduce the risk of unintended AI-generated actions.
This node checks my Alpaca paper trading account via the Trading API for simulated buying power, existing simulated positions, and simulated portfolio drawdown, and applies predefined rules independently of the LLM's output. If RSI is extreme, it can flag the asset as overbought and block further BUY signals. If a sector has hit its risk budget, the node vetoes the simulated trade.

Notice the orange BLOCKED tags for TSLA and MSFT above. Within this simulation, the system recognized that there was no existing TSLA position to sell, so it skipped the short signal rather than acting on it. That's the hard-coded guardrail operating as programmed. The pipeline isn't designed to automatically submit a simulated order based on every model-generated output.
3. The Sentiment Node (The Qualitative Engine)
Where the Signal Node looks at the past, the Sentiment Node looks at the present: the macro and company-specific narrative driving the market right now.
For this I built a RAG (Retrieval-Augmented Generation) pipeline. Throughout the day, AlphaDesk ingests live financial news, converts headlines and article snippets into vector embeddings, and stores them in Pinecone, a scalable vector database.
When the Sentiment Node picks up the state for a given ticker (NVDA, say), it queries Pinecone for the most relevant articles from the past 24 hours, pulls that context, and scores overall sentiment as bullish, bearish, or neutral.

As shown above, the system pulls in article content, scores each item, and rolls those scores into a sentiment gauge that is incorporated as an input to the model. The resulting sentiment score may be inaccurate or incomplete and should not be relied upon when making an investment decision.
4. The Decision Node (The Brain)
This is where it comes together. By the time the state dictionary reaches the Decision Node, it's carrying technical indicators, risk constraints, and vector-searched news sentiment all at once.
This node formats all of that into an engineered prompt and sends it to Llama-3.3-70b, an open-source LLM. Routing this through a standard API would add too much latency (in trading, waiting 10 seconds for a response isn't acceptable), so I host the model on Groq, which uses purpose-built LPUs to get sub-second inference.
The LLM is used as the decision-generating component within the simulation. It processes the prompt, evaluates conflicting inputs, such as bearish technical indicators, bullish news sentiment, and the availability of a programmed risk budget, and returns a structured JSON output of BUY, SELL or HOLD, together with a plain-English rationale.

You can see the generated rationale laid out above: “Given the budget exhaustion and the mildly positive news sentiment, it's best to hold the current position.” Watching the system generate a HOLD output in circumstances like this, in real time, is one of the more satisfying parts of the whole build.
*The rationale is generated by the model and may be inaccurate, incomplete, or unsuitable for actual trading.
5.The Simulated-Order Submission Node
If the Decision Node returns a BUY or SELL and the Risk Node hasn't vetoed it, the state reaches the Simulated-Order Submission Node. This node turns the JSON output into a payload and submits it to Alpaca's Paper Trading API. Using the alpaca-py SDK, it submits a market order for the calculated quantity, the Paper Trading API simulates the order and resulting fill, and the node logs everything back into the database.
Data Persistence and Real-Time Streaming: The Underlying Infrastructure
Building the agentic pipeline was only half the job. A trading system simulator also needs a backend that can store historical data, track performance, and stream updates to the UI in real time.
For persistence I went with PostgreSQL, extended with TimescaleDB. Market data is inherently time-series: every minute bar, every fill, every NAV snapshot needs to be indexed by timestamp. For this project, I used TimescaleDB hypertables to partition the data across time intervals and support time-series queries. I set up dedicated hypertables for market_bars, trade_fills, and agent_logs.
Every time the The Simulated-Order Submission Node completes a trade, it writes the fill price, quantity, Alpaca paper-order ID, and the model's rationale straight into the TimescaleDB ledger.
To keep the frontend from constantly polling the database, I added Redis as a pub/sub broker. When a node in the LangGraph pipeline finishes its work, it publishes to a Redis channel; the FastAPI backend subscribes and pushes the update over WebSockets to the Next.js 15 frontend.
That's the piece that makes the platform feel alive. I can open the dashboard and watch the Cognitive Console fill in with the model's reasoning in real time, entirely asynchronously.
The 48-Hour Deployment Nightmare
If you've built a complex side project solo, you already know the particular pain of deployment. Building on localhost is fun. Putting it on the internet is a different story.
With Next.js on Vercel, the front-end deployment was straightforward. I connected the GitHub repo, hit deploy, and the dashboard was live within minutes.
The backend deployment presented immediate technical challenges.
Orchestrating a containerized FastAPI server, a TimescaleDB instance, and a Redis broker on Railway turned into a genuinely grueling 48 hours. A stateful, cron-driven agent pipeline needs everything talking to everything else, correctly, all the time.
I spent two days straight debugging Dockerfiles, chasing why database connections kept timing out mid-LangGraph-run, and trying to keep the Redis channels from dropping WebSocket connections. The model would generate a decision, and then the execution node would crash because the DB connection had already timed out thirty seconds earlier.
After about 48 hours of staring at crash loops at 3 AM, I gave up for the night.
A few hours of sleep and a rewrite of the connection-pooling logic using SQLAlchemy's async engine later, it was finally stable.
Even so, I'll admit that running something this heavy on the free tier of a cloud host keeps me a little paranoid. A cron-driven state machine hitting an LLM and a database every 5 minutes isn't light, and I'm always half-expecting the backend to fall over from inactivity limits or memory pressure. It was a good lesson though: building the initial trading logic was only one part of the challenge. Hosting, monitoring, and maintaining a distributed trading system introduced a different set of engineering and operational considerations.
Under the Hood: Code Implementation and Alpaca Integration
To make the architecture concrete, here's some of the actual implementation. I deliberately avoided community wrapper libraries and stuck with Alpaca's official Python SDK (alpaca-py). The native classes are clean enough that there was no real reason to reach for anything else.
Fetching Historical Data
Everything starts with data ingestion. Before the Signal Node can compute RSI or moving averages, it needs clean historical bars. Here's the module that pulls 5-minute bars from Alpaca, shaped for downstream pandas work:
# data_ingestion/alpaca_market_data.py
import os
import pandas as pd
from datetime import datetime, timedelta
from alpaca.data.historical import StockHistoricalDataClient
from alpaca.data.requests import StockBarsRequest
from alpaca.data.timeframe import TimeFrame
class AlpacaMarketData:
def __init__(self):
"""
Initialize the Alpaca StockHistoricalDataClient using environment variables.
Requires ALPACA_API_KEY and ALPACA_SECRET_KEY to be set.
"""
self.api_key = os.getenv('ALPACA_API_KEY')
self.secret_key = os.getenv('ALPACA_SECRET_KEY')
if not self.api_key or not self.secret_key:
raise ValueError("Alpaca API credentials are missing from environment variables.")
self.stock_client = StockHistoricalDataClient(
api_key=self.api_key,
secret_key=self.secret_key
)
def get_5min_bars(self, symbol: str, lookback_days: int = 5) -> pd.DataFrame:
"""
Fetch OHLCV bars for the given symbol to feed the Signal Node.
Args:
symbol (str): The stock ticker (e.g., 'AAPL')
lookback_days (int): How many days of historical data to retrieve.
Returns:
pd.DataFrame: A pandas DataFrame containing the historical bars.
"""
end_date = datetime.now()
start_date = end_date - timedelta(days=lookback_days)
request_params = StockBarsRequest(
symbol_or_symbols=symbol,
timeframe=TimeFrame.Minute,
start=start_date,
end=end_date
)
try:
bars = self.stock_client.get_stock_bars(request_params)
df = bars.df
if not df.empty:
df.reset_index(inplace=True)
return df
except Exception as e:
print(f"Error fetching data from Alpaca for {symbol}: {str(e)}")
return pd.DataFrame()
if __name__ == "__main__":
fetcher = AlpacaMarketData()
print("Fetching Alpaca market data for pipeline initialization...")
aapl_df = fetcher.get_5min_bars("AAPL", lookback_days=2)
print(aapl_df.tail())Orchestrating the State Machine with LangGraph
Once the data is fetched, it gets injected into the LangGraph state. What I like about LangGraph is how explicit it makes the edges and conditional routing of the workflow.
I'm not sharing the actual prompts used in the Decision Node, but here's a stripped-down look at how the assembly line is defined:
# agents/graph.py
from langgraph.graph import StateGraph, END
from typing import TypedDict, Dict, Any
import pandas as pd
# Define the state dictionary that will pass between nodes
class AgentState(TypedDict):
symbol: str
market_data: pd.DataFrame
technical_signals: Dict[str, Any]
risk_approved: bool
sentiment_context: str
decision: Dict[str, str]
# Initialize the StateGraph with our custom State schema
workflow = StateGraph(AgentState)
# Node Definitions (abstracted for brevity)
def compute_technical_signals(state: AgentState) -> AgentState:
# Uses Alpaca data to calculate RSI, MACD, etc.
return state
def check_alpaca_buying_power(state: AgentState) -> AgentState:
# Queries Alpaca API for account balance and enforces risk guardrails
return state
def fetch_pinecone_news(state: AgentState) -> AgentState:
# Queries Pinecone vector DB for relevant news embeddings
return state
def generate_llm_decision(state: AgentState) -> AgentState:
# Prompts Groq/Llama-3 with the accumulated state to generate BUY/SELL/HOLD
return state
def execute_alpaca_trade(state: AgentState) -> AgentState:
# If approved, sends a MarketOrderRequest via Alpaca Trading API
return state
def should_execute_trade(state: AgentState) -> str:
# Conditional edge logic based on the LLM's JSON output
decision = state.get("decision", {}).get("action", "HOLD")
if decision in ["BUY", "SELL"] and state.get("risk_approved") == True:
return "execute"
return "hold"
# Graph Assembly (defining the assembly line)
workflow.add_node("signal_node", compute_technical_signals)
workflow.add_node("risk_node", check_alpaca_buying_power)
workflow.add_node("sentiment_node", fetch_pinecone_news)
workflow.add_node("decision_node", generate_llm_decision)
workflow.add_node("execution_node", execute_alpaca_trade)
# Standard, sequential flow
workflow.add_edge("signal_node", "risk_node")
workflow.add_edge("risk_node", "sentiment_node")
workflow.add_edge("sentiment_node", "decision_node")
# Conditional routing based on the LLM's final decision
workflow.add_conditional_edges(
"decision_node",
should_execute_trade,
{
"execute": "execution_node",
"hold": END
}
)
workflow.add_edge("execution_node", END)
workflow.set_entry_point("signal_node")
app = workflow.compile()Submitting a Simulated Order
Finally, if the model generates an eligible BUY or SELL output, the Simulated-Order Submission Node uses the Alpaca Trading API. The alpaca-py SDK makes submitting orders straightforward, abstracting away the REST headers and payload formatting entirely:
# agents/execution_node.py
from alpaca.trading.client import TradingClient
from alpaca.trading.requests import MarketOrderRequest
from alpaca.trading.enums import OrderSide, TimeInForce
def execute_alpaca_trade(state: AgentState) -> AgentState:
"""
Final node in the LangGraph pipeline. Sends the order to Alpaca.
"""
action = state["decision"].get("action")
symbol = state["symbol"]
quantity = state["decision"].get("quantity", 1)
# Initialize the Trading Client (paper=True for simulation)
trading_client = TradingClient(api_key=API_KEY, secret_key=SECRET_KEY, paper=True)
try:
order_side = OrderSide.BUY if action == "BUY" else OrderSide.SELL
market_order_data = MarketOrderRequest(
symbol=symbol,
qty=quantity,
side=order_side,
time_in_force=TimeInForce.DAY
)
market_order = trading_client.submit_order(order_data=market_order_data)
print(f"Submitted {action} order for {quantity} shares of {symbol}. Order ID: {market_order.id}")
except Exception as e:
print(f"Failed to execute trade for {symbol}: {str(e)}")
return stateThis is exactly why I chose Alpaca. When most of your attention is going toward LLM prompts, vector embeddings, and LangGraph orchestration, the last thing you want is to also be fighting your broker's API. For this educational project, I found Alpaca's API straightforward to integrate into the rest of my stack.
What’s Next
This project demonstrated a prototype of a multi-agent AI pipeline capable of generating trading outputs autonomously in a simulated environment, but it's far from finished. Before I'd consider evaluating it for use with real capital, AlphaDesk needs some serious upgrades.
Here's what I'm planning next:
- Move to live WebSocket streaming: Right now the whole pipeline polls 5-minute bars over REST. Integrating Alpaca's WebSocket streams, and reacting to more frequent data updates could reduce the delay between the simulation’s receipt of market data and its response. More frequent data does not ensure improved execution quality, accuracy, or trading performance.
- Deepen the domain expertise: I'm a computer science student, not a quant researcher. The software side of AlphaDesk (sub-second inference, vector search, state management) is solid, but the actual signal math (basic RSI and moving averages) is elementary. The obvious next step is finding someone with real financial domain expertise to build out more sophisticated alpha models.
- Build out risk modeling: The Risk Node currently runs on static, hard-coded guardrails. I'd like to add dynamic volatility scaling, ATR or GARCH-based, so the system can adjust position sizing based on predefined volatility metrics.
- Evaluate potential live use: Once the logic is further developed, bugs are addressed, and the system has been backtested across a wider range of market conditions, one potential future step would be evaluating whether it is appropriate for live trading.
Note: AlphaDesk is an educational simulation and does not provide investment advice or recommendations or guarantee any trading outcome. Paper trading is a simulation and may not account for all conditions that affect actual trading, including market impact, liquidity, slippage, order priority, price availability, and latency. Automated and AI-assisted trading systems involve risks, including model errors, inaccurate or incomplete data, software failures, cybersecurity events, and unintended orders. Users are responsible for evaluating, testing, monitoring, and implementing appropriate controls for their trading systems.
What I’d Build Differently
Building AlphaDesk was the most challenging and, honestly, the most rewarding project of my academic career so far. It confirmed for me that I want to work at the intersection of serious software engineering and financial markets.
Over a few months this forced me to figure out how to run deterministic code alongside probabilistic AI models, manage stateful deployments on real cloud infrastructure, and integrate with financial APIs without the whole thing falling over.
Alpaca gave me the developer-first building blocks to take a fairly ambitious idea and turn it into a functioning, automated trading system prototype in a simulated environment. If you're trying to break into fintech or algorithmic trading, my experience shows one way a student developer can start learning about the technical infrastructure behind algorithmic trading. For me, a solid architectural plan, a developer-friendly API like Alpaca, and enough patience to survive a few 3 AM deployment crashes made it possible to build and test the project.
Additional Alpaca Resources
If you want to learn about building and testing a simulated trading application, here are the resources I found most useful:
- Alpaca Trading API (docs.alpaca.markets/docs/trading-api) is the place to start. The paper trading quickstart provides instructions for submitting simulated orders.
- Alpaca Market Data API (docs.alpaca.markets/docs/about-market-data-api) provides the historical and real-time data that powers everything. For this project, I used the available market-data functionality to get started.
- Alpaca Paper Trading (docs.alpaca.markets/docs/paper-trading) lets you test trading applications using simulated funds before considering live deployment. Paper trading is a simulation and does not replicate all conditions or risks associated with live trading.
About the Author
My name is Yuvraj Singh Hajari, I'm 21, and I live in India. I am a final-year Computer Science and Engineering student at the Vellore Institute of Technology. I've recently completed a Summer 2026 internship at Toshiba in its R&D department. I constantly draw inspiration from different domains like sports, finance, and classroom environments to build projects across Cloud, AI-ML, Full-Stack, and Computer Vision. My work ranges from AWS projects, RAG pipelines and legal voice agents to CV-based green cover monitoring systems, culminating most recently in the fintech space with AlphaDesk. When I am not working on a project, I'm usually watching movies as it's my greatest hobby. My favourite movies are The Social Network and Mr. & Mrs. Smith. If not that then I'm catching up on Premier League highlights, or supporting FC Barcelona. For the record, I have been a Barça fan since childhood, so I promise I am not just saying that because of Alpaca's ties to Catalonia.
**The Paper Trading API is offered by AlpacaDB, Inc. and does not require real money or permit a user to transact in real securities in the market. Providing use of the Paper Trading API is not an offer or solicitation to buy or sell securities, securities derivative or futures products of any kind, or any type of trading or investment advice, recommendation or strategy, given or in any manner endorsed by AlpacaDB, Inc. or any AlpacaDB, Inc. affiliate. Information made available through the Paper Trading API is not an offer or solicitation of any kind in any jurisdiction where AlpacaDB, Inc. or any AlpacaDB, Inc. affiliate is not authorized to do business.
Alpaca is not affiliated with the third-party companies, platforms, or projects referenced in this article. Each party is responsible for its own products, services, and liabilities.
Alpaca may have reviewed or edited this article for clarity, accuracy, or compliance. Publication does not constitute Alpaca’s endorsement of AlphaDesk, its trading methodology, any AI-generated output, or any third-party product or service referenced in the article. Alpaca does not guarantee the accuracy, timeliness, completeness, or usefulness of information supplied by the author or other third parties.
All investments involve risk, including the possible loss of principal. Past performance does not guarantee future results, and there is no guarantee that any investment strategy will achieve its objectives. Past hypothetical backtest results do not guarantee future returns, and actual results may vary from the analysis. Any symbols or examples shown are for demonstration purposes only and do not constitute investment advice or a recommendation to buy or sell any security.
Securities brokerage services are provided by Alpaca Securities LLC (dba "Alpaca Clearing"), member FINRA/SIPC, a wholly-owned subsidiary of AlpacaDB, Inc. Technology and services are offered by AlpacaDB, Inc.
This is not an offer, solicitation of an offer, or advice to buy or sell securities or open a brokerage account in any jurisdiction where Alpaca Securities is not registered or licensed, as applicable.