DEV Community

Windy Tony
Windy Tony

Posted on

I Built an AI System That Generates Trading Signals Across 4 Stock Markets — Here's How

The Problem

As a developer, I've always been fascinated by the intersection of AI and finance. But most trading tools are either:

  • Too expensive ($200+/month for Bloomberg Terminal)
  • Too complex (requires a PhD in quantitative finance)
  • Too opaque (black-box algorithms you can't understand or customize)

So I built my own. An open-source Python system that scans US, Hong Kong, Singapore, and China A-share markets, generates trading signals using technical analysis, and delivers them in real-time.

The Architecture

┌─────────────────┐
│  Yahoo Finance   │ ← Free real-time data
│  API (yfinance)  │
└────────┬────────┘
         │
┌────────▼────────┐
│  Signal Engine   │ ← SMA crossovers, RSI, Momentum
│  (Python)        │
└────────┬────────┘
         │
┌────────▼────────┐
│  Scoring System  │ ← -5 to +5 composite score
│  + Risk Manager  │
└────────┬────────┘
         │
┌────────▼────────┐
│  Output: JSON    │ ← Actionable BUY/SELL/HOLD
│  + Markdown      │
└─────────────────┘
Enter fullscreen mode Exit fullscreen mode

Core Signal Generation

The engine uses three complementary indicators:

1. SMA Crossover System

import yfinance as yf
import numpy as np

def get_signals(ticker: str, period: str = "3mo"):
    data = yf.download(ticker, period=period)
    close = data['Close'].values.flatten()

    sma5 = np.mean(close[-5:])
    sma10 = np.mean(close[-10:])
    sma20 = np.mean(close[-20:])
    sma50 = np.mean(close[-50:]) if len(close) >= 50 else None

    score = 0
    if sma5 > sma10: score += 1
    if sma5 > sma20: score += 1
    if sma10 > sma20: score += 1
    if sma50 and sma20 > sma50: score += 1

    return score  # 0-4, higher = more bullish
Enter fullscreen mode Exit fullscreen mode

2. RSI (Relative Strength Index)

def calculate_rsi(prices, period=14):
    deltas = np.diff(prices)
    gains = np.where(deltas > 0, deltas, 0)
    losses = np.where(deltas < 0, -deltas, 0)

    avg_gain = np.mean(gains[-period:])
    avg_loss = np.mean(losses[-period:])

    if avg_loss == 0:
        return 100

    rs = avg_gain / avg_loss
    return 100 - (100 / (1 + rs))
Enter fullscreen mode Exit fullscreen mode

RSI Interpretation:

  • RSI < 30 → Oversold (potential buy signal)
  • RSI > 70 → Overbought (potential sell signal)
  • RSI 30-70 → Neutral zone

3. Momentum Score

def momentum_score(close):
    if len(close) < 20:
        return 0

    change_5d = (close[-1] - close[-5]) / close[-5]
    change_20d = (close[-1] - close[-20]) / close[-20]

    score = 0
    if change_5d > 0.02: score += 1
    if change_5d > 0.05: score += 1
    if change_20d > 0.05: score += 1
    if change_20d > 0.10: score += 1

    return score
Enter fullscreen mode Exit fullscreen mode

Multi-Market Coverage

The system scans four markets with different trading hours:

Market Tickers Hours (Local) API
US (NYSE/NASDAQ) AAPL, NVDA, MSFT, TSLA, etc. 9:30-16:00 ET yfinance
Hong Kong (HKEX) 0700.HK, 9988.HK, etc. 9:30-16:00 HKT yfinance
Singapore (SGX) D05.SI, O39.SI, etc. 9:00-17:00 SGT yfinance
China A-Shares 600519.SS, 000858.SZ 9:30-15:00 CST yfinance

Real Results: Today's Signals (Feb 22, 2026)

Here's what the system generated this morning:

Signal Ticker Price RSI Score
STRONG BUY NVDA $189.82 48.8 +3
BUY AMZN $210.11 25.3 +2
BUY META $655.66 26.2 +2
STRONG SELL AMD $200.15 33.7 -3
SELL MSFT -2

Key insight: AMZN and META are showing RSI values below 30 (oversold territory), suggesting potential bounce opportunities. Meanwhile, the broader market (SPY/QQQ) shows sell signals, indicating a selective stock-picking environment rather than a broad bull market.

Risk Management Layer

Every signal includes a risk framework:

def position_size(capital, risk_per_trade=0.02, stop_loss_pct=0.05):
    """Never risk more than 2% of capital per trade"""
    risk_amount = capital * risk_per_trade
    position = risk_amount / stop_loss_pct
    return min(position, capital * 0.25)  # Max 25% in single position
Enter fullscreen mode Exit fullscreen mode

Rules:

  1. 2% Rule — Never risk more than 2% of total capital on a single trade
  2. 25% Cap — No single position exceeds 25% of portfolio
  3. Stop Loss — Every entry has a predefined exit point
  4. Correlation Check — Avoid overloading on correlated assets

What I Learned Building This

  1. Simple beats complex. A basic SMA crossover + RSI system outperforms most retail traders who use gut feelings.

  2. Data quality matters more than algorithm sophistication. Yahoo Finance is free but has occasional gaps. Always validate.

  3. The hardest part isn't the code — it's the discipline. The system generates signals. Following them consistently is the real challenge.

  4. Multi-market scanning reveals opportunities you'd never find manually. The AH-share premium (same company listed in both Hong Kong and mainland China) creates regular arbitrage windows.

Try It Yourself

The core engine is about 400 lines of Python. You need:

pip install yfinance numpy pandas
Enter fullscreen mode Exit fullscreen mode

Start with paper trading (simulated). Track your signals for at least 30 days before committing real capital.

What's Next

I'm building a web dashboard that displays real-time signals with interactive charts. If you're interested in the full source code or want to collaborate, drop a comment below or check out my project:

AI Profit Store — Where AI meets financial intelligence.


Disclaimer: This is for educational purposes only. Past performance does not guarantee future results. Always do your own research before making investment decisions.


What trading indicators do you find most reliable? Have you built similar systems? Let me know in the comments!

Top comments (0)