Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions src/clis/binance/asks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
site: binance
name: asks
description: Order book ask prices for a trading pair
domain: data-api.binance.vision
strategy: public
browser: false

args:
symbol:
type: str
required: true
positional: true
description: "Trading pair symbol (e.g. BTCUSDT, ETHUSDT)"
limit:
type: int
default: 10
description: Number of price levels (5, 10, 20, 50, 100)

pipeline:
- fetch:
url: https://data-api.binance.vision/api/v3/depth?symbol=${{ args.symbol }}&limit=${{ args.limit }}

- select: asks

- map:
rank: ${{ index + 1 }}
ask_price: ${{ item.0 }}
ask_qty: ${{ item.1 }}

- limit: ${{ args.limit }}

columns: [rank, ask_price, ask_qty]
63 changes: 63 additions & 0 deletions src/clis/binance/commands.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import fs from 'node:fs';
import yaml from 'js-yaml';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { executePipeline } from '../../pipeline.js';

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / docs-build

Cannot find module '../../pipeline.js' or its corresponding type declarations.

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / unit-test (ubuntu-latest, 22, 2)

Cannot find module '../../pipeline.js' or its corresponding type declarations.

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / build (macos-latest)

Cannot find module '../../pipeline.js' or its corresponding type declarations.

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / build (macos-latest)

Cannot find module '../../pipeline.js' or its corresponding type declarations.

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Cannot find module '../../pipeline.js' or its corresponding type declarations.

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / build (windows-latest)

Cannot find module '../../pipeline.js' or its corresponding type declarations.

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Cannot find module '../../pipeline.js' or its corresponding type declarations.

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

Cannot find module '../../pipeline.js' or its corresponding type declarations.

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / bun-test

Cannot find module '../../pipeline.js' or its corresponding type declarations.

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / unit-test (ubuntu-latest, 22, 1)

Cannot find module '../../pipeline.js' or its corresponding type declarations.

Check failure on line 4 in src/clis/binance/commands.test.ts

View workflow job for this annotation

GitHub Actions / audit

Cannot find module '../../pipeline.js' or its corresponding type declarations.

function loadPipeline(name: string): any[] {
const file = new URL(`./${name}.yaml`, import.meta.url);
const def = yaml.load(fs.readFileSync(file, 'utf-8')) as { pipeline: any[] };
return def.pipeline;
}

function mockJsonOnce(payload: unknown) {
vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
json: vi.fn().mockResolvedValue(payload),
}));
}

afterEach(() => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
});

describe('binance YAML adapters', () => {
it('sorts top pairs by numeric quote volume', async () => {
mockJsonOnce([
{ symbol: 'SMALL', lastPrice: '1', priceChangePercent: '1.2', highPrice: '1', lowPrice: '1', quoteVolume: '9.9' },
{ symbol: 'LARGE', lastPrice: '2', priceChangePercent: '2.3', highPrice: '2', lowPrice: '2', quoteVolume: '100.0' },
{ symbol: 'MID', lastPrice: '3', priceChangePercent: '3.4', highPrice: '3', lowPrice: '3', quoteVolume: '11.0' },
]);

const result = await executePipeline(null, loadPipeline('top'), { args: { limit: 3 } });

expect(result.map((item: any) => item.symbol)).toEqual(['LARGE', 'MID', 'SMALL']);
expect(result.map((item: any) => item.rank)).toEqual([1, 2, 3]);
});

it('sorts gainers by numeric percent change', async () => {
mockJsonOnce([
{ symbol: 'TEN', lastPrice: '1', priceChangePercent: '10.0', quoteVolume: '100' },
{ symbol: 'NINE', lastPrice: '1', priceChangePercent: '9.5', quoteVolume: '100' },
{ symbol: 'HUNDRED', lastPrice: '1', priceChangePercent: '100.0', quoteVolume: '100' },
]);

const result = await executePipeline(null, loadPipeline('gainers'), { args: { limit: 3 } });

expect(result.map((item: any) => item.symbol)).toEqual(['HUNDRED', 'TEN', 'NINE']);
});

it('keeps only TRADING pairs', async () => {
mockJsonOnce({
symbols: [
{ symbol: 'BTCUSDT', baseAsset: 'BTC', quoteAsset: 'USDT', status: 'TRADING' },
{ symbol: 'OLDPAIR', baseAsset: 'OLD', quoteAsset: 'USDT', status: 'BREAK' },
],
});

const result = await executePipeline(null, loadPipeline('pairs'), { args: { limit: 10 } });

expect(result).toEqual([
{ symbol: 'BTCUSDT', base: 'BTC', quote: 'USDT', status: 'TRADING' },
]);
});
});
32 changes: 32 additions & 0 deletions src/clis/binance/depth.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
site: binance
name: depth
description: Order book bid prices for a trading pair
domain: data-api.binance.vision
strategy: public
browser: false

