From 44e8639a86a5539d4633feaf7b74ac16e4170435 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 23 Apr 2025 17:06:57 +0900 Subject: [PATCH] feat(upbit): define new CCXT Pro watchOHLCV API - added checking timeframe logic. --- ts/src/pro/upbit.ts | 47 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/ts/src/pro/upbit.ts b/ts/src/pro/upbit.ts index f1ec82d1c1dc2..56c3570073968 100644 --- a/ts/src/pro/upbit.ts +++ b/ts/src/pro/upbit.ts @@ -3,10 +3,11 @@ import upbitRest from '../upbit.js'; import { ArrayCache, ArrayCacheBySymbolById } from '../base/ws/Cache.js'; -import type { Int, Str, Order, OrderBook, Trade, Ticker, Dict, Balances, Tickers, Strings } from '../base/types.js'; +import type { Int, Str, Order, OrderBook, Trade, Ticker, Dict, Balances, Tickers, Strings, OHLCV } from '../base/types.js'; import { sha256 } from '../static_dependencies/noble-hashes/sha256.js'; import { jwt } from '../base/functions/rsa.js'; import Client from '../base/ws/Client.js'; +import { InvalidOrder } from '../base/errors.js'; // --------------------------------------------------------------------------- @@ -20,6 +21,7 @@ export default class upbit extends upbitRest { 'watchTickers': true, 'watchTrades': true, 'watchTradesForSymbols': true, + 'watchOHLCV': true, 'watchOrders': true, 'watchMyTrades': true, 'watchBalance': true, @@ -203,6 +205,27 @@ export default class upbit extends upbitRest { return orderbook.limit (); } + /** + * @method + * @name upbit#watchOHLCV + * @description watches information an OHLCV with timestamp, openingPrice, highPrice, lowPrice, tradePrice, baseVolume in 1s. + * @see https://docs.upbit.com/kr/reference/websocket-candle for Upbit KR + * @see https://global-docs.upbit.com/reference/websocket-candle for Upbit Global + * @param {string} symbol unified market symbol of the market orders were made in + * @param {string} timeframe specifies the OHLCV candle interval to watch. As of now, Upbit only supports 1s candles. + * @param {int} [since] the earliest time in ms to fetch orders for + * @param {int} [limit] the maximum number of order structures to retrieve + * @param {object} [params] extra parameters specific to the exchange API endpoint + * @returns {OHLCV[]} a list of [OHLCV structures]{@link https://docs.ccxt.com/#/?id=ohlcv-structure} + */ + async watchOHLCV (symbol: string, timeframe = '1s', since: Int = undefined, limit: Int = undefined, params = {}): Promise { + if (timeframe !== '1s') { + throw new InvalidOrder (this.id + ' watchOHLCV does not support' + timeframe + ' candle.'); + } + const timeFrameOHLCV = 'candle.' + timeframe; + return await this.watchPublic (symbol, timeFrameOHLCV); + } + handleTicker (client: Client, message) { // 2020-03-17T23:07:36.511Z "onMessage" // { type: "ticker", @@ -332,6 +355,27 @@ export default class upbit extends upbitRest { client.resolve (stored, messageHash); } + handleOHLCV (client: Client, message) { + // { + // type: 'candle.1s', + // code: 'KRW-USDT', + // candle_date_time_utc: '2025-04-22T09:50:34', + // candle_date_time_kst: '2025-04-22T18:50:34', + // opening_price: 1438, + // high_price: 1438, + // low_price: 1438, + // trade_price: 1438, + // candle_acc_trade_volume: 1145.8935, + // candle_acc_trade_price: 1647794.853, + // timestamp: 1745315434125, + // stream_type: 'REALTIME' + // } + const marketId = this.safeString (message, 'code'); + const messageHash = 'candle.1s:' + marketId; + const ohlcv = this.parseOHLCV (message); + client.resolve (ohlcv, messageHash); + } + async authenticate (params = {}) { this.checkRequiredCredentials (); const wsOptions: Dict = this.safeDict (this.options, 'ws', {}); @@ -657,6 +701,7 @@ export default class upbit extends upbitRest { 'trade': this.handleTrades, 'myOrder': this.handleMyOrder, 'myAsset': this.handleBalance, + 'candle.1s': this.handleOHLCV, }; const methodName = this.safeString (message, 'type'); const method = this.safeValue (methods, methodName);