Why the Calendar Matters
NFP, CPI, interest rate decisions — these events move markets more in 5 minutes than technical indicators move them in a week. A trading bot that ignores the economic calendar is flying blind. The TickAtlas API provides calendar data so your strategies can account for upcoming volatility.
This guide covers two approaches: the defensive approach (avoid trading around news) and the offensive approach (trade the news itself).
Fetching Calendar Data
import requests
from datetime import datetime, timedelta
API_KEY = "your_api_key_here"
BASE_URL = "https://tickatlas.com/v1"
HEADERS = {"X-API-Key": API_KEY}
def get_upcoming_events(hours_ahead: int = 24) -> list[dict]:
"""Fetch economic events in the next N hours."""
resp = requests.get(f"{BASE_URL}/calendar", params={
"from": datetime.utcnow().isoformat(),
"to": (datetime.utcnow() + timedelta(hours=hours_ahead)).isoformat()
}, headers=HEADERS)
return resp.json()["data"]["events"]
events = get_upcoming_events(24)
for event in events:
print(f"{event['datetime']} | {event['currency']} | "
f"{event['impact']} | {event['event']}") API Response Format
// GET /v1/calendar?from=2026-03-28T00:00:00Z&to=2026-03-29T00:00:00Z&offset=0&limit=100
{
"success": true,
"data": {
"events": [
{
"datetime": "2026-03-28T12:30:00Z",
"currency": "USD",
"impact": "high",
"event": "Non-Farm Payrolls",
"forecast": "180K",
"previous": "175K"
},
{
"datetime": "2026-03-28T12:30:00Z",
"currency": "USD",
"impact": "high",
"event": "Unemployment Rate",
"forecast": "3.8%",
"previous": "3.9%"
},
{
"datetime": "2026-03-28T09:00:00Z",
"currency": "EUR",
"impact": "medium",
"event": "CPI Flash Estimate",
"forecast": "2.4%",
"previous": "2.6%"
}
],
"pagination": {
"offset": 0,
"limit": 100,
"total": 3,
"has_more": false
}
}
} Strategy 1: News Avoidance Filter
The simplest and safest approach: do not open new trades within 30 minutes of high-impact events. This prevents your bot from entering positions right before a spike.
def is_safe_to_trade(symbol: str, buffer_minutes: int = 30) -> bool:
"""Check if any high-impact events are near for this symbol's currencies."""
# Extract currencies from pair (e.g., EURUSD -> EUR, USD)
base = symbol[:3]
quote = symbol[3:]
events = get_upcoming_events(hours_ahead=1)
now = datetime.utcnow()
for event in events:
if event["impact"] != "high":
continue
if event["currency"] not in (base, quote):
continue
event_time = datetime.fromisoformat(event["datetime"].replace("Z", ""))
minutes_until = (event_time - now).total_seconds() / 60
# Too close to a high-impact event
if -15 < minutes_until < buffer_minutes:
print(f"Avoiding {symbol}: {event['event']} in {minutes_until:.0f}min")
return False
return True
# Usage in your trading bot
for pair in ["EURUSD", "GBPUSD", "USDJPY"]:
if is_safe_to_trade(pair):
# ... run your normal strategy
pass
else:
print(f"Skipping {pair} — news event approaching") Strategy 2: Pre-News Positioning
Before a major event, check where technical indicators stand. If RSI is already at an extreme and a high-impact event is approaching, the odds of a large move increase.
def pre_news_analysis(symbol: str) -> dict:
"""Analyze technicals before an upcoming news event."""
# Fetch current indicators
ind_resp = requests.get(f"{BASE_URL}/indicators", params={
"symbol": symbol,
"timeframe": "H1",
}, headers=HEADERS)
data = ind_resp.json()["data"]
indicators = data["indicators"]
rsi = indicators["RSI_14"]
atr = indicators["ATR_14"]
close = data["ohlcv"]["close"]
return {
"symbol": symbol,
"rsi": rsi,
"rsi_zone": "oversold" if rsi < 30 else "overbought" if rsi > 70 else "neutral",
"bb_position": "lower" if close < indicators["BB_lower"] else
"upper" if close > indicators["BB_upper"] else "middle",
"expected_move": atr * 2, # News events often produce 2x ATR moves
} Strategy 3: Post-News Momentum
Wait for the initial spike to settle (15-30 minutes after the event), then check if the move has created a new trend. Trade in the direction of the post-news momentum.
def post_news_momentum(symbol: str) -> str:
"""Check for post-news momentum after a high-impact event."""
resp = requests.get(f"{BASE_URL}/indicators", params={
"symbol": symbol,
"timeframe": "M15", # Use short timeframe for post-news
}, headers=HEADERS)
data = resp.json()["data"]["indicators"]
rsi = data["RSI_14"]
macd_hist = data["MACD_hist"]
adx = data["ADX"]
# Strong post-news trend: high ADX + aligned RSI and MACD
if adx > 30:
if macd_hist > 0 and rsi > 55:
return "BUY — strong post-news bullish momentum"
elif macd_hist < 0 and rsi < 45:
return "SELL — strong post-news bearish momentum"
return "WAIT — momentum not confirmed yet" Impact Classification Guide
High Impact
NFP, CPI, interest rate decisions, GDP. Can move majors 50-200 pips. Always avoid or trade with extreme caution.
Medium Impact
PMI, retail sales, employment change. Typical move: 20-50 pips. Consider widening stops around these events.
Low Impact
Consumer confidence, trade balance. Usually less than 20 pips. Safe to trade through in most cases.
Further Reading
Run this against live data.
Every account starts pay-as-you-go with $2.50 of credit and no card. Paste the key into the samples above and the requests work unchanged.