Skip to main content

Рыночные данные (Candles)

JT-LIB предоставляет мощную систему для работы с рыночными данными, включая получение исторических свечей, буферизацию данных и анализ рынка. Система построена вокруг CandlesBuffer для эффективного управления данными и getHistory для получения исторических данных.

Получение свечей - исторические данные

Функция getHistory

getHistory — основная функция для получения исторических данных свечей.

getHistory(symbol: string, timeframe: TimeFrame, startTime: number, limit?: number): Promise<OHLC[]>

Параметры:

  • symbol — торговый символ (например, 'BTC/USDT')
  • timeframe — таймфрейм свечей ('1m', '5m', '15m', '1h', '4h', '1d', '1w', '1M')
  • startTime — время начала в миллисекундах
  • limit — количество свечей (по умолчанию: максимально доступное)

Возвращает: Массив свечей в формате [timestamp, open, high, low, close, volume]

Примеры использования

// Получение последних 100 свечей за 1 час
const timeFrom = tms() - 1000 * 60 * 60 * 24 * 7; // 7 дней назад
const candles = await getHistory('BTC/USDT', '1h', timeFrom, 100);

// Получение дневных свечей за последний месяц
const monthAgo = Date.now() - 30 * 24 * 60 * 60 * 1000;
const dailyCandles = await getHistory('ETH/USDT', '1d', monthAgo, 30);

// Получение минутных свечей для анализа
const minuteCandles = await getHistory('BTC/USDT', '1m', Date.now() - 60 * 60 * 1000, 60);

Формат данных свечей

// Каждая свеча представлена массивом:
type OHLC = [number, number, number, number, number, number];
// [timestamp, open, high, low, close, volume]

// Пример:
const candle = [1614556800000, 50000, 51000, 49000, 50500, 1000];
// timestamp: 1614556800000 (время открытия свечи)
// open: 50000 (цена открытия)
// high: 51000 (максимальная цена)
// low: 49000 (минимальная цена)
// close: 50500 (цена закрытия)
// volume: 1000 (объем торгов)

CandlesBuffer - буферизация данных

CandlesBuffer — класс для эффективного управления буфером свечей с автоматическим обновлением. В JT-LIB буферы управляются через глобальный сервис CandlesBufferService, который предотвращает создание дублирующих буферов для одинаковых символов и таймфреймов.

Основные возможности

  • Глобальное кэширование — один буфер на комбинацию symbol+timeframe
  • Автоматическое обновление — подписка на события onTick для обновления данных
  • Предзагрузка данных — автоматическая загрузка исторических данных при инициализации
  • Управление размером буфера — ограничение максимального размера буфера
  • Доступ к OHLC данным — методы для получения open, high, low, close, volume

Получение буфера через глобальный сервис

// Получение буфера через глобальный сервис (рекомендуемый способ)
const buffer = await globals.candlesBufferService.getBuffer({
symbol: 'BTC/USDT',
timeframe: '1h',
preloadCandlesCount: 250, // количество свечей для предзагрузки
maxBufferLength: 1000 // максимальный размер буфера
});

// Буфер автоматически инициализируется и кэшируется
// При повторном запросе с теми же параметрами вернется существующий буфер

Параметры CandlesBufferOptions

interface CandlesBufferOptions {
symbol: string; // торговый символ
timeframe: string | number; // таймфрейм
preloadCandlesCount?: number; // количество свечей для предзагрузки (по умолчанию: 250)
maxBufferLength?: number; // максимальный размер буфера (по умолчанию: 1000)
}

Как работает кэширование

Сервис CandlesBufferService создает уникальный ключ для каждого буфера: ${symbol}-${timeframe}. При первом запросе создается новый буфер, при повторных запросах с теми же параметрами возвращается существующий буфер.

Методы CandlesBuffer

// Получение всех свечей
const candles = buffer.getCandles();

// Получение конкретной свечи (shift = 0 - последняя свеча)
const lastCandle = buffer.getCandle(0);
const prevCandle = buffer.getCandle(1);

// Получение OHLC данных последней свечи
const close = buffer.close();
const high = buffer.high();
const low = buffer.low();
const open = buffer.open();
const volume = buffer.volume();
const timestamp = buffer.tms();

