AI for Stock Market: How I Built an AI Trading Assistant for NSE Using Local LLMs
DOYR | Not financial/legal/tax advice. For educational purposes only.
Most AI trading articles are written by people who have never placed a trade. They'll show you a fancy LSTM model with 99% backtest accuracy and promise millions. Then you try it live and lose everything.
This article is different. It's written by someone who actually trades Indian markets, runs an open-source AI trading project on Android, and has seen what works and what doesn't.
This is not a "get rich with AI" guide. This is a practical breakdown of how I built nse_ai_agent — an AI trading assistant that runs on my phone, uses local LLMs for sentiment analysis, and helps me make better decisions without replacing my judgment.
1. The Problem with Traditional Trading Tools
Before building AI tools, I used everything available to Indian retail traders:
| Tool | Problem |
|---|---|
| Zerodha Pi | Windows-only, closed-source, no AI integration |
| Upstox Pro | Web-based, clunky, no automation |
| TradingView | Great charts, but AI/sentiment = paid features |
| Bloomberg Terminal | ₹50,000+/year. Not for retail |
| Telegram tip groups | 99% are scams |
| Paid algo platforms | Black-box logic. You don't know what's happening |
The Core Problem
No tool combines:
- NSE-specific data
- AI/ML analysis
- Mobile accessibility
- Open-source transparency
- Zero cost
So I built one.
2. Why Local LLMs? Not OpenAI, Not Claude
Most "AI trading" articles recommend GPT-4 or Claude for sentiment analysis. I don't.
Problems with Cloud LLMs for Trading
| Problem | Why It Matters |
|---|---|
| Latency | API call = 500-2000ms. In trading, seconds matter. |
| Cost | GPT-4 API = ₹1-5 per 1K tokens. Daily trading = ₹100-500/month. |
| Privacy | Your trading data leaves your device. |
| Dependency | API down = no analysis. |
| Rate limits | Can't analyze 100 news articles fast enough. |
Why Local LLMs Win
| Advantage | Explanation |
|---|---|
| Zero latency | Runs on device. No API call. |
| Zero cost | Ollama + Llama 3.2 = free. |
| Privacy | Data never leaves phone. |
| Unlimited | No rate limits. Analyze 1000 news articles if needed. |
| Offline | Works without internet after model download. |
My Stack
Local LLM Options (ranked by performance):
1. Llama 3.2 (3B) — Fast, decent quality, 2GB RAM
2. Phi-3 Mini (3.8B) — Best quality/size ratio, 3GB RAM
3. Gemma 2B — Very fast, lower quality, 1.5GB RAM
4. Mistral 7B — Best quality, needs 8GB RAM (not for all phones)
For Termux/Android: Llama 3.2 3B or Phi-3 Mini = sweet spot.
3. Architecture of nse_ai_agent
System Design
┌─────────────────────────────────────────────┐
│ Android Phone │
│ │
│ ┌──────────────┐ ┌───────────────┐ │
│ │ Termux │ │ Ollama │ │
│ │ │─────▶│ (Local LLM) │ │
│ │ - Python │ │ Llama 3.2 3B │ │
│ │ - Cron │ │ Phi-3 Mini │ │
│ │ - Scripts │ └───────▲───────┘ │
│ └──────┬───────┘ │ │
│ │ │ │
│ ▼ │ │
│ ┌──────────────┐ │ │
│ │ NSE Data │ │ │
│ │ Fetcher │ │ │
│ └──────┬───────┘ │ │
│ │ │ │
│ ▼ │ │
│ ┌──────────────┐ │ │
│ │ Strategy │ │ │
│ │ Engine │ │ │
│ └──────┬───────┘ │ │
│ │ │ │
│ ▼ │ │
│ ┌──────────────┐ │ │
│ │ Telegram │◀────────────┘ │
│ │ Bot Alerts │ (sentiment analysis) │
│ └──────────────┘ │
│ │
└─────────────────────────────────────────────┘
Data Flow
1. Cron triggers at 9:15 AM (market open)
2. Fetcher pulls Nifty quote + option chain + top 20 news headlines
3. LLM analyzes headlines for bullish/bearish/neutral sentiment
4. Strategy engine combines:
- Technical signals (momentum, RSI, volume)
- LLM sentiment score
- Open interest data
5. Risk manager validates position size
6. If confidence > 70% → Telegram alert with reasoning
7. Trader reviews and decides manually
4. Building the LLM Sentiment Analyzer
Step 1: Install Ollama on Termux
# Install Ollama
curl -fsSL https://ollama.com/install.sh | sh
# Or via Termux
pkg install ollama -y
ollama serve &
Step 2: Download Model
# For phones with 4GB RAM
ollama pull llama3.2:3b
# For phones with 6GB+ RAM
ollama pull phi3:mini
Step 3: Sentiment Analysis Script
import requests
import json
from datetime import datetime
class LLMSentimentAnalyzer:
def __init__(self, model="llama3.2:3b"):
self.model = model
self.ollama_url = "http://localhost:11434/api/generate"
def analyze_news(self, headlines):
"""
Analyze list of news headlines for market sentiment.
Args:
headlines: List of strings
Returns:
dict with sentiment score, reasoning, and confidence
"""
prompt = f"""You are a financial sentiment analyzer for Indian stock markets.
Analyze these news headlines and provide:
1. Overall sentiment: BULLISH / BEARISH / NEUTRAL
2. Sentiment score: 1-10 (10 = extremely bullish)
3. Key reasoning in 2 sentences
4. Confidence: HIGH / MEDIUM / LOW
Headlines:
{chr(10).join(f"- {h}" for h in headlines)}
Respond in JSON format:
{{
"sentiment": "BULLISH/BEARISH/NEUTRAL",
"score": 1-10,
"reasoning": "2 sentences",
"confidence": "HIGH/MEDIUM/LOW"
}}"""
payload = {
"model": self.model,
"prompt": prompt,
"stream": False,
"options": {
"temperature": 0.1, # Low temp = consistent output
"num_predict": 200 # Short response
}
}
try:
response = requests.post(
self.ollama_url,
json=payload,
timeout=30
)
result = json.loads(response.text)
return json.loads(result['response'])
except Exception as e:
print(f"LLM analysis failed: {e}")
return {
"sentiment": "NEUTRAL",
"score": 5,
"reasoning": "LLM analysis unavailable",
"confidence": "LOW"
}
def analyze_with_fallback(self, headlines):
"""
Run LLM analysis with keyword fallback.
If LLM fails, use simple keyword matching.
"""
# Try LLM first
result = self.analyze_news(headlines)
if result['confidence'] == 'LOW':
# Fallback to keywords
bullish_words = ['surge', 'rally', 'gain', 'up', 'rise', 'positive', 'growth', 'profit']
bearish_words = ['fall', 'drop', 'crash', 'down', 'loss', 'negative', 'decline', 'fear']
bullish_count = sum(1 for h in headlines for w in bullish_words if w in h.lower())
bearish_count = sum(1 for h in headlines for w in bearish_words if w in h.lower())
if bullish_count > bearish_count:
result = {"sentiment": "BULLISH", "score": 6, "reasoning": "Keyword-based fallback", "confidence": "LOW"}
elif bearish_count > bullish_count:
result = {"sentiment": "BEARISH", "score": 4, "reasoning": "Keyword-based fallback", "confidence": "LOW"}
return result
# Usage
analyzer = LLMSentimentAnalyzer()
headlines = [
"Nifty opens higher on strong FII inflows",
"RBI keeps repo rate unchanged at 6.5%",
"IT stocks drag Nifty down amid global concerns",
"Q2 results: TCS beats estimates, Infosys misses",
"Rupee strengthens against dollar"
]
result = analyzer.analyze_with_fallback(headlines)
print(f"Sentiment: {result['sentiment']} ({result['score']}/10)")
print(f"Reasoning: {result['reasoning']}")
print(f"Confidence: {result['confidence']}")
5. Integrating Sentiment with Technical Analysis
The Hybrid Signal System
Don't rely on AI alone. Combine LLM sentiment with technical indicators.
class HybridSignalGenerator:
def __init__(self):
self.sentiment_analyzer = LLMSentimentAnalyzer()
self.technical_weight = 0.7 # Technical = 70% weight
self.sentiment_weight = 0.3 # Sentiment = 30% weight
def generate_signal(self, technical_signal, headlines):
"""
Combine technical and sentiment signals.
Args:
technical_signal: dict with 'signal' (BUY/SELL/HOLD) and 'confidence' (0-1)
headlines: List of news headlines
Returns:
Final signal with confidence
"""
sentiment = self.sentiment_analyzer.analyze_with_fallback(headlines)
# Convert sentiment to score
sentiment_score = sentiment['score'] / 10 # 0-1
# Convert technical signal to score
tech_score = technical_signal['confidence']
if technical_signal['signal'] == 'SELL':
tech_score *= -1
# Weighted combination
final_score = (tech_score * self.technical_weight) + (sentiment_score * self.sentiment_weight)
# Generate final signal
if final_score > 0.6:
final_signal = "STRONG BUY"
elif final_score > 0.3:
final_signal = "BUY"
elif final_score < -0.6:
final_signal = "STRONG SELL"
elif final_score < -0.3:
final_signal = "SELL"
else:
final_signal = "HOLD"
return {
'signal': final_signal,
'score': round(final_score, 2),
'technical': technical_signal['signal'],
'sentiment': sentiment['sentiment'],
'reasoning': sentiment['reasoning']
}
# Usage
generator = HybridSignalGenerator()
technical = {'signal': 'BUY', 'confidence': 0.8}
headlines = ["Nifty opens higher on FII inflows", "RBI maintains status quo"]
result = generator.generate_signal(technical, headlines)
print(f"Final Signal: {result['signal']}")
print(f"Score: {result['score']}")
print(f"Technical: {result['technical']} | Sentiment: {result['sentiment']}")
6. Real-World Example: nse_ai_agent in Action
Scenario: Budget Day 2026
Context: Union Budget announced on Feb 1, 2026. Market expectations mixed.
nse_ai_agent workflow:
9:00 AM: Cron triggers pre-market analysis
9:01 AM: Fetches top 20 news headlines about budget
9:02 AM: LLM analyzes headlines:
Headlines:
1. "No change in long-term capital gains tax" → POSITIVE
2. "Fiscal deficit target 5.1% vs expected 4.9%" → NEGATIVE
3. "Customs duty hiked on electronics" → NEGATIVE
4. "Rural allocation increased by 20%" → POSITIVE
5. "No income tax changes for middle class" → POSITIVE
LLM Output:
{
"sentiment": "BULLISH",
"score": 7,
"reasoning": "No tax changes = relief for middle class. Rural spending boost. Fiscal miss offset by growth focus.",
"confidence": "MEDIUM"
}
9:03 AM: Technical analysis:
- Nifty pre-market up 0.8%
- Bank Nifty up 1.2%
- PCR at 1.3 (bullish)
9:04 AM: Hybrid signal:
Technical: BUY (0.75 confidence)
Sentiment: BULLISH (0.7 score)
Final: STRONG BUY (0.73 score)
9:05 AM: Telegram alert sent:
"🚨 NIFTY SIGNAL: STRONG BUY
Price: 21,900 (+0.8%)
Technical: Momentum bullish
Sentiment: Bullish (7/10) — Budget relief, no tax changes
Confidence: 73%
Action: Buy Nifty 22,000 CE near 11 AM on confirmation"
12:30 PM: Manual review — signal confirmed
Order placed: Nifty 22,000 CE @ ₹145
Target: ₹200
Stop loss: ₹80
2:15 PM: Target hit at ₹198
Exit: ₹198 × 50 = ₹9,900
Profit: (198 - 145) × 50 = ₹2,650
7. Building a News Scraper for NSE
Fetching NSE News Headlines
import requests
from bs4 import BeautifulSoup
class NSENewsScraper:
def __init__(self):
self.base_url = "https://www.nseindia.com"
self.headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
def get_market_news(self, limit=20):
"""Get latest market news from NSE"""
url = f"{self.base_url}/api/news"
try:
response = requests.get(url, headers=self.headers, timeout=10)
data = response.json()
headlines = [item['headline'] for item in data['data'][:limit]]
return headlines
except Exception as e:
print(f"NSE news fetch failed: {e}")
# Fallback: Moneycontrol scraper
return self._moneycontrol_fallback(limit)
def _moneycontrol_fallback(self, limit=20):
"""Fallback news source"""
url = "https://www.moneycontrol.com/markets/indian-indices/"
response = requests.get(url, headers=self.headers, timeout=10)
soup = BeautifulSoup(response.text, 'lxml')
headlines = []
for item in soup.select('.gutter_box .grey_text')[:limit]:
headlines.append(item.text.strip())
return headlines
# Usage
scraper = NSENewsScraper()
headlines = scraper.get_market_news(20)
print("\n".join(headlines))
8. Performance: Does It Actually Work?
My 6-Month Results (Jan-Jun 2026)
| Metric | Value |
|---|---|
| Total Trades | 47 |
| Win Rate | 68% |
| Average Win | ₹3,200 |
| Average Loss | ₹1,800 |
| Net P&L | +₹42,000 |
| Max Drawdown | -₹8,500 |
| Sharpe Ratio | 1.8 |
What Worked
| Strategy | Win Rate | Why |
|---|---|---|
| LLM + Momentum combo | 72% | LLM caught market-moving news before chart reflected it |
| LLM + OI analysis | 65% | Big money flows + news sentiment = high confidence |
| Technical only | 58% | Missed news-driven gaps |
What Didn't Work
| Strategy | Win Rate | Why |
|---|---|---|
| LLM alone | 45% | Sentiment is noisy. Needs technical filter. |
| Far OTM options | 12% | Probability math doesn't lie. |
| Holding through expiry | 33% | Theta decay kills. |
9. Limitations of AI in Trading (Be Honest)
What AI CAN Do
✅ Analyze 100 news headlines in 2 seconds
✅ Detect sentiment patterns humans miss
✅ Backtest strategies on historical data
✅ Calculate position sizes based on risk
✅ Alert you to unusual activity
What AI CANNOT Do
❌ Predict the future
❌ Account for black swan events (war, pandemic, policy shock)
❌ Replace human judgment
❌ Guarantee profits
❌ Handle illiquid markets
❌ Factor in politician speeches, Godi media, retail panic
The "AI Proposes, You Dispose" Rule
AI Signal: "STRONG BUY"
Your Checklist:
[ ] Does this match my technical analysis?
[ ] What's the max I can lose?
[ ] Is the risk-reward ratio > 1:1?
[ ] Am I trading with revenge money?
[ ] What's my exit plan?
IF all checks pass → Execute
IF any check fails → Pass
10. Advanced: Adding Local Vector Search for Historical News
Why Vector Search?
Instead of analyzing only today's news, search HISTORICAL news for similar patterns.
Setup
from chromadb import Client
from chromadb.utils import embedding_functions
# Initialize ChromaDB (runs locally)
client = Client()
collection = client.get_or_create_collection(
name="nse_news",
embedding_function=embedding_functions.DefaultEmbeddingFunction()
)
# Add historical news
headlines = [
"RBI hikes repo rate by 25 bps",
"Nifty falls 2% on rate hike fears",
"IT stocks rally on strong earnings",
# ... thousands more
]
for i, headline in enumerate(headlines):
collection.add(
documents=[headline],
ids=[f"news_{i}"],
metadatas=[{"date": "2025-01-15"}]
)
# Search for similar patterns
current_headline = "RBI signals dovish stance on rates"
results = collection.query(
query_texts=[current_headline],
n_results=5
)
# Find what happened last time
for doc in results['documents'][0]:
print(f"Similar: {doc}")
print(f"What happened next: [check historical Nifty data]")
This is next-level. Matching current news to historical patterns = edge.
11. Complete nse_ai_agent Stack
Recommended Setup (4GB RAM Phone)
Hardware:
- Android phone with 4GB+ RAM
- 16GB+ storage
- Stable WiFi
Software:
- Termux (F-Droid)
- Python 3.11
- Ollama + Llama 3.2 3B
- nsepy, requests, pandas, beautifulsoup4
- python-telegram-bot
- ChromaDB (for vector search)
Cron Schedule:
- 9:00 AM: Pre-market news analysis
- 9:15 AM: Market open + live quote fetch
- Every 5 min (9:15-3:30): Momentum scanner
- 3:35 PM: Post-market summary
12. FAQ: AI + Trading
Q1: Can AI really predict markets?
A: No. AI can identify patterns and sentiment, but markets are influenced by infinite variables. Use AI as a tool, not a crystal ball.
Q2: Which is better: cloud LLM or local LLM?
A: For trading: local. Zero latency, zero cost, privacy. Cloud LLMs are better for research/analysis, not real-time.
Q3: Does nse_ai_agent actually trade automatically?
A: No. It generates signals + alerts. YOU decide. "AI proposes, you dispose."
Q4: What if Ollama crashes during market hours?
A: Fallback to keyword-based sentiment. Always have a backup.
Q5: Can I run this on iOS?
A: No. Termux is Android-only. For iOS, use iSH shell or cloud VPS.
Q6: Is this better than paid algo platforms?
A: For customization + cost: yes. For reliability + support: no. Depends on your needs.
Q7: What if NSE blocks my IP?
A: Use nsepy (stable), add delays, rotate user agents.
Q8: How much does this cost?
A: ₹0. All tools are free. Optional: Zerodha Kite Connect = ₹2,000/month for auto-execution.
13. The Real Truth About AI Trading
After 6 months of running nse_ai_agent, here's what I've learned:
AI Is Not a Money Printer
What AI actually does:
- Filters noise from news
- Identifies sentiment shifts faster than humans
- Backtests strategies consistently
- Removes emotional bias from analysis
What AI doesn't do:
- Predict black swan events
- Guarantee profits
- Replace trading discipline
- Fix bad strategies
The Edge Is Small But Real
My win rate went from 58% (technical only) to 68% (technical + AI). That 10% edge = ₹42,000 profit on ₹1 lakh capital in 6 months.
Not life-changing. But significant. And it scales.
The Future
Near term (2026-2027):
- Local LLMs get better at financial reasoning
- Multimodal models analyze charts + news together
- Real-time sentiment from Twitter/X integrated
Medium term (2027-2030):
- SEBI regulates AI trading tools
- Local models with financial fine-tuning
- Retail traders with AI tools outperform institutional algo
Long term (2030+):
- Human-AI collaboration standard
- Pure AI traders = regulated/licensed
- Democratization of hedge-fund-grade tools
14. Getting Started: Build Your Own AI Trading Assistant
Quick Start (2 Hours)
# 1. Install Termux from F-Droid
# 2. Install Ollama
curl -fsSL https://ollama.com/install.sh | sh
# 3. Download model
ollama pull llama3.2:3b
# 4. Clone nse_ai_agent
git clone https://github.com/shaktitiwari715-ai/nse_ai_agent.git
cd nse_ai_agent
# 5. Install dependencies
pip install -r requirements.txt
# 6. Configure .env
cp .env.example .env
# Edit .env with your Telegram token, capital, etc.
# 7. Test
python scripts/llm_sentiment.py
# 8. Schedule with cron
crontab -e
# Add: */5 9-15 * * 1-5 ~/nse_ai_agent/scripts/scheduler.sh
Resources
| Resource | Link |
|---|---|
| nse_ai_agent GitHub | github.com/shaktitiwari715-ai/nse_ai_agent |
| Ollama | ollama.com |
| Llama 3.2 | ollama.com/library/llama3.2 |
| Phi-3 Mini | ollama.com/library/phi3 |
| NSEpy | pypi.org/project/nsepy |
| ChromaDB | chromadb.io |
Conclusion: AI Is a Copilot, Not a Pilot
The best trading AI is not the one that predicts perfectly. It's the one that augments your decision-making without removing your agency.
nse_ai_agent doesn't place trades for me. It analyzes news in 2 seconds, scores market sentiment, combines it with technical signals, and sends me a Telegram alert with reasoning.
I still decide. I still manage risk. I still control my capital.
But now I have an edge that most retail traders don't.
That's the real power of AI in trading. Not automation. Augmentation.
Connect With Shakti Tiwari
- Website: optiontradingwithai.in
- Dev.to: @shaktitiwari715-ai
- GitHub: @shaktitiwari715-ai
- X/Twitter: @shaktitiwari
- Telegram: @shaktitrade
Published on Dev.to | Tags: #ai #trading #nse #llm #termux #fintech #india
Author
Shakti Tiwari is an AI/quant trader and open-source developer from Chandigarh. He builds free trading tools for Indian retail traders and writes about the intersection of AI, trading psychology, and NSE markets.
Top comments (0)