diff --git a/src/app/components/TradingChart/constants.ts b/src/app/components/TradingChart/constants.ts new file mode 100644 index 0000000000..7bfe5e2a4a --- /dev/null +++ b/src/app/components/TradingChart/constants.ts @@ -0,0 +1,8 @@ +export const SOVRYN_INDEXER_MAINNET = + 'https://indexer.sovryn.app/chart?chainId=30&'; + +export const SOVRYN_INDEXER_TESTNET = + 'https://indexer.test.sovryn.app/chart?chainId=31&'; + +// maximum number of candles that should be loaded in one request +export const CHUNK_SIZE = 1000; diff --git a/src/app/components/TradingChart/datafeed.ts b/src/app/components/TradingChart/datafeed.ts index afe6f99072..d52526c973 100644 --- a/src/app/components/TradingChart/datafeed.ts +++ b/src/app/components/TradingChart/datafeed.ts @@ -23,11 +23,7 @@ import { resolutionMap, supportedResolutions, } from 'app/pages/PerpetualPage/components/TradingChart/helpers'; -import { - getTokensFromSymbol, - hasDirectFeed, - queryPairByChunks, -} from './helpers'; +import { getTokensFromSymbol, queryPairByChunks } from './helpers'; import { CandleDuration } from 'app/pages/PerpetualPage/hooks/graphql/useGetCandles'; import { TradingCandleDictionary } from './dictionary'; import { pushPrice } from 'utils/pair-price-tracker'; @@ -114,7 +110,6 @@ const tradingChartDataFeeds = ( const { baseToken, quoteToken } = getTokensFromSymbol(symbolInfo.name); let items = await queryPairByChunks( - graphqlClient, candleDetails, baseToken, quoteToken, @@ -122,7 +117,6 @@ const tradingChartDataFeeds = ( Math.floor( Math.min(to + candleDetails.candleSeconds, Date.now() / 1e3), ), - hasDirectFeed(symbolInfo.name), ); if (!items || items.length === 0) { diff --git a/src/app/components/TradingChart/dictionary.ts b/src/app/components/TradingChart/dictionary.ts index 2d84814fe3..7265bf7f4e 100644 --- a/src/app/components/TradingChart/dictionary.ts +++ b/src/app/components/TradingChart/dictionary.ts @@ -10,23 +10,89 @@ export class TradingCandleDictionary { >([ [ CandleDuration.M_1, - new CandleDetails('candleStickMinutes', 'D', 1, 5, 60), + new CandleDetails('candleSticksMinutes', 'D', 1, 5, 60, '1m'), + ], + [ + CandleDuration.M_10, + new CandleDetails('candleSticksTenMinutes', 'D', 3, 5, 60 * 10, '10m'), ], [ CandleDuration.M_15, - new CandleDetails('candleStickFifteenMinutes', 'D', 3, 5, 60 * 15), + new CandleDetails( + 'candleSticksFifteenMinutes', + 'D', + 3, + 5, + 60 * 15, + '15m', + ), + ], + [ + CandleDuration.M_30, + new CandleDetails('candleSticksThirtyMinutes', 'D', 3, 5, 60 * 30, '30m'), ], [ CandleDuration.H_1, - new CandleDetails('candleStickHours', 'D', 5, 5, 60 * 60), + new CandleDetails('candleSticksHours', 'D', 5, 5, 60 * 60, '1h'), ], [ CandleDuration.H_4, - new CandleDetails('candleStickFourHours', 'D', 10, 10, 60 * 60 * 4), + new CandleDetails( + 'candleSticksFourHours', + 'D', + 10, + 10, + 60 * 60 * 4, + '4h', + ), + ], + [ + CandleDuration.H_12, + new CandleDetails( + 'candleSticksTwelveHours', + 'D', + 10, + 10, + 60 * 60 * 12, + '12h', + ), ], [ CandleDuration.D_1, - new CandleDetails('candleStickDays', 'D', 90, 90, 60 * 60 * 24), + new CandleDetails('candleSticksDays', 'D', 90, 90, 60 * 60 * 24, '1d'), + ], + [ + CandleDuration.D_3, + new CandleDetails( + 'candleSticksThreeDays', + 'D', + 90, + 90, + 60 * 60 * 24 * 3, + '3d', + ), + ], + [ + CandleDuration.W_1, + new CandleDetails( + 'candleSticksOneWeek', + 'D', + 90, + 90, + 60 * 60 * 24 * 7, + '1w', + ), + ], + [ + CandleDuration.D_30, + new CandleDetails( + 'candleSticksOneMonth', + 'D', + 90, + 90, + 60 * 60 * 24 * 30, + '30d', + ), ], ]); diff --git a/src/app/components/TradingChart/helpers.ts b/src/app/components/TradingChart/helpers.ts index 67c9ec3924..e72ce7a541 100644 --- a/src/app/components/TradingChart/helpers.ts +++ b/src/app/components/TradingChart/helpers.ts @@ -1,46 +1,27 @@ -import { ApolloClient, gql } from '@apollo/client'; import { CandleDetails } from 'app/pages/PerpetualPage/hooks/graphql/useGetCandles'; -import { uniqBy } from 'lodash'; import { Asset } from 'types'; import { getTokenContract } from 'utils/blockchain/contract-helpers'; - -// maximum number of candles that should be loaded in one request -const CHUNK_SIZE = 1000; -const endTimeChache = new Map(); - -export type Bar = { - time: number; - low: number; - high: number; - open: number; - close: number; - volume?: number; -}; - -export type CandleSticksResponse = { - id: string; - open: number; - high: number; - low: number; - close: number; - totalVolume: number; - periodStartUnix: number; -}; +import { Bar } from './types'; +import { + CHUNK_SIZE, + SOVRYN_INDEXER_MAINNET, + SOVRYN_INDEXER_TESTNET, +} from './constants'; +import { isMainnet } from 'utils/classifiers'; type TimestampChunk = { from: number; to: number; }; -const pairstoInvert = ['RBTC/DLLR']; +const pairsToInvert = ['RBTC/DLLR']; -export const shouldInvertPair = (symbolName: string) => - pairstoInvert.includes(symbolName); +const indexerBaseUrl = isMainnet + ? SOVRYN_INDEXER_MAINNET + : SOVRYN_INDEXER_TESTNET; -export const hasDirectFeed = (symbolName: string) => { - const [, quote] = symbolName.split('/') as [Asset, Asset]; - return [Asset.RBTC, Asset.XUSD].includes(quote); -}; +export const shouldInvertPair = (symbolName: string) => + pairsToInvert.includes(symbolName); const splitPeriodToChunks = ( from: number, @@ -74,32 +55,18 @@ const splitPeriodToChunks = ( }; export const queryPairByChunks = async ( - client: ApolloClient, candleDetails: CandleDetails, baseToken: string, quoteToken: string, startTime: number, endTime: number, - hasDirectPair: boolean, - candleLimit: number = CHUNK_SIZE, - preventFill: boolean = false, ): Promise => { const queries = splitPeriodToChunks( startTime, endTime, candleDetails, ).map(item => - queryCandles( - client, - candleDetails, - hasDirectPair, - baseToken, - quoteToken, - item.from, - item.to, - candleLimit, - preventFill, - ), + queryCandles(candleDetails, baseToken, quoteToken, item.from, item.to), ); return Promise.all(queries).then(items => @@ -107,344 +74,27 @@ export const queryPairByChunks = async ( ); }; -type Candle = { - open: string; - high: string; - low: string; - close: string; - totalVolume: string; - periodStartUnix: string; -}; - -const candleToBar = (item: Candle): Bar => ({ - open: Number(item.open), - high: Number(item.high), - low: Number(item.low), - close: Number(item.close), - volume: Number(item.totalVolume), - time: Number(item.periodStartUnix) * 1000, -}); - -const queryDirectPair = async ( - client: ApolloClient, - candleDetails: CandleDetails, - baseToken: string, - quoteToken: string, - startTime: number, - endTime: number, - candleLimit: number = CHUNK_SIZE, -): Promise => { - const query = gql` - { - ${candleDetails.entityName} ( - where: { - baseToken: "${baseToken}" - quoteToken: "${quoteToken}" - periodStartUnix_gte: ${startTime} - periodStartUnix_lte: ${endTime} - } - orderBy: periodStartUnix - orderDirection: desc - first: ${candleLimit} - ) { - id - open - high - low - close - totalVolume - periodStartUnix - } - } - `; - return client - .query({ - query, - }) - .then(response => response.data?.[candleDetails.entityName] || []) - .then(items => items.map(candleToBar)); -}; - -const fillItem = (base: Bar, quote?: Bar, lastQuote?: Bar): Bar | null => { - if (!quote && lastQuote) { - quote = lastQuote; - } - - if (!quote) { - return null; - } - - return { - open: base.open / quote.open, - high: base.high / quote.high, - low: base.low / quote.low, - close: base.close / quote.close, - volume: 0, - time: base.time, - }; -}; - -export const getEndTime = (baseToken: string, quoteToken: string) => { - const key = `${baseToken}-${quoteToken}`; - return endTimeChache.get(key); -}; - -export const setEndTime = ( - baseToken: string, - quoteToken: string, - timestamp: number, -) => { - const key = `${baseToken}-${quoteToken}`; - endTimeChache.set(key, timestamp); -}; - -const getFirstCandleTimestamp = async ( - client: ApolloClient, - candleDetails: CandleDetails, - baseToken: string, - quoteToken: string, -): Promise => { - const query = gql` - { - ${candleDetails.entityName} ( - where: { - baseToken: "${baseToken}" - quoteToken: "${quoteToken}" - } - orderBy: periodStartUnix - orderDirection: asc - first: 1 - ) { - periodStartUnix - } - } - `; - return client - .query({ - query, - }) - .then(response => response.data?.[candleDetails.entityName] || []) - .then(items => items[0]?.periodStartUnix || Date.now() / 1000); -}; - -const getBarOlderThan = async ( - client: ApolloClient, - candleDetails: CandleDetails, - baseToken: string, - quoteToken: string, - timestamp, -): Promise => { - const query = gql` - { - ${candleDetails.entityName} ( - where: { - baseToken: "${baseToken}" - quoteToken: "${quoteToken}" - periodStartUnix_lte: ${timestamp} - } - orderBy: periodStartUnix - orderDirection: desc - first: 1 - ) { - open - close - high - low - totalVolume - periodStartUnix - } - } - `; - return client - .query({ - query, - }) - .then(response => response.data?.[candleDetails.entityName] || []) - .then(items => items.map(candleToBar)) - .then(items => items[0]); -}; - -const getBarNewerThan = async ( - client: ApolloClient, - candleDetails: CandleDetails, - baseToken: string, - quoteToken: string, - timestamp, -): Promise => { - const query = gql` - { - ${candleDetails.entityName} ( - where: { - baseToken: "${baseToken}" - quoteToken: "${quoteToken}" - periodStartUnix_gte: ${timestamp} - } - orderBy: periodStartUnix - orderDirection: asc - first: 1 - ) { - open - close - high - low - totalVolume - periodStartUnix - } - } - `; - return client - .query({ - query, - }) - .then(response => response.data?.[candleDetails.entityName] || []) - .then(items => items.map(candleToBar)) - .then(items => items[0]); -}; - -export const queryCustomPairs = async ( - client: ApolloClient, - candleDetails: CandleDetails, - baseToken: string, - quoteToken: string, - startTime: number, - endTime: number, - candleLimit: number = CHUNK_SIZE, -) => { - return Promise.all([ - queryDirectPair( - client, - candleDetails, - baseToken, - getTokenAddress(Asset.XUSD), - startTime, - endTime, - candleLimit, - ), - queryDirectPair( - client, - candleDetails, - quoteToken, - getTokenAddress(Asset.XUSD), - startTime, - endTime, - candleLimit, - ), - ]).then(e => { - const baseCandles: Bar[] = e[0]; - const quoteCandles: Bar[] = e[1]; - - const items: Bar[] = []; - let lastQuote; - let lastBase; - - for (let base of baseCandles) { - const quote = quoteCandles.find(item => item.time === base.time); - - const item = fillItem(base, quote, lastQuote); - if (item) { - items.push(item); - } - - if (quote) { - lastQuote = quote; - } - } - - for (let quote of quoteCandles) { - const base = items.find(item => item.time === quote.time); - - if (!base && lastBase) { - const item = fillItem(lastBase, quote, lastBase); - if (item) { - items.push(item); - } else { - items.push(lastBase); - } - } - - if (base) { - lastBase = base; - } - } - - return items; - }); -}; - export const queryCandles = async ( - client: ApolloClient, candleDetails: CandleDetails, - directFeed: boolean, baseToken: string, quoteToken: string, startTime: number, endTime: number, - candleLimit: number = CHUNK_SIZE, - preventFill: boolean = false, ) => { try { - const graphStartTime = getEndTime(baseToken, quoteToken); - if (graphStartTime === undefined) { - if (directFeed) { - const firstCandleTimestamp = await getFirstCandleTimestamp( - client, - candleDetails, - baseToken, - quoteToken, - ); - setEndTime(baseToken, quoteToken, firstCandleTimestamp); - } else { - const base = await getFirstCandleTimestamp( - client, - candleDetails, - baseToken, - getTokenAddress(Asset.XUSD), - ); - const quote = await getFirstCandleTimestamp( - client, - candleDetails, - quoteToken, - getTokenAddress(Asset.XUSD), - ); - setEndTime(baseToken, quoteToken, Math.min(base, quote)); - } - } + const fullIndexerUrl = `${indexerBaseUrl}base=${baseToken}"e=${quoteToken}&start=${startTime}&end=${endTime}&timeframe=${candleDetails.candleSymbol}`; - const bars: Bar[] = await (directFeed - ? queryDirectPair( - client, - candleDetails, - baseToken, - quoteToken, - startTime, - endTime, - candleLimit, - ) - : queryCustomPairs( - client, - candleDetails, - baseToken, - quoteToken, - startTime, - endTime, - candleLimit, - )); + const result = await (await fetch(fullIndexerUrl)).json(); - if (preventFill) { - return bars; - } + const bars: Bar[] = result.data.map(item => ({ + time: Number(item.date) * 1000, + low: item.low, + high: item.high, + open: item.open, + close: item.close, + })); - return addMissingBars( - bars, - client, - baseToken, - quoteToken, - candleDetails, - graphStartTime !== undefined && graphStartTime > startTime - ? graphStartTime - : startTime, - endTime, - ); + return bars; } catch (error) { console.error(error); throw new Error(`Request error: ${error}`); @@ -461,171 +111,3 @@ export const getTokensFromSymbol = (symbol: string) => { quoteToken: getTokenAddress(quote as Asset), }; }; - -export const addMissingBars = async ( - bars: Bar[], - client: ApolloClient, - baseToken: string, - quoteToken: string, - candleDetails: CandleDetails, - startTimestamp: number, - endTimestamp: number, -): Promise => { - const seconds = candleDetails.candleSeconds; - const barCount = Math.floor((endTimestamp - startTimestamp) / seconds); - - if (bars.length === 0 && barCount <= 2) { - return []; - } - - let items = uniqBy(bars, 'time').sort((a, b) => a.time - b.time); - - if (items.length === 0) { - const oldestExistingBar = await getBarOlderThan( - client, - candleDetails, - baseToken, - quoteToken, - startTimestamp, - ); - - const newestBar = await getBarNewerThan( - client, - candleDetails, - baseToken, - quoteToken, - endTimestamp, - ); - - items = [ - { - time: startTimestamp * 1000, - open: oldestExistingBar?.open || 0, - close: oldestExistingBar?.open || 0, - high: oldestExistingBar?.open || 0, - low: oldestExistingBar?.open || 0, - volume: 0, - }, - { - time: endTimestamp * 1000, - open: newestBar?.open || 0, - close: newestBar?.open || 0, - high: newestBar?.open || 0, - low: newestBar?.open || 0, - volume: 0, - }, - ]; - } - - // fill previous bars - - const firstBar = items[0]; - - // missing bar count between first bar and start timestamp - const missingBarCountStart = Math.floor( - (firstBar.time / 1000 - startTimestamp) / seconds, - ); - - if (missingBarCountStart > 0) { - let i = missingBarCountStart; - while (i > 0) { - let time = firstBar.time - (i + 1) * seconds * 1000; - - if (time >= Date.now()) { - break; - } - - // time = time < startTimestamp * 1000 ? startTimestamp * 1000 : time; - - items.push({ - open: firstBar.close, - high: firstBar.close, - low: firstBar.close, - close: firstBar.close, - volume: 0, - time, - }); - - i--; - } - } - - items = uniqBy(items, 'time').sort((a, b) => a.time - b.time); - - const lastBar = items[items.length - 1]; - - const missingBarCountEnd = Math.floor( - (endTimestamp - lastBar.time / 1000) / seconds, - ); - - if (missingBarCountEnd >= 1) { - let i = missingBarCountEnd; - while (i > 0) { - let time = lastBar.time + i * seconds * 1000; - items.push({ - open: lastBar.close, - high: lastBar.close, - low: lastBar.close, - close: lastBar.close, - volume: 0, - time, - }); - - i--; - } - } - - items = uniqBy(items, 'time').sort((a, b) => a.time - b.time); - - if (barCount - items.length > 0) { - let index = 0; - const firstItem = items[0]; - const newBars: Bar[] = []; - while (index < barCount) { - const nextTime = firstItem.time + (index + 1) * seconds * 1000; - const search = items.find(item => item.time === nextTime); - - if (search) { - newBars.push(search); - } else { - const searchNext = items.find(item => item.time > nextTime); - - if (searchNext) { - const previous = newBars - .filter(item => item.time < nextTime) - .sort((a, b) => b.time - a.time)[0]; - - const open = previous ? previous.close : searchNext.open; - const close = searchNext.close; - - const high = Math.max(open, close); - const low = Math.min(open, close); - - newBars.push({ - open, - high, - low, - close, - volume: 0, - time: nextTime, - }); - } - } - - index++; - } - items = newBars; - } - - items = items.map((item, index) => { - const next = items[index + 1] || item; - const close = !next.volume ? item.close : next.open; - - return { - ...item, - close, - }; - }); - - return items; -}; diff --git a/src/app/components/TradingChart/index.tsx b/src/app/components/TradingChart/index.tsx index 60f8cfba74..208b697a0d 100644 --- a/src/app/components/TradingChart/index.tsx +++ b/src/app/components/TradingChart/index.tsx @@ -6,7 +6,7 @@ * and make any relevant changes before updating the library version: * https://github.com/tradingview/charting_library/wiki/Breaking-Changes */ -import React, { useEffect, useLayoutEffect, useMemo, useState } from 'react'; +import React, { useEffect, useLayoutEffect, useState } from 'react'; import classNames from 'classnames'; import { widget, @@ -18,11 +18,6 @@ import Datafeed from './datafeed'; import Storage from './storage'; import { noop } from '../../constants'; import { useApolloClient } from '@apollo/client'; -import { hasDirectFeed } from './helpers'; -import { Trans } from 'react-i18next'; -import { translations } from 'locales/i18n'; -import { AssetRenderer } from '../AssetRenderer'; -import { Asset } from 'types'; import { SeriesStyle } from './types'; export enum Theme { @@ -41,13 +36,6 @@ export function TradingChart(props: ChartContainerProps) { const [chart, setChart] = useState(null); const client = useApolloClient(); - const disabledFeatures = useMemo(() => { - if (!hasDirectFeed(props.symbol)) { - return ['header_chart_type']; //don't allow user to switch candle type if using a line chart - } - return []; - }, [props.symbol]); - useEffect(() => { try { // full list of widget config options here: https://github.com/tradingview/charting_library/wiki/Widget-Constructor/cf26598509d8bba6dc95c5fe8208caa5e8474827 @@ -71,7 +59,6 @@ export function TradingChart(props: ChartContainerProps) { 'header_symbol_search', //'header_saveload', //uncomment to disable storing of drawings 'header_compare', - ...disabledFeatures, ], autosize: true, // toolbar_bg: '#a3a3a3', @@ -106,20 +93,13 @@ export function TradingChart(props: ChartContainerProps) { } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [client, JSON.stringify(disabledFeatures)]); + }, [client]); useLayoutEffect(() => { if (chart && hasCharts) { chart.chart().resetData(); - // if quote asset is not RBTC or XUSD, make it line chart, otherwise candle - chart - .chart() - .setChartType( - (hasDirectFeed(props.symbol) - ? SeriesStyle.Candles - : SeriesStyle.Line) as number, - ); + chart.chart().setChartType(SeriesStyle.Candles as number); chart.chart().setSymbol(props.symbol, noop); } @@ -173,17 +153,6 @@ export function TradingChart(props: ChartContainerProps) { - {!hasDirectFeed(props.symbol) && ( -
- , - , - ]} - /> -
- )} ); diff --git a/src/app/components/TradingChart/streaming.ts b/src/app/components/TradingChart/streaming.ts index cbeb4fd861..bda67eb164 100644 --- a/src/app/components/TradingChart/streaming.ts +++ b/src/app/components/TradingChart/streaming.ts @@ -15,12 +15,8 @@ import { CandleDuration } from 'app/pages/PerpetualPage/hooks/graphql/useGetCand import { debug } from 'utils/debug'; import { pushPrice } from 'utils/pair-price-tracker'; import { TradingCandleDictionary } from './dictionary'; -import { - Bar, - getTokensFromSymbol, - hasDirectFeed, - queryPairByChunks, -} from './helpers'; +import { getTokensFromSymbol, queryPairByChunks } from './helpers'; +import { Bar } from './types'; type SubItem = { symbolInfo: any; @@ -55,15 +51,11 @@ export class Streaming { ); queryPairByChunks( - this.client!, details, baseToken, quoteToken, subscriptionItem?.lastBar?.time / 1000, Math.ceil(Date.now() / 1000), - hasDirectFeed(subscriptionItem?.symbolInfo?.name), - 1, - true, ) .then(bars => { bars.reverse().forEach((item, index) => { diff --git a/src/app/components/TradingChart/types.ts b/src/app/components/TradingChart/types.ts index 56da6bdac7..61af03d5b7 100644 --- a/src/app/components/TradingChart/types.ts +++ b/src/app/components/TradingChart/types.ts @@ -10,3 +10,12 @@ export enum SeriesStyle { PointAndFigure = 6, LineBreak = 7, } + +export type Bar = { + time: number; + low: number; + high: number; + open: number; + close: number; + volume?: number; +}; diff --git a/src/app/pages/PerpetualPage/components/TradingChart/helpers.ts b/src/app/pages/PerpetualPage/components/TradingChart/helpers.ts index a7c79f57aa..aecd56866a 100644 --- a/src/app/pages/PerpetualPage/components/TradingChart/helpers.ts +++ b/src/app/pages/PerpetualPage/components/TradingChart/helpers.ts @@ -94,19 +94,19 @@ export const symbolMap = PerpetualPairDictionary.list().reduce( export const resolutionMap: { [key: string]: CandleDuration } = { '1': CandleDuration.M_1, '5': CandleDuration.M_1, - '10': CandleDuration.M_1, + '10': CandleDuration.M_10, '15': CandleDuration.M_15, - '30': CandleDuration.M_15, + '30': CandleDuration.M_30, '60': CandleDuration.H_1, H: CandleDuration.H_1, '240': CandleDuration.H_4, - '720': CandleDuration.H_4, + '720': CandleDuration.H_12, '1440': CandleDuration.D_1, D: CandleDuration.D_1, '1D': CandleDuration.D_1, - '3D': CandleDuration.D_1, - W: CandleDuration.D_1, - '1W': CandleDuration.D_1, - M: CandleDuration.D_1, - '1M': CandleDuration.D_1, + '3D': CandleDuration.D_3, + W: CandleDuration.W_1, + '1W': CandleDuration.W_1, + M: CandleDuration.D_30, + '1M': CandleDuration.D_30, }; diff --git a/src/app/pages/PerpetualPage/hooks/graphql/useGetCandles.ts b/src/app/pages/PerpetualPage/hooks/graphql/useGetCandles.ts index 6759581949..e0e71cdd88 100644 --- a/src/app/pages/PerpetualPage/hooks/graphql/useGetCandles.ts +++ b/src/app/pages/PerpetualPage/hooks/graphql/useGetCandles.ts @@ -94,10 +94,16 @@ export const generateFirstCandleQuery = ( export enum CandleDuration { M_1 = 'M_1', + M_10 = 'M_10', M_15 = 'M_15', + M_30 = 'M_30', H_1 = 'H_1', H_4 = 'H_4', + H_12 = 'H_12', D_1 = 'D_1', + D_3 = 'D_3', + W_1 = 'W_1', + D_30 = 'D_30', } export class CandleDetails { @@ -108,12 +114,14 @@ export class CandleDetails { public intervalBack: number, public startDaysFromNow: number, // Number of days back to start from in default query public candleSeconds: number, + public candleSymbol: string, ) { this.entityName = entityName; this.resolutionBack = resolutionBack; this.intervalBack = intervalBack; this.startDaysFromNow = startDaysFromNow; this.candleSeconds = candleSeconds; + this.candleSymbol = candleSymbol; } } @@ -124,23 +132,89 @@ export class CandleDictionary { >([ [ CandleDuration.M_1, - new CandleDetails('candleSticksMinutes', 'D', 1, 5, 60), + new CandleDetails('candleSticksMinutes', 'D', 1, 5, 60, '1m'), + ], + [ + CandleDuration.M_10, + new CandleDetails('candleSticksTenMinutes', 'D', 3, 5, 60 * 10, '10m'), ], [ CandleDuration.M_15, - new CandleDetails('candleSticksFifteenMinutes', 'D', 3, 5, 60 * 15), + new CandleDetails( + 'candleSticksFifteenMinutes', + 'D', + 3, + 5, + 60 * 15, + '15m', + ), + ], + [ + CandleDuration.M_30, + new CandleDetails('candleSticksThirtyMinutes', 'D', 3, 5, 60 * 30, '30m'), ], [ CandleDuration.H_1, - new CandleDetails('candleSticksHours', 'D', 5, 5, 60 * 60), + new CandleDetails('candleSticksHours', 'D', 5, 5, 60 * 60, '1h'), ], [ CandleDuration.H_4, - new CandleDetails('candleSticksFourHours', 'D', 10, 10, 60 * 60 * 4), + new CandleDetails( + 'candleSticksFourHours', + 'D', + 10, + 10, + 60 * 60 * 4, + '4h', + ), + ], + [ + CandleDuration.H_12, + new CandleDetails( + 'candleSticksTwelveHours', + 'D', + 10, + 10, + 60 * 60 * 12, + '12h', + ), ], [ CandleDuration.D_1, - new CandleDetails('candleSticksDays', 'D', 90, 90, 60 * 60 * 24), + new CandleDetails('candleSticksDays', 'D', 90, 90, 60 * 60 * 24, '1d'), + ], + [ + CandleDuration.D_3, + new CandleDetails( + 'candleSticksThreeDays', + 'D', + 90, + 90, + 60 * 60 * 24 * 3, + '3d', + ), + ], + [ + CandleDuration.W_1, + new CandleDetails( + 'candleSticksOneWeek', + 'D', + 90, + 90, + 60 * 60 * 24 * 7, + '1w', + ), + ], + [ + CandleDuration.D_30, + new CandleDetails( + 'candleSticksOneMonth', + 'D', + 90, + 90, + 60 * 60 * 24 * 30, + '30d', + ), ], ]); diff --git a/yarn.lock b/yarn.lock index a3581282ac..c28f90ae02 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8813,15 +8813,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001248, caniuse-lite@^1.0.30001317: - version "1.0.30001487" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001487.tgz" - integrity sha512-83564Z3yWGqXsh2vaH/mhXfEM0wX+NlBCm1jYHOb97TrTWJEmPTccZgeLTPBUUb0PNVo+oomb7wkimZBIERClA== - -caniuse-lite@^1.0.30001507: - version "1.0.30001508" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001508.tgz#4461bbc895c692a96da399639cc1e146e7302a33" - integrity sha512-sdQZOJdmt3GJs1UMNpCCCyeuS2IEGLXnHyAo9yIO5JJDjbjoVRij4M1qep6P6gFpptD1PqIYgzM+gwJbOi92mw== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001248, caniuse-lite@^1.0.30001317, caniuse-lite@^1.0.30001507: + version "1.0.30001649" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001649.tgz" + integrity sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ== capital-case@^1.0.4: version "1.0.4"