args:
symbol:
type: str
required: true
positional: true
description: "Trading pair symbol (e.g. BTCUSDT, ETHUSDT)"
limit:
type: int
default: 10
description: Number of price levels (5, 10, 20, 50, 100)

pipeline:
- fetch:
url: https://data-api.binance.vision/api/v3/depth?symbol=${{ args.symbol }}&limit=${{ args.limit }}

- select: bids

- map:
rank: ${{ index + 1 }}
bid_price: ${{ item.0 }}
bid_qty: ${{ item.1 }}

- limit: ${{ args.limit }}

columns: [rank, bid_price, bid_qty]
40 changes: 40 additions & 0 deletions src/clis/binance/gainers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
site: binance
name: gainers
description: Top gaining trading pairs by 24h price change
domain: data-api.binance.vision
strategy: public
browser: false

args:
limit:
type: int
default: 10
description: Number of trading pairs

pipeline:
- fetch:
url: https://data-api.binance.vision/api/v3/ticker/24hr

- filter: item.priceChangePercent

- map:
symbol: ${{ item.symbol }}
price: ${{ item.lastPrice }}
change_24h: ${{ item.priceChangePercent }}
volume: ${{ item.quoteVolume }}
sort_change: ${{ Number(item.priceChangePercent) }}

- sort:
by: sort_change
order: desc

- map:
rank: ${{ index + 1 }}
symbol: ${{ item.symbol }}
price: ${{ item.lastPrice }}
change_24h: ${{ item.priceChangePercent }}
volume: ${{ item.quoteVolume }}

- limit: ${{ args.limit }}

columns: [rank, symbol, price, change_24h, volume]
36 changes: 36 additions & 0 deletions src/clis/binance/klines.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
site: binance
name: klines
description: Candlestick/kline data for a trading pair
domain: data-api.binance.vision
strategy: public
browser: false

args:
symbol:
type: str
required: true
positional: true
description: "Trading pair symbol (e.g. BTCUSDT, ETHUSDT)"
interval:
type: str
default: 1d
description: "Kline interval (1m, 5m, 15m, 1h, 4h, 1d, 1w, 1M)"
limit:
type: int
default: 10
description: Number of klines (max 1000)

pipeline:
- fetch:
url: https://data-api.binance.vision/api/v3/klines?symbol=${{ args.symbol }}&interval=${{ args.interval }}&limit=${{ args.limit }}

- map:
open: ${{ item.1 }}
high: ${{ item.2 }}
low: ${{ item.3 }}
close: ${{ item.4 }}
volume: ${{ item.5 }}

- limit: ${{ args.limit }}

columns: [open, high, low, close, volume]
39 changes: 39 additions & 0 deletions src/clis/binance/losers.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
site: binance
name: losers
description: Top losing trading pairs by 24h price change
domain: data-api.binance.vision
strategy: public
browser: false

args:
limit:
type: int
default: 10
description: Number of trading pairs

pipeline:
- fetch:
url: https://data-api.binance.vision/api/v3/ticker/24hr

- filter: item.priceChangePercent