// Очистка буфера
buffer.clear();

// Получение времени последнего обновления
const lastUpdate = buffer.getLastTimeUpdated();

Временные интервалы - работа с таймфреймами

Поддерживаемые таймфреймы

JT-LIB поддерживает следующие таймфреймы:

ТаймфреймМинутыОписание
'1m'11 минута
'5m'55 минут
'15m'1515 минут
'1h'601 час
'4h'2404 часа
'1d'14401 день
'1w'100801 неделя
'1M'432001 месяц

Конвертация таймфреймов

import { convertTimeframeToString, convertTimeframeToNumber } from 'jt-lib';

// Конвертация в строку
const tfString = convertTimeframeToString(60); // '1h'
const tfString2 = convertTimeframeToString('m60'); // '1h'

// Конвертация в число (минуты)
const tfNumber = convertTimeframeToNumber('1h'); // 60
const tfNumber2 = convertTimeframeToNumber('1d'); // 1440

Округление времени по таймфрейму

import { roundTimeByTimeframe } from 'jt-lib';

const timestamp = Date.now();
const roundedTime = roundTimeByTimeframe(timestamp, '1h');
// Округляет время до начала часа

Обработка рыночных данных - как анализировать рынок

CandlesBufferService - глобальное управление буферами

CandlesBufferService — глобальный сервис для управления буферами свечей. Сервис автоматически создается в BaseScript и доступен через globals.candlesBufferService.

// Получение буфера через глобальный сервис
const buffer = await globals.candlesBufferService.getBuffer({
symbol: 'BTC/USDT',
timeframe: '1h',
preloadCandlesCount: 500
});

// Сервис автоматически управляет кэшированием буферов
// Буферы создаются по ключу: `${symbol}-${timeframe}`
// При повторном запросе с теми же параметрами возвращается существующий буфер

Интеграция с индикаторами

CandlesBuffer интегрируется с системой индикаторов:

import { BaseIndicator } from 'jt-lib';

class MyIndicator extends BaseIndicator {
constructor(symbol: string, timeframe: TimeFrame, buffer: CandlesBuffer) {
super(symbol, timeframe, buffer);
}

calculate() {
const candles = this.candlesBuffer.getCandles();
// Логика расчета индикатора
}
}

Практические примеры анализа

Простой анализ тренда

class Script extends BaseScript {
private buffer: CandlesBuffer;

async onInit() {
// Получение буфера через глобальный сервис
this.buffer = await globals.candlesBufferService.getBuffer({
symbol: this.symbols[0],
timeframe: '1h',
preloadCandlesCount: 100
});
}

async onTick() {
const candles = this.buffer.getCandles();

if (candles.length < 20) return;

// Анализ тренда по последним 20 свечам
const recentCandles = candles.slice(-20);
const avgHigh = recentCandles.reduce((sum, c) => sum + c.high, 0) / 20;
const avgLow = recentCandles.reduce((sum, c) => sum + c.low, 0) / 20;

const currentPrice = this.buffer.close();

if (currentPrice > avgHigh) {
log('TrendAnalysis', 'Восходящий тренд', { currentPrice, avgHigh, avgLow }, true);
} else if (currentPrice < avgLow) {
log('TrendAnalysis', 'Нисходящий тренд', { currentPrice, avgHigh, avgLow }, true);
} else {
log('TrendAnalysis', 'Боковое движение', { currentPrice, avgHigh, avgLow }, true);
}
}
}

Анализ волатильности

class Script extends BaseScript {
private buffer: CandlesBuffer;

async onInit() {
// Получение буфера через глобальный сервис
this.buffer = await globals.candlesBufferService.getBuffer({
symbol: this.symbols[0],
timeframe: '4h',
preloadCandlesCount: 50
});
}

async onTick() {
const candles = this.buffer.getCandles();

if (candles.length < 10) return;

// Расчет волатильности
const recentCandles = candles.slice(-10);
const volatilities = recentCandles.map(candle =>
(candle.high - candle.low) / candle.close
);

const avgVolatility = volatilities.reduce((sum, v) => sum + v, 0) / 10;

log('VolatilityAnalysis', `Средняя волатильность: ${(avgVolatility * 100).toFixed(2)}%`, { avgVolatility }, true);

if (avgVolatility > 0.05) {
log('VolatilityAnalysis', 'Высокая волатильность', { avgVolatility }, true);
} else if (avgVolatility < 0.02) {
log('VolatilityAnalysis', 'Низкая волатильность', { avgVolatility }, true);
}
}
}

