In this blog post, we'll explore how to connect to the Tokyo Stock Exchange (TSE) via stock APIs to monitor real-time Japanese market data and perform historical analysis. By leveraging stock APIs, high-frequency real-time quote APIs, and market data APIs, you can easily access real-time stock quotes, financial market data, and more from Japanese exchanges. We'll also dive into technical analysis using the classic MACD indicator, which is perfect for financial API development and helping investors grasp market trends.

First, I'll compare several APIs that support the Japanese market. Then, using iTick API as an example, I'll walk you through fetching data and implementing MACD analysis to kickstart your quantitative projects.
1. Comparing Japanese Stock APIs
There are several providers offering Japanese stock APIs, each with strengths in data quality, real-time capabilities, pricing, and use cases.
To help you choose, here's a side-by-side comparison of four popular APIs that provide real-time quotes and historical data from the Tokyo Stock Exchange.
| API Name | Key Features | Pricing Model | Best For |
|---|---|---|---|
| iTick API | Unified request headers for easy integration. Covers real-time quotes (Tick/Quote), multi-timeframe K-lines, and WebSocket pushes. Comprehensive data with low latency. | Free tier available. | Personal development, quantitative trading, projects needing structured data. |
| StockTV API | Supports global market integration with built-in indicators like SMA and RSI returned directly. | Limited free credits + pay-per-use. | Teams needing cross-market data or pre-computed indicators. |
| Alpha Vantage | Free access to basic real-time and historical data across global markets. | Completely free, but strict rate limits (e.g., 5 calls/minute). | Learning, prototyping non-high-frequency strategies. |
| Yahoo Finance API | Broad data coverage with free access. | Free. | Educational demos, simple queries—not for high-stability production. |
2. Hands-On: Fetching Data and Calculating MACD with iTick API
Let's get practical with iTick API, from setup to data retrieval and MACD computation.
Step 1: Set Up Your Environment and Get Your API Key
- Register and Get a Token: Head to the iTick website, sign up, and grab your API token from the dashboard.
- Install Python Libraries: Run this in your terminal:
pip install requests pandas numpy
Step 2: Fetch Japanese Stock K-Line Data
We'll use historical K-line data for MACD calculations. iTick's K-line endpoint is flexible, supporting timeframes from 1-minute to monthly.
Here's code to fetch 50 bars of 5-minute K-line data for Toyota Motor (code: 7203).
import requests
import pandas as pd
# 1. Set up API request headers (common to all iTick endpoints)
headers = {
"accept": "application/json",
"token": "your_token_here" # Replace with your actual token
}
# 2. Build the request URL
# Parameters:
# region=JP for Japanese market
# code=7203 for Toyota Motor
# kType=2 for 5-minute K-lines (1:1-min, 2:5-min, ..., 8:daily)
# limit=50 to get 50 bars
url = "https://api.itick.org/stock/kline?region=JP&code=7203&kType=2&limit=50"
# 3. Send the request and handle the response
response = requests.get(url, headers=headers)
data = response.json()
if data["code"] == 0: # Success
kline_list = data["data"]
# Convert to Pandas DataFrame for easier analysis
df = pd.DataFrame(kline_list)
# Rename columns for readability
df.rename(columns={'t': 'timestamp', 'o': 'open', 'h': 'high',
'l': 'low', 'c': 'close', 'v': 'volume'}, inplace=True)
# Convert timestamp to datetime
df['datetime'] = pd.to_datetime(df['timestamp'], unit='s')
df.set_index('datetime', inplace=True)
print(f"Successfully fetched {len(df)} K-line bars")
print(df[['open', 'high', 'low', 'close', 'volume']].head())
else:
print(f"Request failed: {data['msg']}")
Step 3: Calculate the MACD Indicator
MACD (Moving Average Convergence Divergence) is a popular momentum indicator consisting of three components: DIF (Difference), DEA (Signal Line), and MACD Histogram. The standard parameters are (12, 26, 9).
We can implement it easily with Pandas and NumPy:
import numpy as np
def calculate_ema(series, period):
"""Calculate Exponential Moving Average (EMA)"""
return series.ewm(span=period, adjust=False).mean()
def calculate_macd(df, fast=12, slow=26, signal=9):
"""
Calculate MACD and add to DataFrame
:param df: DataFrame with 'close' prices
:param fast: Fast EMA period
:param slow: Slow EMA period
:param signal: Signal EMA period
"""
# Calculate fast and slow EMAs
df['EMA_fast'] = calculate_ema(df['close'], fast)
df['EMA_slow'] = calculate_ema(df['close'], slow)
# Calculate DIF (Difference)
df['DIF'] = df['EMA_fast'] - df['EMA_slow']
# Calculate DEA (Signal line, EMA of DIF)
df['DEA'] = calculate_ema(df['DIF'], signal)
# Calculate MACD Histogram (multiplied by 2 for visual emphasis)
df['MACD_hist'] = 2 * (df['DIF'] - df['DEA'])
return df
# Apply MACD to the fetched K-line data
df_with_macd = calculate_macd(df)
# View results
print(df_with_macd[['close', 'DIF', 'DEA', 'MACD_hist']].tail())
Key Insights:
- Golden/Dead Cross: A "golden cross" (buy signal) occurs when DIF crosses above DEA from below. A "dead cross" (sell signal) is the opposite.
- Zero Line: DIF and DEA above zero indicate a bullish market; below zero suggests bearish.
- Histogram: The height shows trend strength; positive bars are bullish, negative are bearish.
Step 4: Simple Visualization
Visualizing the price and MACD together helps spot relationships intuitively.
import matplotlib.pyplot as plt
# Create figure and axes
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10), gridspec_kw={'height_ratios': [3, 1]})
# Subplot 1: Plot price and EMAs
ax1.plot(df_with_macd.index, df_with_macd['close'], label='Close Price', linewidth=1.5, color='black')
ax1.plot(df_with_macd.index, df_with_macd['EMA_fast'], label=f'EMA{12}', alpha=0.7)
ax1.plot(df_with_macd.index, df_with_macd['EMA_slow'], label=f'EMA{26}', alpha=0.7)
ax1.set_title('Toyota Motor (7203.T) - Price & MACD')
ax1.set_ylabel('Price')
ax1.legend()
ax1.grid(True, alpha=0.3)
# Subplot 2: Plot MACD DIF, DEA, and Histogram
ax2.plot(df_with_macd.index, df_with_macd['DIF'], label='DIF', color='blue', linewidth=1.5)
ax2.plot(df_with_macd.index, df_with_macd['DEA'], label='DEA', color='red', linewidth=1.5)
# Histogram bars: green for positive, red for negative
colors = ['green' if x >= 0 else 'red' for x in df_with_macd['MACD_hist']]
ax2.bar(df_with_macd.index, df_with_macd['MACD_hist'], color=colors, alpha=0.5, width=0.01, label='MACD Hist')
ax2.axhline(y=0, color='grey', linestyle='--', linewidth=0.8)
ax2.set_ylabel('MACD')
ax2.legend()
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Step 5: Real-Time MACD Monitoring with WebSocket
WebSocket enables real-time, bidirectional communication for live data. Use it to monitor stock quotes and update MACD dynamically.
class RealTimeMACDMonitor:
"""Real-Time MACD Monitor"""
def __init__(self, stock_codes, token, fast_period=12, slow_period=26, signal_period=9):
self.stock_codes = stock_codes if isinstance(stock_codes, list) else [stock_codes]
self.token = token
self.fast_period = fast_period
self.slow_period = slow_period
self.signal_period = signal_period
# Store historical data
self.historical_data = {code: pd.DataFrame() for code in self.stock_codes}
# MACD states
self.macd_states = {code: {
'dif': None,
'dea': None,
'histogram': None,
'signal': 0 # 0: no signal, 1: golden cross, -1: dead cross
} for code in self.stock_codes}
def update_data(self, stock_code, new_price_data):
"""Update stock data and recalculate MACD"""
if stock_code not in self.historical_data:
return
# Add new data
df = self.historical_data[stock_code]
new_df = pd.DataFrame([new_price_data])
if len(df) == 0:
self.historical_data[stock_code] = new_df
else:
self.historical_data[stock_code] = pd.concat([df, new_df])
# Keep recent data (e.g., last 100 bars)
if len(self.historical_data[stock_code]) > 100:
self.historical_data[stock_code] = self.historical_data[stock_code].iloc[-100:]
# Calculate MACD if enough data
if len(self.historical_data[stock_code]) >= self.slow_period + 10:
df_with_macd = calculate_macd(
self.historical_data[stock_code],
self.fast_period,
self.slow_period,
self.signal_period
)
# Update MACD state
last_row = df_with_macd.iloc[-1]
prev_row = df_with_macd.iloc[-2] if len(df_with_macd) > 1 else None
self.macd_states[stock_code]['dif'] = last_row['DIF']
self.macd_states[stock_code]['dea'] = last_row['DEA']
self.macd_states[stock_code]['histogram'] = last_row['MACD_hist']
# Detect signal changes
if prev_row is not None:
# Golden cross detection
if last_row['DIF'] > last_row['DEA'] and prev_row['DIF'] <= prev_row['DEA']:
self.macd_states[stock_code]['signal'] = 1
print(f"⚠️ {stock_code} MACD Golden Cross Signal! DIF={last_row['DIF']:.2f}, DEA={last_row['DEA']:.2f}")
# Dead cross detection
elif last_row['DIF'] < last_row['DEA'] and prev_row['DIF'] >= prev_row['DEA']:
self.macd_states[stock_code]['signal'] = -1
print(f"⚠️ {stock_code} MACD Dead Cross Signal! DIF={last_row['DIF']:.2f}, DEA={last_row['DEA']:.2f}")
def get_macd_summary(self):
"""Get MACD status summary for all monitored stocks"""
summary = []
for code, state in self.macd_states.items():
if state['dif'] is not None:
signal_text = "No Signal"
if state['signal'] == 1:
signal_text = "Golden Cross (Buy)"
elif state['signal'] == -1:
signal_text = "Dead Cross (Sell)"
summary.append({
'Stock Code': code,
'DIF': state['dif'],
'DEA': state['dea'],
'Histogram': state['histogram'],
'Signal': signal_text
})
return pd.DataFrame(summary)
3. Wrapping Up and Tips
Connecting to the Tokyo Stock Exchange for quantitative analysis is straightforward, as shown in this guide.
- API Selection: Start with free or low-cost options like iTick's free tier to test ideas. Upgrade to paid plans for higher frequency and reliability once your strategy is solid.
- Data Fundamentals: No matter the API, reliable and accurate data is key to successful quant strategies. Cross-verify sources for critical decisions.
- Beyond MACD: This is just an entry point. Combine MACD with RSI, Bollinger Bands, or integrate real-time quote APIs for more advanced trading systems.
Note: This post is for informational purposes only and not investment advice. Markets involve risk—invest wisely.
Reference: https://blog.itick.org/stock-api/free-japan-stock-api-comparison
GitHub: https://github.com/itick-org/
Top comments (0)