- map:
symbol: ${{ item.symbol }}
price: ${{ item.lastPrice }}
change_24h: ${{ item.priceChangePercent }}
volume: ${{ item.quoteVolume }}
sort_change: ${{ Number(item.priceChangePercent) }}

- sort:
by: sort_change

- map:
rank: ${{ index + 1 }}
symbol: ${{ item.symbol }}
price: ${{ item.lastPrice }}
change_24h: ${{ item.priceChangePercent }}
volume: ${{ item.quoteVolume }}

- limit: ${{ args.limit }}

columns: [rank, symbol, price, change_24h, volume]
30 changes: 30 additions & 0 deletions src/clis/binance/pairs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
site: binance
name: pairs
description: List active trading pairs on Binance
domain: data-api.binance.vision
strategy: public
browser: false

args:
limit:
type: int
default: 20
description: Number of trading pairs

pipeline:
- fetch:
url: https://data-api.binance.vision/api/v3/exchangeInfo

- select: symbols

- filter: item.status === 'TRADING'

- map:
symbol: ${{ item.symbol }}
base: ${{ item.baseAsset }}
quote: ${{ item.quoteAsset }}
status: ${{ item.status }}

- limit: ${{ args.limit }}

columns: [symbol, base, quote, status]
30 changes: 30 additions & 0 deletions src/clis/binance/price.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
site: binance
name: price
description: Quick price check for a trading pair
domain: data-api.binance.vision
strategy: public
browser: false

args:
symbol:
type: str
required: true
positional: true
description: "Trading pair symbol (e.g. BTCUSDT, ETHUSDT)"

pipeline:
- fetch:
url: https://data-api.binance.vision/api/v3/ticker/24hr?symbol=${{ args.symbol }}

- map:
symbol: ${{ item.symbol }}
price: ${{ item.lastPrice }}
change: ${{ item.priceChange }}
change_pct: ${{ item.priceChangePercent }}
high: ${{ item.highPrice }}
low: ${{ item.lowPrice }}
volume: ${{ item.volume }}
quote_volume: ${{ item.quoteVolume }}
trades: ${{ item.count }}

columns: [symbol, price, change, change_pct, high, low, volume, quote_volume, trades]
25 changes: 25 additions & 0 deletions src/clis/binance/prices.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
site: binance
name: prices
description: Latest prices for all trading pairs
domain: data-api.binance.vision
strategy: public
browser: false

args:
limit:
type: int
default: 20
description: Number of prices

pipeline:
- fetch:
url: https://data-api.binance.vision/api/v3/ticker/price

- map:
rank: ${{ index + 1 }}
symbol: ${{ item.symbol }}
price: ${{ item.price }}

- limit: ${{ args.limit }}

columns: [rank, symbol, price]
45 changes: 45 additions & 0 deletions src/clis/binance/ticker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
site: binance
name: ticker
description: 24h ticker statistics for top trading pairs by volume
domain: data-api.binance.vision
strategy: public
browser: false

args:
limit:
type: int
default: 20
description: Number of tickers

pipeline:
- fetch:
url: https://data-api.binance.vision/api/v3/ticker/24hr

- map:
symbol: ${{ item.symbol }}
price: ${{ item.lastPrice }}
change_pct: ${{ item.priceChangePercent }}
high: ${{ item.highPrice }}
low: ${{ item.lowPrice }}
volume: ${{ item.volume }}
quote_vol: ${{ item.quoteVolume }}
trades: ${{ item.count }}
sort_volume: ${{ Number(item.quoteVolume) }}

- sort:
by: sort_volume
order: desc

- map:
symbol: ${{ item.symbol }}
price: ${{ item.lastPrice }}
change_pct: ${{ item.priceChangePercent }}
high: ${{ item.highPrice }}
low: ${{ item.lowPrice }}
volume: ${{ item.volume }}
quote_vol: ${{ item.quoteVolume }}
trades: ${{ item.count }}

- limit: ${{ args.limit }}

columns: [symbol, price, change_pct, high, low, volume, quote_vol, trades]
Loading
Loading