I've been trading crypto on and off for a few years. Mostly off after the losses.
My biggest problem wasn't the charts. It was me. I'd see a loss, get frustrated, immediately enter another trade to "make it back." Classic revenge trading. Or I'd take a setup on the 15-minute chart while completely ignoring that the daily chart was screaming the opposite direction.
Nothing in my trading setup actually warned me before I made these mistakes. The charts just... sit there. They don't say "hey, you just lost, maybe don't trade for the next hour."
So I built something that does.
What I Built
LenQuant is a Chrome extension that overlays on top of Binance, Bybit, OKX, and TradingView. It adds a side panel with:
- Market regime detection - Is this a trending market or choppy garbage?
- Multi-timeframe analysis - Do 15m, 1h, 4h, Daily agree or conflict?
- Behavioral tracking - How long since your last trade? Was it a loss?
- AI trade planning - Entry, stop, targets generated from market context
And a few other things: wallet tracking across exchanges, watchlist, alerts, journal.
The Technical Parts
DOM Extraction Instead of APIs
One decision I'm pretty happy with: I didn't require API keys for wallet tracking.
Most trading tools ask you to paste in your exchange API keys. That's a security nightmare. Users have to trust you not to steal their keys. Exchanges can change API formats and break your integration.
Instead, LenQuant reads position data directly from the DOM when users have their exchange tab open. The extension content script finds the elements showing positions, extracts the values, and displays them in the panel.
// Simplified example of DOM extraction
const positions = document.querySelectorAll('.position-row');
positions.forEach(row => {
const symbol = row.querySelector('.symbol')?.textContent;
const size = row.querySelector('.size')?.textContent;
const pnl = row.querySelector('.pnl')?.textContent;
// Store and display in panel
});
Obviously the real code handles selector differences between exchanges, error cases, etc. But the core idea: no API keys, just read what's already on screen.
Tradeoff: Only works when the exchange tab is open. But traders usually have their exchange open anyway, so this hasn't been an issue.
Market Regime Classification
I classify market conditions into three buckets: trending, ranging, choppy. Uses a combination of:
- ATR (Average True Range) - Volatility measurement
- ADX (Average Directional Index) - Trend strength
- RSI patterns - Momentum behavior
function classifyRegime(atr, adx, rsiPattern) {
if (adx > 25 && atr.increasing) {
return 'trending';
}
if (adx < 20 && atr.stable) {
return 'ranging';
}
if (atr.erratic && rsiPattern === 'whipsaw') {
return 'choppy';
}
return 'uncertain';
}
The "choppy" classification is the money. Most of my losses happened in choppy markets. Knowing when to sit out is more valuable than knowing when to enter.
Multi-Timeframe Analysis
For MTF confluence, I scan four timeframes simultaneously and score how aligned they are.
const timeframes = ['15m', '1h', '4h', '1d'];
async function calculateConfluence(symbol) {
const trends = await Promise.all(
timeframes.map(tf => getTrend(symbol, tf))
);
const bullish = trends.filter(t => t === 'bullish').length;
const bearish = trends.filter(t => t === 'bearish').length;
const confluenceScore = Math.max(bullish, bearish) / timeframes.length * 100;
return {
score: confluenceScore,
direction: bullish > bearish ? 'bullish' : 'bearish',
conflicting: bullish > 0 && bearish > 0
};
}
When someone tries to go long on a 15m setup but the 4h and daily are both bearish, they get a warning. Simple idea, but surprisingly effective at preventing bad entries.
Behavioral Tracking
This is probably the most "creepy" feature, but it's also the most useful.
The extension tracks:
- Time since last trade
- Whether last trade was a win or loss
- How many trades today
- Pattern of trades (rapid fire? evenly spaced?)
function checkRevengeTradingRisk(tradeHistory) {
const lastTrade = tradeHistory[tradeHistory.length - 1];
if (!lastTrade) return { risk: 'low' };
const minutesSinceLast = (Date.now() - lastTrade.closedAt) / 60000;
const wasLoss = lastTrade.pnl < 0;
if (wasLoss && minutesSinceLast < 10) {
return {
risk: 'high',
message: 'You closed a losing trade 10 minutes ago. Take a break.'
};
}
// ... more checks for overtrading, tilt, etc.
}
I know, it sounds obvious. But when you're in the heat of trading and just took a loss, your brain doesn't naturally think "wait, let me cool off." Having software tell you is different from telling yourself.
AI Integration
For trade plan generation, I send market context to OpenAI/Anthropic:
- Current price and recent price action
- Support/resistance levels
- Regime classification
- MTF confluence data
- Recent news (if applicable)
The response includes entry triggers, stop-loss placement with reasoning, and multiple targets.
async function generateTradePlan(symbol, context) {
const prompt = `
You are a professional trader analyzing ${symbol}.
Current price: ${context.price}
Regime: ${context.regime}
MTF Confluence: ${context.confluence}%
Key levels: ${context.levels.join(', ')}
Generate a trade plan with:
- Entry trigger
- Stop-loss with reasoning
- Three targets with reasoning
- Confidence score (0-100)
- Key risks
`;
const response = await callLLM(prompt);
return parseTradePlan(response);
}
Important: The AI doesn't trade for you. It generates plans. You still decide whether to execute. This is intentional - I wanted a tool that makes me a better trader, not a bot that trades for me.
What I Learned Building This
1. Chrome Extension APIs are Actually Pretty Good
Manifest V3 gets a lot of hate, but building with it wasn't bad. Service workers for background logic, content scripts for DOM access, side panels for UI. The separation makes sense.
The main pain point: debugging service worker crashes. They get terminated when idle, and if you have state that didn't get saved, it's gone. Learned to persist everything to chrome.storage.local.
2. DOM Extraction is Fragile
Every exchange styles their pages differently. Binance Futures has different classes than Binance Spot. Bybit recently redesigned their UI and broke my selectors.
My approach: I have a selector config per exchange that I update when things break. Users can also report broken extraction, and I can often fix it same-day - I also have different layers of fallback with network detection and on last case with APIs
3. Traders Have Strong Opinions
The feedback has been... opinionated. Some people want more indicators. Some want fewer. Some want alerts every time price moves 0.1%. Some never want to see a notification.
Current approach: make everything configurable. Don't assume I know what the user wants.
4. Performance Matters More Than I Expected
Running real-time analysis on multiple symbols while a user is trying to trade means you can't slow down their page. Web Workers for heavy computation, debouncing on DOM observations, lazy loading for components.
Current State
The extension is live on the Chrome Web Store. Free tier gives you 25 analyses per day, which is enough for most traders. Paid tiers unlock the full feature set.
If you trade crypto and want to try it: lenquant.com
If you're a dev building Chrome extensions and have questions about anything I mentioned here, happy to answer in comments.
Top comments (0)