Symbol & data refactoring for Nautilus
This commit is contained in:
@@ -12,17 +12,17 @@ export class CCXTFetcher {
|
||||
|
||||
/**
|
||||
* Parse ticker string to exchange and symbol
|
||||
* Expected format: "EXCHANGE:SYMBOL" (e.g., "BINANCE:BTC/USDT")
|
||||
* Expected format: "SYMBOL.EXCHANGE" (e.g., "BTC/USDT.BINANCE")
|
||||
*/
|
||||
parseTicker(ticker) {
|
||||
const parts = ticker.split(':');
|
||||
if (parts.length !== 2) {
|
||||
throw new Error(`Invalid ticker format: ${ticker}. Expected "EXCHANGE:SYMBOL"`);
|
||||
const lastDot = ticker.lastIndexOf('.');
|
||||
if (lastDot === -1) {
|
||||
throw new Error(`Invalid ticker format: ${ticker}. Expected "SYMBOL.EXCHANGE"`);
|
||||
}
|
||||
|
||||
return {
|
||||
exchange: parts[0].toLowerCase(),
|
||||
symbol: parts[1]
|
||||
exchange: ticker.slice(lastDot + 1).toLowerCase(),
|
||||
symbol: ticker.slice(0, lastDot)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -101,9 +101,9 @@ export class CCXTFetcher {
|
||||
const { exchange: exchangeName, symbol } = this.parseTicker(ticker);
|
||||
const exchange = this.getExchange(exchangeName);
|
||||
|
||||
// Convert microseconds to milliseconds
|
||||
const startMs = Math.floor(parseInt(startTime) / 1000);
|
||||
const endMs = Math.floor(parseInt(endTime) / 1000);
|
||||
// Convert nanoseconds to milliseconds
|
||||
const startMs = Math.floor(parseInt(startTime) / 1_000_000);
|
||||
const endMs = Math.floor(parseInt(endTime) / 1_000_000);
|
||||
|
||||
// Map period seconds to CCXT timeframe
|
||||
const timeframe = this.secondsToTimeframe(periodSeconds);
|
||||
@@ -208,7 +208,7 @@ export class CCXTFetcher {
|
||||
/**
|
||||
* Fetch recent trades for realtime tick data
|
||||
* @param {string} ticker - Ticker in format "EXCHANGE:SYMBOL"
|
||||
* @param {string} since - Optional timestamp in microseconds to fetch from
|
||||
* @param {string} since - Optional timestamp in nanoseconds to fetch from
|
||||
* @returns {Promise<Array>} Array of trade ticks
|
||||
*/
|
||||
async fetchRecentTrades(ticker, since = null) {
|
||||
@@ -216,8 +216,8 @@ export class CCXTFetcher {
|
||||
const exchange = this.getExchange(exchangeName);
|
||||
|
||||
try {
|
||||
// Convert microseconds to milliseconds if provided
|
||||
const sinceMs = since ? Math.floor(parseInt(since) / 1000) : undefined;
|
||||
// Convert nanoseconds to milliseconds if provided
|
||||
const sinceMs = since ? Math.floor(parseInt(since) / 1_000_000) : undefined;
|
||||
|
||||
const trades = await exchange.fetchTrades(symbol, sinceMs, 1000);
|
||||
|
||||
@@ -243,25 +243,24 @@ export class CCXTFetcher {
|
||||
/**
|
||||
* Convert CCXT OHLCV array to our OHLC format
|
||||
* CCXT format: [timestamp, open, high, low, close, volume]
|
||||
* Uses denominators from market metadata for proper integer representation
|
||||
* Uses precision fields from market metadata for proper integer representation
|
||||
*/
|
||||
convertToOHLC(candle, ticker, periodSeconds, metadata) {
|
||||
const [timestamp, open, high, low, close, volume] = candle;
|
||||
|
||||
// Use denominators from metadata
|
||||
const tickDenom = metadata.tickDenom || 100;
|
||||
const baseDenom = metadata.baseDenom || 100000000;
|
||||
const priceMult = Math.pow(10, metadata.pricePrecision ?? 2);
|
||||
const sizeMult = Math.pow(10, metadata.sizePrecision ?? 8);
|
||||
|
||||
return {
|
||||
ticker,
|
||||
timestamp: (timestamp * 1000).toString(), // Convert ms to microseconds
|
||||
open: Math.round(open * tickDenom).toString(),
|
||||
high: Math.round(high * tickDenom).toString(),
|
||||
low: Math.round(low * tickDenom).toString(),
|
||||
close: Math.round(close * tickDenom).toString(),
|
||||
volume: Math.round(volume * baseDenom).toString(),
|
||||
open_time: (timestamp * 1000).toString(),
|
||||
close_time: ((timestamp + periodSeconds * 1000) * 1000).toString()
|
||||
timestamp: (timestamp * 1_000_000).toString(), // Convert ms to nanoseconds
|
||||
open: Math.round(open * priceMult).toString(),
|
||||
high: Math.round(high * priceMult).toString(),
|
||||
low: Math.round(low * priceMult).toString(),
|
||||
close: Math.round(close * priceMult).toString(),
|
||||
volume: Math.round(volume * sizeMult).toString(),
|
||||
open_time: (timestamp * 1_000_000).toString(),
|
||||
close_time: ((timestamp + periodSeconds * 1000) * 1_000_000).toString()
|
||||
};
|
||||
}
|
||||
|
||||
@@ -272,35 +271,33 @@ export class CCXTFetcher {
|
||||
createGapBar(timestampMs, ticker, periodSeconds, metadata) {
|
||||
return {
|
||||
ticker,
|
||||
timestamp: (timestampMs * 1000).toString(), // Convert ms to microseconds
|
||||
timestamp: (timestampMs * 1_000_000).toString(), // Convert ms to nanoseconds
|
||||
open: null,
|
||||
high: null,
|
||||
low: null,
|
||||
close: null,
|
||||
volume: null,
|
||||
open_time: (timestampMs * 1000).toString(),
|
||||
close_time: ((timestampMs + periodSeconds * 1000) * 1000).toString()
|
||||
open_time: (timestampMs * 1_000_000).toString(),
|
||||
close_time: ((timestampMs + periodSeconds * 1000) * 1_000_000).toString()
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert CCXT trade to our Tick format
|
||||
* Uses denominators from market metadata for proper integer representation
|
||||
* Uses precision fields from market metadata for proper integer representation
|
||||
*/
|
||||
convertToTick(trade, ticker, metadata) {
|
||||
// Use denominators from metadata
|
||||
const tickDenom = metadata.tickDenom || 100;
|
||||
const baseDenom = metadata.baseDenom || 100000000;
|
||||
const quoteDenom = metadata.quoteDenom || tickDenom;
|
||||
const priceMult = Math.pow(10, metadata.pricePrecision ?? 2);
|
||||
const sizeMult = Math.pow(10, metadata.sizePrecision ?? 8);
|
||||
|
||||
const price = Math.round(trade.price * tickDenom);
|
||||
const amount = Math.round(trade.amount * baseDenom);
|
||||
const quoteAmount = Math.round((trade.price * trade.amount) * quoteDenom);
|
||||
const price = Math.round(trade.price * priceMult);
|
||||
const amount = Math.round(trade.amount * sizeMult);
|
||||
const quoteAmount = Math.round((trade.price * trade.amount) * priceMult);
|
||||
|
||||
return {
|
||||
trade_id: trade.id || `${trade.timestamp}`,
|
||||
ticker,
|
||||
timestamp: (trade.timestamp * 1000).toString(), // Convert ms to microseconds
|
||||
timestamp: (trade.timestamp * 1_000_000).toString(), // Convert ms to nanoseconds
|
||||
price: price.toString(),
|
||||
amount: amount.toString(),
|
||||
quote_amount: quoteAmount.toString(),
|
||||
|
||||
Reference in New Issue
Block a user