TypeScript
Node.js / TypeScript Integration
Type-safe access to 42 financial indicators, rule-based market summaries, and market data. Works with Express, Next.js, serverless functions, and any Node.js environment.
~10 min setupREST + JSONX-API-Key authentication
~10 minTypical setup
Programming LanguagesIntegration type
REST + JSONUniversal interface
X-API-KeyOne auth pattern
Installation
The client uses the built-in fetch API (Node 18+). No external dependencies required.
bash
# For older Node versions, install node-fetch
npm install node-fetch TypeScript Interfaces
Full type definitions for all API responses:
typescript
// types.ts — TypeScript interfaces for TickAtlas API responses
// Every success response is { success: true, data: T }. Errors are
// { success: false, error: { code, message, docs } }.
interface ApiEnvelope<T> {
success: boolean;
data: T;
}
// GET /v1/indicator — exactly these eight fields.
interface IndicatorResponse {
symbol: string;
timeframe: string;
indicator: string;
value: number | null;
bid: number | null;
ask: number | null;
updated_at: string | null;
server_time: string | null;
}
// GET /v1/quote
interface QuoteResponse {
symbol: string;
bid: number;
ask: number;
spread: number;
spread_pips?: number;
timestamp: string;
}
// GET /v1/summary — "summary" is the human-readable text.
interface SummaryResponse {
symbol: string;
timeframe: string;
bias: "bullish" | "bearish" | "neutral";
bias_strength: string | null;
confidence: number;
trend_score: number;
momentum_score: number;
signals: { trend: string; momentum: string; volatility: string; volume: string } | null;
bullish_signals: string[];
bearish_signals: string[];
neutral_signals: string[];
summary: string;
recommendations: string[];
updated_at: string | null;
}
// GET /v1/screener
interface ScreenerResult {
symbol: string;
value: number | null;
bid: number | null;
}
interface ScreenerResponse {
indicator: string;
timeframe: string;
filter: { min: number | null; max: number | null };
results: ScreenerResult[];
total_matches: number;
} Client Class
A type-safe client with automatic rate limit handling:
typescript
// tickatlas.ts — Type-safe API client
const BASE_URL = "https://tickatlas.com/v1";
export class TickAtlasClient {
private apiKey: string;
constructor(apiKey: string) {
this.apiKey = apiKey;
}
private async request<T>(endpoint: string, params: Record<string, string>): Promise<T> {
const url = new URL(`${BASE_URL}/${endpoint}`);
Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v));
const res = await fetch(url.toString(), {
headers: { "X-API-Key": this.apiKey },
});
if (res.status === 429) {
const retryAfter = parseInt(res.headers.get("Retry-After") || "2", 10);
await new Promise((r) => setTimeout(r, retryAfter * 1000));
return this.request<T>(endpoint, params);
}
if (!res.ok) {
throw new Error(`TickAtlas API error: ${res.status} ${res.statusText}`);
}
// Unwrap the { success, data } envelope so callers get T directly.
const body = (await res.json()) as ApiEnvelope<T>;
return body.data;
}
async indicator(symbol: string, indicator: string, timeframe = "H1"): Promise<IndicatorResponse> {
return this.request<IndicatorResponse>("indicator", { symbol, indicator, timeframe });
}
async indicators(symbol: string, timeframe = "H1") {
return this.request("indicators", { symbol, timeframe });
}
async summary(symbol: string, timeframe = "H1"): Promise<SummaryResponse> {
return this.request<SummaryResponse>("summary", { symbol, timeframe });
}
async quote(symbol: string): Promise<QuoteResponse> {
return this.request<QuoteResponse>("quote", { symbol });
}
async screener(indicator: string, opts: { timeframe?: string; min?: number; max?: number } = {}): Promise<ScreenerResponse> {
const params: Record<string, string> = { indicator, timeframe: opts.timeframe || "H1" };
if (opts.min !== undefined) params.min = String(opts.min);
if (opts.max !== undefined) params.max = String(opts.max);
return this.request<ScreenerResponse>("screener", params);
}
async multi(symbols: string[], indicators: string[], timeframe = "H1") {
return this.request("multi", {
symbols: symbols.join(","),
indicators: indicators.join(","),
timeframe,
});
}
async ohlc(symbol: string, timeframe = "H1", limit = 100) {
return this.request("ohlc", { symbol, timeframe, limit: String(limit) });
}
async heatmap(timeframe = "H1") {
return this.request("heatmap", { timeframe });
}
async calendar() {
return this.request("calendar", {});
}
} Express Middleware Example
Inject market data into your Express routes:
typescript
// Express middleware — inject market data into requests
import express from "express";
import { TickAtlasClient } from "./tickatlas";
const app = express();
const claw = new TickAtlasClient(process.env.CLAW_API_KEY!);
// Middleware to attach current RSI to request context
app.use("/api/trade", async (req, res, next) => {
try {
const symbol = req.query.symbol as string || "EURUSD";
const rsi = await claw.indicator(symbol, "RSI_14", "H1");
req.marketData = { rsi };
next();
} catch (err) {
res.status(502).json({ error: "Market data unavailable" });
}
});
app.get("/api/trade/signal", (req, res) => {
const { rsi } = req.marketData;
// Your rule, your thresholds — the API returns the value, not a call.
const action = rsi.value < 30 ? "BUY" : rsi.value > 70 ? "SELL" : "HOLD";
res.json({ symbol: rsi.symbol, rsi: rsi.value, action });
});
app.listen(3000); Scheduled Data Fetch
Use node-cron to fetch market summaries on a schedule:
typescript
// Scheduled data fetch with node-cron
import cron from "node-cron";
import { TickAtlasClient } from "./tickatlas";
const claw = new TickAtlasClient(process.env.CLAW_API_KEY!);
// Fetch market summary every hour on the hour
cron.schedule("0 * * * *", async () => {
const symbols = ["EURUSD", "GBPUSD", "XAUUSD", "BTCUSD"];
for (const symbol of symbols) {
const summary = await claw.summary(symbol, "H1");
console.log(
`[${new Date().toISOString()}] ${symbol}: ` +
`bias=${summary.bias} confidence=${summary.confidence}%`
);
// Store in database, send alert, etc.
if (summary.confidence > 80) {
console.log(` HIGH CONFIDENCE: ${summary.summary}`);
}
}
});
console.log("Scheduled market summary fetcher running...");