Поддержка и сопротивление

class Script extends BaseScript {
private buffer: CandlesBuffer;

async onInit() {
// Получение буфера через глобальный сервис
this.buffer = await globals.candlesBufferService.getBuffer({
symbol: this.symbols[0],
timeframe: '1d',
preloadCandlesCount: 100
});
}

async onTick() {
const candles = this.buffer.getCandles();

if (candles.length < 50) return;

// Поиск уровней поддержки и сопротивления
const highs = candles.map(c => c.high);
const lows = candles.map(c => c.low);

const resistance = Math.max(...highs.slice(-20));
const support = Math.min(...lows.slice(-20));

const currentPrice = this.buffer.close();

log('SupportResistance', `Поддержка: ${support}, Сопротивление: ${resistance}`, { support, resistance, currentPrice }, true);

if (currentPrice > resistance * 0.99) {
log('SupportResistance', 'Пробой сопротивления', { currentPrice, resistance }, true);
} else if (currentPrice < support * 1.01) {
log('SupportResistance', 'Пробой поддержки', { currentPrice, support }, true);
}
}
}

Оптимизация производительности

Управление размером буфера

// Для долгосрочного анализа используйте большие буферы
const longTermBuffer = await globals.candlesBufferService.getBuffer({
symbol: 'BTC/USDT',
timeframe: '1d',
preloadCandlesCount: 1000,
maxBufferLength: 2000
});

// Для краткосрочного анализа - меньшие буферы
const shortTermBuffer = await globals.candlesBufferService.getBuffer({
symbol: 'BTC/USDT',
timeframe: '1m',
preloadCandlesCount: 100,
maxBufferLength: 500
});

Автоматическое кэширование буферов

class Script extends BaseScript {
private hourlyBuffer: CandlesBuffer;
private dailyBuffer: CandlesBuffer;

async onInit() {
// Буферы автоматически кэшируются через глобальный сервис
// При повторном запросе с теми же параметрами вернется существующий буфер
this.hourlyBuffer = await globals.candlesBufferService.getBuffer({
symbol: this.symbols[0],
timeframe: '1h'
});

this.dailyBuffer = await globals.candlesBufferService.getBuffer({
symbol: this.symbols[0],
timeframe: '1d'
});
}
}

Интеграция с другими компонентами

BaseScript + CandlesBuffer

class Script extends BaseScript {
private buffer: CandlesBuffer;

async onInit() {
// Получение буфера через глобальный сервис
this.buffer = await globals.candlesBufferService.getBuffer({
symbol: this.symbols[0],
timeframe: getArgString('timeframe', '1h'),
preloadCandlesCount: getArgNumber('candlesCount', 250)
});
}

async onTick() {
// Анализ рыночных данных
const trend = this.analyzeTrend();
const volatility = this.calculateVolatility();

// Принятие торговых решений на основе анализа
if (trend === 'bullish' && volatility < 0.03) {
// Логика покупки
}
}
}

OrdersBasket + Market Data

class Script extends BaseScript {
private basket: OrdersBasket;
private buffer: CandlesBuffer;

async onInit() {
this.basket = new OrdersBasket({
symbol: this.symbols[0],
connectionName: this.connectionName
});
await this.basket.init();

// Получение буфера через глобальный сервис
this.buffer = await globals.candlesBufferService.getBuffer({
symbol: this.symbols[0],
timeframe: '1h'
});
}

async onTick() {
const currentPrice = this.basket.close();
const bufferPrice = this.buffer.close();

// Сравнение данных из разных источников
if (Math.abs(currentPrice - bufferPrice) > currentPrice * 0.001) {
warning('PriceValidation', 'Расхождение в ценах между источниками', { currentPrice, bufferPrice, difference: Math.abs(currentPrice - bufferPrice) });
}
}
}

Следующие шаги