{"version":3,"file":"3446.9cc7848f.js","mappings":"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","sources":["webpack://@finviz/website/../charts/app/constants/colors.js","webpack://@finviz/website/./js/app/header/market-badge.tsx","webpack://@finviz/website/./js/app/header/time.tsx","webpack://@finviz/website/./js/app/header/utils.ts","webpack://@finviz/website/./js/main/components/input.tsx","webpack://@finviz/website/./js/main/components/list/hooks.tsx","webpack://@finviz/website/./js/main/components/list/list-item.tsx","webpack://@finviz/website/./js/main/components/list/list.tsx","webpack://@finviz/website/./js/main/components/combo-box/combo-box-item.tsx","webpack://@finviz/website/./js/main/components/combo-box/combo-box.tsx","webpack://@finviz/website/./js/main/components/search/constants.ts","webpack://@finviz/website/./js/main/components/centered.tsx","webpack://@finviz/website/./js/main/components/search/search-error.tsx","webpack://@finviz/website/./js/main/components/highlight.tsx","webpack://@finviz/website/./js/main/components/search/search-item.tsx","webpack://@finviz/website/./js/main/components/search/util.ts","webpack://@finviz/website/./js/main/components/search/search-list.tsx","webpack://@finviz/website/./js/main/components/search/search.tsx","webpack://@finviz/website/./js/main/components/combo-box/hooks.ts","webpack://@finviz/website/./js/main/components/tooltip/tooltip-box.tsx","webpack://@finviz/website/./js/main/components/tooltip/tooltip.tsx","webpack://@finviz/website/./js/main/components/tooltip/tooltip-trigger.tsx","webpack://@finviz/website/./js/main/components/tooltip/hooks.ts","webpack://@finviz/website/./js/main/components/tooltip/tooltip-arrow.tsx","webpack://@finviz/website/./js/main/components/tooltip/types.ts","webpack://@finviz/website/./js/main/services/api.ts","webpack://@finviz/website/../charts/app/canvas/element.ts","webpack://@finviz/website/../charts/app/canvas/line.ts","webpack://@finviz/website/../charts/app/canvas/text.ts","webpack://@finviz/website/../charts/app/canvas/thumb.ts","webpack://@finviz/website/../charts/app/canvas/cache.js","webpack://@finviz/website/../charts/app/models/chart_settings/interfaces.ts","webpack://@finviz/website/../charts/app/charts/utils.ts","webpack://@finviz/website/../charts/app/charts/base_chart.ts","webpack://@finviz/website/../charts/app/charts/candle_stick.ts","webpack://@finviz/website/../charts/app/charts/candle_stick_hollow.ts","webpack://@finviz/website/../charts/app/charts/heikin_ashi.ts","webpack://@finviz/website/../charts/app/charts/line_chart.ts","webpack://@finviz/website/../charts/app/charts/market_sentiment.ts","webpack://@finviz/website/../charts/app/charts/multi_line_chart.ts","webpack://@finviz/website/../charts/app/charts/ohlc_chart.ts","webpack://@finviz/website/../charts/app/charts/perf_chart.ts","webpack://@finviz/website/../charts/app/charts/charts.ts","webpack://@finviz/website/../charts/app/constants/common.ts","webpack://@finviz/website/../charts/app/utils/chart-date-range-utils.ts","webpack://@finviz/website/../charts/app/controllers/renderUtils.ts","webpack://@finviz/website/../charts/app/helpers/atr.ts","webpack://@finviz/website/../charts/app/helpers/math.ts","webpack://@finviz/website/../charts/app/indicator-calculation/ema.ts","webpack://@finviz/website/../charts/app/indicator-calculation/main.ts","webpack://@finviz/website/../charts/app/models/chart/contstants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/index.ts","webpack://@finviz/website/../charts/app/models/constants.ts","webpack://@finviz/website/../charts/app/models/mouse/mouse-utils.ts","webpack://@finviz/website/../charts/app/models/mouse/mouse.ts","webpack://@finviz/website/../charts/app/models/pane.ts","webpack://@finviz/website/../charts/app/models/quoteCache.ts","webpack://@finviz/website/../charts/app/models/quote.ts","webpack://@finviz/website/../charts/app/models/quote/constants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/constants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/interactive_chart_settings.ts","webpack://@finviz/website/../charts/app/models/settings.ts","webpack://@finviz/website/../charts/app/models/utils.ts","webpack://@finviz/website/../charts/app/indicator-calculation/bb.ts","webpack://@finviz/website/../charts/app/overlays/overlay.ts","webpack://@finviz/website/../charts/app/overlays/bb.ts","webpack://@finviz/website/../charts/app/overlays/dch.ts","webpack://@finviz/website/../charts/app/overlays/ema.ts","webpack://@finviz/website/../charts/app/overlays/ema2.ts","webpack://@finviz/website/../charts/app/overlays/hilo.ts","webpack://@finviz/website/../charts/app/overlays/hline.ts","webpack://@finviz/website/../charts/app/overlays/ic.ts","webpack://@finviz/website/../charts/app/overlays/icf.ts","webpack://@finviz/website/../charts/app/overlays/kch.ts","webpack://@finviz/website/../charts/app/overlays/none.ts","webpack://@finviz/website/../charts/app/overlays/patterns.ts","webpack://@finviz/website/../charts/app/overlays/pp.ts","webpack://@finviz/website/../charts/app/overlays/sar.ts","webpack://@finviz/website/../charts/app/indicator-calculation/sma.ts","webpack://@finviz/website/../charts/app/overlays/sma.ts","webpack://@finviz/website/../charts/app/overlays/sma2.ts","webpack://@finviz/website/../charts/app/overlays/str.ts","webpack://@finviz/website/../charts/app/overlays/vp.ts","webpack://@finviz/website/../charts/app/indicator-calculation/vwap.ts","webpack://@finviz/website/../charts/app/overlays/vwap.ts","webpack://@finviz/website/../charts/app/overlays/overlays.ts","webpack://@finviz/website/../charts/app/utils.ts","webpack://@finviz/website/../charts/app/utils/abort_controller.ts","webpack://@finviz/website/../charts/app/utils/canvas.ts","webpack://@finviz/website/../charts/app/utils/chart.ts","webpack://@finviz/website/../charts/app/utils/colors.ts","webpack://@finviz/website/../charts/app/utils/convert_ta.ts","webpack://@finviz/website/../charts/app/utils/cursor.ts","webpack://@finviz/website/../charts/app/utils/draw_in_visible_area.ts","webpack://@finviz/website/../charts/app/utils/fetch_api.ts","webpack://@finviz/website/../charts/app/utils/helpers.ts","webpack://@finviz/website/../charts/types/shared.ts"],"sourcesContent":["// Keep in sync with Website repository colors.js file in: config/colors.js\r\n\r\nmodule.exports = {\r\n white: '#fff',\r\n black: '#000',\r\n inherit: 'inherit',\r\n transparent: 'transparent',\r\n current: 'currentColor',\r\n finviz: {\r\n 'blue-gray': '#262931',\r\n blue: '#4fa4f4',\r\n },\r\n gray: {\r\n 50: '#f3f3f5',\r\n 100: '#dedfe5',\r\n 200: '#c3c6d0',\r\n 300: '#a3a8b9',\r\n 400: '#868ea5',\r\n 500: '#676f85',\r\n 600: '#4c5263',\r\n 700: '#353945',\r\n 750: '#2c303b',\r\n 800: '#22262f',\r\n 900: '#14161d',\r\n },\r\n red: {\r\n 50: '#fef0f0',\r\n 100: '#fcd6d6',\r\n 200: '#fbb4b4',\r\n 300: '#fd8487',\r\n 400: '#fb5057',\r\n 500: '#d91e2b',\r\n 600: '#9f1f2a',\r\n 700: '#691f24',\r\n 800: '#45171a',\r\n 900: '#280e0f',\r\n },\r\n orange: {\r\n 50: '#fef2eb',\r\n 100: '#fdd9c5',\r\n 200: '#fab889',\r\n 300: '#ef9323',\r\n 400: '#ca7b14',\r\n 500: '#a0600e',\r\n 600: '#79460a',\r\n 700: '#583006',\r\n 800: '#3d1e03',\r\n 900: '#261101',\r\n },\r\n amber: {\r\n 50: '#fef2e7',\r\n 100: '#fedab5',\r\n 200: '#fbba56',\r\n 300: '#de9c1a',\r\n 400: '#bb830f',\r\n 500: '#956600',\r\n 600: '#704b00',\r\n 700: '#4f3400',\r\n 800: '#372200',\r\n 900: '#211300',\r\n },\r\n yellow: {\r\n 50: '#fdf2df',\r\n 100: '#fcdc86',\r\n 200: '#f3c736',\r\n 300: '#cda30b',\r\n 400: '#b08900',\r\n 500: '#8b6a00',\r\n 600: '#664e21',\r\n 700: '#46371e',\r\n 800: '#2f2516',\r\n 900: '#1b150d',\r\n },\r\n brightYellow: {\r\n 50: '#fff699',\r\n 100: '#fff200',\r\n },\r\n lime: {\r\n 50: '#ebfad6',\r\n 100: '#caec90',\r\n 200: '#aad547',\r\n 300: '#8db61e',\r\n 400: '#769913',\r\n 500: '#5b7800',\r\n 600: '#435900',\r\n 700: '#2e3e00',\r\n 800: '#1e2a00',\r\n 900: '#111900',\r\n },\r\n green: {\r\n 50: '#e7f7e8',\r\n 100: '#beeac1',\r\n 200: '#86d895',\r\n 300: '#34c062',\r\n 400: '#00a449',\r\n 500: '#19803d',\r\n 600: '#265d35',\r\n 700: '#1e4027',\r\n 800: '#162b1b',\r\n 900: '#0d1810',\r\n },\r\n emerald: {\r\n 50: '#ddfaee',\r\n 100: '#a2f0d2',\r\n 200: '#4dddaf',\r\n 300: '#25be93',\r\n 400: '#1d9f7b',\r\n 500: '#157e60',\r\n 600: '#035d47',\r\n 700: '#004139',\r\n 800: '#002c22',\r\n 900: '#001a13',\r\n },\r\n teal: {\r\n 50: '#e0f8fc',\r\n 100: '#9beef7',\r\n 200: '#4fd8e5',\r\n 300: '#27b9c4',\r\n 400: '#109ba5',\r\n 500: '#007c83',\r\n 600: '#005b62',\r\n 700: '#004045',\r\n 800: '#002b2e',\r\n 900: '#00191b',\r\n },\r\n blue: {\r\n 50: '#ebf4fe',\r\n 100: '#cae2fc',\r\n 200: '#9bcbfa',\r\n 300: '#57aefb',\r\n 400: '#2f91ef',\r\n 500: '#306dca',\r\n 600: '#2f5091',\r\n 700: '#263766',\r\n 800: '#1b2542',\r\n 900: '#101527',\r\n },\r\n violet: {\r\n 50: '#f4f2fe',\r\n 100: '#e1dbfd',\r\n 200: '#c9befc',\r\n 300: '#ad9bfb',\r\n 400: '#9978f9',\r\n 500: '#7c51e7',\r\n 600: '#5e36b8',\r\n 700: '#402979',\r\n 800: '#2a1e4e',\r\n 900: '#18122c',\r\n },\r\n purple: {\r\n 50: '#f9f1fe',\r\n 100: '#eed8fd',\r\n 200: '#e1b6fc',\r\n 300: '#d38bfb',\r\n 400: '#c85bf9',\r\n 500: '#ae27e0',\r\n 600: '#8514ac',\r\n 700: '#60077e',\r\n 800: '#44005a',\r\n 900: '#2a003a',\r\n },\r\n pink: {\r\n 50: '#fef1f4',\r\n 100: '#fdd6e1',\r\n 200: '#fcb2c7',\r\n 300: '#f984aa',\r\n 400: '#f25090',\r\n 500: '#cd2a74',\r\n 600: '#9d1658',\r\n 700: '#700c42',\r\n 800: '#4e052b',\r\n 900: '#32011a',\r\n },\r\n}\r\n","import classnames from 'classnames'\r\n\r\nimport { isAftermarket, isHoliday, isPremarket } from './utils'\r\n\r\nexport enum MarketBadgeType {\r\n None,\r\n Open,\r\n Closed,\r\n Premarket,\r\n Aftermarket,\r\n}\r\n\r\nexport function getMarketBadgeText(type: MarketBadgeType, _date?: Date) {\r\n switch (type) {\r\n case MarketBadgeType.Open:\r\n return {\r\n label: 'Markets Open',\r\n }\r\n case MarketBadgeType.Closed:\r\n // const holiday = getHoliday(date)\r\n\r\n return {\r\n label: 'Markets Closed',\r\n // description: holiday && (\r\n // <>\r\n // The markets observe U.S. holidays and are closed on\r\n //
\r\n // {holiday.label}\r\n // \r\n // ),\r\n }\r\n case MarketBadgeType.Premarket:\r\n return {\r\n label: 'Premarket',\r\n // description: (\r\n // <>\r\n // An additional time window when trading is possible.\r\n //
\r\n // We report it as the time between 7:00 AM and 9:30 AM\r\n // \r\n // ),\r\n }\r\n case MarketBadgeType.Aftermarket:\r\n return {\r\n label: 'Aftermarket',\r\n // description: (\r\n // <>\r\n // An additional time window when trading is still possible.\r\n //
\r\n // We report it as the time between 4:00 PM and 6:30 PM\r\n // \r\n // ),\r\n }\r\n }\r\n}\r\n\r\nexport function getMarketBadgeType(time: Date, hasUserPremium?: boolean) {\r\n if (isHoliday(time)) return MarketBadgeType.Closed\r\n if (isPremarket(time, hasUserPremium)) return MarketBadgeType.Premarket\r\n if (isAftermarket(time, hasUserPremium)) return MarketBadgeType.Aftermarket\r\n // if (isMarketOpen(time, hasUserPremium)) return MarketBadgeType.Open\r\n\r\n return MarketBadgeType.None\r\n}\r\n\r\nexport interface MarketBadgeProps {\r\n badge: MarketBadgeType\r\n className?: string\r\n}\r\n\r\nexport function MarketBadge({ badge, className }: MarketBadgeProps) {\r\n if (badge === MarketBadgeType.None) return null\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import throttle from 'lodash.throttle'\r\nimport * as React from 'react'\r\n\r\nimport { Tooltip, TooltipTrigger, useTooltipState } from '../../main/components/tooltip'\r\nimport { Heading } from '../../main/components/typography'\r\nimport { useResizeObserver } from '../../main/hooks/use-resize-observer'\r\nimport { MarketBadge, MarketBadgeProps, getMarketBadgeText, getMarketBadgeType } from './market-badge'\r\nimport { TimeFormatType, getDate, getFormattedDateString } from './utils'\r\n\r\nconst UPDATE_INTERVAL = 10000\r\n\r\nenum TimeBreakpointMode {\r\n container,\r\n window,\r\n}\r\n\r\nexport interface TimeBreakpoint {\r\n minWidth: number\r\n marketBadgeText: boolean\r\n timeFormat: TimeFormatType\r\n}\r\n\r\nconst BREAKPOINTS: TimeBreakpoint[] = [\r\n { minWidth: -Infinity, marketBadgeText: false, timeFormat: 'timeOnly' },\r\n { minWidth: 140, marketBadgeText: false, timeFormat: 'short' },\r\n { minWidth: 180, marketBadgeText: false, timeFormat: 'long' },\r\n { minWidth: 255, marketBadgeText: true, timeFormat: 'long' },\r\n]\r\n\r\nfunction getTimeState(fixedTime?: string | Date, hasUserPremium: boolean = FinvizSettings.hasUserPremium) {\r\n const time = getDate(fixedTime)\r\n const badge = getMarketBadgeType(time, hasUserPremium)\r\n\r\n return { time, badge }\r\n}\r\n\r\nfunction TooltipBadge(props: MarketBadgeProps & { time: Date }) {\r\n const state = useTooltipState({ placement: 'bottom' })\r\n const badge = getMarketBadgeText(props.badge, props.time)\r\n\r\n if (!badge) return null\r\n\r\n return (\r\n <>\r\n \r\n
\r\n \r\n
\r\n
\r\n \r\n \r\n {badge.label}\r\n \r\n {/* {badge.description && {badge.description}} */}\r\n \r\n \r\n )\r\n}\r\n\r\nfunction StaticBadge(props: MarketBadgeProps & { time: Date }) {\r\n const badge = getMarketBadgeText(props.badge, props.time)\r\n\r\n if (!badge) return null\r\n\r\n return (\r\n <>\r\n \r\n {`${badge.label} · `}\r\n \r\n )\r\n}\r\n\r\n/**\r\n * Find matching breakpoint or return the last (largest) one\r\n */\r\nfunction findMatchingBreakpoint(compareWidth: number | undefined, breakpoints: TimeBreakpoint[]) {\r\n if (typeof compareWidth !== 'number') return breakpoints[breakpoints.length - 1]\r\n\r\n const matchingBreakpoints = breakpoints.filter((breakpoint) => compareWidth >= breakpoint.minWidth)\r\n\r\n return matchingBreakpoints.pop() ?? breakpoints[breakpoints.length - 1]\r\n}\r\n\r\nfunction getCurrentWidth(mode: TimeBreakpointMode, element: HTMLElement | null) {\r\n return mode === TimeBreakpointMode.window ? window.innerWidth : element?.clientWidth ?? 0\r\n}\r\n\r\ninterface TimeProps extends React.HTMLProps {\r\n /**\r\n * Set custom time to display\r\n */\r\n fixedTime?: string | Date\r\n\r\n /**\r\n * What to measure the breakpoints to\r\n * - `container` parent element\r\n * - `window` window\r\n *\r\n * @default \"container\"\r\n */\r\n breakpointMode?: keyof typeof TimeBreakpointMode\r\n\r\n /**\r\n * Defines what information is visible at which breakpoint. Local mode measures\r\n * the component wrapper div and global mode measures window width. The definitions\r\n * must be ascending in width\r\n */\r\n breakpoints?: TimeBreakpoint[]\r\n}\r\n\r\nexport function Time({\r\n className,\r\n fixedTime,\r\n breakpointMode = 'container',\r\n breakpoints = BREAKPOINTS,\r\n ...props\r\n}: TimeProps) {\r\n const ResizeObserver = useResizeObserver()\r\n const rootRef = React.useRef(null)\r\n const [state, setState] = React.useState(getTimeState(fixedTime))\r\n const [currentBreakpoint, setBreakpoint] = React.useState(null)\r\n\r\n React.useEffect(() => {\r\n const interval = setInterval(() => setState(getTimeState(fixedTime)), UPDATE_INTERVAL)\r\n return () => clearInterval(interval)\r\n }, [fixedTime])\r\n\r\n React.useEffect(() => {\r\n if (!ResizeObserver || !rootRef.current) return\r\n\r\n if (!currentBreakpoint) {\r\n const currentWidth = getCurrentWidth(TimeBreakpointMode[breakpointMode], rootRef.current)\r\n setBreakpoint(findMatchingBreakpoint(currentWidth, breakpoints))\r\n }\r\n\r\n const handleResize = throttle(() => {\r\n const currentWidth = getCurrentWidth(TimeBreakpointMode[breakpointMode], rootRef.current)\r\n const foundBreakpoint = findMatchingBreakpoint(currentWidth, breakpoints)\r\n\r\n if (foundBreakpoint !== currentBreakpoint) setBreakpoint(foundBreakpoint)\r\n }, 150)\r\n\r\n const observer = new ResizeObserver((entries) => {\r\n window.requestAnimationFrame(() => {\r\n if (Array.isArray(entries) && entries.length > 0) handleResize()\r\n })\r\n })\r\n\r\n observer.observe(rootRef.current)\r\n window.addEventListener('resize', handleResize)\r\n\r\n return () => {\r\n observer.disconnect()\r\n window.removeEventListener('resize', handleResize)\r\n }\r\n }, [ResizeObserver, currentBreakpoint, breakpoints, breakpointMode])\r\n\r\n return (\r\n
\r\n {currentBreakpoint && (\r\n
\r\n {currentBreakpoint.marketBadgeText ? (\r\n \r\n ) : (\r\n \r\n )}\r\n {getFormattedDateString(state.time, currentBreakpoint.timeFormat)}\r\n
\r\n )}\r\n
\r\n )\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\n/**\r\n * Check if a given date is DST in the US\r\n * - begins on the second Sunday in March\r\n * - ends on the first Sunday in November\r\n *\r\n * Keep in sync with https://github.com/finvizhq/charts/blob/master/app/utils.ts\r\n */\r\nexport function getIsDstInNy(date: Date) {\r\n const dayNumber = date.getDate()\r\n const monthIndex = date.getMonth()\r\n const dayOfWeek = date.getDay()\r\n const previousSunday = dayNumber - dayOfWeek\r\n if (monthIndex < 2 || monthIndex > 10) {\r\n return false\r\n }\r\n if (monthIndex > 2 && monthIndex < 10) {\r\n return true\r\n }\r\n return monthIndex === 2 ? previousSunday >= 8 : previousSunday <= 0\r\n}\r\n\r\nexport function getDate(seed?: string | number | Date | null) {\r\n var date = seed != null ? new Date(seed) : new Date()\r\n const dateAsNY = new Date(\r\n date.getUTCFullYear(),\r\n date.getUTCMonth(),\r\n date.getUTCDate(),\r\n date.getUTCHours() - 5,\r\n date.getUTCMinutes(),\r\n date.getUTCSeconds()\r\n )\r\n const isDst = getIsDstInNy(dateAsNY)\r\n\r\n if (isDst) {\r\n dateAsNY.setUTCHours(dateAsNY.getUTCHours() + 1)\r\n }\r\n\r\n return dateAsNY\r\n}\r\n\r\nfunction getWeekDay(date: Date) {\r\n return date.toLocaleDateString('en-US', { weekday: 'short' })\r\n}\r\n\r\nfunction getMonth(date: Date, uppercase = true) {\r\n const name = date.toLocaleDateString('en-US', { month: 'short' })\r\n return uppercase ? name.toUpperCase() : name\r\n}\r\n\r\nfunction getDay(date: Date) {\r\n return date.getDate().toString().padStart(2, '0')\r\n}\r\n\r\nfunction getTime(date: Date) {\r\n return date.toLocaleString('en-US', { hour: 'numeric', minute: 'numeric', hour12: true })\r\n}\r\n\r\nenum TimeFormat {\r\n long,\r\n short,\r\n dateOnly,\r\n timeOnly,\r\n}\r\n\r\nexport type TimeFormatType = keyof typeof TimeFormat\r\n\r\nexport function getFormattedDateString(date: Date = getDate(), format: TimeFormatType = 'long') {\r\n switch (TimeFormat[format]) {\r\n case TimeFormat.long:\r\n return `${getWeekDay(date)} ${getMonth(date)} ${getDay(date)} ${date.getFullYear()} ${getTime(date)} ET`\r\n case TimeFormat.short:\r\n return `${getWeekDay(date)} ${getMonth(date)} ${getDay(date)} ${getTime(date)}`\r\n case TimeFormat.dateOnly:\r\n return `${getMonth(date, false)} ${getDay(date)}`\r\n case TimeFormat.timeOnly:\r\n return getTime(date)\r\n }\r\n}\r\n\r\nexport function formatDate(value: Date | unknown, inputOrOutputFormat: string, outputFormat?: string): string {\r\n return dateFns.format(\r\n dateFns.isDate(value) ? (value as Date) : dateFns.parse(`${value}`, inputOrOutputFormat, new Date()),\r\n outputFormat ?? inputOrOutputFormat\r\n )\r\n}\r\n\r\nexport function isPremarket(date: Date = getDate(), isPremium = FinvizSettings.hasUserPremium) {\r\n const dayOfWeek = date.getDay()\r\n const min = date.getMinutes()\r\n const hours = date.getHours()\r\n\r\n if (isPremium && dayOfWeek !== 0 && dayOfWeek !== 6 && (hours === 7 || hours === 8 || (hours === 9 && min < 30))) {\r\n return true\r\n }\r\n return false\r\n}\r\n\r\nexport function isAftermarket(date: Date = getDate(), isPremium = FinvizSettings.hasUserPremium) {\r\n const dayOfWeek = date.getDay()\r\n const min = date.getMinutes()\r\n\r\n if (\r\n isPremium &&\r\n dayOfWeek !== 0 &&\r\n dayOfWeek !== 6 &&\r\n (date.getHours() === 16 || date.getHours() === 17 || (date.getHours() === 18 && min < 30))\r\n ) {\r\n return true\r\n }\r\n return false\r\n}\r\n\r\n/**\r\n * https://www.nyse.com/markets/hours-calendars\r\n */\r\nconst HOLIDAY_DATES = [\r\n {\r\n label: \"New Year's Day\",\r\n test: (day: number, month: number) => month === 1 && day === 1,\r\n },\r\n {\r\n label: 'Martin Luther King, Jr. Day',\r\n test: (day: number, month: number) => month === 1 && day === 15,\r\n },\r\n {\r\n label: 'Presidents Day',\r\n test: (day: number, month: number) => month === 2 && day === 19,\r\n },\r\n {\r\n label: 'Good Friday',\r\n test: (day: number, month: number) => month === 3 && day === 29,\r\n },\r\n {\r\n label: 'Memorial Day',\r\n test: (day: number, month: number) => month === 5 && day === 27,\r\n },\r\n {\r\n label: 'Juneteenth Holiday',\r\n test: (day: number, month: number) => month === 6 && day === 19,\r\n },\r\n {\r\n label: 'Early Close',\r\n test: (day: number, month: number, hours: number) => month === 7 && day === 3 && hours >= 13,\r\n },\r\n {\r\n label: 'Independence Day',\r\n test: (day: number, month: number) => month === 7 && day === 4,\r\n },\r\n {\r\n label: 'Labor Day',\r\n test: (day: number, month: number) => month === 9 && day === 2,\r\n },\r\n {\r\n label: 'Thanksgiving Day',\r\n test: (day: number, month: number) => month === 11 && day === 28,\r\n },\r\n {\r\n label: 'Day after Thanksgiving (closed from 1 PM)',\r\n test: (day: number, month: number, hours: number) => month === 11 && day === 29 && hours >= 13,\r\n },\r\n {\r\n label: 'Christmas Day',\r\n test: (day: number, month: number) => month === 12 && day === 25,\r\n },\r\n]\r\n\r\nexport function getHoliday(date: Date = getDate()) {\r\n var day = date.getDate()\r\n var month = date.getMonth() + 1\r\n var hours = date.getHours()\r\n\r\n return HOLIDAY_DATES.find((holiday) => holiday.test(day, month, hours))\r\n}\r\n\r\nexport function isHoliday(date: Date = getDate()) {\r\n return !!getHoliday(date)\r\n}\r\n\r\nexport function isMarketOpen(date: Date = getDate(), isPremium = FinvizSettings.hasUserPremium) {\r\n if (isPremarket(date, isPremium) || isAftermarket(date, isPremium) || isHoliday(date)) {\r\n return false\r\n }\r\n\r\n const dayOfWeek = date.getDay()\r\n const hour = date.getHours()\r\n const minute = date.getMinutes()\r\n\r\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6\r\n // Day starts at 9:30\r\n const dayStarted = hour === 9 ? minute >= 30 : hour >= 10\r\n // Ends at 16:00\r\n const dayEnded = hour >= 16\r\n\r\n return !isWeekend && dayStarted && !dayEnded\r\n}\r\n","import classnames from 'classnames'\r\nimport { ForwardedRef, HTMLProps, PropsWithChildren, ReactNode, forwardRef, useMemo } from 'react'\r\n\r\nimport { ButtonPadding } from './button'\r\nimport { Icon, IconNameType, isValidIconName } from './icon'\r\nimport { Label } from './typography'\r\n\r\nexport enum InputTheme {\r\n none,\r\n light,\r\n dark,\r\n navigationBar,\r\n}\r\n\r\nexport enum InputRounding {\r\n none = '',\r\n regular = 'rounded-md',\r\n}\r\n\r\n/**\r\n * Enum for input size. Only set size on larger viewports to avoid page zooming\r\n */\r\nexport enum InputSize {\r\n small = 'h-6 text-2xs', // 24px height\r\n regular = 'h-7 text-2xs', // 28px height\r\n medium = 'h-8 text-sm', // 32px height\r\n large = 'h-9 text-sm', // 36px height\r\n}\r\n\r\nfunction getInputTheme(theme: InputTheme, isError = false) {\r\n switch (theme) {\r\n case InputTheme.none:\r\n return {}\r\n case InputTheme.dark:\r\n return {\r\n input: classnames('border bg-gray-800 text-gray-50 disabled:bg-gray-700 disabled:text-gray-400', {\r\n 'border-gray-600 hover:border-gray-400 focus:border-blue-400 focus:hover:border-blue-400 disabled:border-gray-700':\r\n !isError,\r\n 'border-red-400': isError,\r\n }),\r\n icon: classnames({\r\n 'text-gray-500 group-focus-within:text-blue-400': !isError,\r\n 'text-red-400': isError,\r\n }),\r\n }\r\n case InputTheme.navigationBar:\r\n return {\r\n input: classnames(\r\n 'border bg-transparent disabled:border-gray-700 disabled:bg-gray-700 disabled:text-gray-400',\r\n {\r\n 'border-gray-100 dark:border-gray-600 text-gray-750 dark:text-gray-50':\r\n !isError && !FinvizSettings.hasUserPremium,\r\n 'border-gray-600 text-gray-50': !isError && FinvizSettings.hasUserPremium,\r\n 'border-red-400': isError,\r\n }\r\n ),\r\n icon: classnames({\r\n 'text-gray-500': !isError,\r\n 'text-red-400': isError,\r\n }),\r\n }\r\n default:\r\n return {\r\n input: classnames(\r\n 'border', // Base styles\r\n 'bg-white disabled:bg-gray-50 disabled:text-gray-500', // Light\r\n 'dark:bg-gray-800 dark:disabled:bg-gray-700 dark:disabled:text-gray-400', // Dark\r\n {\r\n 'border-gray-100 hover:border-gray-300 focus:border-blue-400 hover:focus:border-blue-400 disabled:hover:border-gray-100 dark:border-gray-600 dark:hover:border-gray-400 dark:focus:border-blue-400 dark:hover:focus:border-blue-400 dark:disabled:border-gray-700':\r\n !isError,\r\n 'border-red-400': isError,\r\n }\r\n ),\r\n icon: classnames({\r\n 'text-gray-300 group-focus-within:text-blue-400 dark:text-gray-500': !isError,\r\n 'text-red-400': isError,\r\n }),\r\n }\r\n }\r\n}\r\n\r\ntype OmitNativeProps = Omit, 'label' | 'size'>\r\n\r\nexport interface InputProps {\r\n /**\r\n * Label which is rendered above the input\r\n */\r\n label?: ReactNode\r\n\r\n /**\r\n * Optional label layout switch\r\n */\r\n isHorizontalLabel?: boolean\r\n\r\n /**\r\n * Optional label className override\r\n */\r\n labelClassName?: string\r\n\r\n /**\r\n * Theme for the input\r\n *\r\n * @default light\r\n */\r\n theme?: keyof typeof InputTheme\r\n\r\n /**\r\n * Input size. This setting is ignored on mobile to avoid zoom\r\n *\r\n * @default regular\r\n */\r\n size?: keyof typeof InputSize\r\n\r\n /**\r\n * Border radius of the input\r\n *\r\n * @default regular\r\n */\r\n rounding?: keyof typeof InputRounding\r\n\r\n /**\r\n * Hide value stepper for number inputs\r\n */\r\n showNumberStepper?: boolean\r\n\r\n /**\r\n * Element to display on left the side of the input or name of the icon\r\n */\r\n leftContent?: JSX.Element | IconNameType\r\n\r\n /**\r\n * Element to display on right the side of the input or name of the icon\r\n */\r\n rightContent?: JSX.Element | IconNameType\r\n\r\n /**\r\n * Additional class names for the input\r\n */\r\n inputClass?: string\r\n\r\n /**\r\n * Error label to display under the input\r\n */\r\n error?: ReactNode\r\n\r\n /**\r\n * Additional info to display under the input\r\n */\r\n caption?: ReactNode\r\n\r\n /**\r\n * Disables setting text size to 16px on mobile. Only use for pages which aren’t\r\n * responsive\r\n */\r\n isMobileStyleEnabled?: boolean\r\n}\r\n\r\nexport type InputHTMLProps = OmitNativeProps\r\n\r\nexport type InputComponentProps = InputProps & InputHTMLProps\r\n\r\nfunction InputComponent(\r\n {\r\n label,\r\n isHorizontalLabel,\r\n labelClassName,\r\n size = 'regular',\r\n theme = 'light',\r\n rounding = 'regular',\r\n type,\r\n showNumberStepper = type === 'number',\r\n leftContent,\r\n rightContent,\r\n inputClass,\r\n error,\r\n caption,\r\n className,\r\n isMobileStyleEnabled = true,\r\n ...props\r\n }: InputComponentProps,\r\n ref: ForwardedRef\r\n) {\r\n const inputTheme = useMemo(() => getInputTheme(InputTheme[theme], !!error), [theme, error])\r\n const isLeftStringIcon = isValidIconName(leftContent)\r\n const isRightStringIcon = isValidIconName(rightContent)\r\n const inputSize = InputSize[size]\r\n\r\n const commonSideContentClassnames = useMemo(\r\n () => ({\r\n 'flex absolute w-3 items-center justify-center': true,\r\n 'text-gray-500 dark:text-gray-600': theme === 'light',\r\n 'text-gray-600': theme === 'dark',\r\n }),\r\n [theme]\r\n )\r\n\r\n return (\r\n
\r\n
\r\n \r\n {caption && typeof caption !== 'boolean' && (\r\n {caption}\r\n )}\r\n {error && typeof error !== 'boolean' && {error}}\r\n \r\n )\r\n}\r\n\r\ninterface InputCaptionProps extends Omit, 'size'> {\r\n size?: keyof typeof InputSize\r\n}\r\n\r\nfunction InputCaption({ size = 'regular', ...props }: PropsWithChildren) {\r\n return (\r\n \r\n )\r\n}\r\n\r\ntype TextareaProps = Omit & OmitNativeProps\r\n\r\nfunction TextareaComponent(\r\n { label, theme = 'light', rounding = 'regular', inputClass, error, caption, className, ...props }: TextareaProps,\r\n ref: ForwardedRef\r\n) {\r\n const textareaTheme = useMemo(() => getInputTheme(InputTheme[theme], !!error), [theme, error])\r\n\r\n return (\r\n
\r\n \r\n {caption && typeof caption !== 'boolean' && (\r\n {caption}\r\n )}\r\n {error && typeof error !== 'boolean' && {error}}\r\n
\r\n )\r\n}\r\n\r\nexport const Input = forwardRef(InputComponent)\r\nexport const Textarea = forwardRef(TextareaComponent)\r\n","import * as React from 'react'\r\nimport * as Reakit from 'reakit/Composite'\r\n\r\nexport const ListContext = React.createContext(null)\r\n\r\nexport function useListState(options?: Reakit.CompositeInitialState) {\r\n return Reakit.useCompositeState({ ...options, loop: true, unstable_virtual: true })\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as Reakit from 'reakit/Composite'\r\n\r\nimport { BUTTON_DEFAULT_ELEMENT, Button, ButtonComponentProps, ButtonTheme } from '../button'\r\nimport { ListContext } from './hooks'\r\n\r\nexport interface ListItemProps {\r\n /**\r\n * Theme when the button is selected\r\n */\r\n activeTheme?: keyof typeof ButtonTheme\r\n\r\n /**\r\n * Close parent popover when the item is clicked\r\n */\r\n closeOnSelect?: boolean\r\n\r\n /**\r\n * OnChange callback when item is clicked or navigated to\r\n * @private\r\n */\r\n onSelectItem?: (item: string, closeOnSelect?: boolean) => void\r\n}\r\n\r\nexport function ListItem({\r\n as,\r\n activeTheme = 'blue',\r\n onSelectItem,\r\n onClick,\r\n onKeyPress,\r\n className,\r\n closeOnSelect = true,\r\n children,\r\n ...props\r\n}: React.PropsWithChildren & ButtonComponentProps) {\r\n const state = React.useContext(ListContext)\r\n\r\n return (\r\n {\r\n onClick?.(ev)\r\n onSelectItem?.(ev.currentTarget.id, closeOnSelect)\r\n }}\r\n onKeyPress={(ev) => {\r\n onKeyPress?.(ev)\r\n onSelectItem?.(ev.currentTarget.id, closeOnSelect)\r\n }}\r\n >\r\n {(itemProps: ButtonComponentProps) => {\r\n const active = Boolean(itemProps['aria-selected'])\r\n\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n }}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as Reakit from 'reakit/Composite'\r\n\r\nimport { ListContext } from './hooks'\r\nimport { ListItem } from './list-item'\r\n\r\ninterface ListProps extends Omit {\r\n /**\r\n * The returned object from `useListState`\r\n */\r\n state: Reakit.CompositeStateReturn\r\n\r\n /**\r\n * The selected option\r\n */\r\n selectedIndex?: number\r\n\r\n /**\r\n * Callback when selected option index changes\r\n */\r\n onChange?: (selectedIndex: number, closeParent?: boolean) => void\r\n\r\n /**\r\n * Whether or not default styles should be included for the list\r\n * @default true\r\n */\r\n includeBaseStyles?: boolean\r\n}\r\n\r\nexport function List({ state, selectedIndex, includeBaseStyles = true, onChange, children, ...props }: ListProps) {\r\n const prevSelected = React.useRef(null)\r\n\r\n // Select option when `selectedIndex` changes\r\n React.useEffect(() => {\r\n if (\r\n selectedIndex !== undefined &&\r\n selectedIndex >= 0 &&\r\n prevSelected.current !== selectedIndex &&\r\n state.items.length > selectedIndex\r\n ) {\r\n state.move(state.items[selectedIndex].id)\r\n prevSelected.current = selectedIndex\r\n }\r\n }, [selectedIndex, state, state.items.length])\r\n\r\n const onSelectItem = React.useCallback(\r\n (id: string, closeParent: boolean) => {\r\n onChange?.(\r\n state.items.findIndex((item) => item.id === id),\r\n closeParent\r\n )\r\n },\r\n [onChange, state.items]\r\n )\r\n\r\n return (\r\n \r\n \r\n {React.Children.map(children, (child) => {\r\n if (!React.isValidElement(child)) return child\r\n\r\n if (child.type === ListItem) {\r\n return React.cloneElement(child, { ...child.props, onSelectItem: onSelectItem })\r\n }\r\n\r\n return child\r\n })}\r\n \r\n \r\n )\r\n}\r\n","// Disable rule as the component is external\r\n\r\n/* eslint-disable react/jsx-pascal-case */\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as Reakit from 'reakit/Combobox'\r\n\r\nimport { Button, ButtonProps } from '../button'\r\nimport { PropsWithAs } from '../types'\r\n\r\nconst DEFAULT_ELEMENT = 'button'\r\n\r\nexport interface ComboBoxItemProps extends ButtonProps {\r\n /**\r\n * The returned object from `useComboBoxState`\r\n */\r\n state?: Reakit.unstable_ComboboxStateReturn\r\n\r\n /**\r\n * Value for the combo box item\r\n */\r\n value: string\r\n}\r\n\r\nexport function ComboBoxItem({\r\n as: asComponent,\r\n state,\r\n children,\r\n ...props\r\n}: PropsWithAs & ComboBoxItemProps) {\r\n return (\r\n \r\n {(itemProps) => {\r\n const selected = state?.currentId === itemProps.id\r\n\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n }}\r\n \r\n )\r\n}\r\n","// Disable rule as the component is external\r\n\r\n/* eslint-disable react/jsx-pascal-case */\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as Reakit from 'reakit/Combobox'\r\nimport { Portal } from 'reakit/Portal'\r\n\r\nimport { Box, BoxProps } from '../box'\r\nimport { getExtendedDialogState, useZIndex } from '../dialog'\r\nimport { Input, InputProps } from '../input'\r\nimport { ComboBoxItem } from './combo-box-item'\r\n\r\ninterface ComboBoxProps extends Omit {\r\n /**\r\n * The returned object from `useComboBoxState`\r\n */\r\n state: Reakit.unstable_ComboboxStateReturn\r\n\r\n /**\r\n * Additional props for the input\r\n */\r\n inputProps?: Partial & Omit, 'size'>\r\n\r\n /**\r\n * Additional props for the popover\r\n */\r\n popoverProps?: Partial\r\n\r\n /**\r\n * Callback when user presses enter\r\n */\r\n onChange: (value: string) => void\r\n\r\n /**\r\n * Id for testing purposes\r\n */\r\n inputTestId?: string\r\n}\r\n\r\nexport function ComboBox({\r\n state,\r\n children,\r\n inputProps,\r\n popoverProps,\r\n onChange,\r\n inputTestId,\r\n 'aria-label': ariaLabel,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const { isFullyClosed } = getExtendedDialogState(state)\r\n const zIndex = useZIndex()\r\n\r\n React.useEffect(() => {\r\n if (inputProps?.autoFocus) {\r\n state.unstable_referenceRef.current?.focus({ preventScroll: true })\r\n }\r\n // Only focus input on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n return (\r\n <>\r\n {\r\n if (ev.key === 'Enter') {\r\n onChange(state.inputValue)\r\n }\r\n inputProps?.onKeyDown?.(ev)\r\n }}\r\n data-testid={inputTestId}\r\n />\r\n {!isFullyClosed && (\r\n \r\n \r\n {({ onTransitionEnd, onAnimationEnd, ...innerProps }) => (\r\n
\r\n \r\n {React.Children.map(children, (child) => {\r\n if (!React.isValidElement(child)) return child\r\n\r\n if (child.type === ComboBoxItem) {\r\n return React.cloneElement(\r\n child as React.ReactElement>,\r\n {\r\n state,\r\n onMouseUp: () => {\r\n onChange(child.props.value)\r\n },\r\n }\r\n )\r\n }\r\n\r\n return child\r\n })}\r\n \r\n
\r\n )}\r\n
\r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import { Instrument } from '../../types'\r\n\r\nexport const INSTRUMENT_CATEGORIES = [\r\n { name: 'All', instrument: undefined },\r\n { name: 'Stocks', instrument: Instrument.Stock },\r\n { name: 'Futures', instrument: Instrument.Futures },\r\n { name: 'Forex', instrument: Instrument.Forex },\r\n { name: 'Crypto', instrument: Instrument.Crypto },\r\n]\r\n","import classnames from 'classnames'\r\nimport { HTMLProps, PropsWithChildren } from 'react'\r\n\r\nexport function Centered(props: PropsWithChildren>) {\r\n return
\r\n}\r\n","import { FallbackProps } from 'react-error-boundary'\r\n\r\nimport { link } from '../../services/routing'\r\nimport { Button } from '../button'\r\nimport { Centered } from '../centered'\r\nimport { Icon } from '../icon'\r\nimport { Heading, Paragraph } from '../typography'\r\n\r\nexport function SearchError(props: FallbackProps) {\r\n return (\r\n \r\n \r\n \r\n Error fetching the results\r\n \r\n \r\n There’s been an error fetching your results. Please try again or{' '}\r\n \r\n contact support\r\n \r\n .\r\n \r\n \r\n \r\n )\r\n}\r\n","import { useMemo } from 'react'\r\n\r\ninterface HighlightProps {\r\n /**\r\n * Search string that will be highlighted\r\n */\r\n highlight: string\r\n /**\r\n * Text to be highlighted\r\n */\r\n text: string\r\n}\r\n\r\nexport function Highlight({ highlight, text }: HighlightProps) {\r\n const index = text.toLowerCase().indexOf(highlight.toLowerCase())\r\n\r\n const processedText = useMemo(\r\n () => ({\r\n before: text.substring(0, index),\r\n highlight: text.substring(index, index + highlight.length),\r\n after: text.substring(index + highlight.length),\r\n }),\r\n [highlight.length, index, text]\r\n )\r\n\r\n if (index < 0 || highlight.length < 1) return {text}\r\n\r\n return (\r\n <>\r\n {processedText.before}\r\n {!!processedText.highlight.length && (\r\n \r\n {processedText.highlight}\r\n \r\n )}\r\n {processedText.after}\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { SearchApiResult } from '../../services/api'\r\nimport { ComboBoxItem, ComboBoxItemProps } from '../combo-box'\r\nimport { Highlight } from '../highlight'\r\nimport { PropsWithAs } from '../types'\r\n\r\ninterface SearchItemProps extends Pick {\r\n item: SearchApiResult\r\n chartIndex?: number\r\n itemProps: Partial>\r\n}\r\n\r\nexport function SearchItem(props: SearchItemProps) {\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {props.item.exchange}\r\n \r\n )\r\n}\r\n","import { getSanitizedTicker } from '../../../app/shared/ticker-sanitizer'\r\nimport { link } from '../../services/routing'\r\nimport { Instrument } from '../../types'\r\nimport { cleanTicker, getInstrumentForTicker } from '../../util'\r\n\r\nexport function getRedirectForTicker(tickerRaw: string) {\r\n const ticker = getSanitizedTicker(tickerRaw, true)\r\n const instrument = cleanTicker(ticker) ? getInstrumentForTicker(ticker) : null\r\n let redirectLink = ''\r\n\r\n switch (instrument) {\r\n case Instrument.Stock:\r\n redirectLink = link.toQuote(ticker)\r\n break\r\n case Instrument.Forex:\r\n redirectLink = link.toForexChartDetail(ticker)\r\n break\r\n case Instrument.Futures:\r\n redirectLink = link.toFuturesChartDetail(ticker)\r\n break\r\n case Instrument.Crypto:\r\n redirectLink = link.toCryptoChartDetail(ticker)\r\n break\r\n default:\r\n return link.toSearch(ticker)\r\n }\r\n\r\n return redirectLink + (FinvizSettings.quoteSearchExt ?? '')\r\n}\r\n","import { useQuery } from '@tanstack/react-query'\r\nimport React from 'react'\r\nimport * as Reakit from 'reakit/Combobox'\r\n\r\nimport { searchApiRequest } from '../../services/api'\r\nimport { link } from '../../services/routing'\r\nimport { Instrument } from '../../types'\r\nimport { Button } from '../button'\r\nimport { Centered } from '../centered'\r\nimport { COMPONENT_ANIMATION_DURATION } from '../constants'\r\nimport { Spinner } from '../spinner'\r\nimport { SearchItem } from './search-item'\r\nimport { getRedirectForTicker } from './util'\r\n\r\ninterface SearchListProps {\r\n state: Reakit.unstable_ComboboxStateReturn\r\n instrument?: Instrument\r\n chartIndex?: number\r\n isShowAllVisible: boolean\r\n isSearchItemLink: boolean\r\n onTickerSelected?: (ticker: string) => void\r\n}\r\n\r\nexport function SearchList(props: SearchListProps) {\r\n const { data, isLoading } = useQuery(\r\n ['search', props.state.inputValue, props.instrument],\r\n () => searchApiRequest(props.state.inputValue, props.instrument),\r\n { enabled: props.state.inputValue.length > 0, keepPreviousData: true, cacheTime: Infinity, staleTime: Infinity }\r\n )\r\n const { setAnimated, hide, animated } = props.state\r\n\r\n React.useEffect(() => {\r\n if (!isLoading && !data?.length && !props.isShowAllVisible) {\r\n setAnimated(1)\r\n hide()\r\n } else if (animated !== COMPONENT_ANIMATION_DURATION) {\r\n setAnimated(COMPONENT_ANIMATION_DURATION)\r\n }\r\n }, [isLoading, data, setAnimated, hide, props.isShowAllVisible, animated])\r\n\r\n if (isLoading) {\r\n return (\r\n \r\n \r\n \r\n )\r\n }\r\n\r\n return (\r\n
\r\n {data && data.length !== 0 && (\r\n
\r\n {data.map((item) => (\r\n ) => {\r\n ev.preventDefault()\r\n props.onTickerSelected?.(item.ticker)\r\n props.state?.setInputValue('')\r\n },\r\n }\r\n }\r\n />\r\n ))}\r\n
\r\n )}\r\n {props.isShowAllVisible && (\r\n \r\n Show All Results\r\n \r\n )}\r\n
\r\n )\r\n}\r\n","import { Placement } from '@popperjs/core'\r\nimport { useQueryErrorResetBoundary } from '@tanstack/react-query'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport { ErrorBoundary } from 'react-error-boundary'\r\n\r\nimport { getSanitizedTicker } from '../../../app/shared/ticker-sanitizer'\r\nimport { ComboBox, useComboBoxState } from '../combo-box'\r\nimport { getExtendedDialogState } from '../dialog'\r\nimport { IconNameType } from '../icon'\r\nimport { InputSize, InputTheme } from '../input'\r\nimport { List, ListItem, useListState } from '../list'\r\nimport { INSTRUMENT_CATEGORIES } from './constants'\r\nimport { SearchError } from './search-error'\r\nimport { SearchList } from './search-list'\r\nimport { getRedirectForTicker } from './util'\r\n\r\ninterface SearchProps {\r\n autoFocus?: boolean\r\n defaultValue?: string\r\n defaultPlacement?: Placement\r\n placeholder?: string\r\n theme?: keyof typeof InputTheme\r\n size?: keyof typeof InputSize\r\n allowCategorySwitching?: boolean\r\n inputClass?: string\r\n popoverClass?: string\r\n chartIndex?: number\r\n isMatchInputAndBoxWidth?: boolean\r\n isSearchIcon?: boolean\r\n isShowAllVisible?: boolean\r\n isSearchItemLink?: boolean\r\n rightContent?: JSX.Element | IconNameType\r\n onTickerSelected?: (ticker: string) => void\r\n}\r\n\r\nexport function Search({\r\n isSearchIcon = true,\r\n isShowAllVisible = true,\r\n isSearchItemLink = true,\r\n ...props\r\n}: SearchProps) {\r\n const { reset } = useQueryErrorResetBoundary()\r\n const state = useComboBoxState({\r\n minValueLength: 1,\r\n inputValue: props.defaultValue,\r\n placement: props.defaultPlacement ?? 'bottom-start',\r\n })\r\n const { isFullyClosed } = getExtendedDialogState(state)\r\n const listState = useListState({ orientation: 'vertical' })\r\n const [category, setCategory] = React.useState(0)\r\n\r\n const changeCategory = React.useRef((ev: React.KeyboardEvent) => {\r\n switch (ev.key) {\r\n case 'ArrowRight':\r\n state.first()\r\n break\r\n case 'ArrowUp':\r\n setCategory((state) => (state - 1 + INSTRUMENT_CATEGORIES.length) % INSTRUMENT_CATEGORIES.length)\r\n break\r\n case 'ArrowDown':\r\n setCategory((state) => (state + 1) % INSTRUMENT_CATEGORIES.length)\r\n break\r\n }\r\n })\r\n\r\n /**\r\n * The search box can be child of a modal/dialog so we need to handle ESC\r\n * otherwise it would close both the combobox and the parent.\r\n */\r\n const onInputKeyDown = React.useCallback(\r\n (ev: React.KeyboardEvent) => {\r\n if (ev.key === 'Escape' && state.visible) {\r\n ev.stopPropagation()\r\n state.hide()\r\n }\r\n },\r\n // We only use `visible` and `hide` and don’t need the full state\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [state.visible, state.hide]\r\n )\r\n\r\n /**\r\n * Reset to category \"All\" when the combobox closes\r\n */\r\n React.useEffect(() => {\r\n if (isFullyClosed) {\r\n setCategory(0)\r\n }\r\n }, [isFullyClosed])\r\n\r\n return (\r\n {\r\n // prevent combobox from setting input value on input blur\r\n e.preventDefault()\r\n },\r\n inputClass: props.inputClass,\r\n rightContent: props.rightContent,\r\n ...(isSearchIcon && { leftContent: 'search' }),\r\n }}\r\n popoverProps={{\r\n className: classnames(props.popoverClass, 'sm:px-0 z-dialog', {\r\n 'w-full sm:w-110 px-2': !props.isMatchInputAndBoxWidth,\r\n 'min-w-[340px]': props.isMatchInputAndBoxWidth,\r\n }),\r\n style: {\r\n width: props.isMatchInputAndBoxWidth\r\n ? state.unstable_referenceRef.current?.getBoundingClientRect().width ?? 340\r\n : undefined,\r\n maxWidth: '100vw',\r\n },\r\n }}\r\n onChange={(value) => {\r\n if (isSearchItemLink) {\r\n window.location.href = getRedirectForTicker(value)\r\n } else {\r\n props.onTickerSelected?.(getSanitizedTicker(value))\r\n state.setInputValue('')\r\n }\r\n }}\r\n {...(props.chartIndex !== undefined && { inputTestId: `chart-${props.chartIndex}-settings-search-input` })}\r\n >\r\n
\r\n {props.allowCategorySwitching && (\r\n setCategory(index)}\r\n onKeyDown={changeCategory.current}\r\n >\r\n {INSTRUMENT_CATEGORIES.map((category) => (\r\n {category.name}\r\n ))}\r\n \r\n )}\r\n {!isFullyClosed && (\r\n \r\n \r\n \r\n )}\r\n
\r\n \r\n )\r\n}\r\n","import * as Reakit from 'reakit/Combobox'\r\n\r\nimport { COMPONENT_ANIMATION_DURATION } from '../constants'\r\n\r\nexport function useComboBoxState(options?: Reakit.unstable_ComboboxInitialState) {\r\n return Reakit.unstable_useComboboxState({\r\n ...options,\r\n animated: COMPONENT_ANIMATION_DURATION,\r\n modal: false,\r\n inline: true,\r\n unstable_offset: [0, 5],\r\n })\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { TooltipColor } from './types'\r\n\r\nexport interface TooltipBoxProps extends Omit, 'ref'> {\r\n /**\r\n * Color of the tooltip. If se to `none`, the tooltip will have default color\r\n * based on light/dark theme\r\n *\r\n * @default 'none'\r\n */\r\n color?: keyof typeof TooltipColor\r\n}\r\n\r\nexport const TooltipBox = React.forwardRef(function TooltipBox(\r\n { color = 'none', ...props }: TooltipBoxProps,\r\n ref: React.ForwardedRef\r\n) {\r\n const tooltipColor = TooltipColor[color]\r\n\r\n return (\r\n \r\n {props.children}\r\n
\r\n )\r\n})\r\n","import * as React from 'react'\r\nimport * as Reakit from 'reakit/Tooltip'\r\n\r\nimport { isIos } from '../../../app/shared/isMobile'\r\nimport { getExtendedDialogState } from '../dialog'\r\nimport { TooltipArrow } from './tooltip-arrow'\r\nimport { TooltipBox, TooltipBoxProps } from './tooltip-box'\r\n\r\ninterface TooltipProps extends TooltipBoxProps {\r\n /**\r\n * The returned object from `useTooltipState`\r\n */\r\n state: Reakit.TooltipStateReturn\r\n}\r\n\r\nexport function Tooltip({ state, children, color = 'none', ...props }: React.PropsWithChildren) {\r\n const { isFullyClosed } = getExtendedDialogState(state)\r\n\r\n // On iOS depending on composition TooltipTrigger doesn't work properly if Tooltip isn't always rendered\r\n // and causes bug on interactive elements with tooltip like selects, buttons, etc. when on first click\r\n // only tooltip appears but select, button or etc. doesn't receive event so it won't open, also on first click\r\n // in iOS safari onClick event isn't fired no TooltipTrigger, just onPointerDown, and thus further breaking logic\r\n // because our custom callback which are placed in onClick aren't invoked, after debugging we think that this\r\n // is bug caused by combination of reakit behaviour when isn't always rendered and way of events\r\n // firing by iOS Safari and thus not worth debugging internal reakit logic as we are looking to\r\n // replace it altogether\r\n if (isFullyClosed && !isIos()) return null\r\n return (\r\n \r\n {({ onTransitionEnd, onAnimationEnd, ...tooltipProps }) => (\r\n
\r\n \r\n \r\n \r\n \r\n {children}\r\n \r\n
\r\n )}\r\n
\r\n )\r\n}\r\n","import * as React from 'react'\r\nimport * as Reakit from 'reakit/Tooltip'\r\n\r\ninterface TooltipButtonProps extends Reakit.TooltipReferenceHTMLProps {\r\n state: Reakit.TooltipStateReturn\r\n\r\n /**\r\n * Whether or not should trigger element call blur to return focus back to body after click\r\n *\r\n * @default false\r\n */\r\n isBlurAfterClick?: boolean\r\n\r\n /**\r\n * Whether to ignore default mouse enter/leave tooltip trigger interactions\r\n * and hide tooltip only after clicking outside of the trigger element\r\n *\r\n * @default false\r\n */\r\n isHideOnClickOutside?: boolean\r\n}\r\n/**\r\n * The trigger button component which handles ref & focus return, etc.\r\n */\r\nexport const TooltipTrigger = React.forwardRef(\r\n (\r\n {\r\n state,\r\n isBlurAfterClick,\r\n isHideOnClickOutside,\r\n onClick,\r\n onMouseEnter,\r\n onMouseLeave,\r\n ...props\r\n }: TooltipButtonProps,\r\n ref: React.ForwardedRef\r\n ) => (\r\n {\r\n if (isBlurAfterClick && document.activeElement instanceof HTMLElement) {\r\n document.activeElement.blur()\r\n }\r\n onClick?.(e)\r\n }}\r\n onMouseEnter={(e) => {\r\n if (isHideOnClickOutside) e.preventDefault()\r\n onMouseEnter?.(e)\r\n }}\r\n onMouseLeave={(e) => {\r\n if (isHideOnClickOutside) e.preventDefault()\r\n onMouseLeave?.(e)\r\n }}\r\n {...props}\r\n {...state}\r\n >\r\n {props.children}\r\n \r\n )\r\n)\r\n","import * as Reakit from 'reakit/Tooltip'\r\n\r\nimport { COMPONENT_ANIMATION_DURATION } from '../constants'\r\n\r\n/**\r\n * Hook which provides state to tooltips\r\n */\r\nexport function useTooltipState(settings?: Reakit.TooltipInitialState) {\r\n return Reakit.useTooltipState({\r\n ...settings,\r\n animated: COMPONENT_ANIMATION_DURATION,\r\n })\r\n}\r\n","import classnames from 'classnames'\r\n\r\nimport { TooltipColor } from './types'\r\n\r\ntype PositionMain = 'auto' | 'top' | 'bottom' | 'left' | 'right'\r\ntype PositionSecondary = 'start' | 'end'\r\ntype Placement = PositionMain | `${PositionMain}-${PositionSecondary}`\r\n\r\nconst transformMap: Record = {\r\n auto: '',\r\n top: 'rotateZ(180deg)',\r\n right: 'rotateZ(-90deg)',\r\n bottom: 'rotateZ(360deg)',\r\n left: 'rotateZ(90deg)',\r\n}\r\n\r\ninterface TooltipArrowProps {\r\n color?: keyof typeof TooltipColor\r\n placement: Placement\r\n className?: string\r\n}\r\n\r\n/**\r\n * Custom arrow for the dropdown\r\n */\r\nexport function TooltipArrow({ placement, color = 'none', className }: TooltipArrowProps) {\r\n const positionMain = placement.split('-')[0] as PositionMain\r\n const arrowColor = TooltipColor[color]\r\n\r\n return (\r\n \r\n \r\n \r\n )\r\n}\r\n","export enum TooltipColor {\r\n none,\r\n green,\r\n red,\r\n orange,\r\n blue,\r\n dark,\r\n}\r\n","import * as Sentry from '@sentry/browser'\r\n\r\nimport { PortfolioDefinition } from '../modules/portfolio/types'\r\nimport { Instrument } from '../types'\r\n\r\n// Keep in sync with ContentType in https://github.com/finvizhq/charts/blob/master/app/utils/fetch_api.ts\r\n// START\r\nexport enum ContentType {\r\n ApplicationJson = 'application/json',\r\n ApplicationJsonUTF = 'application/json; charset=utf-8', // WriteAsJsonAsync\r\n FormUrlEncoded = 'application/x-www-form-urlencoded',\r\n Html = 'text/html; charset=utf-8',\r\n}\r\n\r\nfunction parseResponseForContentType(response: string, contentType: ContentType) {\r\n switch (contentType) {\r\n case ContentType.ApplicationJson:\r\n case ContentType.ApplicationJsonUTF:\r\n case ContentType.FormUrlEncoded:\r\n return JSON.parse(response)\r\n default:\r\n return response\r\n }\r\n}\r\n// END\r\n\r\nexport class ThrowableError extends Error {\r\n status: number\r\n isServerError = false\r\n body: unknown\r\n extra: Record = {}\r\n\r\n constructor(status: number, message = 'ThrowableError', body = '', extra: Record = {}) {\r\n super(`${status} ${message}`)\r\n this.status = status\r\n this.isServerError = status >= 500\r\n this.body = body\r\n this.extra = extra\r\n }\r\n}\r\n\r\nexport interface CancelablePromise extends Promise {\r\n cancel?: () => void\r\n}\r\n\r\n/**\r\n * General api fetch utility which returns a cancelable promise\r\n */\r\nexport function apiRequest(\r\n url: string,\r\n { query, headers = {}, ...options }: RequestInit & { query?: Record } = {},\r\n throwOnAllErrors = false\r\n): CancelablePromise {\r\n const controller = 'AbortController' in window ? new AbortController() : undefined\r\n const requestUrl = query ? `${url}?${new URLSearchParams(query)}` : url\r\n const contentType: ContentType = (headers as any)['Content-Type'] ?? ContentType.ApplicationJson\r\n\r\n const requestOptions = {\r\n ...options,\r\n headers: {\r\n 'Content-Type': contentType,\r\n ...headers,\r\n },\r\n }\r\n const request = fetch(requestUrl, { ...requestOptions, signal: controller?.signal })\r\n\r\n const cancelableRequest: CancelablePromise = request\r\n .then(async (response) => {\r\n const textResponse = await response.text()\r\n const responseContentType: ContentType = (response.headers.get('Content-Type') as any) ?? ContentType.Html\r\n\r\n try {\r\n const parsedResponse = parseResponseForContentType(textResponse, responseContentType)\r\n if (!response.ok || response.status >= 500) {\r\n throw new ThrowableError(response.status, response.statusText, parsedResponse, {\r\n rayId: response.headers.get('cf-ray'),\r\n })\r\n }\r\n\r\n return parsedResponse\r\n } catch (error: any) {\r\n if (error instanceof ThrowableError) {\r\n throw error\r\n }\r\n throw new ThrowableError(response.status, error.message, textResponse, {\r\n rayId: response.headers.get('cf-ray'),\r\n })\r\n }\r\n })\r\n .catch((error: ThrowableError) => {\r\n if (error.status >= 500) {\r\n Sentry.withScope((scope) => {\r\n scope.setContext('Cloudflare', error.extra)\r\n\r\n if (error.status === 500) {\r\n Sentry.captureException(error)\r\n } else {\r\n Sentry.captureMessage(`${error.status} ${error.message}`)\r\n }\r\n })\r\n }\r\n if (throwOnAllErrors) {\r\n throw error\r\n }\r\n })\r\n\r\n if (controller) {\r\n cancelableRequest.cancel = () => controller.abort()\r\n }\r\n\r\n return cancelableRequest\r\n}\r\n\r\nexport interface SearchApiResult {\r\n ticker: string\r\n company: string\r\n exchange: string\r\n}\r\n\r\nexport function searchApiRequest(input = '', instrument?: Instrument) {\r\n return apiRequest('/api/suggestions.ashx', { query: { input, instrument } }, true)\r\n}\r\n\r\nexport function portfoliosRequest() {\r\n return apiRequest<{ portfolios: PortfolioDefinition[] }>('/api/portfolio_data.ashx', {\r\n query: {\r\n fields: 'portfolios',\r\n },\r\n })\r\n}\r\n\r\nexport function lastCloseRequest(ticker: string) {\r\n return apiRequest('/request_quote.ashx', {\r\n query: {\r\n t: ticker,\r\n },\r\n })\r\n}\r\n\r\ninterface PortfolioLimitResult {\r\n transactions: number\r\n limitTransactions: number\r\n}\r\n\r\nexport function portfolioLimitRequest(portfolioId: number) {\r\n return apiRequest('/api/portfolio_data.ashx', {\r\n query: {\r\n pid: portfolioId,\r\n fields: 'transactions,limitTransactions',\r\n },\r\n })\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\nimport mergewith from 'lodash.mergewith'\r\nimport omit from 'lodash.omit'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n ObjectHash,\r\n PaneArea,\r\n RequireByKey,\r\n TodoObjectHashAnyType,\r\n} from '../../types/shared'\r\nimport Thumb from '../canvas/thumb'\r\nimport {\r\n CanvasElementType,\r\n ChartElementType,\r\n ChartEventType,\r\n IVisibility,\r\n IndicatorType,\r\n MacroTimeframe,\r\n MicroMacroTimeframe,\r\n OverlayType,\r\n SetVisibilityTo,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport { isInRange } from '../utils/helpers'\r\n\r\nexport type TodoModalConfig = TodoObjectHashAnyType\r\ntype TodoPositionTimestamps = TodoObjectHashAnyType\r\n\r\nexport interface DefaultAttrs extends ObjectHash {\r\n positionTimestamps?: TodoPositionTimestamps\r\n visibility?: IVisibility\r\n}\r\n\r\nexport type EdgeValues = { minX?: number; maxX?: number; minY?: number; maxY?: number }\r\n\r\nclass Element extends Spine.Module {\r\n static type: CanvasElementType | OverlayType | ChartElementType | IndicatorType | ChartEventType =\r\n CanvasElementType.element\r\n\r\n static fromObject(obj: T['attrs'], model: T['model']) {\r\n return new this(obj, model) as T\r\n }\r\n\r\n static getNumOfBarsBuffer(\r\n _?: RequireByKey | RequireByKey\r\n ) {\r\n return 0\r\n }\r\n\r\n isCreator = false\r\n isCreatorDialogOpen = false\r\n attrs: Attrs = {} as Attrs\r\n\r\n model: any\r\n _thumbs: Thumb[]\r\n\r\n getDefaults?(): Partial\r\n renderCross?(ctx: RenderingContext2DType): void\r\n renderCrossText?(\r\n ctx: RenderingContext2DType,\r\n crossIndex: number,\r\n getDataByCrossIndex?: (key: keyof Quote, shouldReturnRoundedString?: boolean) => string | undefined\r\n ): void\r\n\r\n renderContent?(ctx: RenderingContext2DType): void\r\n renderGrid?(ctx: RenderingContext2DType): void\r\n renderLabels?(ctx: RenderingContext2DType): void\r\n declare defaults?: Partial\r\n getModalConfigBase?(): TodoModalConfig\r\n declare modalConfig?: TodoModalConfig\r\n getMinMax?(): { min: number; max: number }\r\n setupAxis?(fx: ScaleAxis): void | { min: number; max: number }\r\n\r\n activeThumb: Thumb | null = null\r\n isMouseDown = false\r\n isSelected = false\r\n isHovered = false\r\n isEditInProgress = false\r\n edgeXYValues: EdgeValues | null = null\r\n declare scaled?: ObjectHash | Partial\r\n\r\n declare toolsCallback: () => void\r\n\r\n constructor(values: Partial, model: Model) {\r\n super(values, model)\r\n this.model = model\r\n if (this.getDefaults) {\r\n this.set(this.getDefaults() || {})\r\n } else {\r\n this.set(this.defaults || {})\r\n }\r\n this.set(values)\r\n this._thumbs = []\r\n\r\n this.onMouseDown = this.onMouseDown.bind(this)\r\n this.onMouseMove = this.onMouseMove.bind(this)\r\n this.onMouseUp = this.onMouseUp.bind(this)\r\n this.bind('mousedown', this.onMouseDown)\r\n this.bind('mousemove', this.onMouseMove)\r\n this.bind('mouseup', this.onMouseUp)\r\n this.bind('change', () => {\r\n // elements is optional because this.model is not Pane in all usecases, e.g. base_chart extends this element and sets Chart as model\r\n const element = this.getIsChartEvent()\r\n ? this.model.chartEvents?.()?.findByAttribute('instance', this)\r\n : this.model.elements?.()?.findByAttribute('instance', this)\r\n\r\n element?.trigger('change', element)\r\n })\r\n }\r\n\r\n get type() {\r\n return (this.constructor as typeof Element).type\r\n }\r\n\r\n getThumbs() {\r\n return this._thumbs\r\n }\r\n\r\n moveBy(_: number, __: number) {}\r\n\r\n setIsSelected(isSelected: boolean) {\r\n this.isSelected = isSelected\r\n this.trigger('change')\r\n }\r\n\r\n setIsHovered(isHovered: boolean) {\r\n this.isHovered = isHovered\r\n this.trigger('change')\r\n }\r\n\r\n getShouldRenderThumbs() {\r\n return this.isSelected || this.isHovered\r\n }\r\n\r\n getIsPaneSelection(): boolean {\r\n const paneModel = this.model.elements().findByAttribute('instance', this)?.pane() as PaneModel | undefined\r\n return paneModel?.selection === this\r\n }\r\n\r\n set(obj: Partial) {\r\n const attrsSubset = Object.keys(obj).reduce(\r\n (acc, key) => ({ ...acc, [key]: this.attrs[key] }),\r\n {} as Partial\r\n )\r\n if (JSON.stringify(obj) !== JSON.stringify(attrsSubset)) {\r\n const customizer = (objValue: Partial, srcValue: Partial, key: keyof Attrs) => {\r\n if (this.getIsDrawing() && key === 'visibility') {\r\n return srcValue ?? {}\r\n }\r\n }\r\n mergewith(this.attrs, obj, customizer)\r\n if (this.getIsPaneSelection() && !this.getIsCreator()) {\r\n this.cachePointPositionTimestamp()\r\n }\r\n this.trigger('change', this)\r\n }\r\n this.edgeXYValues = null\r\n return this\r\n }\r\n\r\n get(key: T) {\r\n return this.attrs[key]\r\n }\r\n\r\n getBoundingPointKeys = (): { x: string[]; y: string[] } | void => {}\r\n\r\n fx = (x: number) => this.model.scale.x(x)\r\n\r\n fy = (y: number) => this.model.scale.y(y)\r\n\r\n scale({ x, y }: { x: string[]; y: string[] }) {\r\n this.scaled = {}\r\n x.forEach((el) => {\r\n Object.defineProperty(this.scaled, el, {\r\n get: () => this.fx(this.attrs[el]),\r\n })\r\n })\r\n\r\n y.forEach((el) => {\r\n Object.defineProperty(this.scaled, el, {\r\n get: () => this.fy(this.attrs[el]),\r\n })\r\n })\r\n }\r\n\r\n render(_: RenderingContext2DType) {}\r\n\r\n renderThumbs(context: CanvasRenderingContext2D) {\r\n const isHoveredThumbStyle = this.isHovered && !this.isSelected\r\n if (isHoveredThumbStyle) {\r\n context.globalAlpha = 0.5\r\n }\r\n this.getThumbs().map((thumb) => thumb.render(context))\r\n context.globalAlpha = 1\r\n }\r\n\r\n onMouseDown(area: PaneArea) {\r\n this.isMouseDown = true\r\n this.isEditInProgress = true\r\n for (const thumb of this.getThumbs()) {\r\n if (thumb.isInArea(area)) {\r\n this.activeThumb = thumb\r\n this.activeThumb.startEditing(area)\r\n return\r\n }\r\n }\r\n }\r\n\r\n onMouseMove(area: PaneArea) {\r\n if (!area.mouseDown) {\r\n return\r\n }\r\n if (this.activeThumb != null) {\r\n this.activeThumb.moveTo(area)\r\n this.trigger('change')\r\n }\r\n }\r\n\r\n onMouseUp(_?: PaneArea) {\r\n this.isMouseDown = false\r\n this.isEditInProgress = false\r\n this.activeThumb = null\r\n if (!this.getIsCreator() && !this.getIsChartEvent()) {\r\n this.cachePointPositionTimestamp()\r\n }\r\n this.trigger('change', this)\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart().quote()\r\n if (quote) {\r\n const { x: xPointKeys } = this.getBoundingPointKeys()!\r\n const positionTimestamps = xPointKeys.reduce((acc, key) => {\r\n const positionX = this.attrs[key]\r\n const timeStamp = positionX && quote.getTimestampFomPositionX(positionX)\r\n return {\r\n ...acc,\r\n [key]: timeStamp,\r\n }\r\n }, {}) as TodoPositionTimestamps\r\n this.set({ positionTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionTimestamps } = this.attrs\r\n if (!quote || !positionTimestamps) {\r\n // positionTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const pointPoitionsFromTimestamp = Object.entries(positionTimestamps).reduce(\r\n (acc, [key, timestamp]) => ({\r\n ...acc,\r\n [key]: timestamp && quote.getPositionXFromTimestamp(timestamp),\r\n }),\r\n {}\r\n )\r\n this.set(pointPoitionsFromTimestamp)\r\n }\r\n\r\n thumbsAreInArea(area: PaneArea) {\r\n for (const thumb of this.getThumbs()) {\r\n if (thumb.isInArea(area)) {\r\n return true\r\n }\r\n }\r\n return false\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n isDrawingElementLockedOrInvisible() {\r\n return this.model.chart().chart_layout().isLockDrawingsActive || !this.getIsVisible()\r\n }\r\n\r\n getModalConfig() {\r\n let config\r\n if (this.getModalConfigBase) {\r\n config = merge({}, this.getModalConfigBase())\r\n } else {\r\n config = merge({}, this.modalConfig)\r\n }\r\n if (this.getIsDrawing()) {\r\n config.inputs.push({ type: 'visibility', name: 'visibility', label: 'Visibility' })\r\n }\r\n if (config.title == null) {\r\n config.title = this.name\r\n }\r\n for (const input of config.inputs) {\r\n if (input.default != null) {\r\n input.value = input.default\r\n }\r\n if (this.attrs[input.name] != null) {\r\n input.value = this.attrs[input.name]\r\n }\r\n }\r\n return config\r\n }\r\n\r\n toObject() {\r\n return merge({}, this.attrs, { type: this.type })\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return this.toObject()\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return this.attrs.positionTimestamps ? Object.keys(this.attrs.positionTimestamps) : []\r\n }\r\n\r\n toAutosaveConfig() {\r\n // We don't want to save attrs which are stored in \"position timestamps\" because they are relative to timeframe for example\r\n // so in order to keep drawings in sync across different timeframes we can't rely on its position but we have to rely on \"position timestamps\" and then call updateScales to calculate correct positions for given timeframe\r\n return omit(this.toConfig(), this.getAutosaveOmittedProperties()) as Partial\r\n }\r\n\r\n replaceMyself(element: Element) {\r\n setTimeout(() => {\r\n element.cachePointPositionTimestamp()\r\n const el = this.model.elements().findByAttribute('instance', this)\r\n if (!el) {\r\n // Temporary code below\r\n // additional info gaining for https://finvizcom.sentry.io/issues/3990343438/events/e87ce8b4108341cf81f15ec78707c65e/?project=33153&query=is%3Aunresolved+Cannot+read+properties+of+undefined&referrer=previous-event&statsPeriod=14d&stream_index=0\r\n window.Sentry?.captureMessage('element.ts replaceMyself', {\r\n extra: {\r\n oldElement: {\r\n type: this?.type,\r\n isCreator: this?.isCreator,\r\n isMouseDown: this?.isMouseDown,\r\n isSelected: this?.isSelected,\r\n isHovered: this?.isHovered,\r\n isEditInProgress: this?.isEditInProgress,\r\n },\r\n newElement: {\r\n type: element?.type,\r\n isCreator: element?.isCreator,\r\n isMouseDown: element?.isMouseDown,\r\n isSelected: element?.isSelected,\r\n isHovered: element?.isHovered,\r\n isEditInProgress: element?.isEditInProgress,\r\n },\r\n },\r\n })\r\n } else {\r\n el.replace(element)\r\n }\r\n })\r\n }\r\n\r\n toString() {\r\n return this.name\r\n }\r\n\r\n getIsCreator() {\r\n return this.isCreator\r\n }\r\n\r\n getIsCreatorDialogOpen() {\r\n return this.isCreatorDialogOpen\r\n }\r\n\r\n release() {\r\n this.cachePointPositionTimestamp()\r\n this.unbind()\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart().chart_layout())\r\n }\r\n\r\n getIsDrawing() {\r\n return !!this.type.startsWith('canvas/')\r\n }\r\n\r\n getIsChartEvent() {\r\n return !!this?.type.startsWith('chartEvent/')\r\n }\r\n\r\n getIsVisible() {\r\n const { micro, macro } = MicroMacroTimeframe[this.model.chart().quote().timeframe as TIMEFRAME]\r\n const visibility = this.attrs.visibility?.[macro]\r\n\r\n // this.attrs.visibility.minutes === undefined: drawing visible on any minutes timeframe\r\n if (visibility === undefined) return true\r\n // this.attrs.visibility.minutes === {}: drawing invisible on any minutes timeframe\r\n if (Object.keys(visibility).length === 0) return false\r\n // this.attrs.visibility.minutes === {from: 5, to: 15}: drawing visible on minutes TF between 5 & 15 interval\r\n return isInRange({ value: micro, min: visibility.from, max: visibility.to })\r\n }\r\n\r\n setVisibilityTo(setTo: SetVisibilityTo) {\r\n const { macro, micro } = MicroMacroTimeframe[this.model.chart().quote().timeframe as TIMEFRAME]\r\n const currentIndex = Object.keys(MacroTimeframe).indexOf(macro)\r\n\r\n let timeframesToSet: string[] = []\r\n let attrsToSet: { from?: number; to?: number } = {}\r\n\r\n switch (setTo) {\r\n case SetVisibilityTo.currentAndAbove: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index < currentIndex)\r\n attrsToSet = { from: micro }\r\n break\r\n }\r\n case SetVisibilityTo.currentAndBelow: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index > currentIndex)\r\n attrsToSet = { to: micro }\r\n break\r\n }\r\n case SetVisibilityTo.currentOnly: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index !== currentIndex)\r\n attrsToSet = { from: micro, to: micro }\r\n break\r\n }\r\n case SetVisibilityTo.all:\r\n default: {\r\n this.set({ visibility: {} } as Partial)\r\n return\r\n }\r\n }\r\n\r\n this.set({\r\n visibility: Object.assign({}, ...timeframesToSet.map((item) => ({ [item]: {} })), { [macro]: attrsToSet }),\r\n } as Partial)\r\n }\r\n\r\n getEdgeXYValues() {\r\n const { x: xPoints, y: yPoints } = this.getBoundingPointKeys() ?? {}\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n xPoints?.forEach((key) => {\r\n const positionX = this.attrs[key]\r\n if (positionX !== undefined) {\r\n edgeXYValues.minX = Math.min(positionX, edgeXYValues.minX ?? positionX)\r\n edgeXYValues.maxX = Math.max(positionX, edgeXYValues.maxX ?? positionX)\r\n }\r\n })\r\n yPoints?.forEach((key) => {\r\n const positionY = this.attrs[key]\r\n if (positionY !== undefined) {\r\n edgeXYValues.minY = Math.min(positionY, edgeXYValues.minY ?? positionY)\r\n edgeXYValues.maxY = Math.max(positionY, edgeXYValues.maxY ?? positionY)\r\n }\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n\r\n getIsInChartView(chart: Chart, options?: { omitX?: boolean; omitY?: boolean }) {\r\n const { minX, maxX, minY, maxY } = this.getEdgeXYValues()\r\n\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n if (!options?.omitX) {\r\n const isMaxXInvalid = maxX === undefined || isNaN(maxX)\r\n const isMinXInvalid = minX === undefined || isNaN(minX)\r\n if (\r\n !isMaxXInvalid &&\r\n !isMinXInvalid &&\r\n !(this.fx(maxX) >= -chart.leftOffset && this.fx(minX) <= -chart.leftOffset + chart.width)\r\n ) {\r\n return false\r\n }\r\n }\r\n\r\n if (!options?.omitY) {\r\n if (minY === undefined || maxY === undefined) {\r\n return true\r\n }\r\n\r\n const topBound = this.model.scale.y.invert(0)\r\n const bottomBound = this.model.scale.y.invert(this.model.height)\r\n return topBound >= minY && bottomBound <= maxY\r\n }\r\n\r\n // If all checks fall through, render element\r\n return true\r\n }\r\n}\r\n\r\nexport default Element\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\ninterface ILineAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n dashLength: number\r\n lineWidth: number\r\n strokeStyle: string\r\n}\r\n\r\nclass Line extends Element {\r\n static type = CanvasElementType.line\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.render = this.render.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'l',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'r',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n lineWidth: 1,\r\n strokeStyle: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { x1, y1, x2, y2, lineWidth } = this.attrs\r\n const roundedXY = getRoundedObject({ x1, y1, x2, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineWidth', this.attrs.lineWidth)\r\n context.set('strokeStyle', this.attrs.strokeStyle)\r\n\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([this.attrs.dashLength])\r\n }\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([])\r\n }\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'l') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area, this.attrs) <= 10) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nexport default Line\r\n","import { PaneArea, RequireByKey, TextAttrs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport Element, { TodoModalConfig } from './element'\r\n\r\nexport interface Area {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport type ITextAttrs = RequireByKey & Partial\r\n\r\nconst DEFAULTS: Partial = {\r\n text: '',\r\n font: {\r\n size: 20,\r\n family: 'Arial',\r\n style: 'normal',\r\n weight: 'normal',\r\n },\r\n lineHeight: 20,\r\n // left | right | center | start | end\r\n textAlign: TextAlign.left,\r\n // top | hanging | middle | alphabetic | ideographic | bottom\r\n textBaseline: TextBaseline.alphabetic,\r\n padding: {\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n },\r\n}\r\n\r\nclass Text extends Element {\r\n static type = CanvasElementType.text\r\n\r\n static getMergedPropsWithDefaults>(\r\n propKey: T,\r\n props: Partial = {}\r\n ) {\r\n return {\r\n ...DEFAULTS[propKey],\r\n ...Object.entries(props).reduce((acc, [key, value]) => (value ? { ...acc, [key]: value } : acc), {}),\r\n }\r\n }\r\n\r\n name = 'Anchored text'\r\n declare context: CanvasRenderingContext2D\r\n declare width: number\r\n declare height: number\r\n declare font: string\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n // TODO: revisit this getter, when you call `this.width` you don't expect/want context change\r\n if (this.context) {\r\n this.setupContext(this.context)\r\n }\r\n return this.measure() + this.attrs.padding.left + this.attrs.padding.right\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const count = this.getLines().length\r\n return this.attrs.lineHeight * count + this.attrs.padding.top + this.attrs.padding.bottom\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'font', {\r\n get() {\r\n const f = this.attrs.font\r\n return `${f.style} ${f.weight} ${f.size}pt ${f.family}`\r\n },\r\n })\r\n }\r\n\r\n getModalConfigBase() {\r\n return {\r\n inputs: [\r\n { type: 'multiline_string', name: 'text', required: true },\r\n { type: 'font', name: 'font' },\r\n {\r\n type: 'background',\r\n name: 'fillStyle',\r\n label: 'Color',\r\n default: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n {\r\n type: 'background',\r\n name: 'background',\r\n label: 'Background',\r\n default: 'rgba(0,0,0,0)',\r\n },\r\n {\r\n type: 'border',\r\n name: 'border',\r\n min: 0,\r\n default: { color: 'rgba(0,0,0)', width: 0 },\r\n },\r\n ],\r\n } as unknown as TodoModalConfig\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n ...DEFAULTS,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: ['y'] })\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (obj.font?.size && !obj.lineHeight) {\r\n this.attrs.lineHeight = Math.max(obj.font.size, this.attrs.lineHeight)\r\n }\r\n return this\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n this.setupContext(context)\r\n if (this.attrs.angle) {\r\n // TODO background & multiline text\r\n this.context.save()\r\n this.context.translate(this.attrs.x!, this.attrs.y!)\r\n this.context.rotate((this.attrs.angle * Math.PI) / 180)\r\n this.context.fillText(this.attrs.text, 0, 0)\r\n this.context.restore()\r\n } else {\r\n this.renderBackground()\r\n this.renderText()\r\n }\r\n }\r\n\r\n measure(context?: CanvasRenderingContext2D) {\r\n if (context) {\r\n this.setupContext(context)\r\n }\r\n const lines = this.getLines()\r\n let max = 0\r\n for (const line of lines) {\r\n max = Math.max(this.context.measureText(line).width, max)\r\n }\r\n return ~~max\r\n }\r\n\r\n isInArea(testArea: PaneArea) {\r\n const area = this.convertArea(testArea)\r\n // TODO iny align\r\n if (\r\n this.attrs.x! < area.x &&\r\n area.x < this.attrs.x! + this.width &&\r\n this.attrs.y! - this.attrs.font.size < area.y &&\r\n area.y < this.attrs.y! - this.attrs.font.size + this.height\r\n ) {\r\n return true\r\n }\r\n return super.isInArea(testArea)\r\n }\r\n\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle)\r\n context.set('textAlign', this.attrs.textAlign)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n }\r\n\r\n getLines() {\r\n return this.attrs.text.toString().split('\\n')\r\n }\r\n\r\n renderText() {\r\n let { y } = this.attrs // + @attrs.padding.top\r\n for (const line of this.getLines()) {\r\n this.context.fillText(line, this.attrs.x! + this.attrs.padding.left, y!)\r\n y! += this.attrs.lineHeight\r\n }\r\n }\r\n\r\n renderBackground() {\r\n if (!this.attrs.background) {\r\n return\r\n }\r\n\r\n const { width } = this\r\n const { height } = this\r\n const rawHight = height - this.attrs.padding.top - this.attrs.padding.bottom\r\n const { x } = this.attrs\r\n let y = this.attrs.y! - height\r\n\r\n if (this.attrs.textBaseline === 'middle') {\r\n y = this.attrs.y! - rawHight / 2 - this.attrs.padding.top - 1\r\n } else if (this.attrs.textBaseline === 'alphabetic') {\r\n y = this.attrs.y! - this.attrs.lineHeight\r\n }\r\n\r\n this.context.beginPath()\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.rect(x!, y, width, height)\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle)\r\n this.renderBorder()\r\n this.context.closePath()\r\n }\r\n\r\n renderBorder() {\r\n const { lineWidth = 0, strokeStyle, border } = this.attrs\r\n const borderWidth = border?.width ?? 0\r\n\r\n if (lineWidth || this.attrs.strokeStyle || borderWidth > 0) {\r\n this.context.set('strokeStyle', strokeStyle ?? border?.color ?? '')\r\n this.context.set('lineWidth', Math.max(lineWidth, borderWidth))\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n private convertArea(area: PaneArea) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n return {\r\n x: this.model.scale.x(area.x) + this.model.chart().leftOffset + ChartSettings.left.width,\r\n y: this.model.scale.y(area.y) + ChartSettings.top.height,\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x! += this.model.scale.x(x) + 1\r\n this.attrs.y! += this.model.scale.y(y) - this.model.scale.y(0)\r\n }\r\n\r\n getHeight() {\r\n return this.height\r\n }\r\n}\r\n\r\nText.initClass()\r\n\r\nexport default Text\r\n","import { PaneArea, ResizeByThumbFuncProps, ThumbType } from '../../types/shared'\r\nimport { getOffsetFromLineWidth } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\n\r\ntype Area = PaneArea\r\ntype ResizeFunc = (props: ResizeByThumbFuncProps) => void\r\ntype ScaleFunc = () => number\r\n\r\nclass Thumb {\r\n type: ThumbType\r\n lastX = 0\r\n lastY = 0\r\n fx: ScaleFunc\r\n fy: ScaleFunc\r\n resize: ResizeFunc\r\n model: PaneModel\r\n\r\n constructor(type: ThumbType, fx: ScaleFunc, fy: ScaleFunc, resize: ResizeFunc, model: PaneModel) {\r\n this.type = type\r\n this.fx = fx\r\n this.fy = fy\r\n this.resize = resize\r\n this.model = model\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n context.set('fillStyle', ThumbSettings.color)\r\n context.set('strokeStyle', ThumbSettings.borderColor)\r\n context.set('lineWidth', ThumbSettings.borderWidth)\r\n const x = ~~this.x()\r\n const y = ~~this.y()\r\n const thumbWidth = this.getThumbWidth()\r\n const offset = getOffsetFromLineWidth(ThumbSettings.borderWidth)\r\n context.beginPath()\r\n context.rect(x + offset, y + offset, thumbWidth, thumbWidth)\r\n context.fill()\r\n context.stroke()\r\n }\r\n\r\n startEditing(area: Area) {\r\n this.lastX = area.x\r\n return (this.lastY = area.y)\r\n }\r\n\r\n moveTo(area: Area) {\r\n const difX = area.x - this.lastX\r\n const difY = area.y - this.lastY\r\n this.resize({ type: this.type, difX, difY, area })\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n }\r\n\r\n isInArea(area: Area) {\r\n const width = this.model.scale.x.invert(this.getThumbWidth())\r\n const height = this.model.scale.y.invert(0) - this.model.scale.y.invert(this.getThumbWidth())\r\n // +- width/2 because we have coordinates of a center\r\n if (\r\n this.fx() + width / 2 >= area.x &&\r\n this.fx() - width / 2 <= area.x &&\r\n this.fy() + height / 2 > area.y &&\r\n this.fy() - height / 2 < area.y\r\n ) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n getThumbWidth() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return ThumbSettings.size + ThumbSettings.borderWidth * 2\r\n }\r\n\r\n x() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return this.model.scale.x(this.fx()) - ThumbSettings.size / 2\r\n }\r\n\r\n y() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return this.model.scale.y(this.fy()) - ThumbSettings.size / 2\r\n }\r\n}\r\n\r\nexport default Thumb\r\n","import Utils from '../utils'\r\nimport { getContextWithCache } from '../utils/canvas'\r\nimport { captureException, getIsSSr } from '../utils/helpers'\r\n\r\nclass Cache {\r\n constructor() {\r\n this.canvas = getIsSSr() ? null : document.createElement('canvas')\r\n }\r\n\r\n set(callback, width, height) {\r\n this.callback = callback\r\n this.width = width\r\n this.height = height\r\n this.rendered = false\r\n }\r\n\r\n render(context, x, y) {\r\n if (x == null) {\r\n x = 0\r\n }\r\n if (y == null) {\r\n y = 0\r\n }\r\n if (!this.rendered) {\r\n this.refresh()\r\n }\r\n if (this.width < 1 || this.height < 1) {\r\n return\r\n }\r\n\r\n try {\r\n if (this.ratio >= 1 && this.canvas) {\r\n context.drawImage(\r\n this.canvas,\r\n 0,\r\n 0,\r\n ~~(this.width * this.ratio),\r\n ~~(this.height * this.ratio),\r\n x,\r\n y,\r\n this.width,\r\n this.height\r\n )\r\n } else {\r\n context.save()\r\n context.translate(x, y)\r\n this.callback(context)\r\n context.restore()\r\n }\r\n } catch (e) {\r\n captureException(\r\n e,\r\n this.canvas\r\n ? {\r\n extra: {\r\n width: this.width,\r\n height: this.height,\r\n ratio: this.ratio,\r\n cWidth: this.canvas.width,\r\n cHeight: this.canvas.height,\r\n sWidth: window.screen.width,\r\n sHeight: window.screen.height,\r\n },\r\n }\r\n : {}\r\n )\r\n }\r\n }\r\n\r\n refresh() {\r\n if (getIsSSr()) {\r\n return\r\n }\r\n this.canvas.width = this.width\r\n this.canvas.height = this.height\r\n this.context = getContextWithCache(this.canvas)\r\n this.ratio = Utils.getScaleRatio()\r\n Utils.setSizeOnCanvasElement({ canvasElement: this.canvas, width: this.width, height: this.height })\r\n this.context.scale(this.ratio, this.ratio)\r\n\r\n this.callback(this.context)\r\n this.rendered = true\r\n }\r\n}\r\n\r\nexport default Cache\r\n","import { ObjectHash, Theme } from '../../../types/shared'\r\nimport { TextAlign, TextBaseline } from '../../constants/common'\r\nimport { IChartThemeColors, IElementThemeColors, IIndicatorThemeColors } from '../constants'\r\n\r\nexport enum OHLCType {\r\n singleLine = 'singleLine',\r\n dateOnly = 'dateOnly',\r\n timeOnly = 'timeOnly',\r\n}\r\n\r\nexport interface IMargin {\r\n top?: number\r\n right?: number\r\n bottom?: number\r\n left?: number\r\n}\r\n\r\ninterface IPadding {\r\n top?: number\r\n right?: number\r\n bottom?: number\r\n left?: number\r\n}\r\n\r\ninterface IGenericText {\r\n margin: IMargin\r\n font: IFont\r\n}\r\n\r\ninterface IFont {\r\n size?: number\r\n style?: string\r\n weight?: string\r\n family?: string\r\n lineHeight?: number\r\n padding?: IPadding\r\n baseline?: TextBaseline\r\n textAlign?: TextAlign\r\n}\r\n\r\ninterface ISettingsGeneralBase {\r\n Colors: IChartThemeColors\r\n}\r\n\r\nexport interface ISettingsCenterBase {\r\n barWidth: number\r\n barMargin: number\r\n border: number\r\n volumeHeight?: number\r\n}\r\n\r\ninterface ISettingsTopBase {\r\n height: number\r\n}\r\n\r\ninterface ISettingsBottomBase {\r\n height: number\r\n}\r\n\r\ninterface ISettingsLeftBase {\r\n width: number\r\n}\r\n\r\ninterface ISettingsRightBase {\r\n width: number\r\n}\r\n\r\nexport interface ISettings {\r\n ChartSettings: IChartSettings\r\n IndicatorSettings: IIndicatorSettings\r\n MarketSentimentSettings: IMarketSentimentChartSettings\r\n ColorsSettings: Array\r\n ThumbSettings: IThumbSettings\r\n ElementSettings: IElementSettings\r\n}\r\n\r\nexport interface IChartSettings {\r\n general: IChartGeneral\r\n center: ISettingsCenterBase\r\n top: IChartTop\r\n bottom: IChartBottom\r\n left: IChartLeft\r\n right: IChartRight\r\n}\r\n\r\ninterface IChartGeneral {\r\n settingsHeight: number\r\n tickerTimeframeChangeHeight: number\r\n Colors: IChartThemeColors & ObjectHash\r\n}\r\n\r\ninterface IChartTop extends ISettingsTopBase {\r\n baseline: TextBaseline\r\n ticker: IGenericText\r\n ohlc: IOHLC\r\n change: IGenericText\r\n}\r\n\r\ninterface IOHLC extends IGenericText {\r\n type?: OHLCType\r\n}\r\n\r\ninterface IChartBottom extends ISettingsBottomBase {\r\n baseline: TextBaseline\r\n axis: IGenericText\r\n}\r\n\r\ninterface IChartLeft extends ISettingsLeftBase {\r\n overlayLabel: IOverlayLabel\r\n timeframe: IGenericText\r\n volumeAxis: IGenericText\r\n}\r\n\r\ninterface IOverlayLabel extends IGenericText {\r\n labelSpacing: number\r\n}\r\n\r\ninterface IChartRight extends ISettingsRightBase {\r\n axis: IGenericText\r\n}\r\n\r\nexport interface IIndicatorSettings {\r\n general: IIndicatorGeneral\r\n center: ISettingsCenterBase\r\n top: ISettingsTopBase\r\n bottom: ISettingsBottomBase\r\n left: IIndicatorLeft\r\n right: IIndicatorRight\r\n}\r\n\r\ninterface IIndicatorRight extends ISettingsRightBase {\r\n axis: IGenericText\r\n}\r\n\r\ninterface IIndicatorLeft extends ISettingsLeftBase {\r\n indicatorLabel: IIndicatorLabel\r\n}\r\n\r\ninterface IIndicatorLabel extends IGenericText {\r\n labelSpacing: number\r\n}\r\n\r\ninterface IIndicatorGeneral {\r\n Colors: IIndicatorThemeColors\r\n height: number\r\n}\r\n\r\ninterface IMarketSentimentChartSettings {\r\n general: ISettingsGeneralBase\r\n center: ISettingsCenterBase\r\n top: ISettingsTopBase\r\n bottom: ISettingsBottomBase\r\n left: ISettingsLeftBase\r\n right: ISettingsRightBase\r\n}\r\n\r\ninterface IThumbSettings {\r\n size: number\r\n touchSize: number\r\n color: string\r\n borderWidth: number\r\n borderColor: string\r\n}\r\n\r\ninterface IElementSettings {\r\n Colors: IElementThemeColors\r\n defaultFill: string\r\n defaultTransparentFill: string\r\n}\r\n","export enum ChartMinWidthBreakpoints {\r\n xs = 0,\r\n s = 480,\r\n m = 768,\r\n l = 1024,\r\n}\r\n\r\nexport function getChartBreakpoints(chartWidthInPx: number) {\r\n return {\r\n isXs: chartWidthInPx >= ChartMinWidthBreakpoints.xs,\r\n isS: chartWidthInPx >= ChartMinWidthBreakpoints.s,\r\n isM: chartWidthInPx >= ChartMinWidthBreakpoints.m,\r\n isL: chartWidthInPx >= ChartMinWidthBreakpoints.l,\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\nimport merge from 'lodash.merge'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n CustomSpineEvents,\r\n Instrument,\r\n Maybe,\r\n RequireByKey,\r\n Theme,\r\n} from '../../types/shared'\r\nimport Cache from '../canvas/cache'\r\nimport Element from '../canvas/element'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport {\r\n CHART_MARGIN,\r\n ChartElementType,\r\n FONT_SIZE,\r\n IndicatorType,\r\n IntradayTimeframeInterval,\r\n LINE_HEIGHT,\r\n MONTHS,\r\n OFFSET,\r\n PADDING,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TIMEFRAMES_WITH_PRE_MARKET,\r\n TextAlign,\r\n TextBaseline,\r\n getTimeframeLabel,\r\n} from '../constants/common'\r\nimport {\r\n getIsSmallIndexChart,\r\n getPercentageFromValue,\r\n getTranslate,\r\n getValueFromPercentage,\r\n} from '../controllers/renderUtils'\r\nimport Chart from '../models/chart'\r\nimport { getColorOverwrites } from '../models/chart_settings'\r\nimport { ISettings, OHLCType } from '../models/chart_settings/interfaces'\r\nimport { darkerWickColors, thinBarColorsOverride } from '../models/constants'\r\nimport mouseModel from '../models/mouse'\r\nimport PaneModel, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Overlay from '../overlays/overlay'\r\nimport { overlaysByType } from '../overlays/overlays'\r\nimport utils, { dateFromDateString, isRedesignedPage, numberToStringWithUnitsSuffix } from '../utils'\r\nimport {\r\n ITickerChange,\r\n getBarWidthWithMargin,\r\n getBarWidthWithMarginByParts,\r\n getChangeColor,\r\n getShouldUseDarkerWickColors,\r\n getTickerChange,\r\n getTickerChangeFromCloseValues,\r\n getVirtualTimeframeTradedDates,\r\n renderCross,\r\n round,\r\n unmountCanvas,\r\n} from '../utils/chart'\r\nimport { convertColorToHEX, getHEXWithSpecificAplha, getHSVAFromColor, stringifyHSVAColor } from '../utils/colors'\r\nimport { setElementCursor } from '../utils/cursor'\r\nimport { drawInVisibleArea, getFirstBarToRenderIndex, getLastBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { getChartBreakpoints } from './utils'\r\n\r\nexport interface BaseChartAttrs {\r\n overlays: Required['overlays']\r\n}\r\n\r\ntype OhlcLineElements = Array<{ text: string; color: string } | 'space'>\r\n\r\ninterface LastOHLCAttrs {\r\n text: string\r\n x: number\r\n y: number\r\n width: number\r\n textBaseline: TextBaseline\r\n textAlign: TextAlign\r\n}\r\n\r\ninterface IRenderOHLCParameters {\r\n context: CanvasRenderingContext2D\r\n date: Maybe\r\n open?: Maybe\r\n high?: Maybe\r\n low?: Maybe\r\n close?: Maybe\r\n volume?: Maybe\r\n afterHour?: string\r\n isSmallIndexChart?: boolean\r\n isNewestOHLC?: boolean\r\n directRender?: boolean\r\n time?: string\r\n changePercentage?: Maybe\r\n}\r\n\r\ninterface XAxisLabel {\r\n x: number\r\n text: string\r\n textWidth: number\r\n hasPriority?: boolean\r\n allowedOverflow?: number\r\n}\r\n\r\ninterface IRenderXAxisProps {\r\n textRenderer: Text\r\n startBarIndex: number\r\n endBarIndex: number\r\n}\r\n\r\nconst getDateString = ({ date, timeframe }: { date: Date; timeframe: TIMEFRAME }) => {\r\n let dateString = ''\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n switch (timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n case TIMEFRAME.i10:\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n const t =\r\n (((date.getHours() + 11) % 12) + 1).toString().padLeft('00') +\r\n ':' +\r\n date.getMinutes().toString().padLeft('00') +\r\n (date.getHours() < 12 ? 'AM' : 'PM')\r\n dateString = `${MONTHS[month]} ${day} ${t}`\r\n break\r\n case TIMEFRAME.d:\r\n case TIMEFRAME.w:\r\n dateString = `${MONTHS[month]} ${day}`\r\n break\r\n case TIMEFRAME.m:\r\n dateString = `${MONTHS[month]} ${year}`\r\n break\r\n default:\r\n break\r\n }\r\n\r\n return dateString\r\n}\r\n\r\nconst getIsOverlapping = ({\r\n x,\r\n textWidth,\r\n renderedLabelRanges,\r\n}: {\r\n x: number\r\n textWidth: number\r\n renderedLabelRanges: Array<{ from: number; to: number }>\r\n}) =>\r\n renderedLabelRanges.some(({ from, to }) => {\r\n const minX = x - textWidth / 2\r\n const maxX = x + textWidth / 2\r\n return (from < maxX && maxX < to) || (from < minX && minX < to)\r\n })\r\n\r\nfunction getClosestDifferentMinMaxValueIndices(\r\n currentMinIndex: number,\r\n currentMaxIndex: number,\r\n high: number[],\r\n low: number[]\r\n): { minIndex: number; maxIndex: number } {\r\n const hasPreviousIndex = currentMinIndex > 0\r\n const hasNextIndex = currentMaxIndex < high.length - 1\r\n let minIndex = currentMinIndex\r\n let maxIndex = currentMaxIndex\r\n if (hasPreviousIndex) {\r\n minIndex -= 1\r\n }\r\n if (hasNextIndex) {\r\n maxIndex += 1\r\n }\r\n\r\n if (low[minIndex] === high[maxIndex] && (hasPreviousIndex || hasNextIndex)) {\r\n return getClosestDifferentMinMaxValueIndices(minIndex, maxIndex, high, low)\r\n }\r\n\r\n return low[minIndex] < high[maxIndex] ? { minIndex, maxIndex } : { minIndex: maxIndex, maxIndex: minIndex }\r\n}\r\n\r\nconst SMALL_INDEX_CHART_LABEL_BUFFER = 15\r\n\r\nconst gray300 = tailwindColors.gray[300]\r\n\r\nclass BaseChart extends Element {\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n const { ChartSettings } = this.getChartLayoutSettings() as ISettings\r\n return this.model.width - ChartSettings.left.width - ChartSettings.right.width\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const { ChartSettings } = this.getChartLayoutSettings() as ISettings\r\n return this.paneModel.height - ChartSettings.top.height - ChartSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n static getNumOfBarsBuffer({ overlays }: RequireByKey) {\r\n return Math.max(0, ...overlays.map((overlay) => overlaysByType[overlay.type].getNumOfBarsBuffer(overlay)))\r\n }\r\n\r\n static label = 'Chart'\r\n static iconName = ''\r\n\r\n paneModel: PaneModel\r\n model: Chart\r\n data: Quote\r\n specificChartFunctionality: SpecificChartFunctionality\r\n tickerWidth = 0\r\n changeWidth = 0\r\n lastOhlc: Array> = []\r\n overlays: Overlay[] = []\r\n isLargeChart?: boolean\r\n shouldRenderVolume = true\r\n afterChange: {\r\n x: number\r\n y: number\r\n width: number\r\n } | null = null\r\n\r\n declare setupAxisTimeFrame: string\r\n declare volumeFY: d3.ScaleLinear\r\n declare tickerText: Text\r\n declare baseCache: Cache\r\n declare leftOffset: number\r\n declare context: CanvasRenderingContext2D\r\n declare width: number\r\n declare height: number\r\n declare isMobile: boolean\r\n\r\n constructor(values: Partial, paneModel: PaneModel) {\r\n super(values, paneModel)\r\n\r\n this.paneModel = paneModel\r\n this.model = this.paneModel.chart()\r\n this.data = this.model.quote()\r\n const chartLayoutModel = this.model.chart_layout()\r\n this.specificChartFunctionality = chartLayoutModel.specificChartFunctionality\r\n this.isLargeChart = chartLayoutModel.isLargeChart\r\n this.isMobile = utils.isMobile(true)\r\n\r\n this.overlays = []\r\n if (values.overlays) {\r\n for (const overlayDefinition of values.overlays) {\r\n // overlayDefinition.color coming from DB is always string however overlays\r\n // internaly didn't use format as in db (type, color, period) but rather\r\n // more overlay specific parameters eg. (BB: topColor, bottomColor, etc.)\r\n // thus overlayDefinition.color might be undefined\r\n // approach could be reworked in https://github.com/finvizhq/charts/issues/770\r\n // but for now (!overlayDefinition.color) check solve issue as well\r\n const overlay = overlaysByType[overlayDefinition.type].fromObject(\r\n {\r\n ...overlayDefinition,\r\n color:\r\n !overlayDefinition.color || overlayDefinition.color.includes('|')\r\n ? ''\r\n : convertColorToHEX(overlayDefinition.color),\r\n },\r\n this.paneModel\r\n )\r\n this.addOverlay(overlay)\r\n }\r\n delete values.overlays\r\n }\r\n\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderCrossText = this.renderCrossText.bind(this)\r\n this.setupCache = this.setupCache.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n\r\n // this.paneModel.bind('update', this.setupAxis.bind(this))\r\n this.paneModel.bind('update', this.setupCache)\r\n this.paneModel.bind('change', this.trigger.bind(this, 'change'))\r\n this.model = this.paneModel.chart()\r\n // this.model.bind('change', this.setupAxis.bind(this))\r\n this.model.bind('change', this.setupCache)\r\n this.model.bind('change', this.trigger.bind(this, 'change'))\r\n this.model.bind(CustomSpineEvents.IndicatorsChange, this.handleIndicatorsChange.bind(this))\r\n const mouseModelChangeHandler = this.trigger.bind(this, 'change', 'cross')\r\n this.model.bind('destroy', () => {\r\n this.model.unbind('change', this.setupCache)\r\n this.model.unbind(CustomSpineEvents.IndicatorsChange, this.handleIndicatorsChange.bind(this))\r\n mouseModel.unbind('change', mouseModelChangeHandler)\r\n unmountCanvas(this.baseCache.canvas)\r\n })\r\n mouseModel.bind('change', mouseModelChangeHandler)\r\n\r\n this.model.chart_layout().bind('theme', this.setupCache)\r\n this.model.chart_layout().bind('update', this.updateShouldRenderVolume.bind(this))\r\n\r\n this.setupCache()\r\n }\r\n\r\n renderChart() {\r\n throw Error('Implement renderChart')\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n this.data = this.model.quote()\r\n this.leftOffset = this.model.leftOffset\r\n this.context = context\r\n\r\n if (this.data.close.length === 0) {\r\n this.renderChartNotAvailable()\r\n if (!this.getIsRedesignedChart()) this.renderTicker(context)\r\n return\r\n }\r\n\r\n this.context.save()\r\n this.clip()\r\n this.renderVolume()\r\n this.renderChart()\r\n this.renderOverlays()\r\n this.renderPrevClose()\r\n this.renderFadeExtendedHours()\r\n this.context.restore()\r\n if (!this.getIsRedesignedChart()) this.renderTicker(context)\r\n }\r\n\r\n renderGrid(context: CanvasRenderingContext2D) {\r\n this.data = this.model.quote()\r\n this.leftOffset = this.model.leftOffset\r\n this.context = context\r\n // text, xAxis, volumeAxis\r\n this.renderXAxis()\r\n this.baseCache.render(context)\r\n }\r\n\r\n renderTicker(context: CanvasRenderingContext2D) {\r\n if (this.tickerText) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n context.translate(ChartSettings.left.width, 0)\r\n this.tickerText.render(context)\r\n\r\n if (getIsSmallIndexChart(this.specificChartFunctionality) && this.data.ticker === 'RUSSELL 2000') {\r\n const { Colors } = ChartSettings.general\r\n new Text(\r\n {\r\n text: 'ETF',\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top! + FONT_SIZE.XXS + OFFSET.XXS,\r\n font: { size: FONT_SIZE.XXS },\r\n fillStyle: Colors.text,\r\n textBaseline: ChartSettings.top.baseline,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n context.translate(-ChartSettings.left.width, 0)\r\n }\r\n }\r\n\r\n renderTimeframe(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const quote = this.model.quote()\r\n const y = (this.height - this.volumeFY.range()[1] - 4) / 2\r\n\r\n return new Text(\r\n {\r\n text: quote.instrument === Instrument.Group ? 'YEAR PERFORMANCE %' : getTimeframeLabel(quote.timeframe),\r\n x: ChartSettings.left.timeframe.margin.left,\r\n y: ChartSettings.top.height + y + (ChartSettings.left.timeframe.margin.top ?? 0),\r\n angle: -90,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.left.timeframe.font),\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n if (!getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.tickerText = new Text(\r\n {\r\n text: this.data.name || this.data.ticker,\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.ticker.font),\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: Colors.text,\r\n },\r\n this.paneModel\r\n )\r\n } else {\r\n this.tickerText = new Text(\r\n {\r\n text: this.data.name || this.data.ticker,\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top,\r\n font: { size: FONT_SIZE.L, style: 'bold' },\r\n fillStyle: Colors.text,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n this.tickerWidth = this.tickerText.measure(context)\r\n\r\n // render watermark on backend chart\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n new Text(\r\n {\r\n text: '© finviz.com',\r\n x: this.width + ChartSettings.right.width - 2,\r\n y: 1,\r\n font: { size: FONT_SIZE.XS },\r\n textAlign: TextAlign.right,\r\n textBaseline: TextBaseline.top,\r\n fillStyle: 'rgb(136, 193, 233)',\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderChange({ context })\r\n if (!this.lastOhlc[0]) {\r\n this.getOHLC({ context, directRender: false })\r\n }\r\n this.getOHLC({ context })\r\n }\r\n\r\n context.restore()\r\n if (!this.getIsRedesignedChart() && !getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderTimeframe(context)\r\n }\r\n }\r\n\r\n getOHLC({\r\n context,\r\n directRender = true,\r\n data,\r\n date,\r\n dateString = null,\r\n changePercentage = null,\r\n }: {\r\n context: CanvasRenderingContext2D\r\n directRender?: boolean\r\n data?: {\r\n open?: string\r\n high?: string\r\n low?: string\r\n close?: string\r\n volume?: string\r\n }\r\n date?: Date\r\n dateString?: string | null\r\n changePercentage?: ITickerChange | null\r\n }) {\r\n if (!this.data.lastDate) return\r\n\r\n // modulo \"parsing\" is 100% faster than with str.slice()\r\n const lastDate = `${MONTHS[(~~(this.data.lastDate / 100) % 100) - 1]} ${this.data.lastDate % 100}` // YYYYMMDD / 20211118 => Nov 18\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderOHLC({\r\n context,\r\n date: lastDate,\r\n isSmallIndexChart: true,\r\n isNewestOHLC: true,\r\n directRender,\r\n })\r\n } else if (data && date) {\r\n this.renderOHLC({\r\n context,\r\n date: getDateString({ date, timeframe: this.data.timeframe }),\r\n open: data.open,\r\n high: data.high,\r\n low: data.low,\r\n close: data.close,\r\n volume: numberToStringWithUnitsSuffix(Number(data.volume)),\r\n directRender,\r\n changePercentage,\r\n })\r\n } else if (dateString !== null) {\r\n this.renderOHLC({\r\n context,\r\n date: dateString,\r\n open: null,\r\n high: null,\r\n low: null,\r\n close: null,\r\n volume: null,\r\n directRender,\r\n })\r\n } else {\r\n this.renderOHLC({\r\n context,\r\n date: lastDate,\r\n afterHour:\r\n Number.isFinite(this.data.afterClose) && this.data.afterClose !== this.data.lastClose\r\n ? this.roundOhlc(this.data.afterClose)\r\n : undefined,\r\n volume: numberToStringWithUnitsSuffix(this.data.lastVolume),\r\n isNewestOHLC: true,\r\n time: utils.dateFromUnixTimestamp(this.data.date.last()!).toLocaleTimeString('en-US', {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n }),\r\n directRender,\r\n ...this.getRoundedLastData(),\r\n })\r\n }\r\n }\r\n\r\n getRoundedLastData() {\r\n return {\r\n open: this.roundOhlc(this.data.lastOpen),\r\n high: this.roundOhlc(this.data.lastHigh),\r\n low: this.roundOhlc(this.data.lastLow),\r\n close: this.roundOhlc(this.data.lastClose),\r\n }\r\n }\r\n\r\n renderOverlaysLabels(context: CanvasRenderingContext2D) {\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabelsQuotePage(context)\r\n } else if (this.data.close.length !== 0) {\r\n this.renderOverlaysLabelsChartsPage(context)\r\n }\r\n }\r\n\r\n renderOverlaysLabelsQuotePage(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const text = new Text(\r\n {\r\n x: ChartSettings.left.overlayLabel.margin.left,\r\n y: ChartSettings.top.height + ChartSettings.left.overlayLabel.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.left.overlayLabel.font),\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n for (const overlay of this.overlays) {\r\n if (!overlay.isRenderedOverlaysLabel()) {\r\n continue\r\n }\r\n text\r\n .set({\r\n text: overlay.toString(),\r\n y: text.get('y')! + ChartSettings.left.overlayLabel.labelSpacing,\r\n fillStyle: overlay.getLabelColor(),\r\n })\r\n .render(context)\r\n }\r\n }\r\n\r\n getYAxisLeftMargin() {\r\n if (this.data.instrument === Instrument.Crypto && this.data.lastClose <= 0.001) {\r\n return 3\r\n }\r\n return 8\r\n }\r\n\r\n getYAxisLastCloseLabel({ lastClose, firstVisibleClose }: { lastClose: number; firstVisibleClose?: number | null }) {\r\n if (typeof firstVisibleClose === 'number' && this.model.scale === ScaleType.Percentage) {\r\n return `${this.round(getPercentageFromValue({ number: lastClose, base: firstVisibleClose }), 2)}%`\r\n }\r\n return this.round(lastClose)\r\n }\r\n\r\n renderYAxis(\r\n context: CanvasRenderingContext2D,\r\n { lastClose }: RequireByKey, 'lastClose'> = this.data,\r\n renderLabels = true\r\n ) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const contentHeight = this.paneModel.height - ChartSettings.top.height - ChartSettings.bottom.height\r\n let y, lineTicks, textTicks, lastCloseLabel\r\n const translate = getTranslate({ context, xOffset: ChartSettings.left.width, yOffset: ChartSettings.top.height })\r\n translate.do()\r\n const tickCount = Math.floor(this.paneModel.height / 35)\r\n const minMax = this.getMinMax()\r\n const { firstVisibleClose } = minMax\r\n let stepPrice = 0\r\n let placesAxis\r\n\r\n switch (this.model.scale) {\r\n case ScaleType.Percentage: {\r\n if (!firstVisibleClose) return\r\n\r\n const scaleRange = this.paneModel.scaleRange\r\n const { min, max } = scaleRange || minMax\r\n\r\n this.model.updateAttribute('firstBarClose', firstVisibleClose)\r\n\r\n const minPerc = getPercentageFromValue({ number: min, base: firstVisibleClose })\r\n const maxPerc = getPercentageFromValue({ number: max, base: firstVisibleClose })\r\n\r\n const percScale = d3.scaleLinear().range([0, contentHeight]).domain([maxPerc, minPerc]).nice(10)\r\n textTicks = percScale.ticks(Math.min(tickCount, 9))\r\n lineTicks = textTicks.map((tick) => getValueFromPercentage({ number: tick, base: firstVisibleClose }))\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose, firstVisibleClose })\r\n break\r\n }\r\n case ScaleType.Logarithmic: {\r\n if (!firstVisibleClose) return\r\n\r\n const scaleRange = this.paneModel.scaleRange\r\n const { min, max } = scaleRange || minMax\r\n lineTicks = [Math.floor(min)]\r\n const pixelGap = 30\r\n\r\n const negativeScale = []\r\n if (min < 0) {\r\n let previousNegativeTick = Math.min(0, max)\r\n while (this.paneModel.scale.y(previousNegativeTick) + pixelGap < this.paneModel.scale.y(min)) {\r\n const tick = this.paneModel.scale.y.invert(this.paneModel.scale.y(previousNegativeTick) + pixelGap)\r\n if (previousNegativeTick === tick) {\r\n break\r\n }\r\n const range = d3.nice(-previousNegativeTick, -tick, 2)\r\n previousNegativeTick = -range[range.length - 1]\r\n negativeScale.unshift(previousNegativeTick)\r\n }\r\n }\r\n\r\n const positiveScale = []\r\n if (max > 0) {\r\n positiveScale.push(Math.max(this.paneModel.scale.y.invert(this.paneModel.scale.y(min) + pixelGap), 0))\r\n }\r\n while (this.paneModel.scale.y(positiveScale[positiveScale.length - 1]) - pixelGap > 0) {\r\n const previousTick = positiveScale[positiveScale.length - 1]\r\n const positiveScaleY = this.paneModel.scale.y(positiveScale[positiveScale.length - 1])\r\n const tick = this.paneModel.scale.y.invert(positiveScaleY - pixelGap)\r\n if (previousTick === tick) {\r\n break\r\n }\r\n\r\n const range = d3.nice(previousTick, tick, 2)\r\n positiveScale.push(range[range.length - 1])\r\n }\r\n lineTicks = [...negativeScale, ...positiveScale]\r\n textTicks = lineTicks\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose })\r\n break\r\n }\r\n default:\r\n // default to linear scale type\r\n lineTicks = this.paneModel.scale.y.ticks(Math.min(tickCount, 9))\r\n textTicks = lineTicks\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose })\r\n }\r\n\r\n if (textTicks.length >= 2) {\r\n stepPrice = Math.abs(textTicks[1] - textTicks[0])\r\n }\r\n if (stepPrice > 10 || getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n placesAxis = 0\r\n }\r\n\r\n const getYLineText = (val: number, places?: number) => {\r\n switch (this.model.scale) {\r\n case ScaleType.Percentage:\r\n return `${val}%`\r\n default:\r\n return this.round(val, places)\r\n }\r\n }\r\n\r\n const yTickText = new Text(\r\n {\r\n x: this.width + this.getYAxisLeftMargin() + ChartSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n )\r\n\r\n let yTickLine = this.getYLine()\r\n const resetYTicksStyles = () => {\r\n yTickText.set({\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n })\r\n yTickLine = this.getYLine()\r\n }\r\n for (let i = 0; i < lineTicks.length; i++) {\r\n y = Math.round(this.fy(lineTicks[i]))\r\n if (y < 0 || y > contentHeight) continue\r\n if (y === contentHeight) y -= 1 // due pixel perfect rendering of lines, last line is moved outside of \"chart area\" because of 0.5px translate, to compensate for this we subtract 1px\r\n yTickLine.set({ y1: y, y2: y })\r\n yTickText.set({\r\n text: getYLineText(textTicks[i], placesAxis),\r\n y,\r\n })\r\n if (this.model.scale === ScaleType.Percentage && textTicks[i] === 0) {\r\n yTickLine.set({ strokeStyle: Colors.text })\r\n yTickText.set({\r\n font: { weight: 'bold', size: yTickText.attrs.font.size },\r\n fillStyle: Colors.percentageZeroLineText,\r\n })\r\n yTickLine.render(context)\r\n yTickText.render(context)\r\n resetYTicksStyles()\r\n } else {\r\n yTickLine.render(context)\r\n yTickText.render(context)\r\n }\r\n }\r\n translate.undo()\r\n\r\n if (renderLabels) {\r\n this.renderYAxisLabel({ context, yCoordinate: Math.round(this.fy(lastClose)), label: lastCloseLabel })\r\n // if (typeof this.data.afterClose === 'number') {\r\n // this.renderYAxisLabel({\r\n // context,\r\n // yCoordinate: this.getYAxisSecondaryLabelYCoordinate({\r\n // mainLabelValue: lastClose,\r\n // secondaryLabelValue: this.data.afterClose,\r\n // }),\r\n // label: this.getYAxisLastCloseLabel({ lastClose: this.data.afterClose, firstVisibleClose }),\r\n // background: this.getSecondaryLabelBackgroundColor(),\r\n // })\r\n // }\r\n }\r\n }\r\n\r\n getSecondaryLabelBackgroundColor() {\r\n return stringifyHSVAColor(\r\n {\r\n ...getHSVAFromColor(this.getChartLayoutSettings().ChartSettings.general.Colors.currentBackground),\r\n s: 0.3,\r\n },\r\n 'hex'\r\n )\r\n }\r\n\r\n getYAxisSecondaryLabelYCoordinate({\r\n mainLabelValue,\r\n secondaryLabelValue,\r\n }: {\r\n mainLabelValue: number\r\n secondaryLabelValue: number\r\n }) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { lineHeight } = ChartSettings.right.axis.font\r\n const padding = Text.getMergedPropsWithDefaults('padding', ChartSettings.right.axis.font.padding)\r\n\r\n const direction = Math.sign(mainLabelValue - secondaryLabelValue) || 1\r\n const offset = (lineHeight ?? LINE_HEIGHT.S) + (padding.top ?? PADDING.XXS) + (padding.bottom ?? PADDING.XXS)\r\n const mainLabelValuePosition = Math.round(this.fy(mainLabelValue))\r\n const secondaryLabelValuePosition = Math.round(this.fy(secondaryLabelValue))\r\n const offsetedY = mainLabelValuePosition + offset * direction\r\n\r\n return Math.abs(secondaryLabelValuePosition - mainLabelValuePosition) > offset\r\n ? secondaryLabelValuePosition\r\n : offsetedY\r\n }\r\n\r\n renderYAxisLabel({\r\n context,\r\n yCoordinate,\r\n label,\r\n background,\r\n }: {\r\n context: CanvasRenderingContext2D\r\n yCoordinate: number\r\n label: string\r\n background?: string\r\n }) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({ context, xOffset: ChartSettings.left.width, yOffset: ChartSettings.top.height })\r\n const { Colors } = ChartSettings.general\r\n const { size, lineHeight } = ChartSettings.right.axis.font\r\n const padding = Text.getMergedPropsWithDefaults('padding', ChartSettings.right.axis.font.padding)\r\n\r\n translate.do()\r\n new Text(\r\n {\r\n text: label,\r\n x: this.width + this.getYAxisLeftMargin() - padding.left + ChartSettings.right.axis.margin.left!,\r\n y: yCoordinate,\r\n font: Text.getMergedPropsWithDefaults('font', { size, style: 'bold' }),\r\n lineHeight,\r\n padding,\r\n textBaseline: TextBaseline.middle,\r\n fillStyle:\r\n this.specificChartFunctionality === SpecificChartFunctionality.offScreen ? 'black' : Colors.currentText,\r\n background: background || Colors.currentBackground,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n translate.undo()\r\n }\r\n\r\n renderXAxis() {\r\n const { leftOffset, width } = this\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n this.context.save()\r\n if (\r\n this.data.getDrawDays() !== 1 &&\r\n !getIsSmallIndexChart(this.specificChartFunctionality) &&\r\n this.data.instrument !== Instrument.MarketSentiment\r\n ) {\r\n this.clip(true)\r\n }\r\n this.context.translate(ChartSettings.left.width, ChartSettings.top.height)\r\n const textRenderer = new Text(\r\n {\r\n y: this.height + ChartSettings.bottom.axis.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', { size: ChartSettings.bottom.axis.font.size }),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.top,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n\r\n // Ticks are placed at the start of each timeframe period (hour/day/month/year).\r\n // The \"-1\" in the code ensures we start searching from one bar outside the visible area,\r\n // avoiding a tick on the first visible index unless it marks the start of a new timeframe period.\r\n // For example, if the start of December is on December 3rd and the first visible bar is on December 14th,\r\n // we won't display a tick.\r\n const startBarIndex = Math.max(\r\n getFirstBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset,\r\n }) - 1,\r\n 0\r\n )\r\n\r\n const endBarIndex = getLastBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset,\r\n chartWidth: width,\r\n })\r\n\r\n switch (this.data.timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n if (this.data.instrument === Instrument.Stock) {\r\n if (\r\n this.type === ChartElementType.LineChart &&\r\n this.specificChartFunctionality === SpecificChartFunctionality.offScreen &&\r\n this.data.timeframe === 'i5'\r\n ) {\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n } else {\r\n this.renderIntradayXAxis(textRenderer)\r\n }\r\n } else {\r\n this.renderIntradayXAxisFutures({ textRenderer, startBarIndex, endBarIndex })\r\n }\r\n break\r\n case TIMEFRAME.i10:\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderIntradayXAxis(textRenderer)\r\n } else {\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n }\r\n break\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.d:\r\n this.renderDailyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.w:\r\n this.renderWeeklyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.m:\r\n this.renderMonthlyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n default:\r\n break\r\n }\r\n this.context.restore()\r\n }\r\n\r\n isXPointVisible(x: number, buffer = 0) {\r\n return x >= 0 - buffer && x <= this.width + buffer\r\n }\r\n\r\n renderXAxisLabels({\r\n labels,\r\n textRenderer,\r\n allowedOverflow = 0,\r\n }: {\r\n labels: Omit[]\r\n textRenderer: Text\r\n allowedOverflow?: number\r\n }) {\r\n const sortedLabels: XAxisLabel[] = []\r\n const renderedLabelRanges: Array<{ from: number; to: number }> = []\r\n labels.reverse().forEach((label) => {\r\n textRenderer.set({ text: label.text })\r\n const textWidth = Math.floor(textRenderer.measure(this.context))\r\n const newLabel = { ...label, textWidth }\r\n if (label.hasPriority) {\r\n sortedLabels.unshift(newLabel)\r\n } else {\r\n sortedLabels.push(newLabel)\r\n }\r\n })\r\n\r\n sortedLabels.forEach(({ x, text, textWidth }) => {\r\n if (!this.isXPointVisible(x, allowedOverflow)) {\r\n return\r\n }\r\n const halfOfTextWidth = textWidth / 2\r\n const overflowLeft = x - halfOfTextWidth + allowedOverflow\r\n const overflowRight = this.width - (x + halfOfTextWidth) + allowedOverflow\r\n let labelX = x\r\n if (overflowLeft < 0) {\r\n labelX = Math.round(x - overflowLeft)\r\n } else if (overflowRight < 0) {\r\n labelX = Math.round(x + overflowRight)\r\n }\r\n if (getIsOverlapping({ x: labelX, textWidth, renderedLabelRanges })) {\r\n return\r\n }\r\n renderedLabelRanges.push({\r\n from: labelX - halfOfTextWidth - OFFSET.M,\r\n to: labelX + halfOfTextWidth + OFFSET.M,\r\n })\r\n textRenderer.set({ text, x: labelX })\r\n textRenderer.render(this.context)\r\n })\r\n }\r\n\r\n renderIntradayXAxis(textRenderer: Text) {\r\n const interval = IntradayTimeframeInterval[this.data.timeframe as keyof typeof IntradayTimeframeInterval]\r\n const marketStartHour = ~~(this.data.marketStartMinutes / 60)\r\n let marketEndHour = 15 + Math.ceil(this.data.aftermarketLengthMinutes / 60)\r\n const labels = []\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n marketEndHour = 16\r\n }\r\n\r\n const xLine = this.getXLine()\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor: this.model.zoomFactor,\r\n chartLayout: this.model.chart_layout(),\r\n })\r\n\r\n const dayToOffset = this.data.getDayToOffset()\r\n const isSmallIndexChart = getIsSmallIndexChart(this.specificChartFunctionality)\r\n const allowedOverflow = isSmallIndexChart ? SMALL_INDEX_CHART_LABEL_BUFFER : 0\r\n for (const day in dayToOffset) {\r\n const dayIndex = dayToOffset[day]\r\n const date = dateFromDateString(day)\r\n\r\n for (let i = marketStartHour; i <= marketEndHour; i++) {\r\n let x =\r\n ((i * 60 - this.data.marketStartMinutes) / interval) * barWidth +\r\n dayIndex * (this.data.drawMinutesPerDay / interval) * barWidth +\r\n this.leftOffset\r\n if (!this.isXPointVisible(x, allowedOverflow)) {\r\n continue\r\n }\r\n let roundedX = Math.round(x)\r\n\r\n if (i === marketStartHour) {\r\n if (isSmallIndexChart) {\r\n roundedX = Math.round(x - 3 + (30 / interval) * barWidth)\r\n // ~9:30AM\r\n xLine\r\n .set({\r\n x1: roundedX,\r\n x2: roundedX,\r\n })\r\n .render(this.context)\r\n continue\r\n }\r\n if (this.data.premarketLengthMinutes === 0) {\r\n // If there is no premarket, day starts at 9:30 AM\r\n x += (30 / interval) * barWidth\r\n }\r\n roundedX = Math.round(x)\r\n xLine.set({ x1: roundedX, x2: roundedX }).render(this.context)\r\n labels.push({\r\n hasPriority: true,\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n x: roundedX,\r\n })\r\n } else {\r\n xLine.set({ x1: roundedX, x2: roundedX }).render(this.context)\r\n labels.push({\r\n text: ((i + 11) % 12) + 1 + (i < 12 ? 'AM' : 'PM'),\r\n x: roundedX,\r\n })\r\n }\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer, allowedOverflow })\r\n }\r\n\r\n renderIntradayXAxisFutures({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastDay = ''\r\n let lastHours = NaN\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const day = date.getDate() + '-' + date.getMonth()\r\n const hours = date.getHours()\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n\r\n if (day !== lastDay) {\r\n lastDay = day\r\n lastHours = hours\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n x,\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n })\r\n } else if (hours % 2 === 0 && hours !== lastHours) {\r\n lastHours = hours\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({ x, text: ((hours + 11) % 12) + 1 + (hours < 12 ? 'AM' : 'PM') })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n render15MinXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastDay = ''\r\n let x = 0\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const day = date.getDate() + '-' + date.getMonth()\r\n if (day !== lastDay) {\r\n lastDay = day\r\n if (this.data.instrument === Instrument.Stock) {\r\n const barAtMinute = date.getMinutes() + date.getHours() * 60\r\n const indexOffset = (barAtMinute - this.data.marketStartMinutes) / this.data.interval\r\n x = Math.round(this.paneModel.scale.x(this.data.barIndex[i] - indexOffset) + this.leftOffset)\r\n } else {\r\n x = Math.round(this.fx(i) + this.leftOffset)\r\n }\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n x,\r\n })\r\n }\r\n }\r\n\r\n // Offscreen only - if lastDate !== lastBarDate add tick\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n const lastDate = `${MONTHS[(~~(this.data.lastDate / 100) % 100) - 1]} ${(this.data.lastDate % 100)\r\n .toString()\r\n .padLeft('00')}` // YYYYMMDD / 20211118 => Nov 18\r\n\r\n if (labels.length > 0 && labels[labels.length - 1].text !== lastDate) {\r\n const barsInDay = this.data.getBarsInDay()!\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor: this.model.zoomFactor,\r\n chartLayout: this.model.chart_layout(),\r\n })\r\n const dayWidth = barsInDay * barWidth\r\n x += dayWidth\r\n labels.push({\r\n text: lastDate,\r\n x,\r\n })\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n }\r\n }\r\n\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderDailyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastMonth = ''\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n hasPriority: date.getMonth() === 0,\r\n text: date.getMonth() === 0 ? date.getFullYear().toString() : MONTHS[date.getMonth()],\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderWeeklyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastMonth = ''\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n if (date.getMonth() % 3 === 0) {\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n } else {\r\n new Line(\r\n {\r\n x1: x,\r\n x2: x,\r\n y1: 0,\r\n y2: this.height,\r\n strokeStyle: Colors.gridSecondary,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n }\r\n const isYearLabel = date.getMonth() === 0\r\n labels.push({\r\n text: isYearLabel ? date.getFullYear().toString().substring(2) : MONTHS[date.getMonth()][0],\r\n hasPriority: isYearLabel,\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderMonthlyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastYear = null\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const year = date.getFullYear()\r\n const isJanuary = date.getMonth() === 0\r\n if (year !== lastYear && (labels.length !== 0 || isJanuary)) {\r\n lastYear = year\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n text: date.getFullYear().toString(),\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n handleIndicatorsChange() {\r\n this.updateShouldRenderVolume()\r\n this.setupCache()\r\n this.trigger('change')\r\n }\r\n\r\n updateShouldRenderVolume() {\r\n this.shouldRenderVolume = !this.model.chart_layout().getIsIndicatorPresent(IndicatorType.Vol)\r\n }\r\n\r\n getVolumeTicks(count: number, maxHeight: number, fontHeight: number): number[] {\r\n const maxCount = 5\r\n const minCount = 1\r\n if (count > maxCount) {\r\n count = maxCount\r\n }\r\n const ticks = this.volumeFY.ticks(count).filter((tick) => tick !== 0)\r\n if (count <= minCount) {\r\n return [ticks[ticks.length - 1]]\r\n }\r\n // ticks are rendered on middle line so we have +- 1/2 of font size above and below range[min,max]\r\n // so we already have +-1 fontsize space, but in some cases that wouldn't be enough so we need to scale\r\n // dynamically, we add 3px of space per tick gap\r\n if (ticks.length * fontHeight + (ticks.length - 1) * 3 > maxHeight) {\r\n return this.getVolumeTicks(count - 1, maxHeight, fontHeight)\r\n }\r\n return ticks\r\n }\r\n\r\n renderVolumeAxis(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n context.save()\r\n const relativeVolume = Math.max(0, Math.min(2, this.data.relativeVolume))\r\n\r\n const x = 20\r\n const fy = (y: number) => ChartSettings.top.height + this.height - this.height * (0.5 * y)\r\n const height = this.height * (0.5 * relativeVolume)\r\n\r\n const label = new Text(\r\n {\r\n x: 15,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n for (let i = 0.5; i <= 2; i += 0.5) {\r\n const y = Math.round(fy(i))\r\n label\r\n .set({\r\n text: i.toFixed(1),\r\n y: y,\r\n })\r\n .render(context)\r\n\r\n context.set('strokeStyle', 'rgb(130, 130, 130)')\r\n context.beginPath()\r\n context.setLineDash([2, 3])\r\n context.translate(0, 0.5)\r\n context.moveTo(x, y)\r\n context.lineTo(x + 7, y)\r\n context.translate(0, -0.5)\r\n context.stroke()\r\n }\r\n\r\n context.set('fillStyle', 'rgba(0, 135, 255, 0.58)')\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', Colors.grid)\r\n context.setLineDash([])\r\n\r\n context.fillRect(x, Math.round(ChartSettings.top.height + this.height - height), 7, Math.round(height))\r\n context.translate(0.5, 0.5)\r\n context.strokeRect(x, ChartSettings.top.height, 7, this.height)\r\n context.translate(-0.5, -0.5)\r\n\r\n new Text(\r\n {\r\n text: 'RELATIVE\\nVOLUME',\r\n x: 33,\r\n y: ChartSettings.top.height + this.height + 6,\r\n font: { size: FONT_SIZE.XXS },\r\n lineHeight: LINE_HEIGHT.XS,\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.top,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n context.restore()\r\n return\r\n }\r\n const rangeMax = this.volumeFY.range()[1]\r\n const volumeAxisFontSize = ChartSettings.left.volumeAxis.font.size!\r\n const tickCount = Math.floor(rangeMax / volumeAxisFontSize)\r\n const ticks = this.getVolumeTicks(tickCount, rangeMax, volumeAxisFontSize)\r\n const format = this.volumeFY.tickFormat(4, 's')\r\n const text = new Text(\r\n {\r\n x: ChartSettings.left.volumeAxis.margin.left,\r\n font: Text.getMergedPropsWithDefaults('font', { size: ChartSettings.left.volumeAxis.font.size }),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n ticks.forEach((tick) =>\r\n text\r\n .set({\r\n text: format(tick).replace(/G/, 'B'), // https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix\r\n y: ChartSettings.top.height + this.height - this.volumeFY(tick),\r\n })\r\n .render(context)\r\n )\r\n }\r\n\r\n renderVolume() {\r\n if (!this.shouldRenderVolume) return\r\n\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n // Return if the domain bounds are equal, this would put any value in the middle\r\n const [domainFrom, domainTo] = this.volumeFY.domain()\r\n if (this.setupAxisTimeFrame !== this.data.timeframe || domainFrom === domainTo) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height + this.height - 59,\r\n })\r\n translate.do()\r\n const halfBarWidth = this.getHalfBarWidth()\r\n const barWidthWithoutMargin = this.getBarWithoutMarginWidth()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i, x) => {\r\n // Skip render if the value is <= 0\r\n if (this.data.volume[i] <= 0) {\r\n return\r\n }\r\n\r\n this.context.fillStyle = this.data.close[i] < this.data.open[i] ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n const y = Math.round(this.volumeFY(this.data.volume[i]))\r\n this.context.fillRect(x - halfBarWidth, 60, barWidthWithoutMargin, -y)\r\n },\r\n })\r\n translate.undo()\r\n }\r\n\r\n renderOverlays() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n for (const overlay of this.overlays) {\r\n overlay.renderContent(this.context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderCross(context: CanvasRenderingContext2D) {\r\n const isRendered = renderCross({\r\n context,\r\n mouseModel,\r\n paneModel: this.paneModel,\r\n contentWidth: this.width,\r\n contentHeight: this.height,\r\n quote: this.data,\r\n getRoundDecimalPlaces: (price) => this.getPlacesLastClose(price),\r\n onRenderCrossText: !this.getIsRedesignedChart() ? this.renderCrossText : undefined,\r\n })\r\n if (this.getIsRedesignedChart()) {\r\n this.renderCrossText(context, mouseModel.getCrossIndexForPane(this.paneModel))\r\n }\r\n\r\n if (isRendered !== undefined) {\r\n setElementCursor({\r\n elementId: this.model.chart_layout().getHTMLElementId(),\r\n cursor: isRendered ? 'crosshair' : 'default',\r\n conditionalCursor: 'grabbing',\r\n })\r\n }\r\n }\r\n\r\n getDataByCrossIndex(crossIndex: number, key: keyof Quote, shouldReturnRoundedString = true) {\r\n const n = this.data.getDataByBarIndex(key, crossIndex)\r\n if (n !== null) {\r\n return shouldReturnRoundedString ? this.roundOhlc(n) : `${n}`\r\n }\r\n }\r\n\r\n getCrossIndexChange(crossIndex: number) {\r\n const crossDataIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n const crossClose = this.data.close[crossDataIndex] ?? null\r\n const previousClose = this.data.close[crossDataIndex - 1] ?? null\r\n if (crossClose !== null && previousClose !== null) {\r\n return getTickerChangeFromCloseValues({ data: this.data, anchorClose: crossClose, prevClose: previousClose })\r\n }\r\n\r\n return null\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n if (this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabels(context)\r\n if (Number.isNaN(crossIndex)) {\r\n this.getOHLC({ context })\r\n context.restore()\r\n return\r\n }\r\n }\r\n\r\n const dateByBarIndex = this.data.getDataByBarIndex('date', crossIndex)\r\n const date = dateByBarIndex ? utils.dateFromUnixTimestamp(dateByBarIndex) : null\r\n\r\n if (date === null) {\r\n const virtualTradedDates =\r\n this.data.date.length > 0\r\n ? getVirtualTimeframeTradedDates({\r\n dateStart: this.data.date[0],\r\n dateEnd: this.data.date[this.data.date.length - 1],\r\n quote: this.data,\r\n })\r\n : []\r\n this.getOHLC({\r\n context,\r\n dateString: virtualTradedDates[crossIndex]\r\n ? getDateString({\r\n date: utils.dateFromUnixTimestamp(virtualTradedDates[crossIndex]),\r\n timeframe: this.data.timeframe,\r\n })\r\n : null,\r\n })\r\n context.restore()\r\n return\r\n }\r\n\r\n this.getOHLC({\r\n context,\r\n date,\r\n data: {\r\n open: this.getDataByCrossIndex(crossIndex, 'open'),\r\n high: this.getDataByCrossIndex(crossIndex, 'high'),\r\n low: this.getDataByCrossIndex(crossIndex, 'low'),\r\n close: this.getDataByCrossIndex(crossIndex, 'close'),\r\n volume: this.getDataByCrossIndex(crossIndex, 'volume', false),\r\n },\r\n changePercentage: this.getCrossIndexChange(crossIndex),\r\n })\r\n\r\n context.restore()\r\n }\r\n\r\n renderChange({ context }: { context: CanvasRenderingContext2D }) {\r\n const CHANGE_SPACER = 10\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { ticker, change, ohlc } = ChartSettings.top\r\n const { tickerChange, tickerAfterChange } = getTickerChange({ data: this.data })\r\n\r\n if (!tickerChange) {\r\n return\r\n }\r\n\r\n const isOffscreen = this.specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isGroupInstrument = this.data.instrument === Instrument.Group\r\n const changeText = new Text(\r\n {\r\n text: isOffscreen && isGroupInstrument ? tickerChange.percentString : tickerChange.string,\r\n x: !getIsSmallIndexChart(this.specificChartFunctionality)\r\n ? this.width - ChartSettings.top.change.margin.right!\r\n : this.width,\r\n y: ChartSettings.top.change.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.change.font),\r\n textAlign: TextAlign.right,\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: getChangeColor({ change: tickerChange.points, ChartSettings }),\r\n },\r\n this.paneModel\r\n )\r\n this.changeWidth = changeText.measure(context)\r\n changeText.render(context)\r\n\r\n if (isOffscreen && (!this.isLargeChart || isGroupInstrument)) {\r\n return\r\n }\r\n if (tickerAfterChange) {\r\n const afterChangeText = new Text(\r\n {\r\n text: tickerAfterChange?.string,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.change.font),\r\n textAlign: TextAlign.right,\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: getChangeColor({ change: tickerAfterChange.points, ChartSettings }),\r\n },\r\n this.paneModel\r\n )\r\n const afterChangeTextWidth = afterChangeText.measure(context)\r\n const oneLineAHChangeWidth = this.changeWidth + CHANGE_SPACER + afterChangeTextWidth\r\n\r\n if (\r\n ChartSettings.left.width + this.tickerWidth + ticker.margin.left! + OFFSET.S <\r\n ChartSettings.left.width + this.width - oneLineAHChangeWidth - change.margin.right!\r\n ) {\r\n afterChangeText\r\n .set({\r\n x: this.width - ChartSettings.top.change.margin.right! - this.changeWidth - CHANGE_SPACER,\r\n y: ChartSettings.top.change.margin.top,\r\n })\r\n .render(context)\r\n this.afterChange = null\r\n this.changeWidth = oneLineAHChangeWidth\r\n } else if (\r\n this.lastOhlc[0] &&\r\n ChartSettings.left.width +\r\n this.tickerWidth +\r\n ticker.margin.left! +\r\n this.lastOhlc[0].width! +\r\n ohlc.margin.left! +\r\n ohlc.margin.right! <\r\n ChartSettings.left.width + this.width - afterChangeTextWidth - change.margin.right!\r\n ) {\r\n afterChangeText\r\n .set({\r\n x: this.width - ChartSettings.top.change.margin.right!,\r\n y: ChartSettings.top.change.margin.top! - ChartSettings.top.change.font.size! - OFFSET.S,\r\n })\r\n .render(context)\r\n this.changeWidth = Math.max(this.changeWidth, afterChangeTextWidth)\r\n this.afterChange = {\r\n x: this.width - ChartSettings.top.change.margin.right!,\r\n y: ChartSettings.top.change.margin.top! - ChartSettings.top.change.font.size! - OFFSET.S,\r\n width: afterChangeTextWidth,\r\n }\r\n }\r\n }\r\n }\r\n\r\n renderOHLC(parameters: IRenderOHLCParameters) {\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOHLCQuotePage(parameters)\r\n } else {\r\n this.renderOHLCChartsPage(parameters)\r\n }\r\n }\r\n\r\n renderOHLCChartsPage({ context, date, open, high, low, close, volume, changePercentage }: IRenderOHLCParameters) {\r\n const chartBreakpoints = getChartBreakpoints(this.width)\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n const OhlcText = new Text(\r\n {\r\n font: { size: FONT_SIZE.S },\r\n lineHeight: 18,\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n },\r\n this.paneModel\r\n )\r\n\r\n const dateElements = date ? [{ text: date, color: gray300 }] : []\r\n const trendColor = (open ?? 0) > (close ?? 0) ? tailwindColors.red[400] : tailwindColors.green[400]\r\n const oElements = open\r\n ? [\r\n { text: 'O', color: gray300 },\r\n { text: open, color: trendColor },\r\n ]\r\n : []\r\n const hElements = high\r\n ? [\r\n { text: 'H', color: gray300 },\r\n { text: high, color: trendColor },\r\n ]\r\n : []\r\n const lElements = low\r\n ? [\r\n { text: 'L', color: gray300 },\r\n { text: low, color: trendColor },\r\n ]\r\n : []\r\n const cElements = close\r\n ? [\r\n { text: 'C', color: gray300 },\r\n { text: close, color: trendColor },\r\n ]\r\n : []\r\n const volElements = volume\r\n ? [\r\n { text: 'Vol', color: gray300 },\r\n { text: volume, color: trendColor },\r\n ]\r\n : []\r\n const changeElements = changePercentage != null ? [{ text: changePercentage.string, color: trendColor }] : []\r\n\r\n const lines: OhlcLineElements[] = []\r\n\r\n const getFlatLineArrayWithSpaces = (lineElements: OhlcLineElements[]) =>\r\n lineElements.flatMap((elements, index) =>\r\n index > 0 ? ([...(elements.length > 0 ? ['space'] : []), ...elements] as OhlcLineElements) : elements\r\n )\r\n if (chartBreakpoints.isM) {\r\n lines.push(\r\n getFlatLineArrayWithSpaces([\r\n dateElements,\r\n oElements,\r\n hElements,\r\n lElements,\r\n cElements,\r\n volElements,\r\n changeElements,\r\n ])\r\n )\r\n } else if (chartBreakpoints.isS) {\r\n lines.push(getFlatLineArrayWithSpaces([dateElements, changeElements]))\r\n lines.push(getFlatLineArrayWithSpaces([oElements, hElements, lElements, cElements, volElements]))\r\n } else {\r\n lines.push(getFlatLineArrayWithSpaces([dateElements, volElements, changeElements]))\r\n lines.push(getFlatLineArrayWithSpaces([oElements, hElements, lElements, cElements]))\r\n }\r\n\r\n const startX = OFFSET.M - ChartSettings.left.width\r\n let x = startX\r\n let y = OFFSET.M + OhlcText.attrs.lineHeight / 2\r\n\r\n lines.forEach((line) => {\r\n x = startX\r\n line.forEach((lineElement, index, lineElements) => {\r\n const padding = { left: 1, right: 1, top: 0, bottom: 0 }\r\n const { text = '', color = undefined } = lineElement === 'space' ? {} : lineElement\r\n if (index === 0) {\r\n padding.left = 5\r\n } else if (index === lineElements.length - 1) {\r\n padding.right = 5\r\n } else if (lineElement === 'space') {\r\n padding.left = 7\r\n padding.right = 7\r\n if (!chartBreakpoints.isS) {\r\n padding.left = 5\r\n padding.right = 5\r\n }\r\n }\r\n OhlcText.set({ text, fillStyle: color, x, y, padding })\r\n OhlcText.render(context)\r\n x += OhlcText.width\r\n })\r\n y += OhlcText.attrs.lineHeight\r\n })\r\n }\r\n\r\n renderOverlaysLabelsChartsPage(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const chartBreakpoints = getChartBreakpoints(this.width)\r\n const LabelsText = new Text(\r\n {\r\n font: { size: FONT_SIZE.S },\r\n lineHeight: 18,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(ChartSettings.general.Colors.canvasFill, 0.8),\r\n // this function gets (indirectly) called from renderCrossText which is already \"translateX\" by ChartSettings.left.width\r\n x: OFFSET.M - ChartSettings.left.width,\r\n padding: { left: PADDING.S, right: PADDING.S, top: 0, bottom: 0 },\r\n },\r\n this.paneModel\r\n )\r\n\r\n let numberOfNewOhlcLines = 2\r\n if (chartBreakpoints.isM) {\r\n numberOfNewOhlcLines = 1\r\n } else if (chartBreakpoints.isS) {\r\n numberOfNewOhlcLines = 2\r\n }\r\n\r\n // We assume lineheight is the same as OHLC text\r\n const { lineHeight } = LabelsText.attrs\r\n let y = lineHeight * numberOfNewOhlcLines + lineHeight / 2 + OFFSET.M\r\n\r\n for (const overlay of this.overlays) {\r\n if (!overlay.isRenderedOverlaysLabel()) {\r\n continue\r\n }\r\n LabelsText.set({\r\n text: overlay.toString(),\r\n y,\r\n fillStyle: overlay.getLabelColor(),\r\n }).render(context)\r\n y += lineHeight\r\n }\r\n }\r\n\r\n renderOHLCQuotePage({\r\n context,\r\n date,\r\n open,\r\n high,\r\n low,\r\n close,\r\n volume,\r\n afterHour,\r\n isSmallIndexChart = false,\r\n isNewestOHLC = false,\r\n time,\r\n directRender = false,\r\n changePercentage,\r\n }: IRenderOHLCParameters) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { ohlc } = ChartSettings.top\r\n const isOffscreen = this.specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isGroupInstrument = this.data.instrument === Instrument.Group\r\n if (isOffscreen && isGroupInstrument) {\r\n ohlc.type = OHLCType.dateOnly\r\n } else if (isOffscreen && this.data.instrument !== Instrument.Stock && time) {\r\n ohlc.type = OHLCType.timeOnly\r\n }\r\n\r\n const lineTopY = ohlc.type ? ohlc.margin.top : ohlc.margin.top! - ChartSettings.top.ticker.font.size!\r\n const OHLCFontSize = ohlc.font.size!\r\n const centerXOffset =\r\n this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n (this.width -\r\n (this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n this.changeWidth +\r\n (isSmallIndexChart ? 0 : ChartSettings.top.change.margin.right!))) / // smallIndexChart don't have change.margin.right\r\n 2\r\n const leftXOffset = this.tickerWidth + ChartSettings.top.ticker.margin.left! + ohlc.margin.left!\r\n const hasOhlc = ![open, high, low, close, volume].some((ohlcString) => !ohlcString)\r\n const OHLC = hasOhlc\r\n ? {\r\n date: [date ?? ''],\r\n singleLine: [\r\n `${date} O:${open} H:${high} L:${low} C:${close}${\r\n afterHour ? ` AH:${afterHour}` : ''\r\n } Vol:${volume} `,\r\n /*\r\n * this is needed because of the way we render ohlc text down below in renderOHLCToCanvas\r\n * undefined is used instead of null because TS had some issues with `null` even if it is filtered out\r\n * */\r\n changePercentage ? changePercentage.string : undefined,\r\n ].filter((value) => value !== undefined),\r\n }\r\n : {\r\n date: [date ?? ''],\r\n singleLine: [`${date ?? ''}`],\r\n }\r\n\r\n const OHLC_TEXT = new Text(\r\n {\r\n font: { size: OHLCFontSize },\r\n },\r\n this.paneModel\r\n )\r\n\r\n const getOHLCType = () => {\r\n if (!isSmallIndexChart) {\r\n return OHLCType.singleLine\r\n }\r\n return OHLCType.dateOnly\r\n }\r\n\r\n const getOHLCSettings = () => {\r\n switch (ohlc.type || getOHLCType()) {\r\n case OHLCType.singleLine:\r\n return {\r\n text: OHLC.singleLine,\r\n x: [leftXOffset, leftXOffset],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.left,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n case OHLCType.dateOnly:\r\n if (isOffscreen && isGroupInstrument) {\r\n const text = `${OHLC.date} Volume: ${volume}`\r\n const textWidth = OHLC_TEXT.set({ text }).measure(context)\r\n return {\r\n text: [text],\r\n x: [\r\n this.width - ChartSettings.top.change.margin.right! - this.changeWidth - textWidth - CHART_MARGIN.XXL,\r\n ],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.center,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n } else if (isSmallIndexChart) {\r\n return {\r\n text: OHLC.date,\r\n x: [centerXOffset],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.center,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n } else {\r\n const isEnoughSpace =\r\n this.width -\r\n (this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n ohlc.margin.left! +\r\n ohlc.margin.right! +\r\n this.changeWidth +\r\n ChartSettings.top.change.margin.right!) >\r\n OHLC_TEXT.set({ text: OHLC.date[0] }).measure(context)\r\n const alignTop = !isEnoughSpace || ohlc.font.baseline === TextBaseline.top\r\n return {\r\n text: OHLC.date,\r\n x: [leftXOffset],\r\n y: alignTop ? [lineTopY] : [ohlc.margin.top],\r\n textAlign: TextAlign.left,\r\n textBaseline: alignTop ? [TextBaseline.top] : [TextBaseline.alphabetic],\r\n }\r\n }\r\n case OHLCType.timeOnly:\r\n return {\r\n text: [time],\r\n x: [centerXOffset - OHLC_TEXT.set({ text: time }).measure(context) / 2],\r\n y: [lineTopY],\r\n textAlign: TextAlign.center,\r\n textBaseline: [ohlc.font.baseline],\r\n }\r\n default:\r\n return\r\n }\r\n }\r\n\r\n if (!isNewestOHLC) {\r\n context.fillStyle = Colors.canvasFill\r\n this.lastOhlc.forEach((line) => {\r\n const x = (line.textAlign === TextAlign.left ? line.x : line.x! - line.width! / 2)!\r\n const y = (line.textBaseline === TextBaseline.top ? line.y : line.y! - OHLCFontSize)!\r\n context.fillRect(\r\n x - PADDING.XXS,\r\n y - PADDING.XXS,\r\n PADDING.XXS + line.width! + PADDING.XXS,\r\n PADDING.XXS + OHLCFontSize + PADDING.XXS\r\n )\r\n })\r\n\r\n if (this.afterChange) {\r\n context.fillRect(\r\n this.afterChange.x - this.afterChange.width - PADDING.XXS,\r\n this.afterChange.y - ChartSettings.top.change.font.size! - PADDING.XXS,\r\n PADDING.XXS + this.afterChange.width + PADDING.XXS,\r\n PADDING.XXS + ChartSettings.top.change.font.size! + PADDING.XS\r\n )\r\n }\r\n } else {\r\n this.lastOhlc = []\r\n }\r\n\r\n const ohlcSettings = getOHLCSettings()\r\n\r\n const renderOHLCToCanvas = ({\r\n ohlcSet,\r\n render = true,\r\n }: {\r\n ohlcSet?: {\r\n text: (string | undefined)[]\r\n x: number[]\r\n y: (number | undefined)[]\r\n textAlign: TextAlign\r\n textBaseline: (TextBaseline | undefined)[]\r\n }\r\n render?: boolean\r\n }) => {\r\n const isSingleLineWithChange = (ohlc.type || getOHLCType()) === OHLCType.singleLine && changePercentage\r\n ohlcSet?.text.forEach((line: string | undefined, index: number) => {\r\n let i = index\r\n let leftOffset = 0\r\n let fillStyle = Colors.text\r\n let text = line\r\n if (index > 0 && isSingleLineWithChange) {\r\n i -= 1\r\n leftOffset = OHLC_TEXT.measure(context)\r\n text = line\r\n\r\n fillStyle = getChangeColor({ change: changePercentage.points, ChartSettings })\r\n }\r\n const options = {\r\n text,\r\n x: ohlcSet.x[i] + leftOffset,\r\n y: ohlcSet.y[i],\r\n textBaseline: ohlc.font.baseline ? ohlc.font.baseline : ohlcSet.textBaseline[i],\r\n textAlign: ohlc.font.textAlign ? ohlc.font.textAlign : ohlcSet.textAlign,\r\n fillStyle,\r\n }\r\n OHLC_TEXT.set(options)\r\n if (isNewestOHLC) {\r\n this.lastOhlc[i] = { width: OHLC_TEXT.measure(context), ...options }\r\n }\r\n if (render) {\r\n OHLC_TEXT.render(context)\r\n }\r\n })\r\n }\r\n renderOHLCToCanvas({ ohlcSet: ohlcSettings, render: directRender })\r\n\r\n return {\r\n ohlcSettings,\r\n renderOHLCToCanvas,\r\n }\r\n }\r\n\r\n // only for stocks on i1/i3/i5 and one day view\r\n renderFadeExtendedHours() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const period = this.model.quote().timeframe\r\n if (this.data.instrument !== Instrument.Stock) {\r\n return\r\n }\r\n if (![TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3, TIMEFRAME.i5].includes(period)) {\r\n return\r\n }\r\n\r\n const interval = parseInt(period.substring(1), 10)\r\n const dayToOffset = this.data.getDayToOffset()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const halfBarWidth = this.getHalfBarWidth()\r\n for (const day in dayToOffset) {\r\n // todo aftermarket\r\n const dayIndex = dayToOffset[day]\r\n let n0 = (this.data.drawMinutesPerDay / interval) * dayIndex\r\n let n1 = this.data.premarketLengthMinutes / interval + n0 // bars in 90mins from 8am to 9:30am\r\n let x0 = this.paneModel.scale.x(n0) - halfBarWidth\r\n let width = this.paneModel.scale.x(n1) - this.paneModel.scale.x(n0)\r\n this.context.set('fillStyle', Colors.premarketFade)\r\n this.context.fillRect(x0, 0, width, this.height + 1)\r\n\r\n if (this.data.aftermarketLengthMinutes > 0) {\r\n n0 =\r\n (this.data.drawMinutesPerDay / interval) * dayIndex +\r\n (this.data.drawMinutesPerDay - this.data.aftermarketLengthMinutes) / interval\r\n n1 = this.data.aftermarketLengthMinutes / interval + n0 // bars in 90mins from 4pm to 5:30pm\r\n x0 = this.paneModel.scale.x(n0) - halfBarWidth\r\n width = this.paneModel.scale.x(n1) - this.paneModel.scale.x(n0)\r\n\r\n this.context.set('fillStyle', Colors.aftermarketFade)\r\n this.context.fillRect(x0, 0, width, this.height + 1)\r\n }\r\n }\r\n translate.undo()\r\n }\r\n\r\n shouldShowPrevClose() {\r\n const quote = this.model.quote()\r\n const isStock = quote.instrument === Instrument.Stock\r\n const isIntradayWithPreMarket = TIMEFRAMES_WITH_PRE_MARKET.includes(quote.timeframe)\r\n const isIndexChart = this.specificChartFunctionality === SpecificChartFunctionality.smallIndex\r\n\r\n return isStock && (isIntradayWithPreMarket || isIndexChart)\r\n }\r\n\r\n renderPrevClose() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (!this.shouldShowPrevClose()) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const y = Math.round(this.fy(this.model.quote().prevClose))\r\n new Line(\r\n {\r\n x1: 0,\r\n x2: this.width,\r\n y1: y,\r\n y2: y,\r\n strokeStyle: Colors.prevClose,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n translate.undo()\r\n }\r\n\r\n renderChartNotAvailable() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const x = ~~((ChartSettings.left.width + ChartSettings.right.width + this.width) / 2)\r\n const y = ~~((ChartSettings.top.height + ChartSettings.bottom.height + this.height) / 2)\r\n new Text(\r\n {\r\n text: 'Chart not available',\r\n x,\r\n y,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n }\r\n\r\n // private\r\n setupCache() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n /*\r\n * Don't create new Cache instances, because Safari takes too long to free up memory\r\n * leading to canvas.getContext returning null. https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12\r\n *\r\n * To further improve performance, cache.set shouldn't be called when unnecessary,\r\n * because setupCache is called for many model updates. The same applies for indicators/indicator.js.\r\n */\r\n this.baseCache = this.baseCache || new Cache()\r\n\r\n this.baseCache.set(\r\n (context: CanvasRenderingContext2D) => {\r\n if (this.data.close.length === 0) {\r\n this.renderText(context)\r\n return\r\n }\r\n this.renderYAxis(context)\r\n this.renderText(context)\r\n if (!this.getIsMobileChartPage() && this.shouldRenderVolume) {\r\n this.renderVolumeAxis(context)\r\n }\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabels(context)\r\n }\r\n },\r\n this.width + ChartSettings.left.width + ChartSettings.right.width,\r\n this.height + ChartSettings.top.height + ChartSettings.bottom.height\r\n )\r\n }\r\n\r\n // called by controllers/pane on recountScale\r\n setupAxis(fx: ScaleAxis) {\r\n this.data = this.model.quote()\r\n const { volumeHeight } = this.getChartLayoutSettings().ChartSettings.center\r\n\r\n if (typeof fx !== 'function') {\r\n return\r\n }\r\n\r\n const halfBarWidth = this.getHalfBarWidth()\r\n\r\n const volumes = []\r\n for (let i = 0; i < this.data.volume.length; i++) {\r\n const x = fx(this.data.barIndex[i]) - halfBarWidth\r\n if (x + this.model.leftOffset < 0 || x + this.model.leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n volumes.push(this.data.volume[i])\r\n }\r\n\r\n const max = utils.max(volumes) ?? 0\r\n const rangeMax = volumeHeight || 60\r\n this.volumeFY = d3.scaleLinear().range([0, rangeMax]).domain([0, max]).nice(4)\r\n this.setupAxisTimeFrame = this.data.timeframe\r\n }\r\n\r\n // private\r\n clip(addMarginBottom?: boolean) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n if (addMarginBottom == null) {\r\n addMarginBottom = false\r\n }\r\n this.context.beginPath()\r\n let marginBottom = 0\r\n if (addMarginBottom) {\r\n marginBottom = ChartSettings.bottom.height\r\n }\r\n this.context.rect(ChartSettings.left.width, ChartSettings.top.height, this.width, this.height + marginBottom)\r\n this.context.clip()\r\n }\r\n\r\n addOverlay(overlay: Overlay) {\r\n overlay.chart = this\r\n this.overlays.push(overlay)\r\n return this.trigger('change')\r\n }\r\n\r\n setOverlays(overlays: Overlay[]) {\r\n this.overlays = overlays\r\n return this.trigger('change')\r\n }\r\n\r\n removeOverlay(overlay: Overlay) {\r\n for (let index = 0; index < this.overlays.length; index++) {\r\n const el = this.overlays[index]\r\n if (el === overlay) {\r\n this.attrs.overlays.splice(index, 1)\r\n this.overlays.splice(index, 1)\r\n this.trigger('change')\r\n break\r\n }\r\n }\r\n }\r\n\r\n getMinMax(): { min: number; max: number; firstVisibleClose?: number | null } {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n let minIndex = -1\r\n let maxIndex = -1\r\n let firstVisibleClose = null\r\n const data = (this.data = this.model.quote())\r\n\r\n for (let i = 0; i < data.open.length; i++) {\r\n const center = this.fx(i)\r\n if (center + this.model.leftOffset < 0 || center + this.model.leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n if (firstVisibleClose === null) {\r\n firstVisibleClose = data.close[i]\r\n }\r\n if (minIndex === -1 || data.low[minIndex] > data.low[i]) {\r\n minIndex = i\r\n }\r\n if (maxIndex === -1 || data.high[maxIndex] < data.high[i]) {\r\n maxIndex = i\r\n }\r\n }\r\n\r\n if (minIndex === -1 && maxIndex === -1) {\r\n for (\r\n let start = Math.max(data.open.length - 10, 0), i = start, end1 = data.open.length, asc1 = start <= end1;\r\n asc1 ? i < end1 : i > end1;\r\n asc1 ? i++ : i--\r\n ) {\r\n min = Math.min(min, data.low[i])\r\n max = Math.max(max, data.high[i])\r\n }\r\n firstVisibleClose = (max - min) / 2\r\n } else {\r\n if (data.low[minIndex] === data.high[maxIndex]) {\r\n const closestMinMaxIndices = getClosestDifferentMinMaxValueIndices(minIndex, maxIndex, data.high, data.low)\r\n minIndex = closestMinMaxIndices.minIndex\r\n maxIndex = closestMinMaxIndices.maxIndex\r\n }\r\n\r\n min = data.low[minIndex]\r\n max = data.high[maxIndex]\r\n }\r\n\r\n if (this.shouldShowPrevClose() && data.prevClose !== null) {\r\n min = Math.min(min, data.prevClose)\r\n max = Math.max(max, data.prevClose)\r\n }\r\n\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen && !this.model.dateRange) {\r\n min = Math.min(min, data.lastClose)\r\n max = Math.max(max, data.lastClose)\r\n }\r\n return { min, max, firstVisibleClose }\r\n }\r\n\r\n moveBy() {}\r\n\r\n isInArea() {\r\n return false\r\n }\r\n\r\n fx = (x: number) => this.paneModel.scale.x(this.data.barIndex[x])\r\n\r\n fy = (y: number) => this.paneModel.scale.y(y)\r\n\r\n round(n: number, overridePlaces?: number) {\r\n return round({ data: this.data, num: n, overridePlaces: overridePlaces ?? this.getPlacesLastClose() })\r\n }\r\n\r\n roundOhlc(n: number) {\r\n const placesLastClose = this.getPlacesLastClose()\r\n return round({\r\n data: this.data,\r\n num: n,\r\n overridePlaces: placesLastClose ? Math.max(placesLastClose, 2) : undefined,\r\n })\r\n }\r\n\r\n toObject() {\r\n const overlays = this.overlays.map((overlay) => overlay.toObject())\r\n return merge({}, this.attrs, { type: this.type, overlays })\r\n }\r\n\r\n toConfig() {\r\n const overlays = this.overlays.map((overlay) => overlay.toConfig())\r\n return merge({}, this.attrs, { type: this.type, overlays })\r\n }\r\n\r\n getBarWithoutMarginWidth() {\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n chartLayout: this.model.chart_layout(),\r\n zoomFactor: this.model.zoomFactor,\r\n })\r\n return barFillWidth + barBorderWidth * 2\r\n }\r\n\r\n getHalfBarWidth() {\r\n return ~~Math.max(1, this.getBarWithoutMarginWidth() / 2)\r\n }\r\n\r\n getPlacesLastClose(price?: number) {\r\n const { lastClose, instrument } = this.data\r\n const priceAbs = price && Math.abs(price)\r\n if (lastClose >= 100000) {\r\n return 0\r\n } else if (lastClose >= 10000) {\r\n return 1\r\n } else if (instrument === Instrument.Stock && (priceAbs ?? lastClose) < 1) {\r\n return 4\r\n } else if (lastClose === undefined) {\r\n // if lastClose is not defined we'll always display 2 decimpal places, e.g. backtests, screener stats\r\n return 2\r\n }\r\n\r\n return undefined\r\n }\r\n\r\n hasOverlay(type: string) {\r\n return this.overlays.some((x) => x.type === 'overlays/' + type)\r\n }\r\n\r\n getXLine(): Line {\r\n return new Line(\r\n {\r\n y1: 0,\r\n y2: this.height,\r\n strokeStyle: this.getChartLayoutSettings().ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n getYLine(): Line {\r\n return new Line(\r\n {\r\n x1: 0,\r\n x2: this.width,\r\n strokeStyle: this.getChartLayoutSettings().ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart_layout())\r\n }\r\n\r\n getIsMobileChartPage() {\r\n return (\r\n this.isMobile && this.model.chart_layout().specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n )\r\n }\r\n\r\n getCandleLikeChartsRenderingColors() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { theme, specificChartFunctionality } = this.model.chart_layout()\r\n let colors = Colors\r\n const overwrittenColors = getColorOverwrites({\r\n colors,\r\n theme,\r\n })\r\n const overwrittenColorKeys = Object.keys(overwrittenColors)\r\n const hasOverwrittenCandleColor = ['borderUp', 'wickUp', 'borderDown', 'wickDown', 'trendUp', 'trendDown'].some(\r\n (colorKey) => overwrittenColorKeys.includes(colorKey)\r\n )\r\n\r\n const shouldUseDarkerColors =\r\n theme === Theme.light &&\r\n getShouldUseDarkerWickColors({\r\n specificChartFunctionality: specificChartFunctionality,\r\n totalBarWidth: ChartSettings.center.barWidth + ChartSettings.center.border * 2,\r\n })\r\n\r\n if (shouldUseDarkerColors && !hasOverwrittenCandleColor) {\r\n colors = { ...colors, ...darkerWickColors }\r\n }\r\n const isNodeChartWithThinBars =\r\n specificChartFunctionality === SpecificChartFunctionality.offScreen && ChartSettings.center.border === 0\r\n if (isNodeChartWithThinBars && !hasOverwrittenCandleColor) {\r\n colors = { ...colors, ...thinBarColorsOverride, ...overwrittenColors }\r\n }\r\n\r\n return colors\r\n }\r\n\r\n getIsRedesignedChart() {\r\n return this.specificChartFunctionality === SpecificChartFunctionality.chartPage || isRedesignedPage(this)\r\n }\r\n}\r\n\r\nBaseChart.initClass()\r\n\r\nexport default BaseChart\r\n","import { RendererChartBarProps } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport utils from '../utils'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport Chart from './base_chart'\r\n\r\nconst WICK_WIDTH = 1\r\n\r\nclass CandleStick extends Chart {\r\n static type = ChartElementType.CandleStick\r\n static label = 'Candle'\r\n static iconName = 'candleBarBasic'\r\n\r\n getRenderChartBarProps({ index, chartSettingsColors, hasFillAndBorder }: RendererChartBarProps) {\r\n const { trendDown, trendUp, borderDown, borderUp, wickDown, wickUp } = chartSettingsColors\r\n const open = this.data.open[index]\r\n const close = this.data.close[index]\r\n const trendColor = close < open ? trendDown : trendUp\r\n const wickColor = close < open ? wickDown : wickUp\r\n return {\r\n open,\r\n close,\r\n high: this.data.high[index],\r\n low: this.data.low[index],\r\n barFillColor: trendColor,\r\n borderColor: close < open ? borderDown : borderUp,\r\n wickColor: hasFillAndBorder ? wickColor : trendColor,\r\n }\r\n }\r\n\r\n renderChart() {\r\n if (this.setupAxisTimeFrame !== this.data.timeframe) {\r\n return\r\n }\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n chartLayout: this.model.chart_layout(),\r\n zoomFactor: this.model.zoomFactor,\r\n })\r\n const shouldRenderFillAndBorder =\r\n barFillWidth + barBorderWidth * 2 >= 2 &&\r\n !(this.type === ChartElementType.HollowCandleStick && barBorderWidth === 0)\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n const translateForWick = getTranslate({\r\n context: this.context,\r\n xOffset: WICK_WIDTH / 2,\r\n yOffset: 0,\r\n })\r\n\r\n translate.do()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, center: number) => {\r\n const { open, close, high, low, wickColor, borderColor, barFillColor } = this.getRenderChartBarProps({\r\n index: i,\r\n chartSettingsColors: Colors,\r\n hasFillAndBorder: shouldRenderFillAndBorder,\r\n })\r\n\r\n const candleBodyHigh = Math.round(this.fy(utils.max(open, close)))\r\n const candleBodyLow = Math.round(this.fy(utils.min(open, close)))\r\n const candleWickHigh = Math.round(this.fy(high))\r\n const candleWickLow = Math.round(this.fy(low))\r\n\r\n const candleBodyHeight = candleBodyLow - candleBodyHigh\r\n const candleBodyLeftX = center - Math.floor(barBorderWidth + barFillWidth / 2)\r\n const halfBorderWidth = barBorderWidth / 2\r\n\r\n // TODO: revisit for better approach, this solve issue with candlesticks\r\n // with even width are shifted 1px to the left and thus first candle is vertically sliced\r\n if (getIsSSr() && candleBodyLeftX + this.leftOffset < 0) {\r\n return\r\n }\r\n\r\n const isBodyHeightGreaterOrEqualBorders = candleBodyHeight >= barBorderWidth * 2\r\n const isWickLineCandleLessThanOnePixel = !shouldRenderFillAndBorder && candleWickLow - candleWickHigh < 1\r\n\r\n translateForWick.do()\r\n this.context.set('strokeStyle', wickColor)\r\n this.context.beginPath()\r\n this.context.moveTo(center, candleWickHigh)\r\n if (shouldRenderFillAndBorder) {\r\n this.context.lineTo(center, candleBodyHigh)\r\n this.context.moveTo(\r\n center,\r\n candleBodyHigh + (isBodyHeightGreaterOrEqualBorders ? candleBodyHeight : WICK_WIDTH)\r\n )\r\n }\r\n this.context.lineTo(center, isWickLineCandleLessThanOnePixel ? candleWickHigh + 1 : candleWickLow)\r\n this.context.stroke()\r\n translateForWick.undo()\r\n\r\n if (shouldRenderFillAndBorder) {\r\n const hasBorder = barBorderWidth > 0\r\n if (hasBorder) {\r\n this.context.set('strokeStyle', borderColor)\r\n if (isBodyHeightGreaterOrEqualBorders) {\r\n this.context.set('lineWidth', barBorderWidth)\r\n this.context.strokeRect(\r\n candleBodyLeftX + halfBorderWidth,\r\n candleBodyHigh + halfBorderWidth,\r\n barFillWidth + 2 * halfBorderWidth,\r\n candleBodyHeight - 2 * halfBorderWidth\r\n )\r\n this.context.set('lineWidth', WICK_WIDTH)\r\n } else {\r\n this.context.beginPath()\r\n this.context.moveTo(candleBodyLeftX, candleBodyHigh + WICK_WIDTH / 2)\r\n this.context.lineTo(candleBodyLeftX + barFillWidth + 2 * barBorderWidth, candleBodyHigh + WICK_WIDTH / 2)\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n const fillHeight = candleBodyHeight - 2 * barBorderWidth\r\n const hasFill = fillHeight > 0\r\n if (hasFill || !hasBorder) {\r\n this.context.set('fillStyle', hasFill ? barFillColor : borderColor)\r\n this.context.fillRect(\r\n candleBodyLeftX + barBorderWidth,\r\n candleBodyHigh + barBorderWidth,\r\n barFillWidth,\r\n hasFill ? fillHeight : WICK_WIDTH\r\n )\r\n }\r\n }\r\n },\r\n })\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default CandleStick\r\n","import { ChartConfigChartPaneElement, RendererChartBarProps, RequireByKey } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport CandleStick from './candle_stick'\r\n\r\nclass HollowCandleStick extends CandleStick {\r\n static type = ChartElementType.HollowCandleStick\r\n static label = 'Hollow Candle'\r\n static iconName = 'candleBarHollow'\r\n\r\n static getNumOfBarsBuffer(element: RequireByKey) {\r\n return Math.max(1, super.getNumOfBarsBuffer(element))\r\n }\r\n\r\n getRenderChartBarProps({ index, chartSettingsColors }: RendererChartBarProps) {\r\n const open = this.data.open[index]\r\n const close = this.data.close[index]\r\n const isHollow = close > open\r\n const generalTrendColor =\r\n close > this.data.close[index - 1] ? chartSettingsColors.ohlcTrendUp : chartSettingsColors.ohlcTrendDown\r\n const trendColor = index === 0 ? chartSettingsColors.zeroChange : generalTrendColor\r\n return {\r\n open,\r\n close,\r\n high: this.data.high[index],\r\n low: this.data.low[index],\r\n // hollow candles have transparend bodies that's why rgba is here\r\n barFillColor: isHollow ? 'rgba(0, 0, 0, 0)' : trendColor,\r\n borderColor: trendColor,\r\n wickColor: trendColor,\r\n }\r\n }\r\n\r\n toString() {\r\n return `Hollow Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default HollowCandleStick\r\n","import { ChartConfigChartPaneElement, RendererChartBarProps, RequireByKey } from '../../types/shared'\r\nimport { ChartElementType, ScaleType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\nimport { getTickerChangeFromCloseValues } from '../utils/chart'\r\nimport CandleStick from './candle_stick'\r\n\r\ntype OhlcKeys = 'high' | 'low' | 'open' | 'close'\r\n\r\nclass HeikinAshi extends CandleStick {\r\n static type = ChartElementType.HeikinAshi\r\n static label = 'Heikin Ashi'\r\n static iconName = 'candleBarHeikinAshi'\r\n\r\n static getNumOfBarsBuffer(element: RequireByKey) {\r\n return Math.max(1, super.getNumOfBarsBuffer(element))\r\n }\r\n\r\n getRenderChartBarProps = ({ index, chartSettingsColors, hasFillAndBorder }: RendererChartBarProps) => {\r\n const haData = this.data.getHeikinAshiData()\r\n\r\n const open = haData.open[index]\r\n const close = haData.close[index]\r\n const trendColor = close < open ? chartSettingsColors.trendDown : chartSettingsColors.trendUp\r\n const wickColor = close < open ? chartSettingsColors.wickDown : chartSettingsColors.wickUp\r\n return {\r\n open,\r\n close,\r\n high: Math.max(this.data.high[index], open, close),\r\n low: Math.min(open, close, this.data.low[index]),\r\n barFillColor: trendColor,\r\n borderColor: close < open ? chartSettingsColors.borderDown : chartSettingsColors.borderUp,\r\n wickColor: hasFillAndBorder ? wickColor : trendColor,\r\n }\r\n }\r\n\r\n getLastValues = () => {\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const {\r\n open: lastOpen,\r\n close: lastClose,\r\n high: lastHigh,\r\n low: lastLow,\r\n } = this.getRenderChartBarProps({\r\n index: this.data.date.length - 1,\r\n chartSettingsColors: Colors,\r\n })\r\n\r\n return { lastOpen, lastClose, lastHigh, lastLow }\r\n }\r\n\r\n getRoundedLastData() {\r\n const lastOhlc = this.getLastValues()\r\n return {\r\n open: this.roundOhlc(lastOhlc.lastOpen),\r\n high: this.roundOhlc(lastOhlc.lastHigh),\r\n low: this.roundOhlc(lastOhlc.lastLow),\r\n close: this.roundOhlc(lastOhlc.lastClose),\r\n }\r\n }\r\n\r\n renderYAxis = (context: CanvasRenderingContext2D) => {\r\n const { lastClose } = this.getLastValues()\r\n super.renderYAxis(context, { lastClose }, false)\r\n\r\n const { firstVisibleClose } = this.getMinMax()\r\n if (this.model.scale === ScaleType.Percentage && !firstVisibleClose) return\r\n\r\n const originalLatestClose = this.data.close[this.data.close.length - 1]\r\n const heikinLatestCloseLabel = this.getYAxisLastCloseLabel({ lastClose, firstVisibleClose })\r\n const originalLatestCloseLabel = this.getYAxisLastCloseLabel({ lastClose: originalLatestClose, firstVisibleClose })\r\n\r\n this.renderYAxisLabel({ context, yCoordinate: Math.round(this.fy(lastClose)), label: heikinLatestCloseLabel })\r\n\r\n if (heikinLatestCloseLabel === originalLatestCloseLabel) return\r\n\r\n this.renderYAxisLabel({\r\n context,\r\n yCoordinate: this.getYAxisSecondaryLabelYCoordinate({\r\n mainLabelValue: lastClose,\r\n secondaryLabelValue: originalLatestClose,\r\n }),\r\n label: originalLatestCloseLabel,\r\n background: this.getSecondaryLabelBackgroundColor(),\r\n })\r\n }\r\n\r\n getDataByCrossIndex(crossIndex: number, key: keyof Quote, shouldReturnRoundedString = true) {\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const barIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n if (barIndex > -1) {\r\n let value = null\r\n if (['high', 'low', 'open', 'close'].includes(key)) {\r\n const data = this.getRenderChartBarProps({ index: barIndex, chartSettingsColors: Colors })\r\n value = data[key as OhlcKeys]\r\n }\r\n value = value === null ? this.data.getDataByBarIndex(key, crossIndex) : value\r\n if (value !== null) {\r\n return shouldReturnRoundedString ? this.roundOhlc(value) : `${value}`\r\n }\r\n }\r\n }\r\n\r\n getCrossIndexChange(crossIndex: number) {\r\n const barIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n const haData = this.data.getHeikinAshiData()\r\n const crossClose = haData.close[barIndex] ?? null\r\n const previousClose = haData.close[barIndex - 1] ?? null\r\n if (crossClose !== null && previousClose !== null) {\r\n return getTickerChangeFromCloseValues({ data: this.data, anchorClose: crossClose, prevClose: previousClose })\r\n }\r\n\r\n return null\r\n }\r\n\r\n toString() {\r\n return `HA Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default HeikinAshi\r\n","import { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Chart from './base_chart'\r\n\r\nclass LineChart extends Chart {\r\n static type = ChartElementType.LineChart\r\n static label = 'Line'\r\n static iconName = 'lineChartType'\r\n\r\n renderChart() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let first: number | undefined, last: number | undefined\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n this.context.beginPath()\r\n this.context.set('lineWidth', 1)\r\n this.context.set('strokeStyle', Colors.line)\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const y = Math.round(this.fy(this.data.close[i]))\r\n this.context.lineTo(x, y)\r\n last = x\r\n if (first === undefined) {\r\n first = x\r\n }\r\n },\r\n })\r\n if (first !== undefined && last !== undefined) {\r\n this.context.stroke()\r\n this.context.set('fillStyle', Colors.background)\r\n this.context.lineTo(last!, this.height)\r\n this.context.lineTo(first!, this.height)\r\n this.context.fill()\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `Line chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default LineChart\r\n","import Text from '../canvas/text'\r\nimport { ChartElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport { isRedesignEnabled } from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\nconst interval = 3\r\nconst domainMin = -1\r\nconst domainMax = 1\r\nconst red = 'rgba(200, 0, 0, 0.392)'\r\nconst redLine = 'rgb(120, 0, 0)'\r\nconst green = 'rgba(0, 180, 0, 0.392)'\r\nconst greenLine = 'rgb(0, 100, 0)'\r\n\r\nclass MarketSentiment extends Chart {\r\n static type = ChartElementType.MarketSentiment\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n return this.model.width - MarketSentimentSettings.left.width - MarketSentimentSettings.right.width\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n return this.paneModel.height - MarketSentimentSettings.top.height - MarketSentimentSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n declare _data: number[]\r\n declare _dataLastIndex: number | null\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.setupCache = this.setupCache.bind(this)\r\n }\r\n\r\n setupCache() {\r\n super.setupCache()\r\n if (!this.data) {\r\n return\r\n }\r\n const arr: number[] = []\r\n this.data.close.forEach((sum, i) => {\r\n arr[i] = sum / this.data.volume[i]\r\n })\r\n this._data = arr\r\n\r\n let lastIndex = null\r\n for (let i = this.data.volume.length - 1; i >= 0; i--) {\r\n if (this.data.volume[i] !== 0) {\r\n lastIndex = i\r\n break\r\n }\r\n }\r\n this._dataLastIndex =\r\n lastIndex === null\r\n ? null\r\n : Math.min(lastIndex, Math.round((this.data.drawMinutesPerDay - this.data.marketStartMinutes) / interval))\r\n }\r\n\r\n renderChart() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + MarketSentimentSettings.left.width + 0.5,\r\n yOffset: MarketSentimentSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n this.renderLineBullBear(this.context, this._data, 0, 0, 0)\r\n translate.undo()\r\n }\r\n\r\n renderLineBullBear(\r\n context: CanvasRenderingContext2D,\r\n array: number[],\r\n from: number,\r\n oversold: number,\r\n overbought: number\r\n ) {\r\n if (this._dataLastIndex === null) {\r\n return\r\n }\r\n const isRedesign = isRedesignEnabled()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n const domain = [domainMax, domainMin]\r\n\r\n context.save()\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(domain[1]),\r\n this.fx(this._dataLastIndex),\r\n Math.round(this.fy(oversold) - this.fy(domain[1])) - 0.5\r\n )\r\n context.clip()\r\n context.set('fillStyle', red)\r\n context.set('strokeStyle', isRedesign ? Colors.marketDown : redLine)\r\n context.beginPath()\r\n context.moveTo(this.fx(0), Math.round(this.fy(domain[0])))\r\n for (let i = from; i < this.data.close.length; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(array[i])))\r\n }\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(domain[0])))\r\n context.fill()\r\n context.stroke()\r\n context.restore()\r\n\r\n context.save()\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(domain[0]),\r\n this.fx(this._dataLastIndex),\r\n Math.round(this.fy(overbought)) - 0.5\r\n )\r\n context.clip()\r\n context.set('fillStyle', green)\r\n context.set('strokeStyle', isRedesign ? Colors.marketUp : greenLine)\r\n context.beginPath()\r\n context.moveTo(this.fx(0), Math.round(this.fy(domain[1])))\r\n for (let i = from; i < this.data.close.length; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(array[i])))\r\n }\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(domain[1])))\r\n context.fill()\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n renderXAxis() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n const { Colors } = MarketSentimentSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + MarketSentimentSettings.left.width,\r\n yOffset: MarketSentimentSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const xLine = this.getXLine()\r\n const text = new Text(\r\n {\r\n y: this.height + 12,\r\n font: { size: 7 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.bottom,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n let x\r\n\r\n x = this.fx(0)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10) + 2 /* remove overflow */\r\n text.set({ text: '10AM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 20)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 40)\r\n text.set({ text: '12PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 60)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 80)\r\n text.set({ text: '2PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 100)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 120 - 1)\r\n text.set({ text: '4PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText() {}\r\n\r\n renderCrossText() {}\r\n\r\n renderOverlaysLabels() {}\r\n\r\n _compute() {\r\n return { min: domainMin, max: domainMax }\r\n }\r\n\r\n computeVisibleMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { MarketSentimentSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const isRedesign = isRedesignEnabled()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: MarketSentimentSettings.left.width,\r\n yOffset: MarketSentimentSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const yLine = this.getYLine()\r\n for (const tick of [domainMin, 0, domainMax]) {\r\n const y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n }\r\n\r\n const text = new Text(\r\n {\r\n x: this.width + 27,\r\n font: { size: 8 },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n\r\n const fillUp = isRedesign ? Colors.marketUp : greenLine\r\n const fillDown = isRedesign ? Colors.marketDown : redLine\r\n const last = this._data[this._dataLastIndex!]\r\n const percent = this._dataLastIndex !== null ? Math.floor(last * 50 + 50) : 50\r\n text.set({ y: this.fy(0) - 5, fillStyle: fillUp, text: `${percent}%` }).render(context)\r\n text.set({ y: this.fy(0) + 7, fillStyle: fillDown, text: `${100 - percent}%` }).render(context)\r\n\r\n translate.undo()\r\n }\r\n\r\n clip() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n this.context.beginPath()\r\n this.context.rect(MarketSentimentSettings.left.width, MarketSentimentSettings.top.height, this.width, this.height)\r\n this.context.clip()\r\n }\r\n\r\n getMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n toString() {\r\n return `Market sentiment chart`\r\n }\r\n}\r\nMarketSentiment.initClass()\r\n\r\nexport default MarketSentiment\r\n","import { ObjectHash } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { ChartElementType, FONT_SIZE, LINE_HEIGHT, PADDING, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\ninterface MultiLineChartAttrs extends BaseChartAttrs {\r\n tickers: string[]\r\n label?: string\r\n min?: number\r\n max?: number\r\n}\r\n\r\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\nclass MultiLineChart extends Chart {\r\n static type = ChartElementType.MultiLineChart\r\n tickersDimensions: number[] = []\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n }\r\n\r\n renderChart() {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n\r\n this.context.set('lineWidth', 1)\r\n\r\n const quotes: ObjectHash = {}\r\n for (const quote of this.getQuotes()) {\r\n quotes[quote.ticker] = quote\r\n }\r\n\r\n for (let index = this.attrs.tickers.length - 1; index >= 0; index--) {\r\n const ticker = this.attrs.tickers[index]\r\n const quote = quotes[ticker]\r\n this.context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n this.context.beginPath()\r\n for (let i = 0, end = quote.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const x = this.fx(i)\r\n if (x + this.leftOffset < -10 || x + this.leftOffset > this.model.width + 10) {\r\n // margin?\r\n continue\r\n }\r\n const y = Math.round(this.fy(quote.close[i]))\r\n this.context.lineTo(x, y)\r\n }\r\n this.context.stroke()\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const text = this.attrs.label || ''\r\n const y = (this.height - 4) / 2\r\n new Text(\r\n {\r\n text,\r\n x: 28,\r\n y: ChartSettings.top.height + y,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n return this.renderCrossText(context, this.data.close.length - 1)\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const maxTickerLength = utils.max(this.attrs.tickers.map((t) => t.length))\r\n\r\n const date = utils.dateFromUnixTimestamp(this.data.getDataByBarIndex('date', crossIndex) ?? 0)\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n const isLastDate = crossIndex === this.data.close.length - 1\r\n\r\n new Text(\r\n {\r\n text: `${months[month]} ${day} ${year} `,\r\n x: ChartSettings.left.width + (maxTickerLength > 15 ? 200 : 132),\r\n y: 30,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n background: Colors.canvasFill,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n\r\n const quotes: ObjectHash = {}\r\n for (const quote of this.getQuotes()) {\r\n quotes[quote.ticker] = quote\r\n }\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const y = PADDING.S + (PADDING.S + LINE_HEIGHT.M) * index\r\n if (this.tickersDimensions[index]) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n ChartSettings.left.width - PADDING.XXXS,\r\n y - PADDING.XXXS,\r\n PADDING.XXXS + this.tickersDimensions[index] + PADDING.XXXS,\r\n PADDING.XXXS + FONT_SIZE.M + PADDING.XXXS\r\n )\r\n }\r\n const ticker = this.attrs.tickers[index]\r\n const closeValue = quotes[ticker].close[crossIndex]\r\n const text = new Text(\r\n {\r\n text: `${ticker} ${typeof closeValue === 'number' ? closeValue.toFixed(2) : NaN} `,\r\n x: ChartSettings.left.width,\r\n y,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n lineHeight: LINE_HEIGHT.M,\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n if (isLastDate) {\r\n this.tickersDimensions[index] = text.measure(context)\r\n }\r\n text.render(context)\r\n }\r\n }\r\n\r\n computeVisibleMinMax(...arrays: Array) {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n\r\n const { leftOffset } = this.model\r\n for (const arr of arrays) {\r\n for (let i = 0, end = arr.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n\r\n if (min > arr[i]) {\r\n min = arr[i]\r\n }\r\n if (max < arr[i]) {\r\n max = arr[i]\r\n }\r\n }\r\n }\r\n\r\n return { min, max }\r\n }\r\n\r\n getMinMax() {\r\n const quotes = this.getQuotes()\r\n let { min, max } = this.computeVisibleMinMax(...quotes.map((q) => q.close))\r\n if (typeof this.attrs.min !== 'undefined') {\r\n min = this.attrs.min\r\n }\r\n if (typeof this.attrs.max !== 'undefined') {\r\n max = this.attrs.max\r\n }\r\n return { min, max }\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n getQuotes() {\r\n return Quote.select(\r\n (q: Quote) =>\r\n this.attrs.tickers.includes(q.ticker) &&\r\n q.timeframe === this.data?.timeframe &&\r\n this.model.chart_layout().isIdeaId(q.ideaID)\r\n )\r\n }\r\n\r\n toString() {\r\n return `Line chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default MultiLineChart\r\n","import { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Chart from './base_chart'\r\n\r\nclass OHLCChart extends Chart {\r\n static type = ChartElementType.OhlcChart\r\n static label = 'OHLC'\r\n static iconName = 'ohlcChartType'\r\n\r\n renderChart() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const barWithoutMarginWidth = this.getBarWithoutMarginWidth()\r\n\r\n let lineWidth = 1\r\n if (barWithoutMarginWidth >= 40) {\r\n lineWidth = 4\r\n } else if (barWithoutMarginWidth >= 30) {\r\n lineWidth = 3\r\n } else if (barWithoutMarginWidth >= 15) {\r\n lineWidth = 2\r\n }\r\n const lineThickness = lineWidth / 2\r\n const handleLengthFromWick = Math.round(barWithoutMarginWidth / 2 - lineThickness)\r\n const lineOffset = lineWidth % 2 === 0 ? 0 : 0.5\r\n this.context.set('lineWidth', lineWidth)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const barX = ~~(x + 1) + lineOffset // move 1px to right so cursor don't cover bar of ohlc-chart & round for pixel perfect render on zoom\r\n\r\n this.context.beginPath()\r\n this.context.set(\r\n 'strokeStyle',\r\n this.data.close[i] < this.data.open[i] ? Colors.ohlcTrendDown : Colors.ohlcTrendUp\r\n )\r\n\r\n this.context.moveTo(barX, Math.round(this.fy(this.data.high[i])))\r\n this.context.lineTo(barX, Math.round(this.fy(this.data.low[i])))\r\n\r\n if (handleLengthFromWick >= 1) {\r\n const open = Math.round(this.fy(this.data.open[i]))\r\n this.context.moveTo(barX + lineThickness, open + lineOffset) // move to right edge of wick\r\n this.context.lineTo(barX - lineThickness - handleLengthFromWick, open + lineOffset) // draw line to the left\r\n\r\n const close = Math.round(this.fy(this.data.close[i]))\r\n this.context.moveTo(barX - lineThickness, close + lineOffset) // move to left edge of wick\r\n this.context.lineTo(barX + lineThickness + handleLengthFromWick, close + lineOffset) // draw line to the right\r\n }\r\n\r\n this.context.stroke()\r\n },\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `OHLC ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default OHLCChart\r\n","import * as d3 from 'd3'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { ChartElementType, FONT_SIZE, MARGIN, OFFSET, PADDING, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\ninterface PerfChartAttrs extends BaseChartAttrs {\r\n tickers: string[]\r\n label?: string\r\n fromDate: string\r\n toDate: string\r\n min?: number\r\n max?: number\r\n}\r\n\r\nclass PerfChart extends Chart {\r\n static type = ChartElementType.PerfChart\r\n\r\n overlayLabelWidth: ObjectHash\r\n perf: ObjectHash = {}\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.overlayLabelWidth = {}\r\n }\r\n\r\n renderChart() {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n\r\n this.context.beginPath()\r\n this.context.set('lineWidth', 1)\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n if ((this.perf[ticker] != null ? this.perf[ticker].length : 0) > 0) {\r\n this.context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n this.context.beginPath()\r\n for (let i = 0, end = this.data.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n this.context.lineTo(this.fx(i), Math.round(this.fy(this.perf[ticker][i])))\r\n }\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const period = (() => {\r\n switch (this.model.quote().timeframe) {\r\n case 'd':\r\n return 'DAILY'\r\n case 'w':\r\n return 'WEEKLY'\r\n case 'm':\r\n return 'MONTHLY'\r\n default:\r\n return\r\n }\r\n })()\r\n const y = (this.height - 4) / 2\r\n new Text(\r\n {\r\n text: period,\r\n x: 28,\r\n y: ChartSettings.top.height + y,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const date = utils.dateFromUnixTimestamp(this.data.getDataByBarIndex('date', crossIndex) ?? 0)\r\n let dateString = ''\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n switch (this.data.timeframe) {\r\n case 'd':\r\n case 'w':\r\n dateString = `${months[month]} ${day}`\r\n break\r\n case 'm':\r\n dateString = `${months[month]} ${year}`\r\n break\r\n default:\r\n return\r\n }\r\n\r\n let shouldRenderDate = false\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n const tickerData = this.perf[ticker]\r\n if (tickerData?.length) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n ChartSettings.left.width - PADDING.XXXS,\r\n OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index - PADDING.XXXS,\r\n PADDING.XXXS + this.overlayLabelWidth[ticker] + PADDING.XXXS,\r\n PADDING.XXXS + FONT_SIZE.M + PADDING.XXXS\r\n )\r\n const hasData = Number.isFinite(tickerData[crossIndex])\r\n const percentageText = hasData ? `${tickerData[crossIndex].toFixed(2)}%` : ''\r\n shouldRenderDate = shouldRenderDate || hasData\r\n new Text(\r\n {\r\n text: `${ticker} ${percentageText}`,\r\n x: ChartSettings.left.width,\r\n y: OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n }\r\n\r\n if (shouldRenderDate) {\r\n new Text(\r\n {\r\n text: `${dateString} `,\r\n x: ChartSettings.left.width + 132,\r\n y: 30,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n background: Colors.canvasFill,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n }\r\n\r\n renderOverlaysLabels(context: CanvasRenderingContext2D) {\r\n super.renderOverlaysLabels(context)\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n const tickerData = this.perf[ticker]\r\n if (tickerData?.length) {\r\n const lastCrossIndex = this.perf[ticker].length - 1\r\n const hasData = Number.isFinite(tickerData[lastCrossIndex])\r\n const percentageText = hasData ? `${tickerData[lastCrossIndex].toFixed(2)}%` : ''\r\n const text = new Text(\r\n {\r\n text: `${ticker} ${percentageText}`,\r\n x: ChartSettings.left.width,\r\n y: OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n this.overlayLabelWidth = { ...this.overlayLabelWidth, [ticker]: text.measure(context) }\r\n text.render(context)\r\n }\r\n }\r\n }\r\n\r\n _compute() {\r\n this.perf = {}\r\n const quotes = this.getQuotes()\r\n\r\n const fromDate = new Date(this.attrs.fromDate + ' 00:00')\r\n const toDate = new Date(this.attrs.toDate + ' 23:59')\r\n const filteredQuotes = []\r\n for (const quote of quotes) {\r\n const closes = []\r\n for (let i = 0, end = quote.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const date = utils.dateFromUnixTimestamp(quote.date[i])\r\n if (fromDate <= date && date <= toDate) {\r\n closes.push(quote.close[i])\r\n }\r\n }\r\n filteredQuotes.push({ ticker: quote.ticker, close: closes })\r\n }\r\n\r\n const daysCount = d3.max(filteredQuotes, (q) => q.close.length) ?? 0\r\n for (const quote of filteredQuotes) {\r\n this.perf[quote.ticker] = []\r\n const first = quote.close[0]\r\n let offset = 0\r\n if (daysCount > quote.close.length) {\r\n offset = daysCount - quote.close.length\r\n for (let i = 0, end1 = offset, asc1 = end1 >= 0; asc1 ? i < end1 : i > end1; asc1 ? i++ : i--) {\r\n this.perf[quote.ticker][i] = NaN\r\n }\r\n }\r\n for (let i = 0, end2 = quote.close.length, asc2 = end2 >= 0; asc2 ? i < end2 : i > end2; asc2 ? i++ : i--) {\r\n this.perf[quote.ticker][offset + i] = (quote.close[i] * 100) / first - 100\r\n }\r\n }\r\n const { min, max } = this.computeVisibleMinMax(...Object.keys(this.perf).map((x) => this.perf[x]))\r\n return { min, max }\r\n }\r\n\r\n // TODO refactor into ?utils\r\n computeVisibleMinMax(...arrays: Array) {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n\r\n const { leftOffset } = this.model\r\n for (const arr of arrays) {\r\n for (let i = 0, end = arr.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n\r\n if (min > arr[i]) {\r\n min = arr[i]\r\n }\r\n if (max < arr[i]) {\r\n max = arr[i]\r\n }\r\n }\r\n }\r\n\r\n return { min, max }\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context,\r\n xOffset: ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const ticks = this.paneModel.scale.y.ticks(10)\r\n const yLine = this.getYLine()\r\n const text = new Text(\r\n {\r\n x: this.width + 8,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n )\r\n for (const tick of ticks) {\r\n const y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n text.set({ text: tick.toFixed(2), y }).render(context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderXAxis() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n y: this.height + 18,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.bottom,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n const textWidth = text.set({ text: '2020' }).measure(this.context)\r\n\r\n let date = new Date(this.data.date[0] * 1000)\r\n let lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n let monthsInData = 0\r\n this.data.date.forEach((d, index) => {\r\n if (index < 1) {\r\n return\r\n }\r\n\r\n const date = new Date(d * 1000)\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n monthsInData++\r\n }\r\n lastMonth = month\r\n })\r\n\r\n const availableTickSpots = ~~(this.width / textWidth)\r\n const monthsToAvail = monthsInData / availableTickSpots\r\n let renderMonth\r\n if (monthsToAvail <= 1) {\r\n renderMonth = () => true\r\n } else if (monthsToAvail <= 2) {\r\n renderMonth = (x: number) => x % 2 === 0\r\n } else if (monthsToAvail <= 3) {\r\n renderMonth = (x: number) => x % 3 === 0\r\n } else if (monthsToAvail <= 4) {\r\n renderMonth = (x: number) => x % 4 === 0\r\n } else if (monthsToAvail <= 6) {\r\n renderMonth = (x: number) => x % 6 === 0\r\n } else {\r\n renderMonth = (x: number) => x === 0\r\n }\r\n\r\n date = new Date(this.data.date[0] * 1000)\r\n lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n const xLine = this.getXLine()\r\n\r\n for (let i = 0; i < this.data.date.length; i++) {\r\n date = new Date(this.data.date[i] * 1000)\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = this.fx(i)\r\n if (x + this.leftOffset < -15 || x + this.leftOffset > this.width + 15) {\r\n // margin?\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n if (!renderMonth(date.getMonth())) {\r\n continue\r\n }\r\n\r\n text\r\n .set({\r\n text: date.getMonth() === 0 ? date.getFullYear().toString() : months[date.getMonth()],\r\n x: x,\r\n })\r\n .render(this.context)\r\n }\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n getMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n getQuotes() {\r\n return Quote.select(\r\n (q: Quote) =>\r\n this.attrs.tickers.includes(q.ticker) &&\r\n q.timeframe === this.data?.timeframe &&\r\n this.model.chart_layout().isIdeaId(q.ideaID)\r\n )\r\n }\r\n\r\n toString() {\r\n return `Perf chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default PerfChart\r\n","import { ChartElementType } from '../constants/common'\r\nimport candleStick from './candle_stick'\r\nimport hollowCandleStick from './candle_stick_hollow'\r\nimport heikinAshi from './heikin_ashi'\r\nimport lineChart from './line_chart'\r\nimport marketSentiment from './market_sentiment'\r\nimport multiLineCharts from './multi_line_chart'\r\nimport ohlcChart from './ohlc_chart'\r\nimport perfChart from './perf_chart'\r\n\r\nexport const chartsByType = Object.freeze({\r\n [ChartElementType.CandleStick]: candleStick,\r\n [ChartElementType.HeikinAshi]: heikinAshi,\r\n [ChartElementType.HollowCandleStick]: hollowCandleStick,\r\n [ChartElementType.LineChart]: lineChart,\r\n [ChartElementType.MarketSentiment]: marketSentiment,\r\n [ChartElementType.MultiLineChart]: multiLineCharts,\r\n [ChartElementType.OhlcChart]: ohlcChart,\r\n [ChartElementType.PerfChart]: perfChart,\r\n})\r\n","export const FONT_SIZE = {\r\n XXS: 5,\r\n XS: 7,\r\n S: 8,\r\n M: 10,\r\n L: 11,\r\n XXL: 18,\r\n XXXL: 23,\r\n}\r\nexport const LINE_HEIGHT = {\r\n XS: 7,\r\n S: 8,\r\n M: 10,\r\n}\r\nexport const PADDING = {\r\n XXXS: 1,\r\n XXS: 2,\r\n XS: 3,\r\n S: 5,\r\n}\r\nexport const MARGIN = {\r\n XS: 4,\r\n}\r\nexport const CHART_MARGIN = {\r\n S: 15,\r\n M: 30,\r\n L: 35,\r\n XL: 38,\r\n XXL: 48,\r\n}\r\nexport const SETTINGS_HEIGHT = 44\r\nexport const TICKER_TIMEFRAME_CHANGE_HEIGHT = 20\r\nexport const OFFSET = {\r\n XXS: 2,\r\n XS: 4,\r\n S: 6,\r\n M: 8,\r\n XXL: 20,\r\n}\r\nexport const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\nexport enum ChartEditorEnum {\r\n publish = 'publish',\r\n tools = 'tools',\r\n ideas = 'ideas',\r\n settings = 'settings',\r\n timeframe = 'timeframe',\r\n}\r\n\r\nexport enum LayoutType {\r\n '1h1v' = '1h1v',\r\n '1h2v' = '1h2v',\r\n '1h3v' = '1h3v',\r\n '2h1v' = '2h1v',\r\n '2h2v' = '2h2v',\r\n '3h1v' = '3h1v',\r\n '3h2v' = '3h2v',\r\n '1l2r' = '1l2r',\r\n '1t2b' = '1t2b',\r\n}\r\n\r\nexport enum CanvasElementType {\r\n element = 'canvas/element',\r\n arrow = 'canvas/arrow',\r\n brushV1 = 'canvas/brush/brush_v1',\r\n curve = 'canvas/curve',\r\n ellipse = 'canvas/ellipse',\r\n fibonacciRetracements = 'canvas/fibonacci_retracements',\r\n horizontalLine = 'canvas/horizontal_line',\r\n line = 'canvas/line',\r\n measure = 'canvas/measure',\r\n pitchforkV1 = 'canvas/pitchfork/pitchfork_v1',\r\n polygon = 'canvas/polygon',\r\n position = 'canvas/position',\r\n rectangle = 'canvas/rectangle',\r\n rotatedRectangle = 'canvas/rotated_rectangle',\r\n scaledLine = 'canvas/scaled_line',\r\n scaledText = 'canvas/scaled_text',\r\n symbol = 'canvas/symbol',\r\n text = 'canvas/text',\r\n triangle = 'canvas/triangle',\r\n verticalLine = 'canvas/vertical_line',\r\n xabcd = 'canvas/xabcd',\r\n calloutV1 = 'canvas/callout/callout_v1',\r\n elliottWaves = 'canvas/elliott_waves/elliott_waves',\r\n ellipseV1 = 'canvas/ellipse/ellipse_v1',\r\n rotatedRectangleV1 = 'canvas/rotated_rectangle/rotated_rectangle_v1',\r\n}\r\n\r\nexport enum ChartElementType {\r\n CandleStick = 'charts/candle_stick',\r\n HeikinAshi = 'charts/heikin_ashi',\r\n HollowCandleStick = 'charts/candle_stick_hollow',\r\n LineChart = 'charts/line_chart',\r\n OhlcChart = 'charts/ohlc_chart',\r\n MarketSentiment = 'charts/market_sentiment',\r\n MultiLineChart = 'charts/multi_line_chart',\r\n PerfChart = 'charts/perf_chart',\r\n}\r\n\r\nexport enum IndicatorType {\r\n Indicator = 'indicators/indicator',\r\n None = 'indicators/none',\r\n Adx = 'indicators/adx',\r\n Aro = 'indicators/aro',\r\n Aroosc = 'indicators/aroosc',\r\n Atr = 'indicators/atr',\r\n Cci = 'indicators/cci',\r\n Cot = 'indicators/cot',\r\n Fi = 'indicators/fi',\r\n Macd = 'indicators/macd',\r\n Mfi = 'indicators/mfi',\r\n Obv = 'indicators/obv',\r\n Perf = 'indicators/perf',\r\n Rmi = 'indicators/rmi',\r\n Roc = 'indicators/roc',\r\n Rsi = 'indicators/rsi',\r\n Rvol = 'indicators/rvol',\r\n Rwi = 'indicators/rwi',\r\n Stofa = 'indicators/stofa',\r\n Stofu = 'indicators/stofu',\r\n Stosl = 'indicators/stosl',\r\n Trix = 'indicators/trix',\r\n Ult = 'indicators/ult',\r\n Vol = 'indicators/vol',\r\n Wr = 'indicators/wr',\r\n}\r\n\r\nexport enum OverlayType {\r\n Overlay = 'overlays/overlay',\r\n None = 'overlays/none',\r\n Bb = 'overlays/bb',\r\n Dch = 'overlays/dch',\r\n Ema = 'overlays/ema',\r\n Ema2 = 'overlays/ema2',\r\n Hilo = 'overlays/hilo',\r\n Hline = 'overlays/hline',\r\n Ic = 'overlays/ic',\r\n Icf = 'overlays/icf',\r\n Kch = 'overlays/kch',\r\n Patterns = 'overlays/patterns',\r\n Pp = 'overlays/pp',\r\n Sar = 'overlays/sar',\r\n Sma = 'overlays/sma',\r\n Sma2 = 'overlays/sma2',\r\n Str = 'overlays/str',\r\n Vp = 'overlays/vp',\r\n Vwap = 'overlays/vwap',\r\n}\r\n\r\nexport enum ChartEventDbType {\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n Earnings = 'chartEvent/earnings',\r\n}\r\n\r\nexport enum ChartEventType {\r\n ChartEvent = 'chartEvent/chartEvent',\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n Earnings = 'chartEvent/earnings',\r\n}\r\n\r\nexport enum ChartEventBadgeType {\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n EarningsPositive = 'chartEvent/earnings',\r\n EarningsNegative = 'chartEvent/earningsNegative',\r\n EarningsNeutral = 'chartEvent/earningsNeutral',\r\n EarningsFuture = 'chartEvent/earningsFuture',\r\n}\r\n\r\nexport const ChartEventLabels: Record = {\r\n [ChartEventBadgeType.Dividends]: 'Dividends',\r\n [ChartEventBadgeType.Split]: 'Split',\r\n [ChartEventBadgeType.EarningsPositive]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsNegative]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsNeutral]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsFuture]: 'Earnings & Revenue',\r\n}\r\n\r\ninterface LayoutRule {\r\n columns: number\r\n rows: number\r\n count: number\r\n gridAreas?: string[]\r\n}\r\n\r\nexport const LAYOUTS: Record = {\r\n '1h1v': { columns: 1, rows: 1, count: 1 },\r\n '1h2v': { columns: 1, rows: 2, count: 2 },\r\n '1h3v': { columns: 1, rows: 3, count: 3 },\r\n '2h1v': { columns: 2, rows: 1, count: 2 },\r\n '2h2v': { columns: 2, rows: 2, count: 4 },\r\n '3h1v': { columns: 3, rows: 1, count: 3 },\r\n '3h2v': { columns: 3, rows: 2, count: 6 },\r\n '1l2r': {\r\n columns: 2,\r\n rows: 2,\r\n count: 3,\r\n gridAreas: ['1 / 1 / 3 / 2', '1 / 2 / 2 / 3', '2 / 2 / 3 / 3'],\r\n },\r\n '1t2b': {\r\n columns: 2,\r\n rows: 2,\r\n count: 3,\r\n gridAreas: ['1 / 1 / 2 / 3', '2 / 1 / 3 / 2', '2 / 2 / 3 / 3'],\r\n },\r\n}\r\n\r\nexport const SORT_DIRECTION = {\r\n ASC: 'ASC',\r\n DESC: 'DESC',\r\n}\r\n\r\nexport const ICON_SIZE = {\r\n L: 32,\r\n}\r\n\r\n// Keep in sync with the copy in Website repo - Website/js/main/constants.ts\r\nexport enum TIMEFRAME {\r\n i1 = 'i1',\r\n i2 = 'i2',\r\n i3 = 'i3',\r\n i5 = 'i5',\r\n i10 = 'i10',\r\n i15 = 'i15',\r\n i30 = 'i30',\r\n h = 'h',\r\n h2 = 'h2',\r\n h4 = 'h4',\r\n d = 'd',\r\n w = 'w',\r\n m = 'm',\r\n}\r\n\r\nexport type TimeframeAndIntradayType = TIMEFRAME | 'intraday'\r\n\r\nexport const TIMEFRAMES_WITH_PRE_MARKET = [TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3, TIMEFRAME.i5]\r\n\r\nexport const IntradayTimeframeInterval = {\r\n [TIMEFRAME.i1]: 1,\r\n [TIMEFRAME.i2]: 2,\r\n [TIMEFRAME.i3]: 3,\r\n [TIMEFRAME.i5]: 5,\r\n [TIMEFRAME.i10]: 10,\r\n [TIMEFRAME.i15]: 15,\r\n [TIMEFRAME.i30]: 30,\r\n [TIMEFRAME.h]: 60,\r\n [TIMEFRAME.h2]: 120,\r\n [TIMEFRAME.h4]: 240,\r\n}\r\n\r\nexport enum DateRangeType {\r\n d1 = 'd1',\r\n d5 = 'd5',\r\n m1 = 'm1',\r\n m3 = 'm3',\r\n m6 = 'm6',\r\n ytd = 'ytd',\r\n y1 = 'y1',\r\n y2 = 'y2',\r\n y5 = 'y5',\r\n max = 'max',\r\n}\r\n\r\nexport const TIMEFRAME_SECONDS = {\r\n [TIMEFRAME.i1]: 60,\r\n [TIMEFRAME.i2]: 120,\r\n [TIMEFRAME.i3]: 180,\r\n [TIMEFRAME.i5]: 300,\r\n [TIMEFRAME.i10]: 600,\r\n [TIMEFRAME.i15]: 900,\r\n [TIMEFRAME.i30]: 1800,\r\n [TIMEFRAME.h]: 3600,\r\n [TIMEFRAME.h2]: 7200,\r\n [TIMEFRAME.h4]: 14400,\r\n [TIMEFRAME.d]: 86400,\r\n [TIMEFRAME.w]: 604800,\r\n [TIMEFRAME.m]: 2592000,\r\n}\r\n\r\nexport const CRYPTOS = {\r\n BTCUSD: 'BTCUSD',\r\n LTCUSD: 'LTCUSD',\r\n ETHUSD: 'ETHUSD',\r\n XRPUSD: 'XRPUSD',\r\n BCHUSD: 'BCHUSD',\r\n BTCEUR: 'BTCEUR',\r\n LTCEUR: 'LTCEUR',\r\n ETHEUR: 'ETHEUR',\r\n XRPEUR: 'XRPEUR',\r\n BCHEUR: 'BCHEUR',\r\n LTCBTC: 'LTCBTC',\r\n ETHBTC: 'ETHBTC',\r\n XRPBTC: 'XRPBTC',\r\n BCHBTC: 'BCHBTC',\r\n}\r\n\r\nexport enum SpecificChartFunctionality {\r\n default = 'default',\r\n quotePage = 'quotePage',\r\n quotePerf = 'quotePerf',\r\n chartPage = 'chartPage',\r\n smallIndex = 'smallIndex',\r\n offScreen = 'offScreen',\r\n forexPage = 'forexPage',\r\n futuresPage = 'futuresPage',\r\n cryptoPage = 'cryptoPage',\r\n}\r\n\r\nexport enum TextAlign {\r\n left = 'left',\r\n right = 'right',\r\n center = 'center',\r\n start = 'start',\r\n end = 'end',\r\n}\r\n\r\nexport enum TextBaseline {\r\n top = 'top',\r\n hanging_dont_use = 'hanging', // not supported - https://github.com/Automattic/node-canvas/wiki/Compatibility-Status#text-styles\r\n middle = 'middle',\r\n alphabetic = 'alphabetic',\r\n ideographic_dont_use = 'ideographic', // not supported - https://github.com/Automattic/node-canvas/wiki/Compatibility-Status#text-styles\r\n bottom = 'bottom',\r\n}\r\n\r\nexport enum ScaleType {\r\n Linear = 'linear',\r\n Percentage = 'percentage',\r\n Logarithmic = 'logarithmic',\r\n}\r\n\r\nexport enum QuotePollingIntervalInMs {\r\n Default = 3000,\r\n Free = 180000,\r\n Elite = 3000,\r\n EliteStocksReduced = 60000,\r\n}\r\n\r\nexport const EXTRA_MARKET_BUFFER_MINUTES = 30\r\n\r\nexport const ScaleLabel = {\r\n [ScaleType.Linear]: 'Linear',\r\n [ScaleType.Percentage]: 'Percentage',\r\n [ScaleType.Logarithmic]: 'Logarithmic',\r\n}\r\n\r\nexport const PANE_HEIGHT_DEFAULT = {\r\n chart: 400,\r\n indicator: 120,\r\n}\r\n\r\nexport const INDICATOR_LABEL_HEIGHT = 24\r\n\r\nexport const MOBILE_BARS_TO_VIEW = 150 // 5 months of daily bars\r\n\r\nexport const MOBILE_VIEW_BREAKPOINT_WIDTH = 768\r\n\r\nexport const FREE_DATE_RANGES = ['m1', 'm3', 'm6', 'ytd', 'y1', 'y2', 'y5', 'max']\r\n\r\nexport const getTimeframeLabel = (timeframe: string) => {\r\n switch (timeframe) {\r\n case TIMEFRAME.i1:\r\n return '1 MIN'\r\n case TIMEFRAME.i2:\r\n return '2 MIN'\r\n case TIMEFRAME.i3:\r\n return '3 MIN'\r\n case TIMEFRAME.i5:\r\n return '5 MIN'\r\n case TIMEFRAME.i10:\r\n return '10 MIN'\r\n case TIMEFRAME.i15:\r\n return '15 MIN'\r\n case TIMEFRAME.i30:\r\n return '30 MIN'\r\n case TIMEFRAME.h:\r\n return '1 HR'\r\n case TIMEFRAME.h2:\r\n return '2 HR'\r\n case TIMEFRAME.h4:\r\n return '4 HR'\r\n case TIMEFRAME.d:\r\n return 'DAILY'\r\n case TIMEFRAME.w:\r\n return 'WEEKLY'\r\n case TIMEFRAME.m:\r\n return 'MONTHLY'\r\n default:\r\n return ''\r\n }\r\n}\r\n\r\nexport type ChartsPageQueryParams = {\r\n p: string\r\n t: string\r\n l: string\r\n r?: string\r\n i?: string\r\n sidebar?: string\r\n}\r\n\r\nexport type QuotePageQueryParams = {\r\n p?: string\r\n t: string\r\n r?: string\r\n i?: string\r\n ty?: QuotePageQueryChartTypes\r\n}\r\n\r\nexport enum QuotePageQueryChartTypes {\r\n l = 'l',\r\n c = 'c',\r\n cs = 'cs',\r\n hc = 'hc',\r\n ha = 'ha',\r\n o = 'o',\r\n p = 'p',\r\n}\r\n\r\nexport type ChartsOrQuotePageQueryParams = ChartsPageQueryParams | QuotePageQueryParams\r\n\r\nexport enum MacroTimeframe {\r\n // seconds = 'seconds',\r\n minutes = 'minutes',\r\n hours = 'hours',\r\n days = 'days',\r\n weeks = 'weeks',\r\n months = 'months',\r\n}\r\n\r\nexport const MicroMacroTimeframe = {\r\n [TIMEFRAME.i1]: {\r\n micro: 1,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i2]: {\r\n micro: 2,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i3]: {\r\n micro: 3,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i5]: {\r\n micro: 5,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i10]: {\r\n micro: 10,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i15]: {\r\n micro: 15,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i30]: {\r\n micro: 30,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.h]: {\r\n micro: 1,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.h2]: {\r\n micro: 2,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.h4]: {\r\n micro: 4,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.d]: {\r\n micro: 1,\r\n macro: MacroTimeframe.days,\r\n },\r\n [TIMEFRAME.w]: {\r\n micro: 1,\r\n macro: MacroTimeframe.weeks,\r\n },\r\n [TIMEFRAME.m]: {\r\n micro: 1,\r\n macro: MacroTimeframe.months,\r\n },\r\n}\r\n\r\nexport const MicroTimeframeRange = (Object.keys(MicroMacroTimeframe) as TIMEFRAME[]).reduce(\r\n (prev, curr) => ({\r\n ...prev,\r\n [MicroMacroTimeframe[curr].macro]: prev[MicroMacroTimeframe[curr].macro]\r\n ? [...prev[MicroMacroTimeframe[curr].macro], MicroMacroTimeframe[curr].micro]\r\n : [MicroMacroTimeframe[curr].micro],\r\n }),\r\n {} as { [key in MacroTimeframe]: number[] }\r\n)\r\n\r\ntype IRange = {\r\n from?: number\r\n to?: number\r\n}\r\n\r\nexport type IVisibility = {\r\n [key in MacroTimeframe]?: IRange\r\n}\r\n\r\nexport enum SetVisibilityTo {\r\n currentAndAbove,\r\n currentAndBelow,\r\n currentOnly,\r\n all,\r\n}\r\n\r\nexport const QUOTE_FETCH_EVENT = 'quoteFetchEvent'\r\n\r\n// Keep in sync with the clone in Website repo in shared/is-stock-fast-refresh-available.ts\r\nexport const PREMARKET_AFTERMARKET_HOURS = 2.5\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { getChartStartEndDates } from '../controllers/renderUtils'\r\nimport Quote from '../models/quote'\r\n\r\n// **************START**************\r\n// Functions from here until END have to be in sync with\r\n// Finviz-Website: components/timeframe-bar/custom-date-range-utils.ts\r\n// *********************************\r\n\r\nexport enum CustomDateRangePrefixEnum {\r\n Range = 'range',\r\n Prev = 'prev',\r\n}\r\n\r\nexport const CUSTOM_DATE_RANGE = 'custom'\r\nexport const DATE_RANGE_PREFIX_DELMITER = '_'\r\nconst CUSTOM_DATE_RANGE_DELIMITER = 'x'\r\nconst CUSTOM_PREV_RANGE_DELIMITER = '-'\r\n\r\nexport function getParsedDateRange(dateRange: string) {\r\n return dateRange.split(DATE_RANGE_PREFIX_DELMITER)\r\n}\r\n\r\nexport function parseCustomDateRangeUrlParam({ dateRange, anchorDate }: { dateRange: string; anchorDate: Date }) {\r\n const [dateRangePrefix, dateRangeValue] = getParsedDateRange(dateRange)\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n const [dateFromString, dateToString] = dateRangeValue.replace(/-/g, '/').split(CUSTOM_DATE_RANGE_DELIMITER)\r\n const dateFrom = dateFromString ? new Date(dateFromString) : null\r\n const dateTo = dateToString ? new Date(dateToString) : null\r\n return {\r\n start: dateFrom && !Number.isNaN(dateFrom.getTime()) ? dateFrom : null,\r\n end: dateTo && !Number.isNaN(dateTo.getTime()) ? dateFns.endOfDay(dateTo) : null,\r\n }\r\n }\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const [years, months, days] = dateRangeValue.split(CUSTOM_PREV_RANGE_DELIMITER).map(Number)\r\n\r\n if ([years, months, days].some(Number.isNaN)) {\r\n return { start: null, end: null }\r\n }\r\n\r\n return {\r\n start: dateFns.startOfDay(dateFns.sub(anchorDate, { years, months, days: days - 1 })),\r\n end: anchorDate,\r\n }\r\n }\r\n\r\n return { start: null, end: anchorDate }\r\n}\r\n\r\n// **************END**************\r\n// Functions below don't need to be\r\n// in sync with Website repository\r\n// *******************************\r\n\r\nexport function getParsedDateRangeMetaData({ dateRange, quote }: { dateRange: string; quote: Quote }) {\r\n const parsedRange = getChartStartEndDates({ dateRange, quote })\r\n const [dateRangePrefix] = getParsedDateRange(dateRange)\r\n\r\n let startQuoteDate: Date | null = null\r\n let endQuoteDate: Date | null = null\r\n let numOfDaysToRender: number | null = null\r\n\r\n if (parsedRange.start && dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const daysInQuote = quote.getDaysInQuote()\r\n const reversedDaysInQuote = [...daysInQuote].reverse()\r\n const startQuoteDayIndex = reversedDaysInQuote.findIndex((date) => date.getTime() <= parsedRange.start!.getTime())\r\n const endQuoteDayIndex = reversedDaysInQuote.findIndex((date) => date.getTime() <= parsedRange.end!.getTime())\r\n startQuoteDate = reversedDaysInQuote[startQuoteDayIndex] ?? null\r\n endQuoteDate = reversedDaysInQuote[endQuoteDayIndex] ?? null\r\n numOfDaysToRender = quote.interval <= 5 ? startQuoteDayIndex - endQuoteDayIndex + 1 : null\r\n }\r\n\r\n return {\r\n start: parsedRange.start,\r\n end: parsedRange.end,\r\n startQuoteDate,\r\n endQuoteDate,\r\n numOfDaysToRender,\r\n numOfBarsToRender: (numOfDaysToRender ?? 0) * (quote.getBarsInDay() ?? 0) || undefined,\r\n renderDateStart: parsedRange.start && dateFns.startOfDay(parsedRange.start),\r\n renderDateEnd: parsedRange.end && dateFns.endOfDay(parsedRange.end),\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\nimport * as dateFns from 'date-fns'\r\n\r\nimport { Instrument, ObjectHash } from '../../types/shared'\r\nimport {\r\n CHART_MARGIN,\r\n DateRangeType,\r\n PREMARKET_AFTERMARKET_HOURS,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport ChartEventElement from '../models/chart-event-element'\r\nimport ChartLayout from '../models/chart_layout'\r\nimport { IChartSettings, IIndicatorSettings, ISettings } from '../models/chart_settings/interfaces'\r\nimport { CHART_EVENT_BADGE_SIZE } from '../models/constants'\r\nimport Element from '../models/element'\r\nimport Pane, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport Utils from '../utils'\r\nimport utils, { convertLocalToNyTime, dateFromUnixTimestamp, isRedesignedPage } from '../utils'\r\nimport { getBarWidthWithMargin, getZoomFactorForBarsToDisplay } from '../utils/chart'\r\nimport {\r\n DATE_RANGE_PREFIX_DELMITER,\r\n getParsedDateRangeMetaData,\r\n parseCustomDateRangeUrlParam,\r\n} from '../utils/chart-date-range-utils'\r\n\r\ninterface VisibleBarNumberProps {\r\n start: Date | null\r\n end: Date\r\n quote: Quote\r\n dateRange: string\r\n}\r\n\r\ninterface ChartZoomAndLeftOffsetProps extends Omit {\r\n chartVisibleWidth: number\r\n numOfBarsToRender?: number\r\n chartModel: Chart\r\n}\r\n\r\ninterface ChartStartEndDatesProps {\r\n dateRange: string\r\n quote: Quote\r\n}\r\n\r\nexport const getVisibleBarsNumber = ({ start, end, quote, dateRange }: VisibleBarNumberProps) => {\r\n const startInSec = start ? start.getTime() / 1000 : 0\r\n const endInSec = end.getTime() / 1000\r\n const isQuoteDateInRange = (quoteDate: number) => quoteDate >= startInSec && quoteDate <= endInSec\r\n const lastQuoteDateIndex = quote.date.length - 1\r\n let lastVisibleBarIndex = lastQuoteDateIndex\r\n let numOfVisibleBars = 0\r\n if (\r\n [DateRangeType.d1, DateRangeType.d5].includes(dateRange as DateRangeType) &&\r\n quote.instrument === Instrument.Stock\r\n ) {\r\n numOfVisibleBars = quote.drawMinutesPerDay\r\n } else {\r\n let firstVisibleBarIndex = -1\r\n lastVisibleBarIndex = -1\r\n quote.date.forEach((quoteDate, index) => {\r\n if (isQuoteDateInRange(quoteDate)) {\r\n if (firstVisibleBarIndex === -1) {\r\n firstVisibleBarIndex = index\r\n }\r\n lastVisibleBarIndex = index\r\n }\r\n })\r\n numOfVisibleBars = lastVisibleBarIndex - firstVisibleBarIndex + 1\r\n\r\n if (firstVisibleBarIndex === -1 && lastVisibleBarIndex === -1) {\r\n return { numOfVisibleBars: 0, numOfBarsOffset: 0 }\r\n }\r\n }\r\n\r\n return { numOfVisibleBars, numOfBarsOffset: lastQuoteDateIndex - lastVisibleBarIndex }\r\n}\r\n\r\nexport const getChartZoomAndLeftOffset = ({\r\n chartVisibleWidth,\r\n start,\r\n end,\r\n quote,\r\n chartModel,\r\n numOfBarsToRender,\r\n}: ChartZoomAndLeftOffsetProps) => {\r\n const { numOfVisibleBars, numOfBarsOffset } = getVisibleBarsNumber({\r\n start,\r\n end,\r\n quote,\r\n dateRange: chartModel.dateRange,\r\n })\r\n if (numOfVisibleBars === 0) {\r\n return { zoomFactor: chartModel.zoomFactor, leftOffset: chartModel.leftOffset }\r\n }\r\n\r\n const chartLayout = chartModel.chart_layout()\r\n const zoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth,\r\n numOfVisibleBars: numOfBarsToRender ?? numOfVisibleBars,\r\n })\r\n const barWidth = getBarWidthWithMargin({ chartLayout, zoomFactor })\r\n const leftOffset =\r\n getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: {},\r\n barWidth,\r\n numberOfBarsToDraw: numOfBarsToRender,\r\n }) +\r\n numOfBarsOffset * barWidth\r\n return { zoomFactor, leftOffset }\r\n}\r\n\r\nexport const getChartStartEndDates = ({ dateRange, quote }: ChartStartEndDatesProps) => {\r\n const daysInQuote = quote.getDaysInQuote()\r\n const lastDate = dateFromUnixTimestamp(quote.date[quote.date.length - 1])\r\n\r\n if (dateRange.includes(DATE_RANGE_PREFIX_DELMITER)) {\r\n const range = parseCustomDateRangeUrlParam({ dateRange, anchorDate: lastDate })\r\n const end = convertLocalToNyTime(\r\n range.end && range.end.getTime() <= lastDate.getTime() ? range.end : lastDate,\r\n false\r\n )\r\n return {\r\n start: range.start && convertLocalToNyTime(range.start, false),\r\n end,\r\n }\r\n }\r\n\r\n let start\r\n // No condition is needed here, but this would be dateRangePrefix === DateRangePrefixEnum.Enum\r\n switch (dateRange) {\r\n case DateRangeType.d1:\r\n lastDate.setHours(23, 59, 59, 999)\r\n start = daysInQuote.length === 0 ? lastDate : daysInQuote[daysInQuote.length - 1]\r\n break\r\n case DateRangeType.d5:\r\n lastDate.setHours(23, 59, 59, 999)\r\n const startDateIndex = daysInQuote.length === 0 ? -1 : Math.max(daysInQuote.length - 5, 0)\r\n start = startDateIndex === -1 ? lastDate : daysInQuote[startDateIndex]\r\n break\r\n case DateRangeType.m1:\r\n start = dateFns.subMonths(lastDate, 1)\r\n break\r\n case DateRangeType.m3:\r\n start = dateFns.subMonths(lastDate, 3)\r\n break\r\n case DateRangeType.m6:\r\n start = dateFns.subMonths(lastDate, 6)\r\n break\r\n case DateRangeType.ytd:\r\n start = dateFns.startOfYear(lastDate)\r\n break\r\n case DateRangeType.y1:\r\n start = dateFns.subYears(lastDate, 1)\r\n break\r\n case DateRangeType.y2:\r\n start = dateFns.subYears(lastDate, 2)\r\n break\r\n case DateRangeType.y5:\r\n start = dateFns.subYears(lastDate, 5)\r\n break\r\n case DateRangeType.max:\r\n default:\r\n start = null\r\n break\r\n }\r\n\r\n return { start: start && convertLocalToNyTime(start, false), end: convertLocalToNyTime(lastDate, false) }\r\n}\r\n\r\ninterface GetLeftOffsetProps {\r\n quote: Quote\r\n chartModel: Chart\r\n config?: { stretch?: boolean }\r\n barWidth?: number\r\n barIndex?: number\r\n numberOfBarsToDraw?: number\r\n shouldAlignDaysToLeftApplied?: boolean\r\n}\r\n\r\nexport const getMinMaxLeftOffset = ({\r\n newLeftOffset,\r\n chartModel,\r\n barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: chartModel.chart_layout() }),\r\n barIndex,\r\n}: {\r\n newLeftOffset: number\r\n chartModel: Chart\r\n barWidth?: number\r\n barIndex: number\r\n}) => {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const width = chartModel.width - ChartSettings.left.width - ChartSettings.right.width\r\n const numOfBarsInView = Math.floor(width / barWidth)\r\n const fx = (index: number) => index * barWidth\r\n return ~~Utils.min(barWidth / 2, Utils.max(newLeftOffset, width - fx(barIndex + numOfBarsInView)))\r\n}\r\n\r\nexport function getFullChartWidth({\r\n hasAftermarket,\r\n hasPremarket,\r\n timeframeMinutes,\r\n barWidthWithMargin,\r\n}: {\r\n hasPremarket: boolean\r\n hasAftermarket: boolean\r\n timeframeMinutes: number\r\n barWidthWithMargin: number\r\n}) {\r\n const premarketHoursLength = hasPremarket ? PREMARKET_AFTERMARKET_HOURS : 0\r\n const aftermarketHoursLength = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS : 0\r\n const marketMinutesLength = (6.5 + premarketHoursLength + aftermarketHoursLength) * 60\r\n // CHART_MARGIN.L as left offset + CHART_MARGIN.XXL as right offset\r\n return CHART_MARGIN.L + CHART_MARGIN.XXL + (marketMinutesLength / timeframeMinutes) * barWidthWithMargin\r\n}\r\n\r\nexport function getIntradayChartConfig({\r\n timeframeMinutes,\r\n barWidthWithMargin,\r\n hasPremarket,\r\n hasAftermarket,\r\n maxWidth,\r\n}: {\r\n hasPremarket: boolean\r\n hasAftermarket: boolean\r\n timeframeMinutes: number\r\n barWidthWithMargin: number\r\n maxWidth: number\r\n}) {\r\n const fullChartWidth = getFullChartWidth({ hasPremarket, hasAftermarket, barWidthWithMargin, timeframeMinutes })\r\n const offsetChartAfter = 16 // Int from 0-23 , if last quote date is >= this constant `offsetInPx` is applied (chart is moved to the left)\r\n const cropChartMinutesLength = PREMARKET_AFTERMARKET_HOURS * 60\r\n const offsetInPx = (cropChartMinutesLength / timeframeMinutes) * barWidthWithMargin\r\n const chartWidthWithOffset = fullChartWidth - offsetInPx\r\n const shouldCropChart =\r\n hasAftermarket && hasPremarket && maxWidth >= chartWidthWithOffset && maxWidth < fullChartWidth\r\n\r\n return {\r\n fullChartWidth,\r\n offsetInPx: shouldCropChart ? offsetInPx : 0,\r\n chartWidthWithOffset: shouldCropChart ? fullChartWidth - offsetInPx : fullChartWidth,\r\n offsetChartAfter,\r\n }\r\n}\r\n\r\nexport const getLeftOffset = ({\r\n quote,\r\n chartModel,\r\n config,\r\n barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: chartModel.chart_layout() }),\r\n barIndex = getBarIndex(quote),\r\n numberOfBarsToDraw,\r\n shouldAlignDaysToLeftApplied = true,\r\n}: GetLeftOffsetProps) => {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const width = chartModel.width - ChartSettings.left.width - ChartSettings.right.width\r\n const specificChartFunctionality = chartModel.chart_layout().specificChartFunctionality\r\n if (config?.stretch) {\r\n return 0\r\n }\r\n if (getIsSmallIndexChart(specificChartFunctionality)) {\r\n return barWidth\r\n }\r\n const fx = (index: number) => index * barWidth\r\n let leftOffset = width - fx(barIndex) - Math.round(barWidth / 2)\r\n leftOffset = Math.round(Utils.min(barWidth / 2, Utils.max(leftOffset, width - fx(barIndex + 45))))\r\n if (\r\n shouldAlignDaysToLeftApplied &&\r\n shouldAlignDaysToLeft({\r\n quote,\r\n numberOfBarsToDraw,\r\n specificChartFunctionality,\r\n dateRange: chartModel.dateRange,\r\n })\r\n ) {\r\n let drawDaysInOneChart = 1\r\n if (numberOfBarsToDraw) {\r\n drawDaysInOneChart = Math.ceil(numberOfBarsToDraw / quote.getBarsInDay()!)\r\n } else if (quote.interval === 10 || chartModel.dateRange === DateRangeType.d5) {\r\n drawDaysInOneChart = 5\r\n } else if (quote.interval === 15) {\r\n drawDaysInOneChart = 6\r\n } else if (quote.interval === 30) {\r\n drawDaysInOneChart = 12\r\n } else if (quote.interval === 60) {\r\n drawDaysInOneChart = 22\r\n } else if (quote.interval === 120) {\r\n drawDaysInOneChart = 39\r\n } else if (quote.interval === 240) {\r\n drawDaysInOneChart = 78\r\n } else if (quote.interval > 240) {\r\n drawDaysInOneChart = (quote.interval / 30) * 10\r\n }\r\n const { offsetInPx, offsetChartAfter } = getIntradayChartConfig({\r\n hasPremarket: quote.premarket,\r\n hasAftermarket: quote.aftermarket,\r\n barWidthWithMargin: barWidth,\r\n timeframeMinutes: quote.interval,\r\n maxWidth: chartModel.width,\r\n })\r\n const drawDaysWidth = drawDaysInOneChart * quote.getBarsInDay()! * barWidth - offsetInPx\r\n\r\n // +1 is a buffer as it often happens drawDaysWidth is wider than width by tiny amount (< 1/10000 of px)\r\n if (drawDaysWidth <= width + 1) {\r\n const lastQuoteDate = quote.date.last() ? utils.dateFromUnixTimestamp(quote.date.last()!) : null\r\n // Align start of day to left if we have enough space to show all bars in day\r\n const barsToOffset = (Object.keys(quote.getDayToOffset()).length - drawDaysInOneChart) * quote.getBarsInDay()!\r\n const offsetChartInPx = (lastQuoteDate?.getHours() ?? 0) >= offsetChartAfter ? offsetInPx : 0\r\n leftOffset = Math.round(-fx(barsToOffset) + barWidth / 2) - offsetChartInPx\r\n }\r\n }\r\n // getMinMaxLeftOffset move left offset to keep at least one bar in view what isn't desired for offscreen charts\r\n if (specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n return leftOffset\r\n }\r\n return getMinMaxLeftOffset({\r\n newLeftOffset: leftOffset,\r\n chartModel,\r\n barWidth,\r\n barIndex,\r\n })\r\n}\r\n\r\nexport const getBarIndex = (quote: Quote) => quote?.getBarIndex(quote.open?.length ? quote.open.length - 1 : 0) || 0\r\n\r\nexport const getIsSmallIndexChart = (specificChartFunctionality: SpecificChartFunctionality) =>\r\n specificChartFunctionality === SpecificChartFunctionality.smallIndex\r\n\r\ninterface ShouldAlignDaysToLeftProps {\r\n quote: Quote\r\n numberOfBarsToDraw?: number\r\n specificChartFunctionality: SpecificChartFunctionality\r\n dateRange: DateRangeType | null\r\n}\r\n\r\n/**\r\n * Evaluate if days should be aligned to the left\r\n * @param {object} object.quote - Quote model\r\n * @param {string} object.specificChartFunctionality - SpecificChartFunctionality enum\r\n * @returns {boolean} boolean\r\n * */\r\nexport const shouldAlignDaysToLeft = ({\r\n quote,\r\n dateRange,\r\n numberOfBarsToDraw,\r\n specificChartFunctionality,\r\n}: ShouldAlignDaysToLeftProps) => {\r\n const isStockIntraday = quote.isIntraday && quote.instrument === Instrument.Stock\r\n // We don't want this to affect /charts page, only if intraday daterange is applied\r\n const isQuoteOrOffscreen = [SpecificChartFunctionality.quotePage, SpecificChartFunctionality.offScreen].includes(\r\n specificChartFunctionality\r\n )\r\n const isChartPage = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isChartsInradayDateRange =\r\n isChartPage && !!dateRange && [DateRangeType.d1, DateRangeType.d5].includes(dateRange)\r\n const isChartPageWithFixedBars = isChartPage && numberOfBarsToDraw\r\n return isStockIntraday && (isQuoteOrOffscreen || isChartsInradayDateRange || isChartPageWithFixedBars)\r\n}\r\n\r\ninterface ClipProps {\r\n canvasCtx: RenderingContext2DType\r\n width: number\r\n height: number\r\n Settings: ISettings['ChartSettings'] | ISettings['IndicatorSettings']\r\n}\r\n// pane canvasCtx clip\r\nexport const clip = ({ canvasCtx, width, height, Settings }: ClipProps) => {\r\n const contentWidth = width - Settings.left.width - Settings.right.width\r\n const contentHeight = height - Settings.top.height - Settings.bottom.height\r\n canvasCtx.beginPath()\r\n canvasCtx.rect(Settings.left.width, Settings.top.height, contentWidth, contentHeight)\r\n canvasCtx.clip()\r\n}\r\n\r\nexport const getSettings = (paneModel: Pane): IIndicatorSettings | IChartSettings => {\r\n const { ChartSettings, IndicatorSettings } = paneModel.chart().getChartLayoutSettings()\r\n for (const element of paneModel.elements().all()) {\r\n if (element.isIndicator()) {\r\n return IndicatorSettings\r\n }\r\n }\r\n return ChartSettings\r\n}\r\n\r\ninterface RecountScaleProps {\r\n chartModel: Chart\r\n paneModel: Pane\r\n}\r\n\r\ntype ScaledFn = Partial & (d3.ScaleLinear | d3.ScaleSymLog)\r\n\r\nconst getShouldOffsetChartDomain = (elementModel: Element | ChartEventElement) => {\r\n const quote = elementModel.pane().chart().quote()\r\n\r\n return quote.chartEvents.length > 0 && ![TIMEFRAME.w, TIMEFRAME.m].includes(quote.timeframe)\r\n}\r\n\r\nexport const recountScale = ({ chartModel, paneModel }: RecountScaleProps) => {\r\n const { ChartSettings, IndicatorSettings, MarketSentimentSettings } = chartModel.getChartLayoutSettings()\r\n const chartLayout = chartModel.chart_layout()\r\n const barWidthWithMargin = getBarWidthWithMargin({ chartLayout, zoomFactor: chartModel.zoomFactor })\r\n for (const elementModel of [...paneModel.getAllElements(), ...paneModel.getAllChartEvents(false)]) {\r\n const el = elementModel.instance\r\n const isChart = elementModel.isChart()\r\n if (isChart || elementModel.isIndicator()) {\r\n let fx: ScaledFn, Settings: ISettings['MarketSentimentSettings' | 'ChartSettings' | 'IndicatorSettings'], width\r\n const scaleType = isChart ? chartModel.scale : ScaleType.Linear\r\n if (isChart) {\r\n Settings = chartModel.instrument === Instrument.MarketSentiment ? MarketSentimentSettings : ChartSettings\r\n } else {\r\n Settings = IndicatorSettings as ISettings['IndicatorSettings']\r\n }\r\n const contentHeight = paneModel.height - Settings.top.height - Settings.bottom.height\r\n\r\n if (chartModel.stretch) {\r\n width = chartModel.width - Settings.left.width - Settings.right.width\r\n fx = d3\r\n .scaleLinear()\r\n .range([0, width])\r\n .domain([0, Math.max(0, chartModel.quote().close.length - 1)]) as ScaledFn\r\n } else {\r\n fx = ((index: number) => index * barWidthWithMargin) as ScaledFn\r\n fx.invert = (x: number) => x / barWidthWithMargin\r\n fx.width = function (w) {\r\n return this.invert(w) - this.invert(0)\r\n }\r\n }\r\n paneModel.updateAttribute('scale', { x: fx }) // some elements need fx to count getMinMax\r\n\r\n const { min, max } = paneModel.scaleRange || el.getMinMax!()\r\n let fy\r\n\r\n const handleDomainOffset = (currentScale: ScaledFn, scaleCreator: any) => {\r\n if (isChart && getShouldOffsetChartDomain(elementModel)) {\r\n const protectedHeightPx = contentHeight - CHART_EVENT_BADGE_SIZE\r\n const minPx = currentScale(min)\r\n const domain = currentScale.domain()\r\n if (minPx > protectedHeightPx) {\r\n const tempScale = scaleCreator().range([0, protectedHeightPx]).domain([max, min])\r\n const extendedMin = tempScale.invert(contentHeight)\r\n currentScale.domain([domain[0], extendedMin])\r\n }\r\n }\r\n }\r\n\r\n switch (scaleType) {\r\n case ScaleType.Logarithmic:\r\n fy = d3.scaleSymlog().range([0, contentHeight]).domain([max, min]) as ScaledFn\r\n handleDomainOffset(fy, d3.scaleSymlog)\r\n break\r\n default:\r\n fy = d3.scaleLinear().range([0, contentHeight]).domain([max, min]) as ScaledFn\r\n if (!paneModel.scaleRange) {\r\n fy = fy.nice(10)\r\n handleDomainOffset(fy, d3.scaleLinear)\r\n }\r\n break\r\n }\r\n fy.height = function (h: number) {\r\n return this.invert(h) - this.invert(0)\r\n }\r\n paneModel.updateAttribute('scale', {\r\n x: fx,\r\n y: fy,\r\n })\r\n\r\n if (isChart) {\r\n el.setupAxis!(fx as ScaleAxis)\r\n }\r\n break\r\n }\r\n }\r\n}\r\n\r\n// general, only when blurry ends won't be visible or didn't matter\r\nexport const getOffsetFromLineWidth = (lineWidth: number) => (lineWidth % 2 === 0 ? 0 : 0.5)\r\n\r\ninterface IXYOffsetFromLine {\r\n lineWidth: number\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n}\r\n\r\n// return x,y offsets for pixel perfect line rendering\r\nexport const getXYOffsetFromLine = ({ lineWidth, x1, y1, x2, y2 }: IXYOffsetFromLine) => {\r\n // don't add offset is lineWidth is even\r\n if (lineWidth % 2 === 0) {\r\n return { x: 0, y: 0 }\r\n }\r\n if (y1 === y2) {\r\n return { x: 0, y: 0.5 } // horizontal line\r\n } else if (x1 === x2) {\r\n return { x: 0.5, y: 0 } // vertical line\r\n } else {\r\n return { x: 0.5, y: 0.5 } // diagonal line\r\n }\r\n}\r\n\r\nexport const getRoundedObject = (obj: T): T => {\r\n const rounded = Object.entries(obj)\r\n for (let i = 0; i < rounded.length; i++) {\r\n rounded[i][1] = Math.round(rounded[i][1])\r\n }\r\n return Object.fromEntries(rounded) as T\r\n}\r\n\r\ninterface ITranslate {\r\n context: CanvasRenderingContext2D\r\n xOffset: number\r\n yOffset: number\r\n}\r\n\r\ninterface ITranslateObj {\r\n do: () => void\r\n undo: () => void\r\n}\r\n\r\nexport const getTranslate = ({ context, xOffset, yOffset }: ITranslate): ITranslateObj => ({\r\n do: () => context.translate(xOffset, yOffset),\r\n undo: () => context.translate(xOffset * -1, yOffset * -1),\r\n})\r\n\r\ninterface IPercentageScaleValue {\r\n number: number\r\n base: number\r\n}\r\n\r\nexport const getPercentageFromValue = ({ number, base }: IPercentageScaleValue) => ((number - base) / base) * 100\r\n\r\nexport const getValueFromPercentage = ({ number, base }: IPercentageScaleValue) => (number / 100) * base + base\r\n\r\ninterface UpdateZoomAndLeftOffsetByDateRangeProps {\r\n chartModel: Chart\r\n quote: Quote\r\n}\r\n\r\nexport function updateZoomAndLeftOffsetByDateRange({ chartModel, quote }: UpdateZoomAndLeftOffsetByDateRangeProps) {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const chartVisibleWidth = chartModel.width - (ChartSettings.left.width + ChartSettings.right.width)\r\n\r\n const { start, end, numOfBarsToRender } = getParsedDateRangeMetaData({\r\n dateRange: chartModel.dateRange,\r\n quote,\r\n })\r\n\r\n const { zoomFactor, leftOffset } = getChartZoomAndLeftOffset({\r\n chartVisibleWidth,\r\n start,\r\n end,\r\n quote,\r\n numOfBarsToRender,\r\n chartModel: chartModel,\r\n })\r\n\r\n if (chartModel.zoomFactor !== zoomFactor || chartModel.leftOffset !== leftOffset) {\r\n chartModel.updateAttributes({ zoomFactor, leftOffset })\r\n }\r\n}\r\n\r\nexport function renderPane({\r\n chartLayoutModel,\r\n chartModel,\r\n paneModel,\r\n canvasCtx,\r\n shouldRenderCross = false,\r\n}: {\r\n chartLayoutModel: ChartLayout\r\n chartModel: Chart\r\n paneModel: Pane\r\n canvasCtx: CanvasRenderingContext2D\r\n shouldRenderCross?: boolean\r\n}) {\r\n if (paneModel.chart().instrument === Instrument.MarketSentiment) {\r\n canvasCtx.clearRect(0, 0, chartModel.width, paneModel.height)\r\n } else {\r\n canvasCtx.set('fillStyle', chartModel.getChartLayoutSettings().ChartSettings.general.Colors.canvasFill)\r\n canvasCtx.fillRect(0, 0, chartModel.width, paneModel.height)\r\n }\r\n const elements = paneModel.getAllElements()\r\n for (const { instance: elementInstance } of elements) {\r\n if (typeof elementInstance.renderGrid === 'function') {\r\n canvasCtx.save()\r\n elementInstance.renderGrid(canvasCtx)\r\n canvasCtx.restore()\r\n }\r\n }\r\n\r\n const chartEvents = paneModel.getAllChartEvents()\r\n const Settings = getSettings(paneModel)\r\n for (const { instance: elementInstance } of [...elements, ...chartEvents]) {\r\n const isDrawing = elementInstance.getIsDrawing()\r\n const isChartEvent = elementInstance.getIsChartEvent()\r\n\r\n if (isDrawing && (chartLayoutModel.isHideDrawingsActive || !elementInstance.getIsVisible())) {\r\n continue\r\n } else if ((isDrawing || isChartEvent) && !elementInstance.getIsInChartView(chartModel)) {\r\n continue\r\n }\r\n\r\n canvasCtx.save()\r\n if (elementInstance.renderContent != null) {\r\n canvasCtx.save()\r\n clip({\r\n canvasCtx,\r\n width: chartModel.width,\r\n height: paneModel.height,\r\n Settings,\r\n })\r\n canvasCtx.translate(paneModel.chart().leftOffset + Settings.left.width, Settings.top.height)\r\n elementInstance.renderContent(canvasCtx)\r\n canvasCtx.restore()\r\n if (typeof elementInstance.renderLabels === 'function') {\r\n elementInstance.renderLabels(canvasCtx)\r\n }\r\n } else {\r\n elementInstance.render(canvasCtx)\r\n }\r\n if (\r\n shouldRenderCross &&\r\n (chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage ||\r\n isRedesignedPage(chartLayoutModel)) &&\r\n elementInstance.renderCross != null\r\n ) {\r\n elementInstance.renderCross(canvasCtx)\r\n }\r\n canvasCtx.restore()\r\n }\r\n}\r\n","import utils from '../utils'\r\n\r\nclass AverageTrueRange {\r\n period: number\r\n sum: number\r\n count: number\r\n value: number\r\n\r\n constructor(period: number) {\r\n this.period = period\r\n this.sum = 0\r\n this.count = 0\r\n this.value = 0\r\n }\r\n\r\n add(high: number, low: number, prevClose: number) {\r\n const tr = utils.max([high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)])\r\n\r\n if (this.count < this.period) {\r\n this.sum += tr\r\n this.value = this.sum / (this.count + 1)\r\n if (this.count === this.period - 1) {\r\n this.sum /= this.period\r\n }\r\n } else {\r\n this.value = (this.value * (this.period - 1) + tr) / this.period\r\n }\r\n this.count++\r\n }\r\n}\r\n\r\nexport default AverageTrueRange\r\n","import { Instrument, Point } from '../../types/shared'\r\n\r\ninterface LinePoints {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport enum BigNumber {\r\n Thousand,\r\n Million,\r\n Billion,\r\n Trillion,\r\n}\r\n\r\nexport const BIG_NUMBER_VALUES = {\r\n [BigNumber.Thousand]: 1e3,\r\n [BigNumber.Million]: 1e6,\r\n [BigNumber.Billion]: 1e9,\r\n [BigNumber.Trillion]: 1e12,\r\n}\r\n\r\nconst BIG_NUMBER_ZEROES = {\r\n [BigNumber.Thousand]: 3,\r\n [BigNumber.Million]: 6,\r\n [BigNumber.Billion]: 9,\r\n [BigNumber.Trillion]: 12,\r\n}\r\n\r\nconst BIG_NUMBER_SUFFIX = {\r\n [BigNumber.Thousand]: 'K',\r\n [BigNumber.Million]: 'M',\r\n [BigNumber.Billion]: 'B',\r\n [BigNumber.Trillion]: 'T',\r\n}\r\n\r\nconst math = {\r\n dotProduct(p1: Point, p2: Point) {\r\n return p1.x * p2.x + p1.y * p2.y\r\n },\r\n\r\n crossProduct(p1: Point, p2: Point) {\r\n return p1.x * p2.y - p1.y * p2.x\r\n },\r\n\r\n distance(p1: Point, p2: Point) {\r\n return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))\r\n },\r\n\r\n lineEquation(line: LinePoints) {\r\n // ax + by + c = 0\r\n if (line.x1 === line.x2) {\r\n return {\r\n a: 1,\r\n b: 0,\r\n c: -line.x1,\r\n }\r\n }\r\n const k = (line.y2 - line.y1) / (line.x2 - line.x1)\r\n return {\r\n a: -k,\r\n b: 1,\r\n c: k * line.x1 - line.y1,\r\n k,\r\n }\r\n },\r\n\r\n pointInPolygon(point: Point, polygon: Point[]) {\r\n // http://alienryderflex.com/polygon/\r\n let j = polygon.length - 1\r\n let oddNodes = false\r\n for (let i = 0; i < polygon.length; i++) {\r\n const p = polygon[i]\r\n if (\r\n ((p.y < point.y && polygon[j].y >= point.y) || (polygon[j].y < point.y && p.y >= point.y)) &&\r\n (p.x <= point.x || polygon[j].x <= point.x)\r\n ) {\r\n if (p.x + ((point.y - p.y) / (polygon[j].y - p.y)) * (polygon[j].x - p.x) < point.x) {\r\n oddNodes = !oddNodes\r\n }\r\n }\r\n j = i\r\n }\r\n return oddNodes\r\n },\r\n\r\n distanceToLine(point: Point, line: LinePoints) {\r\n const { a, b, c } = this.lineEquation(line)\r\n const dist = Math.abs(a * point.x + b * point.y + c) / Math.sqrt(a * a + b * b)\r\n return dist\r\n },\r\n\r\n distanceToSegment(point: Point, line: LinePoints) {\r\n const l2 = Math.pow(line.x1 - line.x2, 2) + Math.pow(line.y1 - line.y2, 2)\r\n if (l2 === 0) {\r\n return Math.sqrt(Math.pow(point.x - line.x1, 2) + Math.pow(point.y - line.y1, 2))\r\n }\r\n const t = ((point.x - line.x1) * (line.x2 - line.x1) + (point.y - line.y1) * (line.y2 - line.y1)) / l2\r\n if (t < 0) {\r\n return Math.sqrt(Math.pow(point.x - line.x1, 2) + Math.pow(point.y - line.y1, 2))\r\n }\r\n if (t > 1) {\r\n return Math.sqrt(Math.pow(point.x - line.x2, 2) + Math.pow(point.y - line.y2, 2))\r\n }\r\n const x = line.x1 + t * (line.x2 - line.x1)\r\n const y = line.y1 + t * (line.y2 - line.y1)\r\n return Math.sqrt(Math.pow(point.x - x, 2) + Math.pow(point.y - y, 2))\r\n },\r\n\r\n getInstrumentDecimalPlaces({ value, instrument }: { value: number; instrument?: Instrument }) {\r\n if (instrument === Instrument.Crypto && value <= 0.001) {\r\n return 8\r\n }\r\n\r\n if ((instrument !== Instrument.Stock && value <= 6) || (instrument === Instrument.Stock && value < 1)) {\r\n return 4\r\n }\r\n\r\n return 2\r\n },\r\n\r\n formatBigNumber(number: number, toFixed?: number, minNumber?: BigNumber) {\r\n const absNum = Math.abs(number)\r\n const getString = ({ num, suffix, zeroes }: { num: number; suffix: string; zeroes: number }) => {\r\n const str = num.toString()\r\n if (str.includes('e')) {\r\n const splitString = str.split('e')\r\n const addZeroes = Number(splitString[1]) - zeroes\r\n return Math.round(Number(splitString[0])).toString().padEnd(Math.max(0, addZeroes), '0') + suffix\r\n }\r\n const sign = Math.sign(num)\r\n const numberByZeroesCount = Math.pow(10, zeroes)\r\n const result = (absNum / numberByZeroesCount) * sign\r\n return (Number.isInteger(result) ? result : result.toFixed(toFixed !== undefined ? toFixed : 1)) + suffix\r\n }\r\n\r\n if (absNum >= BIG_NUMBER_VALUES[BigNumber.Trillion] || minNumber === BigNumber.Trillion) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Trillion],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Trillion],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Billion] || minNumber === BigNumber.Billion) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Billion],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Billion],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Million] || minNumber === BigNumber.Million) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Million],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Million],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Thousand] || minNumber === BigNumber.Thousand) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Thousand],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Thousand],\r\n })\r\n } else {\r\n return toFixed !== undefined ? number.toFixed(toFixed) : number.toString()\r\n }\r\n },\r\n\r\n round({\r\n value,\r\n lastClose = 0,\r\n instrument,\r\n overridePlaces,\r\n }: {\r\n value: number\r\n lastClose?: number\r\n instrument?: Instrument\r\n overridePlaces?: number\r\n }) {\r\n if (Math.abs(value) >= BIG_NUMBER_VALUES[BigNumber.Million]) {\r\n return this.formatBigNumber(value, overridePlaces)\r\n }\r\n\r\n const places =\r\n typeof overridePlaces === 'number'\r\n ? overridePlaces\r\n : this.getInstrumentDecimalPlaces({ value: lastClose, instrument })\r\n\r\n if (value < 0.000001) {\r\n // There was an issue with getting NaN when rounding small numbers with latter method\r\n return value.toFixed(places)\r\n }\r\n return Number(`${Math.round(Number(`${value}e+${places}`))}e-${places}`).toFixed(places)\r\n },\r\n\r\n perpendicularPointToLine({ line, distance }: { line: LinePoints; distance: number }) {\r\n if (distance === 0) {\r\n return { x: line.x2, y: line.y2 }\r\n }\r\n\r\n let yAxisCoeficient\r\n let xAxisCoeficient\r\n\r\n if (line.x1 <= line.x2 && line.y1 >= line.y2) {\r\n xAxisCoeficient = -1\r\n yAxisCoeficient = -1\r\n } else if (line.x1 <= line.x2 && line.y1 <= line.y2) {\r\n xAxisCoeficient = 1\r\n yAxisCoeficient = -1\r\n } else if (line.x1 >= line.x2 && line.y1 >= line.y2) {\r\n xAxisCoeficient = -1\r\n yAxisCoeficient = 1\r\n } else {\r\n // conditions falling to else: (line.x1 >= line.x2 && line.y1 <= line.y2)\r\n xAxisCoeficient = 1\r\n yAxisCoeficient = 1\r\n }\r\n\r\n const radAngle = Math.atan2(Math.abs(line.x2 - line.x1), Math.abs(line.y2 - line.y1))\r\n const x = line.x2 + xAxisCoeficient * (distance * Math.cos(radAngle))\r\n const y = line.y2 + yAxisCoeficient * (distance * Math.sin(radAngle))\r\n return { x, y }\r\n },\r\n\r\n rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n }: {\r\n rotationAxisPoint: Point\r\n angle: number\r\n pointToRotate: Point\r\n }) {\r\n // return newCoordinates for pointToRotate after rotation defined by\r\n // angle around rotationAxisPoint\r\n const sin = Math.sin(angle)\r\n const cos = Math.cos(angle)\r\n const rotatedX =\r\n cos * (pointToRotate.x - rotationAxisPoint.x) +\r\n sin * (pointToRotate.y - rotationAxisPoint.y) +\r\n rotationAxisPoint.x\r\n const rotatedY =\r\n cos * (pointToRotate.y - rotationAxisPoint.y) -\r\n sin * (pointToRotate.x - rotationAxisPoint.x) +\r\n rotationAxisPoint.y\r\n return { x: rotatedX, y: rotatedY }\r\n },\r\n sharedPointLinesAngle({\r\n sharedPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n sharedPoint: Point\r\n oldLinePoint: Point\r\n newLinePoint: Point\r\n }) {\r\n // return angle between line from sharedPoint to oldLinePoint and\r\n // line from sharedPoint to newLinePoint\r\n const numerator =\r\n oldLinePoint.y * (sharedPoint.x - newLinePoint.x) +\r\n sharedPoint.y * (newLinePoint.x - oldLinePoint.x) +\r\n newLinePoint.y * (oldLinePoint.x - sharedPoint.x)\r\n const denominator =\r\n (oldLinePoint.x - sharedPoint.x) * (sharedPoint.x - newLinePoint.x) +\r\n (oldLinePoint.y - sharedPoint.y) * (sharedPoint.y - newLinePoint.y)\r\n const ratio = numerator / denominator\r\n\r\n return Math.atan(ratio)\r\n },\r\n\r\n twoSegmentLinesIntersection(p1: Point, p2: Point, p3: Point, p4: Point) {\r\n // line intercept math by Paul Bourke http://paulbourke.net/geometry/pointlineplane/\r\n // Determine the intersection point of two line segments\r\n // Return FALSE if the lines don't intersect\r\n\r\n // Check if none of the lines are of length 0\r\n if ((p1.x === p2.x && p1.y === p2.y) || (p3.x === p4.x && p3.y === p4.y)) {\r\n return false\r\n }\r\n\r\n const denominator = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y)\r\n\r\n // Lines are parallel\r\n if (denominator === 0) {\r\n return false\r\n }\r\n\r\n const ua = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denominator\r\n const ub = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denominator\r\n\r\n // is the intersection along the segments\r\n if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {\r\n return false\r\n }\r\n\r\n // Return a object with the x and y coordinates of the intersection\r\n const x = p1.x + ua * (p2.x - p1.x)\r\n const y = p1.y + ua * (p2.y - p1.y)\r\n\r\n return { x, y }\r\n },\r\n\r\n // https://stackoverflow.com/a/60368757\r\n checkLineIntersection(line1_p1: Point, line1_p2: Point, line2_p1: Point, line2_p2: Point) {\r\n // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point\r\n let a, b\r\n const result: { x: number; y: number; onLine1: boolean; onLine2: boolean } = {\r\n x: 0,\r\n y: 0,\r\n onLine1: false,\r\n onLine2: false,\r\n }\r\n const denominator =\r\n (line2_p2.y - line2_p1.y) * (line1_p2.x - line1_p1.x) - (line2_p2.x - line2_p1.x) * (line1_p2.y - line1_p1.y)\r\n if (denominator === 0) {\r\n return false\r\n }\r\n\r\n a = line1_p1.y - line2_p1.y\r\n b = line1_p1.x - line2_p1.x\r\n const numerator1 = (line2_p2.x - line2_p1.x) * a - (line2_p2.y - line2_p1.y) * b\r\n const numerator2 = (line1_p2.x - line1_p1.x) * a - (line1_p2.y - line1_p1.y) * b\r\n a = numerator1 / denominator\r\n b = numerator2 / denominator\r\n\r\n // if we cast these lines infinitely in both directions, they intersect here:\r\n result.x = line1_p1.x + a * (line1_p2.x - line1_p1.x)\r\n result.y = line1_p1.y + a * (line1_p2.y - line1_p1.y)\r\n\r\n // if line1 is a segment and line2 is infinite, they intersect if:\r\n if (a > 0 && a < 1) {\r\n result.onLine1 = true\r\n }\r\n // if line2 is a segment and line1 is infinite, they intersect if:\r\n if (b > 0 && b < 1) {\r\n result.onLine2 = true\r\n }\r\n // if line1 and line2 are segments, they intersect if both of the above are true\r\n return result\r\n },\r\n\r\n // ray is considered line1, segment is considered line2\r\n getRayToLineSegmentIntersection(rayOrigin: Point, rayEnd: Point, segmentStart: Point, segmentEnd: Point) {\r\n const lineIntersection = this.checkLineIntersection(rayOrigin, rayEnd, segmentStart, segmentEnd)\r\n\r\n if (\r\n !lineIntersection ||\r\n lineIntersection.onLine1 ||\r\n this.dotProduct(\r\n this.subtractPoints(rayOrigin, lineIntersection as Point),\r\n this.subtractPoints(rayOrigin, rayEnd)\r\n ) <= 0\r\n )\r\n return false\r\n return { ...lineIntersection, x: Math.round(lineIntersection.x), y: Math.round(lineIntersection.y) } // sometimes edge value can have crazy precision instead of `0` something like `5.684341886080802e-14` which is basically 0.00000000000005684341886080802 we should round it\r\n },\r\n\r\n getMiddlePointOnLineSegment(P1: Point, P2: Point) {\r\n const x = (P1.x - P2.x) / 2 + P2.x\r\n const y = (P1.y - P2.y) / 2 + P2.y\r\n return { x, y }\r\n },\r\n\r\n normalizeVector(v: Point) {\r\n const length = Math.sqrt(v.x * v.x + v.y * v.y)\r\n return { x: v.x / length, y: v.y / length }\r\n },\r\n\r\n multiplyVectorByScalar(v: Point, scalar: number) {\r\n return { x: v.x * scalar, y: v.y * scalar }\r\n },\r\n\r\n addPoints(P1: Point, P2: Point) {\r\n return { x: P1.x + P2.x, y: P1.y + P2.y }\r\n },\r\n\r\n subtractPoints(P1: Point, P2: Point): Point {\r\n return { x: P1.x - P2.x, y: P1.y - P2.y }\r\n },\r\n}\r\n\r\nexport default math\r\n","import { OverlayType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\nexport class ExponentialMovingAverage {\r\n period: number\r\n multiplier: number\r\n sum: number\r\n count: number\r\n value: number\r\n\r\n constructor(period: number) {\r\n this.period = period\r\n this.multiplier = 2 / (this.period + 1)\r\n this.sum = 0\r\n this.count = 0\r\n this.value = 0\r\n }\r\n\r\n add(d: number) {\r\n if (this.count < this.period) {\r\n this.sum += d\r\n this.count++\r\n this.value = this.sum / this.count\r\n } else {\r\n this.value = d * this.multiplier + this.value * (1 - this.multiplier)\r\n }\r\n }\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n ema: number[]\r\n}\r\n\r\nexport class EMACalculation extends MainCalculation {\r\n static type = OverlayType.Ema\r\n\r\n getDefaultCalculatedValues() {\r\n return { ema: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n const ema = new ExponentialMovingAverage(period)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let index = 0; index <= lastIndex; index++) {\r\n ema.add(close[index])\r\n this.calculatedValues.ema[index] = ema.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { IndicatorType, OverlayType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\n\r\ntype OptionValuesType = ObjectHash\r\ntype CalculatedValuesType = ObjectHash\r\ninterface MainProps {\r\n quote?: Quote\r\n options: T\r\n}\r\n\r\nexport type OnValueCalculatedReturnValue = boolean | undefined\r\nexport type OnValueCalculated = ((value: T, dataIndex: number) => OnValueCalculatedReturnValue) | undefined\r\n\r\nexport class MainCalculation<\r\n TOptionValues extends OptionValuesType | undefined = undefined,\r\n TCalculatedValues extends CalculatedValuesType = CalculatedValuesType,\r\n> {\r\n static type: IndicatorType | OverlayType = IndicatorType.Indicator\r\n\r\n quote: NonNullable['quote']>\r\n options: MainProps['options']\r\n\r\n protected _calculatedValues: TCalculatedValues\r\n\r\n constructor({ quote, options }: MainProps) {\r\n this.quote = quote ?? new Quote()\r\n this.options = options\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n }\r\n\r\n get calculatedValues() {\r\n return this._calculatedValues\r\n }\r\n\r\n getDefaultCalculatedValues(): TCalculatedValues {\r\n throw Error('Implement getDefaultCalculatedValues')\r\n }\r\n\r\n calculate(_: OnValueCalculated) {\r\n throw Error('Implement calculate')\r\n }\r\n\r\n getAllCalculatedValues(lastNItems: number) {\r\n const calculatedValues = {} as TCalculatedValues\r\n Object.keys(this.calculatedValues).forEach((key) => {\r\n calculatedValues[key as keyof TCalculatedValues] = this.getCalculatedValues(key, lastNItems)\r\n })\r\n return calculatedValues\r\n }\r\n\r\n getCalculatedValues(key: keyof TCalculatedValues, lastNItems: number) {\r\n return (this.calculatedValues[key] as number[]).slice(-lastNItems) as TCalculatedValues[keyof TCalculatedValues]\r\n }\r\n\r\n /**\r\n * This function is used to construct sql script for db table creation\r\n * and also to build precalculated data object used on node server.\r\n *\r\n * Precalculated data object uses database column names as property keys to simplify data mapping on BE\r\n */\r\n getDbColumnName() {\r\n const { type } = this.constructor as typeof MainCalculation\r\n const typeLabel = type.split('/')[1]\r\n const optionKeys = Object.keys(this.options ?? {}).sort((key1, key2) => key1.localeCompare(key2))\r\n\r\n const optionsStrings = optionKeys.map((key) => `${key.slice(0, 1)}${this.options![key]}`)\r\n return [typeLabel, ...optionsStrings].join('_')\r\n }\r\n}\r\n","/*\r\n * it converts it to numbered index and it causes problems later on\r\n * the reason it's not just numbered enum is that it when used in const below\r\n * */\r\nexport enum ChartSyncablePart {\r\n Crosshair = 'crosshair',\r\n Ticker = 'ticker',\r\n Timeframe = 'timeframe',\r\n}\r\n\r\nexport const ChartPartToAttrsSyncMap = {\r\n [ChartSyncablePart.Ticker]: ['ticker'],\r\n [ChartSyncablePart.Timeframe]: ['timeframe', 'dateRange'],\r\n}\r\n\r\nexport const ChartSyncableParts = [\r\n { value: ChartSyncablePart.Ticker, label: 'Ticker' },\r\n { value: ChartSyncablePart.Timeframe, label: 'Timeframe' },\r\n { value: ChartSyncablePart.Crosshair, label: 'Crosshair' },\r\n]\r\n","import { ObjectHash, Theme } from '../../../types/shared'\r\nimport { IChartThemeColors, chartDarkTheme, chartLightTheme } from '../constants'\r\n\r\nfunction normalizeHexAlpha(hexString = '') {\r\n const hexValue = hexString.replace('#', '')\r\n if (hexValue.length === 6) {\r\n return `${hexString}FF`\r\n }\r\n return hexString\r\n}\r\n\r\nexport const getColorOverwrites = ({\r\n theme,\r\n colors,\r\n}: {\r\n theme: Theme\r\n colors: ObjectHash, Theme>\r\n}) => {\r\n const customColors = colors[theme]\r\n const customColorKeys = Object.keys(customColors) as Array>\r\n const defaultColors = theme === Theme.light ? chartLightTheme : chartDarkTheme\r\n\r\n return customColorKeys.reduce((acc, colorKey) => {\r\n const isDefaultOverWritten =\r\n normalizeHexAlpha(customColors[colorKey]).toLowerCase() !==\r\n normalizeHexAlpha(defaultColors[colorKey]).toLowerCase()\r\n\r\n return isDefaultOverWritten\r\n ? {\r\n ...acc,\r\n [colorKey]: customColors[colorKey],\r\n }\r\n : acc\r\n }, {})\r\n}\r\n","import tailwindColors from '../constants/colors'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\n\r\nexport interface IChartThemeColors {\r\n aftermarketFade: string\r\n background: string\r\n borderDown: string\r\n borderUp: string\r\n canvasFill: string\r\n cross: string\r\n crossText: string\r\n crossTextBackground: string\r\n currentBackground: string\r\n currentText: string\r\n grid: string\r\n gridSecondary: string\r\n indicatorCurrentBackground: string\r\n indicatorCurrentText: string\r\n line: string\r\n marketDown: string\r\n marketUp: string\r\n negativeChange: string\r\n ohlcTrendDown: string\r\n ohlcTrendUp: string\r\n overlayTransparentBackground: string\r\n percentageZeroLineText: string\r\n performanceIndicatorLabel: string\r\n positiveChange: string\r\n premarketFade: string\r\n prevClose: string\r\n text: string\r\n textSecondary: string\r\n trendDown: string\r\n trendUp: string\r\n volumeTrendDown: string\r\n volumeTrendUp: string\r\n wickDown: string\r\n wickUp: string\r\n zeroChange: string\r\n}\r\n\r\nexport interface IIndicatorThemeColors {\r\n line: string\r\n signalLine: string\r\n}\r\n\r\nexport interface IElementThemeColors {\r\n line: string\r\n border: string\r\n textWithoutBackground: string\r\n}\r\n\r\ninterface IDarkerWickColors {\r\n borderUp: string\r\n wickUp: string\r\n borderDown: string\r\n wickDown: string\r\n}\r\n\r\nexport const chartLightTheme: IChartThemeColors = {\r\n aftermarketFade: '#FFFFFF99',\r\n background: '#008CFF0E',\r\n borderDown: '#000000FF',\r\n borderUp: '#000000FF',\r\n canvasFill: '#FFFFFFFF',\r\n cross: '#0000004C',\r\n crossText: '#fff',\r\n crossTextBackground: '#111',\r\n currentBackground: tailwindColors.brightYellow[100],\r\n currentText: tailwindColors.gray[800],\r\n grid: '#D2D2D2FF',\r\n gridSecondary: '#ECECEC',\r\n indicatorCurrentBackground: tailwindColors.gray[600],\r\n indicatorCurrentText: '#fff',\r\n line: '#1E6DC0FF',\r\n marketDown: tailwindColors.red[500],\r\n marketUp: tailwindColors.green[500],\r\n negativeChange: '#C80000FF',\r\n ohlcTrendDown: '#E54040FF',\r\n ohlcTrendUp: '#40A140FF',\r\n overlayTransparentBackground: getHEXWithSpecificAplha('#C9CCD6', 0.25),\r\n percentageZeroLineText: '#111',\r\n performanceIndicatorLabel: '#646464',\r\n positiveChange: '#009600FF',\r\n premarketFade: '#FFFFFF99',\r\n prevClose: '#C80000FF',\r\n text: '#828282',\r\n textSecondary: '#dedede',\r\n trendDown: '#FF0000FF',\r\n trendUp: '#00FF00FF',\r\n volumeTrendDown: '#ffc0c0',\r\n volumeTrendUp: '#a8e0a8',\r\n wickDown: '#000000FF',\r\n wickUp: '#000000FF',\r\n zeroChange: '#000',\r\n}\r\n\r\nexport const chartDarkTheme: IChartThemeColors = {\r\n aftermarketFade: '#4C526133',\r\n background: '#1E6DC019',\r\n borderDown: '#F63538FF',\r\n borderUp: '#30CC5AFF',\r\n canvasFill: tailwindColors.gray[800],\r\n cross: '#404553',\r\n crossText: '#fff',\r\n crossTextBackground: '#111',\r\n currentBackground: tailwindColors.yellow[200],\r\n currentText: tailwindColors.gray[700],\r\n grid: '#363A46FF',\r\n gridSecondary: '#2C303A',\r\n indicatorCurrentBackground: tailwindColors.gray[500],\r\n indicatorCurrentText: '#fff',\r\n line: '#1E6DC0FF',\r\n marketDown: tailwindColors.red[300],\r\n marketUp: tailwindColors.green[300],\r\n negativeChange: tailwindColors.red[400],\r\n ohlcTrendDown: '#E54040FF',\r\n ohlcTrendUp: '#40A140FF',\r\n overlayTransparentBackground: getHEXWithSpecificAplha('#0C0E13', 0.35),\r\n percentageZeroLineText: '#fff',\r\n performanceIndicatorLabel: '#646464',\r\n positiveChange: tailwindColors.green[400],\r\n premarketFade: '#4C526133',\r\n prevClose: '#C80000FF',\r\n text: '#929cb3',\r\n textSecondary: '#929CB399',\r\n trendDown: '#F63538FF',\r\n trendUp: '#30CC5AFF',\r\n volumeTrendDown: '#F635387F',\r\n volumeTrendUp: '#30CC5A7F',\r\n wickDown: '#F63538FF',\r\n wickUp: '#30CC5AFF',\r\n zeroChange: '#929cb3',\r\n}\r\n\r\nexport const darkerWickColors: IDarkerWickColors = {\r\n borderUp: '#006400FF',\r\n wickUp: '#006400',\r\n borderDown: '#6E0000FF',\r\n wickDown: '#6E0000FF',\r\n}\r\n\r\nexport const indicatorLightTheme: IIndicatorThemeColors = {\r\n line: '#000000',\r\n signalLine: tailwindColors.red[400],\r\n}\r\n\r\nexport const indicatorDarkTheme: IIndicatorThemeColors = {\r\n line: '#D07933',\r\n signalLine: tailwindColors.red[400],\r\n}\r\n\r\nexport const elementLightTheme: IElementThemeColors = {\r\n line: '#000000',\r\n border: '#000000',\r\n textWithoutBackground: '#000000',\r\n}\r\n\r\nexport const elementDarkTheme: IElementThemeColors = {\r\n line: '#5faaf4',\r\n border: '#5192D1',\r\n textWithoutBackground: '#929cb3',\r\n}\r\nexport const generalColors: Array = [\r\n '#1f77b4',\r\n '#ff7f0e',\r\n '#2ca02c',\r\n '#d62728',\r\n '#9467bd',\r\n '#8c564b',\r\n '#e377c2',\r\n '#7f7f7f',\r\n '#bcbd22',\r\n '#17becf',\r\n]\r\n\r\n// node chart with thin bars color override\r\nexport const thinBarColorsOverride = {\r\n trendUp: '#00b400',\r\n trendDown: '#b40000',\r\n}\r\n\r\nexport enum AutoSaveState {\r\n Off,\r\n Saved,\r\n Unsaved,\r\n Saving,\r\n}\r\n\r\nexport const CHART_EVENT_BADGE_SIZE = 24\r\n","import endOfDay from 'date-fns/endOfDay'\r\nimport lastDayOfMonth from 'date-fns/lastDayOfMonth'\r\nimport lastDayOfWeek from 'date-fns/lastDayOfWeek'\r\nimport setDate from 'date-fns/set'\r\n\r\nimport { TIMEFRAME, TIMEFRAMES_WITH_PRE_MARKET } from '../../constants/common'\r\nimport { convertLocalToNyTime, dateFromUnixTimestamp } from '../../utils'\r\nimport Chart from '../chart'\r\n\r\nconst MARKET_START = { hours: 9, minutes: 30 }\r\nconst END_OF_DAY = { hours: 23, minutes: 59 }\r\n\r\nfunction getIsDateBeforeMarketStart(date: Date) {\r\n const hours = date.getHours()\r\n const minutes = date.getMinutes()\r\n return hours < MARKET_START.hours || (hours === MARKET_START.hours && minutes < MARKET_START.minutes)\r\n}\r\n\r\nexport function roundTimeForSyncedPane({\r\n sourceChart,\r\n targetChart,\r\n timestamp,\r\n}: {\r\n sourceChart: Chart\r\n targetChart: Chart\r\n timestamp: number\r\n}) {\r\n let dateToReturn = dateFromUnixTimestamp(timestamp)\r\n const sourceChartHasPremarket =\r\n sourceChart.quote().premarket && TIMEFRAMES_WITH_PRE_MARKET.includes(sourceChart.timeframe)\r\n const targetChartHasPremarket =\r\n targetChart.quote().premarket && TIMEFRAMES_WITH_PRE_MARKET.includes(targetChart.timeframe)\r\n\r\n if ([TIMEFRAME.d, TIMEFRAME.w, TIMEFRAME.m].includes(sourceChart.timeframe)) {\r\n dateToReturn = setDate(dateToReturn, MARKET_START)\r\n }\r\n\r\n if (targetChart.timeframe === TIMEFRAME.m) {\r\n dateToReturn = setDate(lastDayOfMonth(dateToReturn), END_OF_DAY)\r\n } else if (targetChart.timeframe === TIMEFRAME.w) {\r\n dateToReturn = setDate(lastDayOfWeek(dateToReturn, { weekStartsOn: 1 }), END_OF_DAY)\r\n } else if (targetChart.timeframe === TIMEFRAME.d && targetChart.quote().instrument !== 'stock') {\r\n dateToReturn = endOfDay(dateToReturn)\r\n }\r\n\r\n if (sourceChartHasPremarket && !targetChartHasPremarket && targetChart.quote().instrument === 'stock') {\r\n dateToReturn = getIsDateBeforeMarketStart(dateToReturn) ? setDate(dateToReturn, MARKET_START) : dateToReturn\r\n }\r\n\r\n return ~~(convertLocalToNyTime(dateToReturn, false).getTime() / 1000)\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\nimport { ChartSyncablePart } from '../chart/contstants'\r\nimport Pane from '../pane'\r\nimport { roundTimeForSyncedPane } from './mouse-utils'\r\n\r\nexport class Mouse extends Spine.Model {\r\n static initClass() {\r\n this.configure('Mouse', 'position')\r\n this.belongsTo('pane', Pane)\r\n }\r\n\r\n declare position: { x: number; y: number } | undefined\r\n declare pane: () => Pane | null\r\n\r\n getIsCrossSyncOn = () => !!this.pane()?.chart().getIsChartPartInSync(ChartSyncablePart.Crosshair)\r\n\r\n getIsMouseInChartOfPane = (pane: Pane) => !!this.pane()?.chart().eql(pane.chart())\r\n\r\n getShouldRenderCrossInPane = (pane: Pane) => this.getIsCrossSyncOn() || this.getIsMouseInChartOfPane(pane)\r\n\r\n getCrossIndexForPane = (pane: Pane) => {\r\n if (this.position) {\r\n if (this.getIsMouseInChartOfPane(pane)) {\r\n return Math.round(this.position.x)\r\n }\r\n const paneOfMouse = this.pane()\r\n if (this.getIsCrossSyncOn() && paneOfMouse) {\r\n const mouseInChart = paneOfMouse.chart()\r\n const currentPaneChart = pane.chart()\r\n const mousePositionTimestamp = mouseInChart.quote().getTimestampFomPositionX(Math.round(this.position.x))\r\n const currentPanePositionX = currentPaneChart.quote().getPositionXFromTimestamp(\r\n roundTimeForSyncedPane({\r\n sourceChart: mouseInChart,\r\n targetChart: currentPaneChart,\r\n timestamp: mousePositionTimestamp,\r\n })\r\n )\r\n return Math.floor(currentPanePositionX)\r\n }\r\n }\r\n\r\n return Number.NaN\r\n }\r\n\r\n getPriceForPane = (pane: Pane) => {\r\n const positionY = this.position?.y ?? null\r\n\r\n if (this.pane()?.eql(pane)) {\r\n return positionY\r\n }\r\n\r\n if (this.getIsCrossSyncOn() && this.pane()) {\r\n const mousePaneIndex = this.pane()?.getIndexInChart()\r\n const currentPaneIndex = pane.getIndexInChart()\r\n return mousePaneIndex === currentPaneIndex ? positionY : null\r\n }\r\n\r\n return null\r\n }\r\n}\r\n\r\n/**\r\n * Mouse is a singleton, so `initClass` must be called before we create the instance\r\n * otherwise it wouldn’t work\r\n */\r\nMouse.initClass()\r\n\r\nconst mouse = Mouse.create()\r\nmouse.save()\r\n\r\nexport default mouse as Mouse\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport { Position, TodoObjectHashAnyType } from '../../types/shared'\r\nimport CanvasElement from '../canvas/element'\r\nimport { ChartEventBadgeType, PANE_HEIGHT_DEFAULT } from '../constants/common'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport Element from './element'\r\nimport { rebuildElementZIndexes } from './utils'\r\n\r\nexport interface ScaleAxis {\r\n (index: number): number\r\n invert: (x: number) => number\r\n domain: () => [currentDomainMax: number, currentDomainMin: number]\r\n width: (x: number) => number\r\n height: (y: number) => number\r\n ticks: (y: number) => number[]\r\n}\r\n\r\nconst CHART_EVENT_BADGE_TYPE_ORDER = [\r\n ChartEventBadgeType.Split,\r\n ChartEventBadgeType.Dividends,\r\n ChartEventBadgeType.EarningsPositive,\r\n ChartEventBadgeType.EarningsNegative,\r\n ChartEventBadgeType.EarningsNeutral,\r\n ChartEventBadgeType.EarningsFuture,\r\n]\r\n\r\nclass Pane extends Spine.Model {\r\n static initClass(\r\n elementModel: typeof Element,\r\n chartEventElementModel: typeof ChartEventElement,\r\n chartModel: typeof Chart\r\n ) {\r\n this.configure('Pane', 'height', 'scale', 'scaleRange', 'instance', 'selection')\r\n this.hasMany('elements', elementModel)\r\n this.hasMany('chartEvents', chartEventElementModel)\r\n this.belongsTo('mainElement', elementModel)\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare id: string\r\n declare chart_id: string\r\n declare height: number\r\n declare scale: {\r\n x: ScaleAxis\r\n y: ScaleAxis\r\n }\r\n\r\n declare instance: any\r\n declare chart: () => Chart\r\n declare mainElement: () => T | null\r\n declare elements: () => Collection\r\n declare chartEvents: () => Collection\r\n selection: CanvasElement | null = null\r\n scaleRange: { min: number; max: number } | null = null\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.elements()\r\n .all()\r\n .forEach((element) => {\r\n element.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n toObject() {\r\n const elements = this.elements()\r\n .all()\r\n .map((el) => el.toObject())\r\n return {\r\n height: this.height,\r\n scale: this.scale,\r\n scaleRange: this.scaleRange,\r\n elements,\r\n }\r\n }\r\n\r\n toConfig(omitKeys = [] as string[]) {\r\n const elements = this.elements()\r\n .all()\r\n .map((el) => el.toConfig())\r\n return omit(\r\n {\r\n height: this.height,\r\n scaleRange: this.scaleRange,\r\n elements,\r\n },\r\n omitKeys\r\n )\r\n }\r\n\r\n move(direction: Position) {\r\n const chartPanes = this.chart().getAllPanes()\r\n const chartPane = chartPanes.find((pane) => !pane.getIsIndicatorPane())\r\n const targetPane = chartPanes.find((pane) => this.eql(pane))\r\n\r\n if (!chartPane || !targetPane) return\r\n\r\n const currentChartPaneRecords = Pane.records.filter((pane) => pane.chart_id === targetPane.chart_id)\r\n const ohterChartPaneRecords = Pane.records.filter((pane) => pane.chart_id !== targetPane.chart_id)\r\n\r\n const targetRecordIndex = currentChartPaneRecords.findIndex((record) => record.id === targetPane.id)\r\n const arrayWithoutTargetRecord = currentChartPaneRecords.filter((_, index) => index !== targetRecordIndex)\r\n const chartRecordIndex = arrayWithoutTargetRecord.findIndex((record) => record.id === chartPane.id)\r\n\r\n const panesAbove = arrayWithoutTargetRecord.slice(0, chartRecordIndex)\r\n const panesBelow = arrayWithoutTargetRecord.slice(chartRecordIndex + 1)\r\n if (direction === Position.Above) {\r\n panesAbove.push(currentChartPaneRecords[targetRecordIndex])\r\n panesAbove.sort((a, b) => a.getNumericId() - b.getNumericId())\r\n }\r\n if (direction === Position.Below) {\r\n panesBelow.push(currentChartPaneRecords[targetRecordIndex])\r\n panesBelow.sort((a, b) => a.getNumericId() - b.getNumericId())\r\n }\r\n\r\n Pane.records = ohterChartPaneRecords.concat([\r\n ...panesAbove,\r\n arrayWithoutTargetRecord[chartRecordIndex],\r\n ...panesBelow,\r\n ])\r\n this.chart().trigger('change', this.chart())\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.chart().chart_layout())\r\n }\r\n\r\n getAllElements() {\r\n return this.elements()\r\n .all()\r\n .sort((a, b) => a.zIndex - b.zIndex)\r\n }\r\n\r\n getAllChartEvents(isSorted = true) {\r\n const chartEvents = [...this.chartEvents().all()]\r\n return isSorted ? chartEvents.sort((a, b) => a.zIndex - b.zIndex) : chartEvents\r\n }\r\n\r\n getChartOrIndicatorElement() {\r\n return this.getAllElements().find((el) => el.isChart() || el.isIndicator()) ?? null\r\n }\r\n\r\n getIsIndicatorPane() {\r\n return !!this.mainElement()?.isIndicator()\r\n }\r\n\r\n getIsChartPane() {\r\n return !!this.mainElement()?.isChart()\r\n }\r\n\r\n resetHeight() {\r\n if (this.getIsIndicatorPane()) {\r\n this.updateAttribute('height', PANE_HEIGHT_DEFAULT.indicator)\r\n }\r\n if (this.getIsChartPane()) {\r\n this.updateAttribute('height', PANE_HEIGHT_DEFAULT.chart)\r\n }\r\n }\r\n\r\n getIndexInChart() {\r\n return this.chart()\r\n .getAllPanes()\r\n .findIndex((chartPane) => chartPane.eql(this))\r\n }\r\n\r\n getElementZIndexRange() {\r\n let max = -1\r\n let min = 1\r\n this.getAllElements().forEach((el) => {\r\n if (el.zIndex > max) {\r\n max = el.zIndex\r\n }\r\n if (el.zIndex < min) {\r\n min = el.zIndex\r\n }\r\n })\r\n return { min, max }\r\n }\r\n\r\n getBelowAboveZeroElements() {\r\n const allPaneElements = this.getAllElements()\r\n const elementsBelowZero: Element[] = []\r\n const elementsAboveZero: Element[] = []\r\n allPaneElements.forEach((el) => {\r\n if (el.zIndex < 0) {\r\n elementsBelowZero.push(el)\r\n }\r\n if (el.zIndex > 0) {\r\n elementsAboveZero.push(el)\r\n }\r\n })\r\n\r\n return { elementsBelowZero, elementsAboveZero }\r\n }\r\n\r\n normalizeZIndexes() {\r\n const { elementsBelowZero, elementsAboveZero } = this.getBelowAboveZeroElements()\r\n rebuildElementZIndexes({ elementsArray: elementsBelowZero, isBelowZero: true })\r\n rebuildElementZIndexes({ elementsArray: elementsAboveZero, isBelowZero: false })\r\n }\r\n\r\n getQuoteRawTicker() {\r\n return this.chart().getQuoteRawTicker()\r\n }\r\n\r\n getNumericId() {\r\n return Number(this.id.replace('c-', ''))\r\n }\r\n\r\n updateChartEventsZIndexes() {\r\n if (!this.scale || !this.scale.hasOwnProperty('x')) {\r\n return\r\n }\r\n\r\n const chartEvents = this.getAllChartEvents(false).sort(\r\n (a, b) => a.instance.attrs.positionTimestamps!.x - b.instance.attrs.positionTimestamps!.x\r\n )\r\n const hoveredChartEvent = chartEvents.find((chartEvent) => chartEvent.instance.isHovered)\r\n const openedChartEvent = chartEvents.find((chartEvent) => chartEvent.instance.isOpen)\r\n\r\n const hoveredTypeChartEventElements: ChartEventElement[] = []\r\n const openedTypeChartEventElements: ChartEventElement[] = []\r\n const nonActiveChartEventElements: ChartEventElement[] = []\r\n\r\n chartEvents.forEach((chartEvent, index) => {\r\n const chartEventsOnSameXPoint = chartEvents.filter(\r\n (chartEvent_B, i) =>\r\n i < index && Math.round(chartEvent.instance.attrs.x) === Math.round(chartEvent_B!.instance.attrs.x)\r\n )\r\n chartEvent.updateAttributes({ yIndex: chartEventsOnSameXPoint.length })\r\n const isHovered = chartEvent.instance === hoveredChartEvent?.instance\r\n const isOpened = chartEvent.instance === openedChartEvent?.instance\r\n const isHoveredType = chartEvent.instance.type === hoveredChartEvent?.instance.type\r\n const isOpenType = chartEvent.instance.type === openedChartEvent?.instance.type\r\n if (!isHovered || !isOpened) {\r\n if (isHoveredType) {\r\n hoveredTypeChartEventElements.push(chartEvent)\r\n } else if (isOpenType) {\r\n openedTypeChartEventElements.push(chartEvent)\r\n } else {\r\n nonActiveChartEventElements.push(chartEvent)\r\n }\r\n }\r\n })\r\n\r\n nonActiveChartEventElements.sort(\r\n (a, b) =>\r\n CHART_EVENT_BADGE_TYPE_ORDER.indexOf(a.instance.getChartEvenBadgeType()) -\r\n CHART_EVENT_BADGE_TYPE_ORDER.indexOf(b.instance.getChartEvenBadgeType())\r\n )\r\n\r\n const chartEventElements = [\r\n ...nonActiveChartEventElements,\r\n ...openedTypeChartEventElements,\r\n openedChartEvent,\r\n ...hoveredTypeChartEventElements,\r\n hoveredChartEvent,\r\n ].filter(Boolean)\r\n chartEventElements.forEach((chartEvent, index) => {\r\n chartEvent!.updateAttributes({ zIndex: index })\r\n })\r\n }\r\n}\r\n\r\nexport default Pane\r\n","import { ObjectHash, RequireByKey } from '../../types/shared'\r\n\r\ninterface HeikinAshiData {\r\n HAOpen: number[]\r\n HAClose: number[]\r\n}\r\n\r\ninterface QuoteValues {\r\n cachedAt: null | number\r\n dayToOffset: ObjectHash[]\r\n dateToIndex: ObjectHash[]\r\n heikinAshiData?: HeikinAshiData\r\n daysInQuote: Date[]\r\n}\r\n\r\ninterface QuoteCacheFunctionProps {\r\n cid: string\r\n key: keyof QuoteValues\r\n fetchedAt: number\r\n value: any\r\n}\r\n\r\nconst quoteCache = {} as ObjectHash\r\n\r\nexport function getCachedQuote({\r\n cid,\r\n key,\r\n fetchedAt,\r\n}: RequireByKey>, 'cid'>) {\r\n const quote = quoteCache[cid]\r\n if (quote?.cachedAt === fetchedAt && key) {\r\n return quote[key]\r\n } else if (!key) {\r\n return quote\r\n }\r\n return null\r\n}\r\n\r\nexport function setCachedQuote({\r\n cid,\r\n key,\r\n value,\r\n fetchedAt,\r\n}: Pick) {\r\n quoteCache[cid] = {\r\n ...(quoteCache[cid]?.cachedAt === fetchedAt ? quoteCache[cid] : {}),\r\n [key]: value,\r\n cachedAt: fetchedAt,\r\n } as QuoteValues\r\n}\r\n\r\nexport function deleteCachedQuote({ cid }: Pick) {\r\n delete quoteCache[cid]\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { isSameMonth, isSameWeek } from 'date-fns'\r\nimport queryString from 'query-string'\r\n\r\nimport { Instrument, ObjectHash, TodoObjectHashAnyType } from '../../types/shared'\r\nimport { ChartEventDbType, ChartEventType, IntradayTimeframeInterval, TIMEFRAME } from '../constants/common'\r\nimport type { ICOT } from '../indicators/cot'\r\nimport { dateFromUnixTimestamp, dateStringFromDate } from '../utils'\r\nimport { getIsAbortError } from '../utils/abort_controller'\r\nimport { getPositionXFromTimestamp, getTimestampFromPositionX } from '../utils/chart'\r\nimport { IDividends, IEarnings, ISplit } from '../utils/chart-events-utils'\r\nimport fetchApi, { NotFoundError } from '../utils/fetch_api'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport { QuoteFetchType, QuoteFetchTypeUrlOption, QuoteUrlOptions } from './quote/constants'\r\nimport { deleteCachedQuote, getCachedQuote, setCachedQuote } from './quoteCache'\r\nimport { getRawTickerForInstrument } from './utils'\r\n\r\nconst quoteRefreshChecksBeforeFullRefresh = 15\r\n\r\ntype TodoPattern = TodoObjectHashAnyType\r\n\r\nexport interface TickerTimeframesProps {\r\n ticker: string\r\n instrument: string\r\n timeframe: string\r\n}\r\n\r\ninterface QuoteFetchOptions {\r\n aftermarket?: boolean\r\n premarket?: boolean\r\n patterns?: boolean\r\n events?: boolean\r\n maxBars?: number\r\n}\r\n\r\ninterface QuoteInternalOptions {\r\n cachePredicate?: (quote: Quote) => boolean\r\n fetchNewDataOnCachedQuote?: boolean\r\n}\r\n\r\ninterface UrlOptions extends QuoteFetchOptions {\r\n ticker: string\r\n instrument: string\r\n timeframe: string\r\n}\r\n\r\ntype ChartEventDataRaw = Omit & { eventType: ChartEventDbType }\r\n\r\nexport interface DataResponse {\r\n COTs: COTData\r\n name: string\r\n ticker: string\r\n instrument: string\r\n interval: number\r\n timeframe: string\r\n open: number[]\r\n high: number[]\r\n low: number[]\r\n close: number[]\r\n date: number[]\r\n volume: number[]\r\n lastOpen: number\r\n lastHigh: number\r\n lastLow: number\r\n lastClose: number\r\n lastDate: number\r\n lastTime: string | null\r\n lastVolume: number\r\n dataId: string\r\n prevClose: number\r\n afterClose: number\r\n afterChange: number\r\n afterTime: string | null\r\n drawMinutesPerDay: number\r\n marketStartMinutes: number\r\n premarketLengthMinutes: number\r\n aftermarketLengthMinutes: number\r\n aftermarket: boolean\r\n premarket: boolean\r\n hasPatterns: boolean\r\n patterns: Array\r\n patternsMinRange: number\r\n patternsMaxRange: number\r\n relativeVolume: number\r\n isIntraday: boolean\r\n noNewData?: boolean\r\n chartEvents?: ChartEventDataRaw[]\r\n}\r\n\r\ninterface COTData {\r\n [code: string]: ICOT\r\n}\r\n\r\nconst emptyQuote = {\r\n open: [],\r\n high: [],\r\n low: [],\r\n close: [],\r\n volume: [],\r\n date: [],\r\n fetchedAt: -1,\r\n numberOfRefreshChecks: 0,\r\n isFetching: false,\r\n is404: false,\r\n COTs: undefined,\r\n name: undefined,\r\n drawMinutesPerDay: undefined,\r\n marketStartMinutes: undefined,\r\n premarketLengthMinutes: undefined,\r\n aftermarketLengthMinutes: undefined,\r\n patterns: [],\r\n patternsMinRange: undefined,\r\n patternsMaxRange: undefined,\r\n relativeVolume: undefined,\r\n lastOpen: undefined,\r\n lastHigh: undefined,\r\n lastLow: undefined,\r\n lastClose: undefined,\r\n lastVolume: undefined,\r\n dataId: undefined,\r\n lastDate: undefined,\r\n prevClose: undefined,\r\n afterClose: undefined,\r\n afterChange: undefined,\r\n chartEvents: [],\r\n}\r\n\r\ninterface ICacheAvailabilityCheckFunctionsArguments {\r\n quote: Quote\r\n options?: QuoteFetchOptions & QuoteInternalOptions\r\n}\r\n\r\nconst doesQuoteAndOptionsMatch = ({ quote, options }: ICacheAvailabilityCheckFunctionsArguments) =>\r\n !quote.premarket === !options?.premarket &&\r\n !quote.aftermarket === !options?.aftermarket &&\r\n !quote.hasPatterns === !options?.patterns &&\r\n // if options.events is false we can reuse quote with events\r\n (!options?.events || !!quote.events)\r\n\r\nconst doesQuoteAndFetchParamsMatch = ({\r\n quote,\r\n ticker,\r\n instrument,\r\n timeframe,\r\n}: {\r\n quote: Quote\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n}) => quote.ticker === ticker && quote.instrument === instrument && quote.timeframe === timeframe\r\n\r\n// either we don't care about matching uuid at all, or they have to match\r\nconst isSameOrNoChartUuid = ({ quote, uuid }: { quote: Quote; uuid?: string }) => !uuid || quote.chartUuid === uuid\r\n\r\nconst isCacheAllowed = ({ quote, options }: ICacheAvailabilityCheckFunctionsArguments) =>\r\n !options?.cachePredicate || options.cachePredicate(quote)\r\n\r\nconst isNotEmptyQuote = (quote: Quote) => quote.fetchedAt !== -1 || quote.isFetching\r\n\r\nexport type QuoteGetParams = {\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n options?: QuoteFetchOptions & QuoteInternalOptions\r\n abortController?: null | AbortController\r\n shouldUseCache?: boolean\r\n chartUuid?: string\r\n}\r\n\r\nfunction getChartEventsWithId({ ticker, chartEvents }: { ticker: string; chartEvents?: ChartEventDataRaw[] }) {\r\n return (\r\n chartEvents?.map((item) => {\r\n let eventType: ChartEventType\r\n switch (item.eventType) {\r\n case ChartEventDbType.Dividends:\r\n eventType = ChartEventType.Dividends\r\n break\r\n case ChartEventDbType.Split:\r\n eventType = ChartEventType.Split\r\n break\r\n case ChartEventDbType.Earnings:\r\n eventType = ChartEventType.Earnings\r\n break\r\n }\r\n return {\r\n ...item,\r\n elementId: `${ticker.toLowerCase()}-${item.eventType}-${item.dateTimestamp}`,\r\n eventType,\r\n }\r\n }) ?? []\r\n )\r\n}\r\n\r\nclass Quote extends Spine.Model {\r\n static initClass() {\r\n this.configure(\r\n 'Quote',\r\n 'ticker',\r\n 'name',\r\n 'instrument',\r\n 'timeframe',\r\n 'open',\r\n 'high',\r\n 'low',\r\n 'close',\r\n 'date',\r\n 'volume',\r\n 'lastOpen',\r\n 'lastHigh',\r\n 'lastLow',\r\n 'lastClose',\r\n 'lastDate',\r\n 'lastVolume',\r\n 'lastTime',\r\n 'dataId',\r\n 'prevClose',\r\n 'COTs',\r\n 'chartEvents',\r\n 'afterClose',\r\n 'afterChange',\r\n 'afterTime',\r\n 'drawMinutesPerDay',\r\n 'marketStartMinutes',\r\n 'premarketLengthMinutes',\r\n 'aftermarketLengthMinutes',\r\n 'aftermarket',\r\n 'premarket',\r\n 'events',\r\n 'hasPatterns',\r\n 'patterns',\r\n 'patternsMinRange',\r\n 'patternsMaxRange',\r\n 'relativeVolume',\r\n 'fetchedAt',\r\n 'isIntraday',\r\n 'interval',\r\n 'drawDays',\r\n 'barIndex',\r\n 'barToDataIndex',\r\n 'fetchingPromise',\r\n 'isFetching',\r\n 'wasFetchAborted',\r\n 'chartUuid',\r\n 'numberOfRefreshChecks',\r\n 'maxBars',\r\n 'ideaID',\r\n 'is404'\r\n )\r\n }\r\n\r\n static async get({\r\n ticker: tickerRaw,\r\n instrument,\r\n timeframe,\r\n options,\r\n abortController,\r\n shouldUseCache = true,\r\n chartUuid,\r\n }: QuoteGetParams): Promise {\r\n const ticker = tickerRaw.replace('@', '')\r\n const [quote] = shouldUseCache\r\n ? Quote.select(\r\n (q) =>\r\n doesQuoteAndFetchParamsMatch({ quote: q, ticker, instrument, timeframe }) &&\r\n isSameOrNoChartUuid({ quote: q, uuid: chartUuid }) &&\r\n isNotEmptyQuote(q) &&\r\n isCacheAllowed({ quote: q, options }) &&\r\n (q.instrument !== Instrument.Stock ||\r\n Number.isInteger(q.ideaID) ||\r\n doesQuoteAndOptionsMatch({ quote: q, options }))\r\n )\r\n : []\r\n\r\n if (quote) {\r\n if (quote.isFetching) {\r\n await quote.getResolvedFetchingPromise()\r\n } else if (options?.fetchNewDataOnCachedQuote) {\r\n await quote.fetchData({ fetchType: QuoteFetchType.NewerData, abortController })\r\n }\r\n return quote\r\n }\r\n\r\n const newQuote = Quote.create({\r\n ...emptyQuote,\r\n ticker,\r\n timeframe,\r\n instrument,\r\n chartUuid,\r\n maxBars: options?.maxBars,\r\n premarket: !!options?.premarket,\r\n aftermarket: !!options?.aftermarket,\r\n hasPatterns: !!options?.patterns,\r\n events: !!options?.events,\r\n })\r\n\r\n await newQuote.fetchData({ fetchType: QuoteFetchType.Refetch, abortController })\r\n\r\n return newQuote\r\n }\r\n\r\n static async getAll(tickersAndTimeframes: Array<{ ticker: string; instrument: Instrument; timeframe: TIMEFRAME }>) {\r\n // TODO: fetch in 1 request\r\n if (tickersAndTimeframes.length === 0) {\r\n return {}\r\n }\r\n\r\n try {\r\n await Promise.all(\r\n tickersAndTimeframes.map(({ ticker, instrument, timeframe }) =>\r\n this.get({ ticker: ticker, instrument, timeframe })\r\n )\r\n )\r\n const data = tickersAndTimeframes.reduce(\r\n (accumulator, currentValue) => ({\r\n ...accumulator,\r\n [currentValue.ticker]: Quote.select(\r\n (q: Quote) =>\r\n q.ticker === currentValue.ticker &&\r\n q.instrument === currentValue.instrument &&\r\n q.timeframe === currentValue.timeframe\r\n )[0],\r\n }),\r\n {}\r\n )\r\n return data\r\n } catch (err) {\r\n // TODO: handle somehow\r\n }\r\n }\r\n\r\n declare ticker: string\r\n declare name: string\r\n declare instrument: Instrument\r\n declare interval: number\r\n declare timeframe: TIMEFRAME\r\n declare open: number[]\r\n declare high: number[]\r\n declare low: number[]\r\n declare close: number[]\r\n declare date: number[]\r\n declare volume: number[]\r\n declare lastOpen: number\r\n declare lastHigh: number\r\n declare lastLow: number\r\n declare lastClose: number\r\n declare lastDate: number\r\n declare lastVolume: number\r\n declare dataId: string\r\n declare prevClose: number\r\n declare COTs: COTData\r\n declare afterClose: number\r\n declare afterChange: number\r\n declare drawMinutesPerDay: number\r\n declare marketStartMinutes: number\r\n declare premarketLengthMinutes: number\r\n declare aftermarketLengthMinutes: number\r\n declare hasPatterns: boolean\r\n declare patterns: Array\r\n declare patternsMinRange: number\r\n declare patternsMaxRange: number\r\n declare relativeVolume: number\r\n declare isIntraday: boolean\r\n declare drawDays?: number\r\n declare barIndex: number[]\r\n /**\r\n * Array of length the same as number of bars\r\n *\r\n * If there's a gap and a bar index has no corresponding data index,\r\n * the last data index is used (or 0 if there's no last data index)\r\n *\r\n * @type {number[]}\r\n */\r\n declare barToDataIndex: number[]\r\n declare chartUuid?: string\r\n declare aftermarket: boolean\r\n declare premarket: boolean\r\n declare fetchedAt: number\r\n declare numberOfRefreshChecks: number\r\n declare isFetching: boolean\r\n declare fetchingPromise?: Promise\r\n declare wasFetchAborted: boolean\r\n declare maxBars?: number\r\n declare ideaID?: number\r\n declare is404?: boolean\r\n declare chartEvents: Array\r\n declare events?: boolean\r\n\r\n async fetchRequest({\r\n abortController,\r\n options = { type: QuoteFetchTypeUrlOption.New },\r\n }: {\r\n abortController?: null | AbortController\r\n options?: QuoteUrlOptions\r\n }) {\r\n let data: DataResponse | null = null\r\n let is404 = false\r\n let wasFetchAborted = false\r\n\r\n const fetchingPromise = fetchApi({\r\n location: this.getUrl(options),\r\n throwOnStatusCodes: [404],\r\n abortController,\r\n })\r\n\r\n this.updateAttributes({\r\n isFetching: true,\r\n fetchingPromise,\r\n })\r\n\r\n try {\r\n data = await fetchingPromise\r\n } catch (err) {\r\n if (getIsAbortError(err as Error)) {\r\n wasFetchAborted = true\r\n } else if (process.env.IS_E2E_TESTING) {\r\n throw new Error('Quote fetch error', { cause: err })\r\n }\r\n is404 = err instanceof NotFoundError\r\n // Ignore network/notfound errors\r\n }\r\n\r\n const shouldUseEmptyQuote = !data && !wasFetchAborted && options.type === QuoteFetchTypeUrlOption.New\r\n\r\n if (process.env.IS_E2E_TESTING && shouldUseEmptyQuote) {\r\n throw new Error('Quote fetch new fail', { cause: { options, is404, wasFetchAborted, data } })\r\n }\r\n\r\n this.updateAttributes({\r\n ...(shouldUseEmptyQuote ? emptyQuote : {}),\r\n is404,\r\n wasFetchAborted,\r\n isFetching: false,\r\n })\r\n\r\n return data\r\n }\r\n\r\n async isPossibleToFetchSequentialData({\r\n abortController,\r\n }: {\r\n abortController?: null | AbortController\r\n } = {}) {\r\n const data = await this.fetchRequest({ abortController })\r\n if (data && data.date.length > 0 && this.date.length > 0) {\r\n return this.date[this.date.length - 1] >= data.date[0]\r\n }\r\n return false\r\n }\r\n\r\n async fetchData({\r\n fetchType,\r\n abortController,\r\n }: {\r\n fetchType: QuoteFetchType\r\n abortController?: null | AbortController\r\n }) {\r\n let options: QuoteUrlOptions\r\n if (fetchType === QuoteFetchType.Refetch) {\r\n options = { type: QuoteFetchTypeUrlOption.New }\r\n } else if (fetchType === QuoteFetchType.NewerData) {\r\n options = { type: QuoteFetchTypeUrlOption.Newer }\r\n if ((this.numberOfRefreshChecks ?? 0) < quoteRefreshChecksBeforeFullRefresh) {\r\n options.dataId = this.dataId\r\n }\r\n } else {\r\n return\r\n }\r\n if (this.instrument === Instrument.Stock) {\r\n options.events = this.events == null ? true : this.events\r\n }\r\n\r\n const data = await this.fetchRequest({ abortController, options })\r\n\r\n if (!data || data.noNewData === true) {\r\n this.updateAttributes({\r\n numberOfRefreshChecks: (this.numberOfRefreshChecks ?? 0) + 1,\r\n })\r\n return\r\n }\r\n if (this.timeframe !== data.timeframe || this.ticker.toLowerCase() !== data.ticker?.toLowerCase()) {\r\n return\r\n }\r\n\r\n const newQuoteData = {\r\n COTs: data.COTs,\r\n name: data.name,\r\n open: data.open,\r\n high: data.high,\r\n low: data.low,\r\n close: data.close,\r\n volume: data.volume,\r\n date: data.date,\r\n drawMinutesPerDay: data.drawMinutesPerDay,\r\n marketStartMinutes: data.marketStartMinutes,\r\n premarketLengthMinutes: data.premarketLengthMinutes,\r\n aftermarketLengthMinutes: data.aftermarketLengthMinutes,\r\n patterns: data.patterns ?? [],\r\n patternsMinRange: data.patternsMinRange,\r\n patternsMaxRange: data.patternsMaxRange,\r\n relativeVolume: data.relativeVolume,\r\n lastOpen: data.lastOpen,\r\n lastHigh: data.lastHigh,\r\n lastLow: data.lastLow,\r\n lastClose: data.lastClose,\r\n lastVolume: data.lastVolume,\r\n dataId: data.dataId,\r\n lastDate: data.lastDate,\r\n lastTime: data.lastTime,\r\n prevClose: data.prevClose,\r\n afterClose: data.afterClose,\r\n afterChange: data.afterChange,\r\n afterTime: data.afterTime,\r\n numberOfRefreshChecks: 0,\r\n chartEvents: data.chartEvents ?? [],\r\n fetchedAt: Date.now(),\r\n }\r\n\r\n if (\r\n !(\r\n fetchType === QuoteFetchType.Refetch ||\r\n [Instrument.Futures, Instrument.Forex, Instrument.Crypto].includes(this.instrument)\r\n )\r\n ) {\r\n /*\r\n * Merges current and new data taking date as index\r\n */\r\n let AIndex = 0\r\n let BIndex = 0\r\n let mergeIndex = -1\r\n while (AIndex < this.date.length || BIndex < data.date.length) {\r\n const ADate = this.date[AIndex]\r\n const BDate = data.date[BIndex]\r\n if (BDate === undefined) {\r\n break\r\n } else if (ADate === BDate) {\r\n // Same date, update OHLCV\r\n this.open[AIndex] = data.open[BIndex]\r\n this.high[AIndex] = data.high[BIndex]\r\n this.low[AIndex] = data.low[BIndex]\r\n this.close[AIndex] = data.close[BIndex]\r\n this.volume[AIndex] = data.volume[BIndex]\r\n AIndex++\r\n BIndex++\r\n } else if (ADate > BDate || ADate === undefined) {\r\n // New bar for a date not yet in our dataset\r\n // If weekly or monthly timeframe & wasn't merged on AIndex\r\n if (mergeIndex === -1 && [TIMEFRAME.w, TIMEFRAME.m].includes(this.timeframe)) {\r\n const prevAIndex = AIndex - 1\r\n const prevDate = dateFromUnixTimestamp(this.date[prevAIndex])\r\n const newDate = dateFromUnixTimestamp(data.date[BIndex])\r\n // If merge bar for weekly is sameWeek or for monthly is sameMonth perform merge on AIndex\r\n if (\r\n (TIMEFRAME.w === this.timeframe && isSameWeek(prevDate, newDate, { weekStartsOn: 1 })) ||\r\n (TIMEFRAME.m === this.timeframe && isSameMonth(prevDate, newDate))\r\n ) {\r\n this.date[prevAIndex] = data.date[BIndex]\r\n this.open[prevAIndex] = data.open[BIndex]\r\n this.high[prevAIndex] = data.high[BIndex]\r\n this.low[prevAIndex] = data.low[BIndex]\r\n this.close[prevAIndex] = data.close[BIndex]\r\n this.volume[prevAIndex] = data.volume[BIndex]\r\n mergeIndex = prevAIndex\r\n // Incrementing BIndex only because we're mergin arrays on AIndex\r\n BIndex++\r\n continue\r\n }\r\n }\r\n this.date.splice(AIndex, 0, data.date[BIndex])\r\n this.open.splice(AIndex, 0, data.open[BIndex])\r\n this.high.splice(AIndex, 0, data.high[BIndex])\r\n this.low.splice(AIndex, 0, data.low[BIndex])\r\n this.close.splice(AIndex, 0, data.close[BIndex])\r\n this.volume.splice(AIndex, 0, data.volume[BIndex])\r\n // Incrementing AIndex because we're changing the array in-place\r\n AIndex++\r\n BIndex++\r\n } else if (ADate < BDate) {\r\n AIndex++\r\n } else {\r\n console.warn('fetchNewerData merge warning')\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData merge warning', {\r\n extra: {\r\n thisDateLength: this.date.length,\r\n dataDateLength: data.date.length,\r\n AIndex,\r\n BIndex,\r\n ADate,\r\n BDate,\r\n },\r\n })\r\n }\r\n }\r\n\r\n newQuoteData.date = this.date\r\n newQuoteData.open = this.open\r\n newQuoteData.high = this.high\r\n newQuoteData.low = this.low\r\n newQuoteData.close = this.close\r\n newQuoteData.volume = this.volume\r\n }\r\n\r\n const hasUpdatedSuccessfully = this.updateAttributes(newQuoteData)\r\n // https://github.com/finvizhq/charts/issues/510\r\n if (!hasUpdatedSuccessfully) {\r\n // attempt to find if this.model.quote() => null is comming from this.save() validation fail\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData save() validation failed', { extra: this })\r\n }\r\n if (!this) {\r\n // or this somehow became null / falsy\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData this is falsy', { extra: this })\r\n }\r\n this.trigger(fetchType, this, fetchType)\r\n }\r\n\r\n async getResolvedFetchingPromise() {\r\n try {\r\n return await this.fetchingPromise\r\n } catch {\r\n // do nothing\r\n }\r\n }\r\n\r\n fetchOlderData() {\r\n return // not yet implemented\r\n // TODO cancel previous request\r\n }\r\n\r\n load(atts: ObjectHash) {\r\n super.load(atts)\r\n const { fetchedAt = 0 } = atts\r\n const { cachedAt } = (getCachedQuote({ cid: this.cid }) as { cachedAt: number } | null) || {}\r\n if (this.timeframe && cachedAt !== fetchedAt) {\r\n setCachedQuote({ cid: this.cid, key: 'cachedAt', value: fetchedAt, fetchedAt })\r\n this.isIntraday = [\r\n TIMEFRAME.i1,\r\n TIMEFRAME.i2,\r\n TIMEFRAME.i3,\r\n TIMEFRAME.i5,\r\n TIMEFRAME.i10,\r\n TIMEFRAME.i15,\r\n TIMEFRAME.i30,\r\n TIMEFRAME.h,\r\n TIMEFRAME.h2,\r\n TIMEFRAME.h4,\r\n ].includes(this.timeframe)\r\n this.interval = this.isIntraday\r\n ? IntradayTimeframeInterval[this.timeframe as keyof typeof IntradayTimeframeInterval]\r\n : 0\r\n this.drawDays = this.getDrawDays()\r\n this.barIndex = this.getBarIndexes()\r\n this.patterns = this.patterns ?? []\r\n this.barToDataIndex = this.barIndex.flatMap((barIndex, index) => {\r\n const lastIndex = this.barIndex[index - 1] ?? -1\r\n return [...Array.from({ length: barIndex - lastIndex - 1 }).fill(Math.max(0, index - 1)), index] as number[]\r\n })\r\n }\r\n if (this.timeframe && this.ticker) {\r\n this.chartEvents = getChartEventsWithId({\r\n ticker: this.ticker,\r\n chartEvents: this.chartEvents as unknown as ChartEventDataRaw[],\r\n })\r\n }\r\n return this\r\n }\r\n\r\n destroy(options?: ObjectHash) {\r\n super.destroy(options)\r\n deleteCachedQuote({ cid: this.cid })\r\n return this\r\n }\r\n\r\n getDrawDays() {\r\n if (this.instrument !== Instrument.Stock) {\r\n return Infinity\r\n }\r\n switch (this.timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n case TIMEFRAME.i10:\r\n return 10\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n return 15\r\n default:\r\n break\r\n }\r\n }\r\n\r\n getHeikinAshiData() {\r\n const cachedHeikinAshiData = getCachedQuote({ cid: this.cid, key: 'heikinAshiData', fetchedAt: this.fetchedAt })\r\n if (cachedHeikinAshiData) {\r\n return cachedHeikinAshiData as unknown as { open: number[]; close: number[] }\r\n }\r\n\r\n const HAClose = this.open.map((_, i) => (this.open[i] + this.high[i] + this.close[i] + this.low[i]) / 4)\r\n const HAOpen = this.open.reduce(\r\n (acc, open, i) => [...acc, (i === 0 ? open + HAClose[0] : acc[i - 1] + HAClose[i - 1]) / 2],\r\n [] as number[]\r\n )\r\n\r\n const heikAshiData = { open: HAOpen, close: HAClose }\r\n\r\n setCachedQuote({ cid: this.cid, key: 'heikinAshiData', value: heikAshiData, fetchedAt: this.fetchedAt })\r\n\r\n return heikAshiData\r\n }\r\n\r\n getDayToOffset(): ObjectHash {\r\n const cachedDayToOffset = getCachedQuote({ cid: this.cid, key: 'dayToOffset', fetchedAt: this.fetchedAt })\r\n if (cachedDayToOffset) {\r\n return cachedDayToOffset as unknown as ObjectHash\r\n }\r\n const dayToOffset: ObjectHash = {}\r\n let day = 0\r\n let lastDay\r\n for (let i = 0, end = this.date.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const date = dateFromUnixTimestamp(this.date[i])\r\n const dateString = dateStringFromDate(date)\r\n if (dateString !== lastDay) {\r\n dayToOffset[dateString] = day\r\n day++\r\n lastDay = dateString\r\n }\r\n }\r\n // for ofscreen renderer we need to add lastDate to have correct dayToOffset because if\r\n // premarket=false in fetch query there isn't other way to distinguish that\r\n if (getIsSSr() && this.lastDate) {\r\n // YYYYMMDD / 20211118 => YYYY-MM-DD\r\n const [yyyy, mm, dd] = [~~(this.lastDate / 10000), ~~(this.lastDate / 100) % 100, this.lastDate % 100]\r\n const lastDate = `${yyyy}-${String(mm).padStart(2, '0')}-${String(dd).padStart(2, '0')}`\r\n\r\n if (lastDay !== lastDate) {\r\n dayToOffset[lastDate] = day\r\n }\r\n }\r\n\r\n setCachedQuote({ cid: this.cid, key: 'dayToOffset', value: dayToOffset, fetchedAt: this.fetchedAt })\r\n return dayToOffset\r\n }\r\n\r\n getDaysInQuote() {\r\n const cachedDayToOffset = getCachedQuote({ cid: this.cid, key: 'daysInQuote', fetchedAt: this.fetchedAt })\r\n if (cachedDayToOffset) {\r\n return cachedDayToOffset as unknown as Date[]\r\n }\r\n const dayToOffset = this.getDayToOffset()\r\n const daysInQuote = Object.keys(dayToOffset)\r\n .map((dateString) => {\r\n const [year, month, day] = dateString.split('-')\r\n return new Date(Number.parseInt(year), Number.parseInt(month) - 1, Number.parseInt(day))\r\n })\r\n .sort((a, b) => a.getTime() - b.getTime())\r\n\r\n setCachedQuote({ cid: this.cid, key: 'daysInQuote', value: daysInQuote, fetchedAt: this.fetchedAt })\r\n return daysInQuote\r\n }\r\n\r\n getBarIndexes() {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return Array.from({ length: this.date.length }).map((_, index) => index)\r\n }\r\n\r\n const barIndex = []\r\n const dayToOffset = this.getDayToOffset()\r\n\r\n for (let i = 0; i < this.date.length; i += 1) {\r\n const date = dateFromUnixTimestamp(this.date[i])\r\n let x = Math.ceil((date.getHours() * 60 + date.getMinutes() - this.marketStartMinutes) / this.interval)\r\n x += dayToOffset[dateStringFromDate(date)] * this.getBarsInDay()! // add days\r\n barIndex[i] = x\r\n }\r\n\r\n return barIndex\r\n }\r\n\r\n getBarIndex(i: number) {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return i\r\n }\r\n return this.barIndex[i]\r\n }\r\n\r\n getBarsInDay() {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return\r\n }\r\n return Math.ceil(this.drawMinutesPerDay / this.interval)\r\n }\r\n\r\n getDataIndexByBarIndex(index: number) {\r\n if (this.barIndex) {\r\n for (let i = 0; i < this.barIndex.length; i++) {\r\n if (this.barIndex[i] === index) {\r\n return i\r\n }\r\n }\r\n }\r\n return -1\r\n }\r\n\r\n getDataByBarIndex(key: keyof Quote, index: number) {\r\n const dataIndex = this.getDataIndexByBarIndex(index)\r\n if (dataIndex > -1) {\r\n const quoteData = this[key as keyof Quote]! as number[]\r\n return quoteData[dataIndex] ?? null\r\n }\r\n return null\r\n }\r\n\r\n getDateToIndex() {\r\n const cachedDateToIndex = getCachedQuote({ cid: this.cid, key: 'dateToIndex', fetchedAt: this.fetchedAt })\r\n if (cachedDateToIndex) {\r\n return cachedDateToIndex as unknown as ObjectHash\r\n }\r\n const dateToIndex: ObjectHash = {}\r\n for (let i = 0; i < this.date.length; i++) {\r\n dateToIndex[this.date[i]] = i\r\n }\r\n setCachedQuote({ cid: this.cid, key: 'dateToIndex', value: dateToIndex, fetchedAt: this.fetchedAt })\r\n return dateToIndex\r\n }\r\n\r\n getTimestampFomPositionX(positionX: number) {\r\n if (this.date.length === 0) {\r\n return 0\r\n }\r\n return getTimestampFromPositionX({\r\n positionX,\r\n quote: this,\r\n })\r\n }\r\n\r\n getPositionXFromTimestamp(timestamp: number) {\r\n if (this.date.length === 0) {\r\n return 0\r\n }\r\n return getPositionXFromTimestamp({\r\n timestamp,\r\n quote: this,\r\n })\r\n }\r\n\r\n getUrl(options: QuoteUrlOptions) {\r\n const config: UrlOptions = {\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n timeframe: this.timeframe || 'd1',\r\n aftermarket: this.aftermarket,\r\n premarket: this.premarket,\r\n patterns: this.hasPatterns,\r\n maxBars: this.maxBars,\r\n ...options,\r\n }\r\n\r\n const isStock = config.instrument === Instrument.Stock\r\n const isBrowserElite = !getIsSSr() && document.location.host === 'elite.finviz.com'\r\n let domain = isBrowserElite && isStock ? 'https://api.finviz.com' : ''\r\n\r\n if (getIsSSr()) {\r\n domain = process.env.BE_API_URL!\r\n }\r\n\r\n return `${domain}/api/quote.ashx?${queryString.stringify({ rev: Date.now(), ...config })}`\r\n }\r\n\r\n getRawTicker() {\r\n return getRawTickerForInstrument(this.instrument, this.ticker)\r\n }\r\n\r\n clearData() {\r\n this.updateAttributes(emptyQuote)\r\n }\r\n}\r\n\r\nQuote.initClass()\r\n\r\nexport default Quote\r\n","export enum QuoteFetchType {\r\n Refetch = 'refetch',\r\n NewerData = 'newerData',\r\n}\r\n\r\nexport enum QuoteFetchTypeUrlOption {\r\n New = 'new',\r\n Newer = 'newer',\r\n}\r\n\r\nexport interface QuoteUrlOptions {\r\n type: QuoteFetchTypeUrlOption\r\n dataId?: string\r\n events?: boolean\r\n}\r\n","export const largeChartFontSize = {\r\n S: 8,\r\n M: 10,\r\n XXL: 16,\r\n XXXL: 24,\r\n}\r\n","import { Theme } from '../../../types/shared'\r\nimport {\r\n CHART_MARGIN,\r\n FONT_SIZE,\r\n LINE_HEIGHT,\r\n OFFSET,\r\n PADDING,\r\n SETTINGS_HEIGHT,\r\n TICKER_TIMEFRAME_CHANGE_HEIGHT,\r\n TextBaseline,\r\n} from '../../constants/common'\r\nimport {\r\n chartDarkTheme,\r\n chartLightTheme,\r\n elementDarkTheme,\r\n elementLightTheme,\r\n generalColors,\r\n indicatorDarkTheme,\r\n indicatorLightTheme,\r\n} from '../constants'\r\nimport { ISettings } from './interfaces'\r\n\r\nexport const INTERACTIVE_CHART_SETTINGS = (theme: Theme): ISettings => ({\r\n ChartSettings: {\r\n general: {\r\n Colors: {\r\n ...(theme === Theme.light ? chartLightTheme : chartDarkTheme),\r\n [Theme.light]: chartLightTheme,\r\n [Theme.dark]: chartDarkTheme,\r\n },\r\n settingsHeight: SETTINGS_HEIGHT,\r\n tickerTimeframeChangeHeight: TICKER_TIMEFRAME_CHANGE_HEIGHT,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 1,\r\n border: 1,\r\n },\r\n top: {\r\n height: CHART_MARGIN.XL,\r\n baseline: TextBaseline.alphabetic,\r\n ticker: {\r\n margin: {\r\n top: 30,\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.XXXL,\r\n style: 'bold',\r\n },\r\n },\r\n ohlc: {\r\n margin: {\r\n top: 30,\r\n left: 30,\r\n right: 30,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n change: {\r\n margin: {\r\n top: 30,\r\n right: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n style: 'bold',\r\n },\r\n },\r\n },\r\n right: {\r\n width: CHART_MARGIN.XXL,\r\n axis: {\r\n margin: {\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n lineHeight: LINE_HEIGHT.S,\r\n padding: {\r\n top: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n right: PADDING.XXS,\r\n },\r\n },\r\n },\r\n },\r\n bottom: {\r\n height: CHART_MARGIN.M,\r\n baseline: TextBaseline.top,\r\n axis: {\r\n margin: {\r\n top: 8,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n },\r\n left: {\r\n width: CHART_MARGIN.L,\r\n overlayLabel: {\r\n labelSpacing: 12,\r\n margin: {\r\n top: -8,\r\n left: 6,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n weight: 'bold',\r\n },\r\n },\r\n timeframe: {\r\n margin: {\r\n top: 0,\r\n left: 28,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n weight: '900',\r\n family: 'Lato, sans-serif',\r\n },\r\n },\r\n volumeAxis: {\r\n margin: {\r\n left: 33,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n },\r\n },\r\n IndicatorSettings: {\r\n general: {\r\n height: 140,\r\n Colors: theme === Theme.light ? indicatorLightTheme : indicatorDarkTheme,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 2,\r\n border: 1,\r\n },\r\n top: {\r\n height: CHART_MARGIN.S,\r\n },\r\n right: {\r\n width: CHART_MARGIN.XXL,\r\n axis: {\r\n margin: {\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n lineHeight: LINE_HEIGHT.S,\r\n padding: {\r\n top: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n right: PADDING.XXS,\r\n },\r\n },\r\n },\r\n },\r\n bottom: {\r\n height: CHART_MARGIN.S,\r\n },\r\n left: {\r\n width: CHART_MARGIN.L,\r\n indicatorLabel: {\r\n labelSpacing: 4,\r\n margin: {\r\n top: OFFSET.S,\r\n left: OFFSET.M,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n style: 'bold',\r\n lineHeight: LINE_HEIGHT.M,\r\n },\r\n },\r\n },\r\n },\r\n MarketSentimentSettings: {\r\n general: {\r\n Colors: theme === Theme.light ? chartLightTheme : chartDarkTheme,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 1,\r\n border: 1,\r\n },\r\n top: {\r\n height: 0,\r\n },\r\n bottom: {\r\n height: 12,\r\n },\r\n left: {\r\n width: 0,\r\n },\r\n right: {\r\n width: 30,\r\n },\r\n },\r\n ColorsSettings: generalColors,\r\n ThumbSettings: {\r\n size: 8,\r\n touchSize: 16,\r\n color: '#ddd',\r\n borderWidth: 1,\r\n borderColor: '#999',\r\n },\r\n ElementSettings: {\r\n Colors: theme === Theme.light ? elementLightTheme : elementDarkTheme,\r\n defaultFill: '#1e6dc066',\r\n defaultTransparentFill: '#1e6dc000',\r\n },\r\n})\r\n","import merge from 'lodash.merge'\r\n\r\nimport { ChartConfigChart } from '../../server/chartConfig'\r\nimport { Instrument, ObjectHash, Theme } from '../../types/shared'\r\nimport { SpecificChartFunctionality } from '../constants/common'\r\nimport Utils, { isRedesignedPage } from '../utils'\r\nimport LayoutModel from './chart_layout'\r\nimport { getColorOverwrites } from './chart_settings'\r\nimport { largeChartFontSize } from './chart_settings/constants'\r\nimport { INTERACTIVE_CHART_SETTINGS } from './chart_settings/interactive_chart_settings'\r\nimport { ISettings } from './chart_settings/interfaces'\r\nimport {\r\n IChartThemeColors,\r\n chartDarkTheme,\r\n chartLightTheme,\r\n elementDarkTheme,\r\n elementLightTheme,\r\n indicatorDarkTheme,\r\n indicatorLightTheme,\r\n} from './constants'\r\n\r\ninterface Config {\r\n theme: Theme\r\n barMargin?: number\r\n barWidth?: number\r\n border?: number\r\n charts?: ChartConfigChart[]\r\n colorsOverride?: Array\r\n volumeHeight?: number\r\n colors?: ObjectHash, Theme>\r\n specificChartFunctionality?: SpecificChartFunctionality\r\n}\r\n\r\nexport function getSettings(config: Config, chartSettings?: ISettings): ISettings {\r\n const settings = merge({}, chartSettings ?? INTERACTIVE_CHART_SETTINGS(config.theme))\r\n\r\n if (config.barWidth != null) {\r\n settings.ChartSettings.center.barWidth = config.barWidth\r\n settings.IndicatorSettings.center.barWidth = config.barWidth\r\n }\r\n if (config.barMargin != null) {\r\n settings.ChartSettings.center.barMargin = config.barMargin\r\n settings.IndicatorSettings.center.barMargin = config.barMargin\r\n }\r\n if (config.border != null) {\r\n settings.ChartSettings.center.border = config.border\r\n settings.IndicatorSettings.center.border = config.border\r\n }\r\n if (config.colorsOverride) {\r\n settings.ColorsSettings = config.colorsOverride\r\n }\r\n if (config.volumeHeight) {\r\n settings.ChartSettings.center.volumeHeight = config.volumeHeight\r\n }\r\n if (config.colors) {\r\n const settingColors = settings.ChartSettings.general.Colors\r\n settings.ChartSettings.general.Colors = {\r\n ...settingColors,\r\n [Theme.light]: {\r\n ...settingColors[Theme.light],\r\n ...getColorOverwrites({ theme: Theme.light, colors: config.colors }),\r\n },\r\n [Theme.dark]: {\r\n ...settingColors[Theme.dark],\r\n ...getColorOverwrites({ theme: Theme.dark, colors: config.colors }),\r\n },\r\n }\r\n }\r\n if (config.specificChartFunctionality === SpecificChartFunctionality.chartPage && Utils.isMobile()) {\r\n settings.ChartSettings.left.width = 0\r\n settings.ChartSettings.top.ticker.margin.left = settings.ChartSettings.left.overlayLabel.margin.left\r\n settings.IndicatorSettings.left.width = 0\r\n }\r\n if (SpecificChartFunctionality.chartPage === config.specificChartFunctionality || isRedesignedPage(config)) {\r\n settings.ChartSettings.top.height = 10\r\n }\r\n\r\n if (config.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n const isGroupInstrument = config.charts?.some(({ instrument }) => instrument === Instrument.Group)\r\n if (isGroupInstrument) {\r\n settings.ChartSettings.top.ohlc.margin.top = 4\r\n settings.ChartSettings.top.ticker.margin.top = 0\r\n settings.ChartSettings.top.ticker.font = {\r\n size: largeChartFontSize.XXL,\r\n style: 'bold',\r\n }\r\n settings.ChartSettings.left.timeframe.margin.top = 12\r\n settings.ChartSettings.left.timeframe.font = {\r\n size: largeChartFontSize.S,\r\n style: 'bold',\r\n }\r\n }\r\n }\r\n\r\n return settings\r\n}\r\n\r\nexport function updateSettings(chart_layout: LayoutModel, theme: string): ISettings {\r\n const settings = merge({}, chart_layout.settings)\r\n const isLight = theme === Theme.light\r\n settings.MarketSentimentSettings.general.Colors = isLight ? { ...chartLightTheme } : { ...chartDarkTheme }\r\n settings.IndicatorSettings.general.Colors = isLight ? { ...indicatorLightTheme } : { ...indicatorDarkTheme }\r\n settings.ElementSettings.Colors = isLight ? { ...elementLightTheme } : { ...elementDarkTheme }\r\n\r\n return settings\r\n}\r\n\r\nexport function getChartLayoutSettings(chart_layout: LayoutModel): ISettings {\r\n const settings = chart_layout.settings\r\n\r\n return {\r\n ...settings,\r\n ChartSettings: {\r\n ...settings.ChartSettings,\r\n general: {\r\n ...settings.ChartSettings.general,\r\n Colors: {\r\n ...settings.ChartSettings.general.Colors,\r\n ...settings.ChartSettings.general.Colors[chart_layout.theme],\r\n },\r\n },\r\n },\r\n }\r\n}\r\n","import { Instrument } from '../../types/shared'\r\nimport ChartLayoutModel from './chart_layout'\r\nimport Element from './element'\r\n\r\nexport const handleRemoveIndicatorPane = ({\r\n paneIndex,\r\n chartLayoutModel,\r\n}: {\r\n paneIndex: number\r\n chartLayoutModel: ChartLayoutModel\r\n}) => {\r\n const charts = chartLayoutModel.getAllCharts()\r\n charts.forEach((chart) => chart.getAllPanes()[paneIndex].destroyCascade())\r\n}\r\n\r\nexport function getNormalizedZIndex({ index, isBelowZero }: { index: number; isBelowZero: boolean }) {\r\n return (index + 1) * (isBelowZero ? -1 : 1)\r\n}\r\n\r\nexport function rebuildElementZIndexes({\r\n elementsArray,\r\n isBelowZero,\r\n}: {\r\n elementsArray: Element[]\r\n isBelowZero: boolean\r\n}) {\r\n const elements = isBelowZero ? [...elementsArray].reverse() : elementsArray\r\n elements.forEach((element, index) => {\r\n const newZIndex = getNormalizedZIndex({ index, isBelowZero })\r\n if (newZIndex !== element.zIndex) {\r\n element.updateAttributes({ zIndex: newZIndex })\r\n }\r\n })\r\n}\r\n\r\nexport function changeElementZIndexes({\r\n elementsArray,\r\n addElement,\r\n oldZIndex,\r\n newZIndex,\r\n isBelowZero = false,\r\n}: {\r\n elementsArray: Element[]\r\n addElement: Element | undefined\r\n oldZIndex: number\r\n newZIndex: number\r\n isBelowZero?: boolean\r\n}) {\r\n const array = isBelowZero ? [...elementsArray].reverse() : elementsArray\r\n const elements =\r\n elementsArray.length === 0 && addElement\r\n ? [...array, addElement]\r\n : array\r\n .filter((_, index) => getNormalizedZIndex({ index, isBelowZero }) !== oldZIndex)\r\n .flatMap((el, index) =>\r\n getNormalizedZIndex({ index, isBelowZero }) === newZIndex && addElement ? [addElement, el] : el\r\n )\r\n\r\n // If there are only 2 drawings and we move a drawing from index 1 to index 2 to have to push it to the array because it's the last element and it didn't get into the array in the flatMap above\r\n if (elements.length < Math.abs(newZIndex) && addElement) {\r\n elements.push(addElement)\r\n }\r\n\r\n rebuildElementZIndexes({ elementsArray: isBelowZero ? [...elements].reverse() : elements, isBelowZero })\r\n}\r\n\r\nexport function getRawTickerForInstrument(instrument: Instrument, ticker: string) {\r\n return `${\r\n [Instrument.Crypto, Instrument.Forex, Instrument.Futures].includes(instrument) && !ticker.includes('@') ? '@' : ''\r\n }${ticker}`\r\n}\r\n","import { OverlayType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n deviations: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n stdDev: number[]\r\n upperBand: number[]\r\n lowerBand: number[]\r\n}\r\n\r\nexport class BbCalculation extends MainCalculation {\r\n static type = OverlayType.Bb\r\n\r\n getDefaultCalculatedValues() {\r\n return {\r\n sma: [],\r\n stdDev: [],\r\n upperBand: [],\r\n lowerBand: [],\r\n }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period, deviations } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sum = 0\r\n for (let i = 0; i < period; i++) {\r\n sum += close[i]\r\n }\r\n for (let i = period; i < close.length; i++) {\r\n sum = sum - close[i - period] + close[i]\r\n this.calculatedValues.sma[i] = sum / period\r\n\r\n let stdDevSum = 0\r\n for (let j = i - period + 1; j <= i; j++) {\r\n stdDevSum += Math.pow(close[j] - this.calculatedValues.sma[i], 2)\r\n }\r\n this.calculatedValues.stdDev[i] = Math.sqrt(stdDevSum / period)\r\n\r\n this.calculatedValues.upperBand[i] = this.calculatedValues.sma[i] + this.calculatedValues.stdDev[i] * deviations\r\n this.calculatedValues.lowerBand[i] = this.calculatedValues.sma[i] - this.calculatedValues.stdDev[i] * deviations\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import {\r\n ChartConfigChartPaneElement,\r\n IModalConfig,\r\n IModalConfigInput,\r\n ObjectHash,\r\n RequireByKey,\r\n} from '../../types/shared'\r\nimport Element from '../canvas/element'\r\nimport BaseChart from '../charts/base_chart'\r\nimport { OverlayType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\nimport { convertColorToHEX, getRGBAValueFromValidColorString } from '../utils/colors'\r\nimport { getParsedIntegersFromPeriodString, isInRange, isPositiveInteger } from '../utils/helpers'\r\n\r\nexport interface IOverlayIsValid {\r\n getIsValid(key: string): boolean | void\r\n}\r\n\r\nconst DEFAULT_LABEL_COLOR = '#0587cd'\r\n\r\nclass Overlay extends Element implements IOverlayIsValid {\r\n static type = OverlayType.Overlay\r\n static label = 'Overlay'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt] = getParsedIntegersFromPeriodString(period)\r\n return periodInt\r\n }\r\n\r\n declare data: Quote\r\n declare chart: BaseChart\r\n\r\n get type() {\r\n return (this.constructor as typeof Overlay).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Overlay).label\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.color ? convertColorToHEX(this.attrs.color) : DEFAULT_LABEL_COLOR\r\n }\r\n\r\n getFreeColor() {\r\n return this.getChartLayoutSettings().ColorsSettings[0]\r\n // TODO proper implementation - example how this could be done:\r\n // let colorsUsed = []\r\n // for (let overlay of this.chart.overlays) {\r\n // let object = overlay.getModalConfig().inputs\r\n // for (let _ in object) {\r\n // let input = object[_]\r\n // if (input.type === 'color') {\r\n // colorsUsed.push(input.value)\r\n // }\r\n // }\r\n // }\r\n // for (let color of colors) {\r\n // if (!colorsUsed.includes(color)) {\r\n // return color\r\n // }\r\n // }\r\n // return colors[0]\r\n }\r\n\r\n renderContent(_?: RenderingContext2DType) {\r\n this.data = this.model.chart().quote()\r\n }\r\n\r\n fx = (x: number) => this.model.scale.x(this.data.barIndex[x])\r\n\r\n getIsValid(_: string): boolean | undefined {\r\n throw Error('Implement')\r\n }\r\n\r\n getIsNumberInputValid({ key, integerOnly = true }: { key: string; integerOnly?: boolean }): boolean {\r\n const input = this.getModalConfig().inputs.find(({ name }: { name: string }) => key === name)\r\n return !!input && isInRange(input) && (!integerOnly || isPositiveInteger(input.value))\r\n }\r\n\r\n isRendered() {\r\n return true\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return this.isRendered()\r\n }\r\n\r\n getModalConfig(): IModalConfig {\r\n return {\r\n title: '',\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toConfig() {\r\n const colors: string[] = []\r\n const periods: string[] = []\r\n\r\n this.getModalConfig().inputs.forEach((input: IModalConfigInput) => {\r\n if (input.type === 'color') {\r\n colors.push(getRGBAValueFromValidColorString(input.value.toString()))\r\n } else {\r\n periods.push(input.value.toString())\r\n }\r\n })\r\n\r\n return { type: this.type, period: periods.join(','), color: colors.join('|') }\r\n }\r\n}\r\n\r\nexport default Overlay\r\n","import { ChartConfigChartPaneElement, RequireByKey, Theme } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { BbCalculation } from '../indicator-calculation/bb'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\nconst BB_COLORS = {\r\n [Theme.light]: {\r\n TOP: '#D386DF',\r\n BOTTOM: '#69C1EA',\r\n MIDDLE: '#CFD2F2',\r\n },\r\n [Theme.dark]: {\r\n TOP: '#D38BFB',\r\n BOTTOM: '#57AEFB',\r\n MIDDLE: '#E1B6FC',\r\n },\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 20,\r\n Deviations: 2.0,\r\n}\r\n\r\ninterface Attrs {\r\n period: number | string\r\n deviations: number\r\n topColor?: string\r\n bottomColor?: string\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const deviations = parseFloat(values[1]) || DEFAULT_PARAMETERS.Deviations\r\n\r\n return [period, deviations]\r\n}\r\n\r\nclass BollingerBands extends Overlay {\r\n static type = OverlayType.Bb\r\n static label = 'Bollinger Bands'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, deviations] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.deviations = deviations\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (typeof this.attrs.period !== 'number') {\r\n return\r\n }\r\n super.renderContent()\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n const theme = this.model.chart().chart_layout().theme as Theme\r\n const { leftOffset, width } = this.model.chart()\r\n const [top, bottom] = this.model.scale.y.domain()\r\n const scaledTop = this.fy(top)\r\n const scaledBottom = this.fy(bottom)\r\n const { close } = this.data\r\n const period = Math.min(this.attrs.period, close.length - 1)\r\n\r\n let firstBarToRender: number | undefined\r\n let lastBarToRender = 0\r\n\r\n // middle line && find first & last bar to render\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', BB_COLORS[theme].MIDDLE)\r\n\r\n const bbCalculation = new BbCalculation({\r\n quote: this.data,\r\n options: {\r\n period,\r\n deviations: this.attrs.deviations,\r\n },\r\n })\r\n\r\n bbCalculation.calculate(({ sma }, dataIndex) => {\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = dataIndex\r\n\r\n context.lineTo(this.fx(dataIndex), Math.round(this.fy(sma[dataIndex])))\r\n\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n lastBarToRender = dataIndex\r\n })\r\n\r\n if (firstBarToRender === undefined) return\r\n context.stroke()\r\n context.set('fillStyle', Colors.overlayTransparentBackground)\r\n\r\n // top line\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRender), scaledTop)\r\n context.set('strokeStyle', BB_COLORS[theme].TOP)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(bbCalculation.calculatedValues.upperBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), scaledTop)\r\n context.fill()\r\n\r\n // bottom line\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRender), scaledBottom)\r\n context.set('strokeStyle', BB_COLORS[theme].BOTTOM)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(bbCalculation.calculatedValues.lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), scaledBottom)\r\n context.fill()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const deviations = {\r\n type: 'number',\r\n label: 'Deviations',\r\n name: 'deviations',\r\n value: this.attrs.deviations ?? DEFAULT_PARAMETERS.Deviations,\r\n required: true,\r\n min: 0.1,\r\n max: 999,\r\n step: 0.1,\r\n }\r\n const topColor = {\r\n type: 'color',\r\n label: 'Top Color',\r\n name: 'topColor',\r\n value: this.attrs.topColor ?? this.getFreeColor(),\r\n }\r\n const bottomColor = {\r\n type: 'color',\r\n label: 'Bottom Color',\r\n name: 'bottomColor',\r\n value: this.attrs.bottomColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, deviations, topColor, bottomColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n deviations: `${deviations.label} must be a number between ${deviations.min} and ${deviations.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'deviations':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'topColor':\r\n case 'bottomColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n const theme = this.model.chart().chart_layout().theme as Theme\r\n return this.attrs.topColor || BB_COLORS[theme].TOP\r\n }\r\n\r\n toString() {\r\n return `BB ${this.attrs.period},${this.attrs.deviations}`\r\n }\r\n}\r\n\r\nBollingerBands.prototype.defaults = { topColor: '#69c1ea', bottomColor: '#d386df' }\r\n\r\nexport default BollingerBands\r\n","import { OverlayType } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n channelStrokeColor: string\r\n channelFillColor: string\r\n medianBandColor: string\r\n}\r\n\r\nconst DEFAULT_PERIOD = 20\r\n\r\nconst COLORS = {\r\n ChannelStroke: '#69c1ea',\r\n ChannelFill: '#69C1EA12',\r\n MedianBandStroke: '#ffa75f',\r\n}\r\n\r\nclass DonchianChannels extends Overlay {\r\n static type = OverlayType.Dch\r\n static label = 'Donchian Channels'\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { period } = this.attrs\r\n const upperBand: number[] = []\r\n const lowerBand: number[] = []\r\n const medianBand: number[] = []\r\n let firstBarToRender = -1\r\n let lastBarToRender = 0\r\n if (this.data.close.length === undefined) {\r\n return\r\n }\r\n\r\n context.save()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', COLORS.ChannelStroke)\r\n context.set('fillStyle', COLORS.ChannelFill)\r\n\r\n //upper band + clip\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n firstBarToRender = firstBarToRender === -1 ? i : firstBarToRender\r\n upperBand[i] = utils.max(this.data.high.slice(Math.max(0, i - period), i + 1))\r\n lowerBand[i] = utils.min(this.data.low.slice(Math.max(0, i - period), i + 1))\r\n medianBand[i] = (upperBand[i] + lowerBand[i]) / 2\r\n\r\n context.lineTo(x, Math.round(this.fy(upperBand[i])))\r\n lastBarToRender = i\r\n },\r\n })\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender), context.canvas.height)\r\n context.clip()\r\n\r\n // lower band + fill\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(0, 0)\r\n context.fill()\r\n\r\n // median band\r\n context.set('strokeStyle', COLORS.MedianBandStroke)\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(medianBand[i])))\r\n }\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PERIOD,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const strokeColor = {\r\n type: 'color',\r\n label: 'Channels Stroke Color',\r\n name: 'strokeColor',\r\n value: this.attrs.channelStrokeColor ?? this.getFreeColor(),\r\n }\r\n const fillColor = {\r\n type: 'color',\r\n label: 'Channels Fill Color',\r\n name: 'fillColor',\r\n value: this.attrs.channelFillColor ?? this.getFreeColor(),\r\n }\r\n const medianBandColor = {\r\n type: 'color',\r\n label: 'Median Band Color',\r\n name: 'medianBandColor',\r\n value: this.attrs.medianBandColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, medianBandColor, strokeColor, fillColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'medianBandColor':\r\n case 'strokeColor':\r\n case 'fillColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.medianBandColor\r\n }\r\n\r\n toString() {\r\n return `Donchian ${this.attrs.period}`\r\n }\r\n}\r\n\r\nDonchianChannels.prototype.defaults = {\r\n medianBandColor: COLORS.MedianBandStroke,\r\n channelStrokeColor: COLORS.ChannelStroke,\r\n channelFillColor: COLORS.ChannelFill,\r\n}\r\n\r\nexport default DonchianChannels\r\n","import { OverlayType } from '../constants/common'\r\nimport { EMACalculation } from '../indicator-calculation/ema'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n deviations: number\r\n color: string\r\n}\r\n\r\nclass EMA extends Overlay {\r\n static type = OverlayType.Ema\r\n static label = 'Exponential Moving Average'\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n const emaCalculation = new EMACalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.attrs.period,\r\n },\r\n })\r\n emaCalculation.calculate(({ ema }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n context.lineTo(x, Math.round(this.fy(ema[dataIndex])))\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, color],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `EMA ${this.attrs.period}`\r\n }\r\n}\r\n\r\nEMA.prototype.defaults = { color: '#ffa75f' }\r\n\r\nexport default EMA\r\n","import { OverlayType } from '../constants/common'\r\nimport EMA from './ema'\r\n\r\nclass EMA2 extends EMA {\r\n static type = OverlayType.Ema2\r\n}\r\n\r\nEMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default EMA2\r\n","import { OverlayType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport { getBarWidthWithMargin } from '../utils/chart'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n lowColor: string\r\n highColor: string\r\n}\r\n\r\nclass HighLow extends Overlay {\r\n static type = OverlayType.Hilo\r\n static label = 'High/Low'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const chartModel = this.model.chart()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { leftOffset, width, zoomFactor } = chartModel\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const halfWidth = barWidth / 2\r\n const period = Math.min(this.attrs.period, this.data.close.length - 1)\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n context.translate(0.5, 0.5)\r\n context.set('fillStyle', Colors.overlayTransparentBackground)\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.highColor)\r\n let prevHigh = -1\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n }\r\n\r\n const x = this.fx(i)\r\n if (this.fx(i + 1) + leftOffset < -10) {\r\n prevHigh = highestHigh\r\n continue\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n\r\n const diff = this.data.barIndex[i] - this.data.barIndex[lastBarToRender]\r\n if (diff > 1 && prevHigh !== highestHigh && prevHigh > 0) {\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(prevHigh)))\r\n }\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(highestHigh)))\r\n context.lineTo(Math.round(x + halfWidth), Math.round(this.fy(highestHigh)))\r\n\r\n prevHigh = highestHigh\r\n lastBarToRender = i\r\n }\r\n context.stroke()\r\n if (firstBarToRender === undefined) return\r\n\r\n // return to start and fill with background color\r\n context.lineTo(this.fx(lastBarToRender) + halfWidth, 0)\r\n context.lineTo(this.fx(firstBarToRender) - halfWidth, 0)\r\n context.fill()\r\n\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.lowColor)\r\n let prevLow = -1\r\n let prevBar = firstBarToRender\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n let lowestLow = this.data.low[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n const x = this.fx(i)\r\n const diff = this.data.barIndex[i] - this.data.barIndex[prevBar]\r\n if (diff > 1 && prevLow !== lowestLow && prevLow > 0) {\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(prevLow)))\r\n }\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(lowestLow)))\r\n context.lineTo(Math.round(x + halfWidth), Math.round(this.fy(lowestLow)))\r\n\r\n prevLow = lowestLow\r\n prevBar = i\r\n }\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n\r\n // return to start and fill with background color\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender) - halfWidth, context.canvas.height)\r\n context.fill()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 50,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const highColor = {\r\n type: 'color',\r\n label: 'High Color',\r\n name: 'highColor',\r\n value: this.attrs.highColor ?? this.getFreeColor(),\r\n }\r\n const lowColor = {\r\n type: 'color',\r\n label: 'Low Color',\r\n name: 'lowColor',\r\n value: this.attrs.lowColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, highColor, lowColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'highColor':\r\n case 'lowColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.highColor\r\n }\r\n\r\n toString() {\r\n return `HILO ${this.attrs.period}`\r\n }\r\n}\r\n\r\nHighLow.prototype.defaults = {\r\n lowColor: '#69c1ea',\r\n highColor: '#d386df',\r\n}\r\n\r\nexport default HighLow\r\n","import { OverlayType } from '../constants/common'\r\nimport { isPositiveFloat } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n price: number\r\n color: string\r\n}\r\n\r\nclass HorizontalLine extends Overlay {\r\n static type = OverlayType.Hline\r\n static label = 'Horizontal Line'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (typeof this.attrs.period === 'string' && this.attrs.price === undefined) {\r\n this.attrs.price = parseFloat(this.attrs.period)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const y = Math.round(this.fy(this.attrs.price))\r\n context.set('strokeStyle', this.attrs.color)\r\n context.translate(0, 0.5)\r\n context.beginPath()\r\n context.moveTo(-this.model.chart().leftOffset, y)\r\n context.lineTo(-this.model.chart().leftOffset + this.model.chart().width, y)\r\n context.stroke()\r\n context.translate(0, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const price = {\r\n type: 'number',\r\n label: 'Price',\r\n name: 'price',\r\n value: this.attrs.price || this.model?.scale?.y?.domain().reduce((a: number, b: number) => a + b, 0) / 2,\r\n required: true,\r\n step: 0.1,\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [price, color],\r\n inputsErrorMessages: {\r\n price: `${price.label} must be number`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'price':\r\n return isPositiveFloat(this.attrs[key])\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `HL ${this.attrs.price}`\r\n }\r\n}\r\n\r\nHorizontalLine.prototype.defaults = { color: '#0587cd' }\r\n\r\nexport default HorizontalLine\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period?: string\r\n conversion: number\r\n base: number\r\n spanB: number\r\n spanAStrokeColor: string\r\n spanAFillColor: string\r\n spanBStrokeColor: string\r\n spanBFillColor: string\r\n conversionLineColor: string\r\n baseLineColor: string\r\n laggingSpanColor: string\r\n}\r\n\r\nconst COLORS = {\r\n SpanA: {\r\n Stroke: '#009600',\r\n Fill: '#00960022',\r\n },\r\n SpanB: {\r\n Stroke: '#C80000',\r\n Fill: '#C8000022',\r\n },\r\n ConversionLine: '#69C1EA',\r\n BaseLine: '#E54040',\r\n LaggingSpan: '#FFA75F',\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Conversion: 9,\r\n Base: 26,\r\n SpanB: 52,\r\n}\r\n\r\nfunction parsePeriod(period: string) {\r\n const [conversion = DEFAULT_PARAMETERS.Conversion, base = DEFAULT_PARAMETERS.Base, spanB = DEFAULT_PARAMETERS.SpanB] =\r\n getParsedIntegersFromPeriodString(period)\r\n return [conversion, base, spanB]\r\n}\r\n\r\nclass IchimokuCloud extends Overlay {\r\n static type = OverlayType.Ic\r\n static label = 'Ichimoku Cloud'\r\n static renderFull = false\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n return Math.max(...parsePeriod(period))\r\n }\r\n\r\n get renderFull() {\r\n return (this.constructor as typeof IchimokuCloud).renderFull\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (\r\n typeof this.attrs.period === 'string' &&\r\n (this.attrs.conversion === undefined || this.attrs.base === undefined || this.attrs.spanB === undefined)\r\n ) {\r\n const [conversion, base, spanB] = parsePeriod(this.attrs.period)\r\n this.attrs.conversion = conversion\r\n this.attrs.base = base\r\n this.attrs.spanB = spanB\r\n }\r\n this.trigger('change')\r\n return this\r\n }\r\n\r\n fx = (x: number) => {\r\n const lastIndex = this.data.close.length - 1\r\n const outsideBar = this.data.barIndex[lastIndex] + x - lastIndex\r\n\r\n return this.model.scale.x(this.data.barIndex[x] ?? outsideBar)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { high, low, close } = this.data\r\n\r\n const {\r\n conversion,\r\n base,\r\n spanB,\r\n spanAFillColor,\r\n spanAStrokeColor,\r\n spanBFillColor,\r\n spanBStrokeColor,\r\n baseLineColor,\r\n conversionLineColor,\r\n laggingSpanColor,\r\n } = this.attrs\r\n\r\n const conversionLine: number[] = []\r\n const baseLine: number[] = []\r\n const senkouSpanA: number[] = []\r\n const senkouSpanB: number[] = []\r\n const conversionStartIndex = conversion - 1\r\n const baseStartIndex = base - 1\r\n const spanBIndex = spanB - 1\r\n const start = Math.min(baseStartIndex, conversionStartIndex)\r\n const end = close.length + baseStartIndex\r\n\r\n if (this.data.close.length === 0) return\r\n\r\n // Calculation\r\n for (let i = start; i < end; i++) {\r\n if (i >= conversionStartIndex && i < close.length) {\r\n const highestHi = Math.max(...high.slice(i - conversionStartIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - conversionStartIndex, i + 1))\r\n conversionLine[i] = (highestHi + lowestLo) / 2\r\n }\r\n\r\n if (i >= baseStartIndex && i < close.length) {\r\n const highestHi = Math.max(...high.slice(i - baseStartIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - baseStartIndex, i + 1))\r\n baseLine[i] = (highestHi + lowestLo) / 2\r\n\r\n senkouSpanA[i + baseStartIndex] = (baseLine[i] + conversionLine[i]) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n\r\n if (i >= spanBIndex) {\r\n const highestHi = Math.max(...high.slice(i - spanBIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - spanBIndex, i + 1))\r\n senkouSpanB[i + baseStartIndex] = (highestHi + lowestLo) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n }\r\n\r\n let lastSpanAX = 0\r\n let lastSpanBX = 0\r\n const cloudStartingX = this.fx(spanBIndex + baseStartIndex)\r\n\r\n context.set('lineWidth', 1)\r\n context.translate(0.5, 0.5)\r\n context.save()\r\n // 1. Senkou Span A\r\n // 1.1 Stroke\r\n context.set('strokeStyle', spanAStrokeColor)\r\n context.set('fillStyle', spanAFillColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(senkouSpanA[i])))\r\n lastSpanAX = x\r\n },\r\n })\r\n context.stroke()\r\n // 1.2 Clipping area\r\n context.lineTo(lastSpanAX, context.canvas.height)\r\n context.lineTo(cloudStartingX, context.canvas.height)\r\n context.clip()\r\n // 1.3 Fill\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n if (i >= senkouSpanA.length) return\r\n context.lineTo(x, Math.round(this.fy(senkouSpanB[i])))\r\n lastSpanBX = x\r\n },\r\n })\r\n context.lineTo(lastSpanBX, 0)\r\n context.lineTo(cloudStartingX, 0)\r\n context.fill()\r\n context.restore()\r\n\r\n // 2. Senkou Span B\r\n // 2.1 Stroke\r\n context.save()\r\n context.set('strokeStyle', spanBStrokeColor)\r\n context.set('fillStyle', spanBFillColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n if (i >= senkouSpanA.length) return\r\n context.lineTo(x, Math.round(this.fy(senkouSpanB[i])))\r\n },\r\n })\r\n context.stroke()\r\n // 2.2 Clipping area\r\n context.lineTo(lastSpanBX, context.canvas.height)\r\n context.lineTo(cloudStartingX, context.canvas.height)\r\n context.clip()\r\n // 2.3 Fill\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(senkouSpanA[i])))\r\n },\r\n })\r\n context.lineTo(lastSpanBX, 0)\r\n context.lineTo(cloudStartingX, 0)\r\n context.fill()\r\n context.restore()\r\n context.translate(-0.5, -0.5)\r\n\r\n if (this.renderFull) {\r\n // conversion line\r\n context.set('strokeStyle', conversionLineColor)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(conversionLine[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n // base line\r\n context.set('strokeStyle', baseLineColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(baseLine[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n // lagging span\r\n context.set('strokeStyle', laggingSpanColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: (x: number) => this.fx(x - base),\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.data.close[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const conversion = {\r\n type: 'number',\r\n label: 'Conversion Line',\r\n name: 'conversion',\r\n value: this.attrs.conversion ?? DEFAULT_PARAMETERS.Conversion,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const base = {\r\n type: 'number',\r\n label: 'Base Line Length',\r\n name: 'base',\r\n value: this.attrs.base ?? DEFAULT_PARAMETERS.Base,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const spanB = {\r\n type: 'number',\r\n label: 'Leading Span B Length',\r\n name: 'spanB',\r\n value: this.attrs.spanB ?? DEFAULT_PARAMETERS.SpanB,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const spanAStrokeColor = {\r\n type: 'color',\r\n label: 'Span A Stroke Color',\r\n name: 'spanAStrokeColor',\r\n value: this.attrs.spanAStrokeColor ?? this.getFreeColor(),\r\n }\r\n const spanAFillColor = {\r\n type: 'color',\r\n label: 'Span A Fill Color',\r\n name: 'spanAFillColor',\r\n value: this.attrs.spanAFillColor ?? this.getFreeColor(),\r\n }\r\n const spanBStrokeColor = {\r\n type: 'color',\r\n label: 'Span B Stroke Color',\r\n name: 'spanBStrokeColor',\r\n value: this.attrs.spanBStrokeColor ?? this.getFreeColor(),\r\n }\r\n const spanBFillColor = {\r\n type: 'color',\r\n label: 'Span B Fill Color',\r\n name: 'spanBFillColor',\r\n value: this.attrs.spanBFillColor ?? this.getFreeColor(),\r\n }\r\n const conversionLineColor = {\r\n type: 'color',\r\n label: 'Conversion Line Color',\r\n name: 'conversionLineColor',\r\n value: this.attrs.conversionLineColor ?? this.getFreeColor(),\r\n }\r\n const baseLineColor = {\r\n type: 'color',\r\n label: 'Base Line Color',\r\n name: 'baseLineColor',\r\n value: this.attrs.baseLineColor ?? this.getFreeColor(),\r\n }\r\n const laggingSpanColor = {\r\n type: 'color',\r\n label: 'Lagging Span Color',\r\n name: 'laggingSpanColor',\r\n value: this.attrs.laggingSpanColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [\r\n conversion,\r\n base,\r\n spanB,\r\n spanAStrokeColor,\r\n spanAFillColor,\r\n spanBStrokeColor,\r\n spanBFillColor,\r\n conversionLineColor,\r\n baseLineColor,\r\n laggingSpanColor,\r\n ],\r\n inputsErrorMessages: {\r\n conversion: `${conversion.label} must be a whole number between ${conversion.min} and ${conversion.max}`,\r\n base: `${base.label} must be a whole number between ${base.min} and ${base.max}`,\r\n spanB: `${spanB.label} must be a whole number between ${spanB.min} and ${spanB.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'conversion':\r\n case 'base':\r\n case 'spanB':\r\n case 'lagging':\r\n return this.getIsNumberInputValid({ key })\r\n case 'spanAStrokeColor':\r\n case 'spanAFillColor':\r\n case 'spanBStrokeColor':\r\n case 'spanBFillColor':\r\n case 'conversionLineColor':\r\n case 'baseLineColor':\r\n case 'laggingSpanColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.spanAStrokeColor\r\n }\r\n\r\n toString() {\r\n return `Ichimoku ${this.attrs.conversion},${this.attrs.base},${this.attrs.spanB}`\r\n }\r\n}\r\n\r\nIchimokuCloud.prototype.defaults = {\r\n spanAStrokeColor: COLORS.SpanA.Stroke,\r\n spanAFillColor: COLORS.SpanA.Fill,\r\n spanBStrokeColor: COLORS.SpanB.Stroke,\r\n spanBFillColor: COLORS.SpanB.Fill,\r\n conversionLineColor: COLORS.ConversionLine,\r\n baseLineColor: COLORS.BaseLine,\r\n laggingSpanColor: COLORS.LaggingSpan,\r\n}\r\n\r\nexport default IchimokuCloud\r\n","import { OverlayType } from '../constants/common'\r\nimport IchimokuCloud from './ic'\r\n\r\nclass IchimokuCloudFull extends IchimokuCloud {\r\n static type = OverlayType.Icf\r\n static label = 'Ichimoku Cloud (Full)'\r\n static renderFull = true\r\n}\r\n\r\nexport default IchimokuCloudFull\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { ExponentialMovingAverage } from '../indicator-calculation/ema'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period?: string\r\n emaPeriod: number\r\n multiplier: number\r\n atrPeriod: number\r\n strokeColor: string\r\n fillColor: string\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n emaPeriod: 20,\r\n multiplier: 2.0,\r\n atrPeriod: 10,\r\n}\r\n\r\nconst COLORS = {\r\n Stroke: '#69C1EA',\r\n Fill: '#69C1EA33',\r\n}\r\n\r\nfunction parsePeriod(period: string) {\r\n const values = period.split(',')\r\n const emaPeriod = parseInt(values[0])\r\n const multiplier = parseFloat(values[1])\r\n const atrPeriod = parseInt(values[2])\r\n\r\n return [emaPeriod, multiplier, atrPeriod]\r\n}\r\n\r\nclass KeltnerChannel extends Overlay {\r\n static type = OverlayType.Kch\r\n static label = 'Keltner Channel'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n return Math.max(...parsePeriod(period)) * 2\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (\r\n typeof this.attrs.period === 'string' &&\r\n (this.attrs.emaPeriod === undefined || this.attrs.multiplier === undefined || this.attrs.atrPeriod === undefined)\r\n ) {\r\n const [emaPeriod, multiplier, atrPeriod] = parsePeriod(this.attrs.period)\r\n this.attrs.emaPeriod = emaPeriod\r\n this.attrs.multiplier = multiplier\r\n this.attrs.atrPeriod = atrPeriod\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { emaPeriod, multiplier, atrPeriod, strokeColor, fillColor } = this.attrs\r\n const ema = new ExponentialMovingAverage(emaPeriod)\r\n const atr = new AverageTrueRange(atrPeriod)\r\n const middleLine: number[] = []\r\n const upperBand: number[] = []\r\n const lowerBand: number[] = []\r\n const start = Math.max(emaPeriod, atrPeriod)\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n\r\n context.save()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', strokeColor)\r\n context.set('fillStyle', fillColor)\r\n\r\n //top line + clip\r\n context.beginPath()\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n ema.add(this.data.close[i])\r\n atr.add(this.data.high[i], this.data.low[i], this.data.close[i - 1])\r\n if (i < start) {\r\n continue\r\n }\r\n\r\n const x = this.fx(i)\r\n if (this.fx(i + 1) + leftOffset < 0) {\r\n continue\r\n }\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n\r\n middleLine[i] = ema.value\r\n upperBand[i] = ema.value + multiplier * atr.value\r\n lowerBand[i] = ema.value - multiplier * atr.value\r\n\r\n context.lineTo(x, Math.round(this.fy(upperBand[i])))\r\n lastBarToRender = i\r\n }\r\n if (firstBarToRender === undefined) {\r\n context.restore()\r\n return\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender), context.canvas.height)\r\n context.clip()\r\n\r\n // bottom line + fill\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(0, 0)\r\n context.fill()\r\n\r\n // middle line\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(middleLine[i])))\r\n }\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n getModalConfig() {\r\n const emaPeriod = {\r\n type: 'number',\r\n label: 'EMA Period',\r\n name: 'emaPeriod',\r\n value: this.attrs.emaPeriod ?? DEFAULT_PARAMETERS.emaPeriod,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const multiplier = {\r\n type: 'number',\r\n label: 'Multiplier',\r\n name: 'multiplier',\r\n value: this.attrs.multiplier ?? DEFAULT_PARAMETERS.multiplier,\r\n required: true,\r\n step: 0.1,\r\n min: 0.0,\r\n max: 999,\r\n }\r\n\r\n const atrPeriod = {\r\n type: 'number',\r\n label: 'ATR Period',\r\n name: 'atrPeriod',\r\n value: this.attrs.atrPeriod ?? DEFAULT_PARAMETERS.atrPeriod,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const strokeColor = {\r\n type: 'color',\r\n label: 'Stroke Color',\r\n name: 'strokeColor',\r\n value: this.attrs.strokeColor ?? this.getFreeColor(),\r\n }\r\n const fillColor = {\r\n type: 'color',\r\n label: 'Fill Color',\r\n name: 'fillColor',\r\n value: this.attrs.fillColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [emaPeriod, multiplier, atrPeriod, strokeColor, fillColor],\r\n inputsErrorMessages: {\r\n emaPeriod: `${emaPeriod.label} must be a whole number between ${emaPeriod.min} and ${emaPeriod.max}`,\r\n multiplier: `${multiplier.label} must be a number between ${multiplier.min} and ${multiplier.max}`,\r\n atrPeriod: `${atrPeriod.label} must be a whole number between ${atrPeriod.min} and ${atrPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'emaPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n case 'multiplier':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'atrPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n case 'strokeColor':\r\n case 'fillColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.strokeColor\r\n }\r\n\r\n toString() {\r\n return `Keltner Channel ${this.attrs.emaPeriod},${this.attrs.multiplier},${this.attrs.atrPeriod}`\r\n }\r\n}\r\n\r\nKeltnerChannel.prototype.defaults = { strokeColor: COLORS.Stroke, fillColor: COLORS.Fill }\r\n\r\nexport default KeltnerChannel\r\n","import { OverlayType } from '../constants/common'\r\nimport Overlay from './overlay'\r\n\r\n// This indicator is used as a placeholder when we need to render TA like chart but don't need any overlay or indicator in the chart\r\nclass None extends Overlay {\r\n static type = OverlayType.None\r\n static label = 'None'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n isRendered() {\r\n return false\r\n }\r\n\r\n getIsValid() {\r\n return true\r\n }\r\n}\r\n\r\nexport default None\r\n","import Text from '../canvas/text'\r\nimport { OverlayType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport Overlay from './overlay'\r\n\r\ntype aboveBelowType = 'above' | 'below'\r\n\r\nclass Patterns extends Overlay {\r\n static type = OverlayType.Patterns\r\n static label = 'Patterns (daily charts)'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const data = this.data\r\n if (data.patterns.length === 0) {\r\n return\r\n }\r\n\r\n const originalScale = {\r\n width: 600,\r\n height: 300,\r\n barsInDay: Math.min(data.close.length, 200),\r\n high: data.patternsMaxRange,\r\n low: data.patternsMinRange,\r\n barWidth: 0,\r\n }\r\n originalScale.barWidth = originalScale.width / 200\r\n\r\n const scaleY = (originalScale.high - originalScale.low) / originalScale.height\r\n const fx = (x: number) => {\r\n if (x === 0) {\r\n return this.fx(0)\r\n }\r\n return this.fx(data.close.length - 1 - ~~(originalScale.barsInDay - x / originalScale.barWidth))\r\n }\r\n const fy = (y: number) => this.fy(originalScale.high - y * scaleY)\r\n const line = (color: string, x1: number, y1: number, x2: number, y2: number) => {\r\n const roundedXY = getRoundedObject({\r\n x1: fx(x1),\r\n y1: fy(y1),\r\n x2: fx(x2),\r\n y2: fy(y2),\r\n })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: 1, ...roundedXY })\r\n context.translate(translateXY.x, translateXY.y)\r\n\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', color)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n }\r\n const text = (text: string, aboveBelow: aboveBelowType, color: string, x1: number, x2: number, y1: number) => {\r\n new Text(\r\n {\r\n x: fx((x1 + x2) / 2),\r\n y: fy(y1) + (aboveBelow === 'above' ? -1 : 2),\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: aboveBelow === 'above' ? TextBaseline.bottom : TextBaseline.top,\r\n fillStyle: color,\r\n textAlign: TextAlign.center,\r\n text,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n const textHS = (text: string, aboveBelow: aboveBelowType, color: string, x1: number, y1: number) => {\r\n new Text(\r\n {\r\n x: fx(x1) + 5,\r\n y: fy(y1) + (aboveBelow === 'above' ? -1 : 2),\r\n font: { size: 9, style: 'bold' },\r\n textBaseline: aboveBelow === 'above' ? TextBaseline.bottom : TextBaseline.top,\r\n fillStyle: color,\r\n textAlign: TextAlign.center,\r\n text,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n const above = (y: number) =>\r\n fy(y) + 10 >= this.model.height - ChartSettings.top.height - ChartSettings.bottom.height ? 'above' : 'below'\r\n const below = (y: number) => (fy(y) <= 15 ? 'below' : 'above')\r\n\r\n const supportColor = 'rgb(0, 150, 220)'\r\n const resistColor = 'rgb(180, 50, 200)'\r\n\r\n for (const pattern of data.patterns) {\r\n const { x1, x2, x3, y3 } = pattern\r\n let { y1, y2 } = pattern\r\n switch (pattern.kind) {\r\n case 1: // Horiz S/R\r\n line('rgba(50, 50, 180, 0.588)', x1, y1, x2, y2)\r\n break\r\n\r\n case 2: // tl resist\r\n line(resistColor, x1, y1, x2, y2)\r\n break\r\n\r\n case 3: // tl support\r\n if (y1 === originalScale.height && y2 === originalScale.height) {\r\n y1 = y2 = originalScale.height - 1\r\n // Maybe just need to check on the new scale?\r\n } // support \"pod grafom\"\r\n line(supportColor, x1, y1, x2, y2)\r\n break\r\n\r\n case 12: // double top\r\n text('Double Top', below(y1), resistColor, x1, x2, y1)\r\n break\r\n\r\n case 13: // double bottom\r\n text('Double Bottom', above(y1), supportColor, x1, x2, y1)\r\n break\r\n\r\n case 14: // multi top\r\n text('Multiple Top', below(y1), resistColor, x1, x2, y1)\r\n break\r\n\r\n case 15: // multi bottom\r\n text('Multiple Bottom', above(y1), supportColor, x1, x2, y1)\r\n break\r\n\r\n case 16: // h&s top\r\n textHS('L', below(y1), resistColor, x1, y1)\r\n textHS('H', below(y2), resistColor, x2, y2)\r\n textHS('R', below(y3), resistColor, x3, y3)\r\n break\r\n\r\n case 17: // h&s bot\r\n textHS('L', above(y1), supportColor, x1, y1)\r\n textHS('H', above(y2), supportColor, x2, y2)\r\n textHS('R', above(y3), supportColor, x3, y3)\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const supportColor = {\r\n type: 'color',\r\n label: 'Support Color',\r\n name: 'supportColor',\r\n value: this.attrs.supportColor ?? this.getFreeColor(),\r\n }\r\n const resistColor = {\r\n type: 'color',\r\n label: 'Resist Color',\r\n name: 'resistColor',\r\n value: this.attrs.resistColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [supportColor, resistColor],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid() {\r\n return true\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return false\r\n }\r\n\r\n toString() {\r\n return ''\r\n }\r\n}\r\n\r\nPatterns.prototype.defaults = { supportColor: '#69c1ea', resistColor: '#d386df' }\r\n\r\nexport default Patterns\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { Instrument } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { OverlayType, TIMEFRAME, TextBaseline } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport Utils from '../utils'\r\nimport { getBarWidthWithMargin, round } from '../utils/chart'\r\nimport { getFirstBarToRenderIndex, getLastBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport Overlay from './overlay'\r\n\r\nenum Calculation {\r\n standard = 'Standard',\r\n fibonacci = 'Fibonacci',\r\n}\r\ntype CalculationType = keyof typeof Calculation\r\n\r\nenum PivotPeriod {\r\n day,\r\n week,\r\n month,\r\n year,\r\n}\r\n\r\ntype PivotPointType = {\r\n pivot: number\r\n res1: number\r\n res2: number\r\n res3: number\r\n sup1: number\r\n sup2: number\r\n sup3: number\r\n}\r\n\r\ninterface Attrs {\r\n period?: string\r\n calculationType: CalculationType\r\n color: string\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n CalculationType: 'standard' as CalculationType,\r\n Color: '#FFA75F',\r\n}\r\nconst FIB_LVL_1 = 0.382\r\nconst FIB_LVL_2 = 0.618\r\nconst DAY_SECONDS = 86400\r\nconst MINUTES_PER_DAY = 1440\r\n\r\nclass PivotPoints extends Overlay {\r\n static type = OverlayType.Pp\r\n static label = 'Pivot Points'\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (period) {\r\n this.attrs.calculationType = period as CalculationType\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n getPeriodType() {\r\n switch (this.data.timeframe) {\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n return PivotPeriod.week\r\n case TIMEFRAME.h4:\r\n case TIMEFRAME.d:\r\n return PivotPeriod.month\r\n case TIMEFRAME.w:\r\n case TIMEFRAME.m:\r\n return PivotPeriod.year\r\n default:\r\n return PivotPeriod.day\r\n }\r\n }\r\n\r\n getIsEnoughData(startIndex: number, endIndex: number, periodType: PivotPeriod) {\r\n let dayGap = 7 // one week for week period\r\n if (periodType === PivotPeriod.month) dayGap = 28 // shortest month\r\n if (periodType === PivotPeriod.year) dayGap = 365\r\n\r\n if (startIndex !== endIndex) {\r\n if (startIndex === 0) {\r\n const daysDiff = (this.data.date[endIndex] - this.data.date[startIndex]) / DAY_SECONDS\r\n // we need to somehow determine if we have data if it starts from index 0\r\n // and we can't easily check if day before is different (different month/week/year)\r\n // so we are at least checking if it is [dayGap] days between start and end date\r\n return daysDiff >= dayGap\r\n } else {\r\n const startDay = Utils.dateFromUnixTimestamp(this.data.date[startIndex])\r\n const beforeDay = Utils.dateFromUnixTimestamp(this.data.date[startIndex - 1])\r\n if (periodType === PivotPeriod.week) {\r\n return beforeDay.getDate() !== startDay.getDate()\r\n } else {\r\n return beforeDay.getMonth() !== startDay.getMonth()\r\n }\r\n }\r\n }\r\n return false\r\n }\r\n\r\n fx = (x: number) => {\r\n const lastIndex = this.data.close.length - 1\r\n const outsideBar = this.data.barIndex[lastIndex] + x - lastIndex\r\n\r\n return this.model.scale.x(this.data.barIndex[x] ?? outsideBar)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n if (this.data.close.length === 0) return\r\n\r\n const chartModel = this.model.chart() as Chart\r\n const { leftOffset, width, zoomFactor } = chartModel\r\n const { left, right } = chartModel.getChartLayoutSettings().ChartSettings\r\n const chartWidth = width - left.width - right.width\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n\r\n const firstBarToRender = getFirstBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n })\r\n const lastBarToRender = getLastBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n chartWidth,\r\n })\r\n\r\n const text = (label: string, price: number, calculatedX: number) => {\r\n new Text(\r\n {\r\n x: calculatedX,\r\n y: this.fy(price) - 13,\r\n font: { size: 8, weight: '900' },\r\n textBaseline: TextBaseline.top,\r\n fillStyle: this.attrs.color,\r\n text: `${label} (${round({ data: this.data, num: price })})`,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n const line = (fromX: number, toX: number, y: number) => {\r\n context.moveTo(fromX, this.fy(y))\r\n context.lineTo(toX, this.fy(y))\r\n }\r\n\r\n let startIndex = -1\r\n let endIndex = -1\r\n const isStock = this.data.instrument === Instrument.Stock\r\n const periodType = this.getPeriodType()\r\n let currentDate = new Date()\r\n let lastDate: Date | undefined\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n for (let index = firstBarToRender; index <= lastBarToRender; index++) {\r\n currentDate = Utils.dateFromUnixTimestamp(this.data.date[index])\r\n\r\n // check if new calculation/render is necessary\r\n switch (periodType) {\r\n case PivotPeriod.day: // only if it is a new day\r\n if (currentDate.getDate() === lastDate?.getDate()) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.week: // only if it is a new week\r\n if (lastDate && dateFns.isSameWeek(lastDate, currentDate, { weekStartsOn: 1 })) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.month: // only if it is a new month\r\n if (currentDate.getMonth() === lastDate?.getMonth()) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.year: // only if it is a new year\r\n if (currentDate.getFullYear() === lastDate?.getFullYear()) {\r\n continue\r\n }\r\n break\r\n }\r\n lastDate = currentDate\r\n\r\n // Find start/end indexes for the entire previous period\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n if (index > 0) {\r\n let previousTradingDay = new Date()\r\n for (let i = index - 1; i >= 0; i--) {\r\n previousTradingDay = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (previousTradingDay.getDate() !== currentDate.getDate()) break\r\n }\r\n previousTradingDay.setHours(0, 0, 0, 0)\r\n const previousNYMidnightTimestamp = Utils.convertLocalToNyTime(previousTradingDay, false).getTime() / 1000\r\n const currentMidnight = new Date(currentDate)\r\n currentMidnight.setHours(0, 0, 0, 0)\r\n const currentNYMidnightTimestamp = Utils.convertLocalToNyTime(currentMidnight, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= previousNYMidnightTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > currentNYMidnightTimestamp)\r\n\r\n // check if we have data for entire day\r\n if (startIndex !== endIndex) {\r\n const diff = this.data.date[endIndex] - this.data.date[startIndex]\r\n const isNonStockFullDay = !isStock && diff >= DAY_SECONDS\r\n const isStockFullDay = isStock && previousTradingDay.getDate() !== currentDate.getDate()\r\n if (!isNonStockFullDay && !isStockFullDay) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n }\r\n }\r\n break\r\n case PivotPeriod.week:\r\n const firstDayCurrentWeek = dateFns.startOfWeek(currentDate, { weekStartsOn: 1 })\r\n const firstDayCurrentWeekTimestamp = Utils.convertLocalToNyTime(firstDayCurrentWeek, false).getTime() / 1000\r\n const firstDayPreviousWeek = dateFns.sub(firstDayCurrentWeek, { weeks: 1 })\r\n const firstDayPreviousWeekTimestamp = Utils.convertLocalToNyTime(firstDayPreviousWeek, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousWeekTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentWeekTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n case PivotPeriod.month:\r\n const firstDayCurrentMonth = dateFns.startOfMonth(currentDate)\r\n const firstDayCurrentMonthTimestamp = Utils.convertLocalToNyTime(firstDayCurrentMonth, false).getTime() / 1000\r\n const firstDayPreviousMonth = dateFns.sub(firstDayCurrentMonth, { months: 1 })\r\n const firstDayPreviousMonthTimestamp =\r\n Utils.convertLocalToNyTime(firstDayPreviousMonth, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousMonthTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentMonthTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n case PivotPeriod.year:\r\n const firstDayCurrentYear = dateFns.startOfYear(currentDate)\r\n const firstDayCurrentYearTimestamp = Utils.convertLocalToNyTime(firstDayCurrentYear, false).getTime() / 1000\r\n const firstDayPreviousYear = dateFns.sub(firstDayCurrentYear, { years: 1 })\r\n const firstDayPreviousYearTimestamp = Utils.convertLocalToNyTime(firstDayPreviousYear, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousYearTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentYearTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n }\r\n\r\n // calculate pivot point if it was found\r\n if (!(startIndex !== -1 && endIndex !== -1 && startIndex < endIndex)) continue\r\n\r\n let pivot, sup1, sup2, sup3, res1, res2, res3\r\n const previousHigh = Math.max(...this.data.high.slice(startIndex, endIndex))\r\n const previousLow = Math.min(...this.data.low.slice(startIndex, endIndex))\r\n const previousClose = this.data.close[endIndex - 1] // endIndex is the beginning of the next period\r\n\r\n if (this.attrs.calculationType === 'standard') {\r\n pivot = (previousHigh + previousLow + previousClose) / 3\r\n sup1 = 2 * pivot - previousHigh\r\n sup2 = pivot - (previousHigh - previousLow)\r\n sup3 = previousLow - 2 * (previousHigh - pivot)\r\n res1 = 2 * pivot - previousLow\r\n res2 = pivot + (previousHigh - previousLow)\r\n res3 = previousHigh + 2 * (pivot - previousLow)\r\n } else {\r\n pivot = (previousHigh + previousLow + previousClose) / 3\r\n sup1 = pivot - (previousHigh - previousLow) * FIB_LVL_1\r\n sup2 = pivot - (previousHigh - previousLow) * FIB_LVL_2\r\n sup3 = pivot - (previousHigh - previousLow)\r\n res1 = pivot + (previousHigh - previousLow) * FIB_LVL_1\r\n res2 = pivot + (previousHigh - previousLow) * FIB_LVL_2\r\n res3 = pivot + (previousHigh - previousLow)\r\n }\r\n\r\n const pivotPoint: PivotPointType = { pivot, sup1, sup2, sup3, res1, res2, res3 }\r\n\r\n // prepare x coordinates for lines rendering\r\n let fromX = this.fx(index)\r\n let toX = this.fx(index)\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n const interval = this.data.interval\r\n const currentX = fromX\r\n\r\n const toDate = new Date(currentDate)\r\n toDate.setHours(16, 0, 0, 0)\r\n if (this.data.aftermarket && interval <= 5) toDate.setHours(18, 30, 0, 0)\r\n if (interval <= 15 && !isStock) toDate.setHours(23, 59, 59, 99)\r\n const toTimestamp = toDate.getTime() / 1000\r\n const toDiffMinutes = (toTimestamp - currentDate.getTime() / 1000) / 60\r\n const toBars = toDiffMinutes / interval\r\n toX = Math.min(currentX + toBars * barWidth, -leftOffset + width)\r\n\r\n const fromDate = new Date(currentDate)\r\n fromDate.setHours(9, 30, 0, 0)\r\n if (this.data.premarket && interval <= 5) fromDate.setHours(7, 0, 0, 0)\r\n if (interval <= 15 && !isStock) fromDate.setHours(0, 0, 0, 0)\r\n const fromTimestamp = fromDate.getTime() / 1000\r\n const fromDiffMinutes = (fromTimestamp - currentDate.getTime() / 1000) / 60\r\n const fromBars = fromDiffMinutes / interval\r\n fromX = currentX + fromBars * barWidth\r\n break\r\n\r\n case PivotPeriod.week:\r\n for (let i = index + 1; i <= lastBarToRender; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (!dateFns.isSameWeek(currentDate, nextDate, { weekStartsOn: 1 })) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (!dateFns.isSameWeek(currentDate, nextDate, { weekStartsOn: 1 })) {\r\n fromX = this.fx(i + 1) // because we need start from current week\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the week\r\n const barsPerDay = Math.ceil((this.data.drawMinutesPerDay ?? MINUTES_PER_DAY) / this.data.interval)\r\n toX += (isStock ? 5 : 7) * barsPerDay * barWidth\r\n }\r\n break\r\n\r\n case PivotPeriod.month:\r\n for (let i = index + 1; i <= lastBarToRender; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getMonth() !== currentDate.getMonth()) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getMonth() !== currentDate.getMonth()) {\r\n fromX = this.fx(i + 1) // because we need start from current month\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the month\r\n const barsPerDay = this.data.isIntraday\r\n ? Math.ceil((this.data.drawMinutesPerDay ?? MINUTES_PER_DAY) / this.data.interval)\r\n : 1\r\n toX += (isStock ? 20 : 30) * barsPerDay * barWidth\r\n }\r\n break\r\n default:\r\n for (let i = index + 1; i <= lastBarToRender; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getFullYear() !== currentDate.getFullYear()) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getFullYear() !== currentDate.getFullYear()) {\r\n fromX = this.fx(i + 1) // because we need start from current year\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the year\r\n toX += (this.data.timeframe === TIMEFRAME.w ? 49 : 12) * barWidth\r\n }\r\n break\r\n }\r\n fromX = Math.max(fromX, -leftOffset)\r\n\r\n // render pivot line\r\n context.beginPath()\r\n line(fromX, toX, pivotPoint.pivot)\r\n context.stroke()\r\n\r\n // render resistance and support lines\r\n context.save()\r\n context.setLineDash([3, 3])\r\n context.beginPath()\r\n line(fromX, toX, pivotPoint.res1)\r\n line(fromX, toX, pivotPoint.res2)\r\n line(fromX, toX, pivotPoint.res3)\r\n line(fromX, toX, pivotPoint.sup1)\r\n line(fromX, toX, pivotPoint.sup2)\r\n line(fromX, toX, pivotPoint.sup3)\r\n context.stroke()\r\n context.restore()\r\n\r\n // render labels if there is enough space\r\n if (toX - fromX >= 48) {\r\n text('P', pivotPoint.pivot, fromX)\r\n text('R1', pivotPoint.res1, fromX)\r\n text('R2', pivotPoint.res2, fromX)\r\n text('R3', pivotPoint.res3, fromX)\r\n text('S1', pivotPoint.sup1, fromX)\r\n text('S2', pivotPoint.sup2, fromX)\r\n text('S3', pivotPoint.sup3, fromX)\r\n }\r\n }\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const calculationType = {\r\n type: 'select',\r\n label: 'Calculation Type',\r\n name: 'calculationType',\r\n value: this.attrs.calculationType ?? DEFAULT_PARAMETERS.CalculationType,\r\n required: true,\r\n items: [\r\n {\r\n value: 'standard',\r\n label: 'Standard',\r\n },\r\n {\r\n value: 'fibonacci',\r\n label: 'Fibonacci',\r\n },\r\n ],\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [calculationType, color],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'calculationType':\r\n case 'color':\r\n return !!this.attrs[key]\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Pivot Points (${Calculation[this.attrs.calculationType]})`\r\n }\r\n}\r\n\r\nPivotPoints.prototype.defaults = {\r\n calculationType: DEFAULT_PARAMETERS.CalculationType,\r\n color: DEFAULT_PARAMETERS.Color,\r\n}\r\n\r\nexport default PivotPoints\r\n","import { OverlayType } from '../constants/common'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n step: number\r\n period: string\r\n maxStep: number\r\n risingColor: string\r\n fallingColor: string\r\n}\r\n\r\nclass SAR extends Overlay {\r\n static type = OverlayType.Sar\r\n static label = 'Parabolic SAR'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (typeof this.attrs.period === 'string' && (this.attrs.step === undefined || this.attrs.maxStep === undefined)) {\r\n const [step = 0, maxStep = 0] = this.attrs.period.split(',').map((x) => parseFloat(x))\r\n this.attrs.step = step\r\n this.attrs.maxStep = maxStep\r\n }\r\n this.trigger('change')\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const data = this.data\r\n const deltaHigh = data.high[1] - data.high[0]\r\n const deltaLow = data.low[0] - data.low[1]\r\n const pdm = deltaHigh > 0 && deltaHigh > deltaLow ? deltaHigh : 0\r\n const mdm = deltaLow > 0 && deltaLow > deltaHigh ? deltaLow : 0\r\n let isLong = pdm >= mdm\r\n\r\n let sar = isLong ? data.low[0] : data.high[0]\r\n let ep = isLong ? data.high[1] : data.low[1]\r\n let newHigh = data.high[0]\r\n let newLow = data.low[0]\r\n let af = this.attrs.step\r\n\r\n for (let i = 1, end = data.close.length, asc = end >= 1; asc ? i < end : i > end; asc ? i++ : i--) {\r\n let sarToDraw\r\n const prevHigh = newHigh\r\n const prevLow = newLow\r\n newHigh = data.high[i]\r\n newLow = data.low[i]\r\n\r\n if (isLong) {\r\n if (newLow <= sar) {\r\n isLong = false\r\n sar = ep\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n\r\n sarToDraw = sar\r\n\r\n af = this.attrs.step\r\n ep = newLow\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n } else {\r\n sarToDraw = sar\r\n\r\n if (newHigh > ep) {\r\n ep = newHigh\r\n af += this.attrs.step\r\n if (af > this.attrs.maxStep) {\r\n af = this.attrs.maxStep\r\n }\r\n }\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n }\r\n } else {\r\n if (newHigh >= sar) {\r\n isLong = true\r\n sar = ep\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n\r\n sarToDraw = sar\r\n\r\n af = this.attrs.step\r\n ep = newHigh\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n } else {\r\n sarToDraw = sar\r\n\r\n if (newLow < ep) {\r\n ep = newLow\r\n af += this.attrs.step\r\n if (af > this.attrs.maxStep) {\r\n af = this.attrs.maxStep\r\n }\r\n }\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n }\r\n }\r\n\r\n const x = Math.round(this.fx(i) - 1.5)\r\n const y = Math.round(this.fy(sarToDraw) - 1.5)\r\n context.set('fillStyle', isLong ? this.attrs.risingColor : this.attrs.fallingColor)\r\n context.fillRect(x, y, 3, 3)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const step = {\r\n type: 'number',\r\n step: 0.01,\r\n min: 0.01,\r\n max: 999,\r\n label: 'Step',\r\n name: 'step',\r\n value: this.attrs.step ?? 0.02,\r\n required: true,\r\n }\r\n const maxStep = {\r\n type: 'number',\r\n step: 0.01,\r\n min: 0.01,\r\n max: 999,\r\n label: 'Maximum Step',\r\n name: 'maxStep',\r\n value: this.attrs.maxStep ?? 0.2,\r\n required: true,\r\n }\r\n const risingColor = {\r\n type: 'color',\r\n label: 'Rising Color',\r\n name: 'risingColor',\r\n value: this.attrs.risingColor ?? this.getFreeColor(),\r\n customizable: false,\r\n }\r\n const fallingColor = {\r\n type: 'color',\r\n label: 'Falling Color',\r\n name: 'fallingColor',\r\n value: this.attrs.fallingColor ?? this.getFreeColor(),\r\n customizable: false,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [step, maxStep, risingColor, fallingColor],\r\n inputsErrorMessages: {\r\n step: `${step.label} must be a number between ${step.min} and ${step.max}`,\r\n maxStep: `${maxStep.label} must be a number between ${maxStep.min} and ${maxStep.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'step':\r\n case 'maxStep': {\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n }\r\n case 'risingColor':\r\n case 'fallingColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.risingColor\r\n }\r\n\r\n toString() {\r\n return `SAR ${this.attrs.step},${this.attrs.maxStep}`\r\n }\r\n}\r\n\r\nSAR.prototype.defaults = {\r\n risingColor: '#69c1ea',\r\n fallingColor: '#d386df',\r\n}\r\n\r\nexport default SAR\r\n","import { OverlayType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n}\r\n\r\nexport class SMACalculation extends MainCalculation {\r\n static type = OverlayType.Sma\r\n declare options: Options\r\n\r\n getDefaultCalculatedValues() {\r\n return { sma: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sum = 0\r\n for (let i = 0; i < this.options.period; i++) {\r\n sum += close[i]\r\n }\r\n for (let i = this.options.period; i <= lastIndex; i++) {\r\n sum = sum - close[i - this.options.period] + close[i]\r\n this.calculatedValues.sma[i] = sum / this.options.period\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { SMACalculation } from '../indicator-calculation/sma'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n step: number\r\n period: string\r\n maxStep: number\r\n risingColor: string\r\n color: string\r\n}\r\n\r\nclass SMA extends Overlay {\r\n static type = OverlayType.Sma\r\n static label = 'Simple Moving Average'\r\n\r\n static getNumOfBarsBuffer(chartConfig: RequireByKey) {\r\n const numOfBarsBuffer = Overlay.getNumOfBarsBuffer(chartConfig)\r\n return numOfBarsBuffer + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const period = Math.min(this.attrs.period, this.data.close.length - 1)\r\n context.beginPath()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n const smaCalculation = new SMACalculation({\r\n quote: this.data,\r\n options: { period },\r\n })\r\n\r\n smaCalculation.calculate(({ sma }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n context.lineTo(x, Math.round(this.fy(sma[dataIndex])))\r\n })\r\n\r\n context.translate(-0.5, -0.5)\r\n context.stroke()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, color],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `SMA ${this.attrs.period}`\r\n }\r\n}\r\n\r\nSMA.prototype.defaults = { color: '#ffa75f' }\r\n\r\nexport default SMA\r\n","import { OverlayType } from '../constants/common'\r\nimport SMA from './sma'\r\n\r\nclass SMA2 extends SMA {\r\n static type = OverlayType.Sma2\r\n}\r\n\r\nSMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default SMA2\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n multiplier: number\r\n uptrendColor: string\r\n downtrendColor: string\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 7,\r\n Multiplier: 3.0,\r\n}\r\n\r\nconst COLORS = {\r\n Uptrend: '#00a000',\r\n Downtrend: '#c80000',\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const multiplier = parseFloat(values[1]) || DEFAULT_PARAMETERS.Multiplier\r\n\r\n return [period, multiplier]\r\n}\r\n\r\nclass Supertrend extends Overlay {\r\n static type = OverlayType.Str\r\n static label = 'Supertrend'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt] = parsePeriod(period)\r\n return periodInt + 1\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, multiplier] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.multiplier = multiplier\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { period, multiplier } = this.attrs\r\n const { high, low, close } = this.data\r\n const atr = new AverageTrueRange(period)\r\n const finalUpperBand: number[] = []\r\n const finalLowerBand: number[] = []\r\n const supertrend: boolean[] = []\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.uptrendColor)\r\n for (let i = 1; i < close.length; i++) {\r\n atr.add(high[i], low[i], close[i - 1])\r\n\r\n // compute bands\r\n const avg = (high[i] + low[i]) / 2\r\n const upperBand = avg + multiplier * atr.value\r\n const lowerBand = avg - multiplier * atr.value\r\n\r\n finalUpperBand[i] = upperBand\r\n finalLowerBand[i] = lowerBand\r\n\r\n // identify supertrend\r\n if (close[i] > finalUpperBand[i - 1]) {\r\n supertrend[i] = true\r\n } else if (close[i] < finalLowerBand[i - 1]) {\r\n supertrend[i] = false\r\n } else {\r\n supertrend[i] = supertrend[i - 1]\r\n }\r\n\r\n // adjust bands\r\n if (supertrend[i] && finalLowerBand[i] < finalLowerBand[i - 1]) {\r\n finalLowerBand[i] = finalLowerBand[i - 1]\r\n }\r\n if (!supertrend[i] && finalUpperBand[i] > finalUpperBand[i - 1]) {\r\n finalUpperBand[i] = finalUpperBand[i - 1]\r\n }\r\n\r\n const x = this.fx(i)\r\n if (i < period || x + leftOffset < 0) {\r\n continue\r\n }\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n\r\n if (supertrend[i] && !supertrend[i - 1]) {\r\n // buy\r\n context.moveTo(this.fx(i - 1), Math.round(this.fy(finalUpperBand[i - 1])))\r\n context.lineTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n } else if (supertrend[i]) {\r\n // keep buying\r\n context.lineTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n } else {\r\n // keep selling\r\n context.moveTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n }\r\n lastBarToRender = i\r\n }\r\n context.stroke()\r\n\r\n if (firstBarToRender === undefined) {\r\n context.translate(-0.5, -0.5)\r\n return\r\n }\r\n\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.downtrendColor)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n if (!supertrend[i] && supertrend[i - 1]) {\r\n // sell\r\n context.moveTo(this.fx(i - 1), Math.round(this.fy(finalLowerBand[i - 1])))\r\n context.lineTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n } else if (!supertrend[i]) {\r\n // keep selling\r\n context.lineTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n } else {\r\n // keep buying\r\n context.moveTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n }\r\n }\r\n context.stroke()\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const multiplier = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'multiplier',\r\n value: this.attrs.multiplier ?? DEFAULT_PARAMETERS.Multiplier,\r\n required: true,\r\n step: 0.1,\r\n min: 0.0,\r\n max: 999,\r\n }\r\n\r\n const uptrendColor = {\r\n type: 'color',\r\n label: 'Uptrend Color',\r\n name: 'uptrendColor',\r\n value: this.attrs.uptrendColor ?? this.getFreeColor(),\r\n }\r\n const downtrendColor = {\r\n type: 'color',\r\n label: 'Downtrend Color',\r\n name: 'downtrendColor',\r\n value: this.attrs.downtrendColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, multiplier, uptrendColor, downtrendColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n multiplier: `${multiplier.label} must be a number between ${multiplier.min} and ${multiplier.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'multiplier':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'uptrendColor':\r\n case 'downtrendColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor(): string {\r\n return this.attrs.uptrendColor\r\n }\r\n\r\n toString() {\r\n return `Supertrend ${this.attrs.period},${this.attrs.multiplier}`\r\n }\r\n}\r\n\r\nSupertrend.prototype.defaults = {\r\n uptrendColor: COLORS.Uptrend,\r\n downtrendColor: COLORS.Downtrend,\r\n}\r\n\r\nexport default Supertrend\r\n","import * as d3 from 'd3'\r\n\r\nimport { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport utils from '../utils'\r\nimport { convertColorToHEX, getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { getFirstBarToRenderIndex, getLastBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\nconst VP_COLORS = {\r\n UP: '#00FF00',\r\n DOWN: '#FF0000',\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 20,\r\n Opacity: 0.3,\r\n}\r\n\r\ninterface Attrs {\r\n period: number | string\r\n opacity: number\r\n upColor?: string\r\n downColor?: string\r\n}\r\n\r\nfunction applyOpacityToColor(color: string, opacity: number) {\r\n return getHEXWithSpecificAplha(convertColorToHEX(color), opacity)\r\n}\r\n\r\nfunction getColorsWithAppliedOpacity(attrs: Attrs) {\r\n return [\r\n applyOpacityToColor(attrs.upColor ?? VP_COLORS.UP, attrs.opacity),\r\n applyOpacityToColor(attrs.downColor ?? VP_COLORS.DOWN, attrs.opacity),\r\n ]\r\n}\r\n\r\n// Only time when we want value to be able to equal start of segment is first segment,\r\n// because start of next segment is equal to end of previous and value would match two segments\r\nfunction isInSegment(val: number, start: number, end: number, notEqualStart: boolean) {\r\n return (notEqualStart ? val > start : val >= start) && val <= end\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const opacity = parseFloat(values[1]) || DEFAULT_PARAMETERS.Opacity\r\n\r\n return [period, opacity]\r\n}\r\n\r\nclass VolumeProfile extends Overlay {\r\n static type = OverlayType.Vp\r\n static label = 'Volume Profile'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, opacity] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.opacity = opacity\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (typeof this.attrs.period !== 'number') {\r\n return\r\n }\r\n super.renderContent()\r\n\r\n const chartModel = this.model.chart() as Chart\r\n const { leftOffset, width } = chartModel\r\n const { left, right } = chartModel.getChartLayoutSettings().ChartSettings\r\n const chartWidth = width - left.width - right.width\r\n\r\n if (this.data.close.length === 0) return\r\n\r\n const firstBarToRender = getFirstBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n })\r\n\r\n const lastBarToRender = getLastBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n chartWidth,\r\n })\r\n\r\n const [upColor, downColor] = getColorsWithAppliedOpacity(this.attrs)\r\n const [minClose, maxClose] = utils.minMax(this.data.close.slice(firstBarToRender, lastBarToRender + 1))\r\n\r\n const segment = Math.abs(maxClose - minClose) / this.attrs.period\r\n const segments = [] // create an empty array to hold the segments\r\n\r\n for (let i = 0; i < this.attrs.period; i++) {\r\n const segmentStart = minClose + segment * i // calculate start of current segment\r\n const segmentEnd = segmentStart + segment // calculate end of current segment\r\n segments.push({ start: segmentStart, end: segmentEnd, up: 0, down: 0 }) // add segment to array\r\n }\r\n\r\n // loop through visible bars and assign volumes to segments\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const segmentIndex: number = segments.findIndex((item, segmentIndex) =>\r\n isInSegment(this.data.close[i], item.start, item.end, !!segmentIndex)\r\n )\r\n if (segmentIndex === -1) continue\r\n const volumeTrend = this.data.close[i] < this.data.open[i] ? 'down' : 'up'\r\n segments[segmentIndex][volumeTrend] += this.data.volume[i]\r\n }\r\n\r\n const max = utils.max(segments.map((item) => item.up + item.down))\r\n const rangeMax = chartWidth * 0.4 // maximum range in pixels where longest bar would reach (now it's 40% of chart width)\r\n const volumeFX = d3.scaleLinear().range([0, rangeMax]).domain([0, max])\r\n\r\n segments.forEach((item) => {\r\n const y = Math.round(this.fy(item.start))\r\n const segmentHeightRaw = Math.round(this.fy(item.end)) - y // raw segment height without gap between segments\r\n const segmentHeight = segmentHeightRaw + (Math.abs(segmentHeightRaw) > 5 ? 2 : 1) // apply gap to segment based on how high segment is\r\n const x = Math.abs(leftOffset) // segments are alligned to left side of chart which equal to absoulute value of leftOffset\r\n const upSegmentWidth = Math.round(volumeFX(item.up))\r\n const downSegmentWidth = Math.round(volumeFX(item.down))\r\n\r\n context.fillStyle = upColor\r\n context.fillRect(x, y, upSegmentWidth, segmentHeight)\r\n context.fillStyle = downColor\r\n context.fillRect(x + upSegmentWidth, y, downSegmentWidth, segmentHeight)\r\n })\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Zones',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const opacity = {\r\n type: 'number',\r\n label: 'Opacity',\r\n name: 'opacity',\r\n value: this.attrs.opacity ?? DEFAULT_PARAMETERS.Opacity,\r\n required: true,\r\n min: 0,\r\n max: 1,\r\n step: 0.1,\r\n }\r\n const upColor = {\r\n type: 'color',\r\n label: 'Up Color',\r\n name: 'upColor',\r\n value: this.attrs.upColor ?? VP_COLORS.UP,\r\n }\r\n const downColor = {\r\n type: 'color',\r\n label: 'Down Color',\r\n name: 'downColor',\r\n value: this.attrs.downColor ?? VP_COLORS.DOWN,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, opacity, upColor, downColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n opacity: `${opacity.label} must be a number between ${opacity.min} and ${opacity.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'opacity':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'upColor':\r\n case 'downColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.upColor || VP_COLORS.UP\r\n }\r\n\r\n toString() {\r\n return `VP ${this.attrs.period}`\r\n }\r\n}\r\n\r\nVolumeProfile.prototype.defaults = { upColor: VP_COLORS.UP, downColor: VP_COLORS.DOWN }\r\n\r\nexport default VolumeProfile\r\n","import { OverlayType } from '../constants/common'\r\nimport { dateFromUnixTimestamp } from '../utils'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\nconst datesAreOnSameDay = (first: Date, second: Date) =>\r\n first.getFullYear() === second.getFullYear() &&\r\n first.getMonth() === second.getMonth() &&\r\n first.getDate() === second.getDate()\r\n\r\ntype DefaultCalculatedValuesType = {\r\n vwap: number[]\r\n}\r\n\r\nexport class VWapCalculation extends MainCalculation {\r\n static type = OverlayType.Vwap\r\n\r\n getDefaultCalculatedValues() {\r\n return { vwap: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { date, close, low, high, volume } = this.quote\r\n const lastIndex = date.length - 1\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let cumulativePV = 0\r\n let cumulativeVolume = 0\r\n\r\n for (let i = 0; i <= lastIndex; i++) {\r\n if (i > 0) {\r\n const prevDate = dateFromUnixTimestamp(date[i - 1])\r\n if (!datesAreOnSameDay(prevDate, dateFromUnixTimestamp(date[i]))) {\r\n cumulativePV = 0\r\n cumulativeVolume = 0\r\n }\r\n }\r\n\r\n const typicalPrice = (close[i] + low[i] + high[i]) / 3\r\n const pv = typicalPrice * volume[i]\r\n\r\n cumulativePV += pv\r\n cumulativeVolume += volume[i]\r\n\r\n this.calculatedValues.vwap[i] = cumulativePV / cumulativeVolume\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { OverlayType } from '../constants/common'\r\nimport { VWapCalculation } from '../indicator-calculation/vwap'\r\nimport PaneModel from '../models/pane'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n color: string\r\n}\r\n\r\nclass VWAP extends Overlay {\r\n static type = OverlayType.Vwap\r\n static label = 'VWAP (intraday charts)'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 1\r\n }\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.attrs.period = 5\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n if (!this.isRendered()) {\r\n return\r\n }\r\n\r\n const { leftOffset, width } = this.model.chart()\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n const vwapCalculation = new VWapCalculation({\r\n quote: this.data,\r\n options: { period: this.attrs.period },\r\n })\r\n\r\n vwapCalculation.calculate(({ vwap }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return // continue\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false // break\r\n }\r\n const y = Math.round(this.fy(vwap[dataIndex]))\r\n context.lineTo(x, y)\r\n })\r\n\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [color],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'color':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n isRendered() {\r\n return this.model.chart().quote().isIntraday\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return this.isRendered()\r\n }\r\n\r\n toString() {\r\n return `VWAP`\r\n }\r\n}\r\n\r\nVWAP.prototype.defaults = { color: '#9467bd' }\r\n\r\nexport default VWAP\r\n","import { OverlayType } from '../constants/common'\r\nimport bb from './bb'\r\nimport dch from './dch'\r\nimport ema from './ema'\r\nimport ema2 from './ema2'\r\nimport hilo from './hilo'\r\nimport hline from './hline'\r\nimport ic from './ic'\r\nimport icf from './icf'\r\nimport kch from './kch'\r\nimport none from './none'\r\nimport overlay from './overlay'\r\nimport patterns from './patterns'\r\nimport pp from './pp'\r\nimport sar from './sar'\r\nimport sma from './sma'\r\nimport sma2 from './sma2'\r\nimport str from './str'\r\nimport vp from './vp'\r\nimport vwap from './vwap'\r\n\r\nexport const overlaysByType = Object.freeze({\r\n [OverlayType.Overlay]: overlay,\r\n [OverlayType.None]: none,\r\n [OverlayType.Bb]: bb,\r\n [OverlayType.Dch]: dch,\r\n [OverlayType.Ema]: ema,\r\n [OverlayType.Ema2]: ema2,\r\n [OverlayType.Hilo]: hilo,\r\n [OverlayType.Hline]: hline,\r\n [OverlayType.Ic]: ic,\r\n [OverlayType.Icf]: icf,\r\n [OverlayType.Kch]: kch,\r\n [OverlayType.Patterns]: patterns,\r\n [OverlayType.Pp]: pp,\r\n [OverlayType.Sar]: sar,\r\n [OverlayType.Sma]: sma,\r\n [OverlayType.Sma2]: sma2,\r\n [OverlayType.Str]: str,\r\n [OverlayType.Vp]: vp,\r\n [OverlayType.Vwap]: vwap,\r\n})\r\n","import {\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n PREMARKET_AFTERMARKET_HOURS,\r\n SpecificChartFunctionality,\r\n} from './constants/common'\r\nimport { captureException, getIsSSr } from './utils/helpers'\r\n\r\nexport { getSanitizedTicker } from './utils/ticker-sanitizer'\r\n\r\nfunction getIsDstInNy(date: Date) {\r\n const dayNumber = date.getDate()\r\n const monthIndex = date.getMonth()\r\n const dayOfWeek = date.getDay()\r\n const previousSunday = dayNumber - dayOfWeek\r\n if (monthIndex < 2 || monthIndex > 10) {\r\n return false\r\n }\r\n if (monthIndex > 2 && monthIndex < 10) {\r\n return true\r\n }\r\n return monthIndex === 2 ? previousSunday >= 8 : previousSunday <= 0\r\n}\r\n\r\nclass Utils {\r\n static min(...args: T[]): number {\r\n if (typeof args[0] === 'number') {\r\n return args[0] < +args[1] ? args[0] : (args[1] as number)\r\n }\r\n let min = args[0][0]\r\n for (const arg of args) {\r\n for (const el of arg as number[]) {\r\n if (el < min) {\r\n min = el\r\n }\r\n }\r\n }\r\n return min\r\n }\r\n\r\n static max(...args: T[]): number {\r\n if (typeof args[0] === 'number') {\r\n return args[0] > +args[1] ? args[0] : (args[1] as number)\r\n }\r\n let max = args[0][0]\r\n for (const arg of args) {\r\n for (const el of arg as number[]) {\r\n if (el > max) {\r\n max = el\r\n }\r\n }\r\n }\r\n return max\r\n }\r\n\r\n static minMax(...args: number[][]) {\r\n let max\r\n let min = (max = args[0][0] as number)\r\n for (const arg of args) {\r\n for (const el of arg) {\r\n if (el < min) {\r\n min = el\r\n }\r\n if (el > max) {\r\n max = el\r\n }\r\n }\r\n }\r\n return [min, max]\r\n }\r\n\r\n static getScaleRatio() {\r\n return (typeof window !== 'undefined' && window.devicePixelRatio) || 1\r\n }\r\n\r\n static setSizeOnCanvasElement({\r\n canvasElement,\r\n width,\r\n height,\r\n ratio = Utils.getScaleRatio(),\r\n }: {\r\n canvasElement: HTMLCanvasElement | null\r\n width: number\r\n height: number\r\n ratio?: number\r\n }) {\r\n if (canvasElement) {\r\n canvasElement.width = width * ratio\r\n canvasElement.height = height * ratio\r\n canvasElement.style.width = width + 'px'\r\n canvasElement.style.height = height + 'px'\r\n }\r\n }\r\n\r\n static getQuoteDateTimestampOffsetInSeconds(referenceDate?: Date) {\r\n const date = referenceDate || new Date()\r\n const dateAsNY = new Date(\r\n date.getUTCFullYear(),\r\n date.getUTCMonth(),\r\n date.getUTCDate(),\r\n date.getUTCHours() - 5,\r\n date.getUTCMinutes(),\r\n date.getUTCSeconds()\r\n )\r\n const isDst = getIsDstInNy(dateAsNY)\r\n return (isDst ? 4 : 5) * 60 * 60\r\n }\r\n\r\n static convertLocalToNyTime(referenceDate: Date, addOffset: boolean) {\r\n const date = new Date(referenceDate)\r\n const quoteDateTimeOffsetInMs = Utils.getQuoteDateTimestampOffsetInSeconds(date) * 1000\r\n const localTimeOffsetInMs = date.getTimezoneOffset() * 60 * 1000\r\n const offsetDirectionCoefficient = addOffset ? 1 : -1\r\n date.setTime(date.getTime() + (localTimeOffsetInMs - quoteDateTimeOffsetInMs) * offsetDirectionCoefficient)\r\n return date\r\n }\r\n\r\n // Keep in sync with the clone in Website repo in shared/isStockFastRefreshAvailable.ts\r\n static isStockFastRefreshAvailable(hasPremarket = true, hasAftermarket = true, bufferMinutes = 30) {\r\n const MARKET_START = { hours: 9, minutes: 30 }\r\n const MARKET_END = { hours: 16, minutes: 0 }\r\n const getMinutes = ({ hours, minutes }: { hours: number; minutes: number }) => hours * 60 + minutes\r\n\r\n const date = convertLocalToNyTime(new Date(), true)\r\n const dayOfWeek = date.getDay()\r\n const currentDayMinutes = date.getHours() * 60 + date.getMinutes()\r\n\r\n const premarketMinutes = hasPremarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n const aftermarketMinutes = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n\r\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6\r\n const isOpen = getMinutes(MARKET_START) - premarketMinutes - bufferMinutes <= currentDayMinutes\r\n const isClosed = getMinutes(MARKET_END) + aftermarketMinutes + bufferMinutes <= currentDayMinutes\r\n return !isWeekend && isOpen && !isClosed\r\n }\r\n\r\n static dateFromUnixTimestamp(timestamp: number) {\r\n /*\r\n * Passing 0 as a param is needed in order to setUTCSeconds work properly.\r\n * The function adds seconds to the date instance if it exceeds 60.\r\n * For more info see the docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds\r\n * */\r\n const date = new Date(0)\r\n date.setUTCSeconds(timestamp)\r\n return Utils.convertLocalToNyTime(date, true)\r\n }\r\n\r\n static dateStringFromDate(date: Date) {\r\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(\r\n 2,\r\n '0'\r\n )}`\r\n }\r\n\r\n static dateFromDateString(dateString: string) {\r\n const [yyyy, mm, dd] = dateString.split('-')\r\n\r\n const date = new Date(Number.parseInt(yyyy), Number.parseInt(mm) - 1, Number.parseInt(dd))\r\n if (Number.isNaN(date.getTime())) {\r\n captureException(new Error('Invalid Date'), { extra: { date } })\r\n }\r\n\r\n return date\r\n }\r\n\r\n static isMobile(testTouchPoints?: boolean) {\r\n if (getIsSSr()) return false\r\n let isMobileOs = false\r\n\r\n // New iOS versions no longer report iPad in user agent\r\n if (navigator.userAgent.indexOf('Macintosh') > -1) {\r\n try {\r\n document.createEvent('TouchEvent')\r\n isMobileOs = true\r\n } catch (e) {}\r\n } else {\r\n isMobileOs = !!navigator.userAgent.match(\r\n /\\b(Android|webOS|i(?:Phone|Pad|Pod)|BlackBerry|Windows (?:Phone|Mobile))\\b/i\r\n )\r\n }\r\n\r\n if (testTouchPoints) {\r\n try {\r\n return (\r\n isMobileOs &&\r\n (window.navigator.msMaxTouchPoints ||\r\n window.navigator.maxTouchPoints ||\r\n 'ontouchstart' in document.createElement('div'))\r\n )\r\n } catch (e) {}\r\n }\r\n\r\n return isMobileOs\r\n }\r\n\r\n static isIPad() {\r\n const matchesIPad = navigator.userAgent.match(/iPad/i)\r\n const matchesIPhone = navigator.userAgent.match(/iPhone/i)\r\n const matchesIPod = navigator.userAgent.match(/iPod/i)\r\n const matchesIOSLike = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints > 0\r\n\r\n return (matchesIOSLike && !matchesIPhone && !matchesIPod) || matchesIPad\r\n }\r\n\r\n static getCookie(name: string) {\r\n const re = new RegExp('(?:(?:^|.*;\\\\s*)' + name + '\\\\s*\\\\=\\\\s*([^;]*).*$)|^.*$')\r\n return document.cookie.replace(re, '$1')\r\n }\r\n\r\n static setCookie(name: string, value: string, expires: Date) {\r\n let cookie = name + '=' + value + '; expires=' + expires.toUTCString()\r\n if (document.location.hostname !== 'localhost') {\r\n cookie += '; domain=.finviz.com'\r\n }\r\n document.cookie = cookie\r\n }\r\n}\r\n\r\nexport default Utils\r\nexport const convertLocalToNyTime = Utils.convertLocalToNyTime\r\nexport const dateFromUnixTimestamp = Utils.dateFromUnixTimestamp\r\nexport const dateStringFromDate = Utils.dateStringFromDate\r\nexport const dateFromDateString = Utils.dateFromDateString\r\n\r\nexport function getFullscreenStatus(): boolean {\r\n return (\r\n document.fullscreenElement ??\r\n document.webkitFullscreenElement ??\r\n document.mozFullScreenElement ??\r\n document.msFullscreenElement ??\r\n false\r\n )\r\n}\r\n\r\nexport function getRequestFullscreen(element: HTMLElement) {\r\n return (\r\n element.requestFullscreen ??\r\n element.webkitRequestFullScreen ??\r\n element.mozRequestFullScreen ??\r\n element.msRequestFullscreen\r\n )\r\n}\r\n\r\nexport function getExitFullscreen() {\r\n return (\r\n document.exitFullscreen ?? document.webkitExitFullscreen ?? document.mozExitFullScreen ?? document.msExitFullscreen\r\n )\r\n}\r\n\r\nexport function ready(fn: () => void) {\r\n if (document.readyState !== 'loading') {\r\n fn()\r\n return\r\n }\r\n\r\n document.addEventListener('DOMContentLoaded', fn)\r\n}\r\n\r\nexport function getChartsDimensions(chartElementId: string) {\r\n const PADDING = 2 // Border widths\r\n const containerElement = document.getElementById(chartElementId)\r\n\r\n const box = containerElement?.getBoundingClientRect()\r\n\r\n return {\r\n width: Math.max((box?.width ?? 0) - PADDING, 0),\r\n height: Math.max((box?.height ?? 0) - PADDING, 0),\r\n }\r\n}\r\n\r\nexport function getIsMobileScreenSize() {\r\n return window.innerWidth < MOBILE_VIEW_BREAKPOINT_WIDTH\r\n}\r\n\r\nexport function getIsMobilePortrait(isMobile?: boolean) {\r\n if (isMobile ?? Utils.isMobile()) {\r\n return window.orientation % 180 === 0\r\n }\r\n return false\r\n}\r\n\r\nexport function numberToStringWithUnitsSuffix(value: number) {\r\n let suffix = ''\r\n if (value >= 1000000000) {\r\n value /= 1000000000\r\n suffix = 'B'\r\n } else if (value >= 1000000) {\r\n value /= 1000000\r\n suffix = 'M'\r\n } else if (value >= 1000) {\r\n value /= 1000\r\n suffix = 'K'\r\n }\r\n\r\n return value.toFixed(2) + suffix\r\n}\r\n\r\nexport function isRedesignEnabled() {\r\n return typeof window !== 'undefined' && window.FinvizSettings?.hasRedesignEnabled\r\n}\r\n\r\nexport function isRedesignedPage(\r\n obj: { specificChartFunctionality?: SpecificChartFunctionality | null },\r\n matchingPages = [\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ]\r\n) {\r\n return (\r\n (isRedesignEnabled() && matchingPages.includes(obj.specificChartFunctionality!)) ||\r\n // Legacy design on quote uses redesigned elements (page header + chart controls)\r\n obj.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n )\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\n\r\nconst requestsAbortControllersCache: ObjectHash = {}\r\n\r\nexport function removeFromAbortCache(key: string) {\r\n delete requestsAbortControllersCache[key]\r\n}\r\n\r\nexport function abortRequest(key: string) {\r\n requestsAbortControllersCache[key]?.abort()\r\n removeFromAbortCache(key)\r\n}\r\n\r\nexport function getIsAbortError(error: Error) {\r\n return error.name === 'AbortError'\r\n}\r\n\r\nexport function createRequestAbortController({\r\n key,\r\n shouldAbortRunningRequest = false,\r\n}: {\r\n key: string\r\n shouldAbortRunningRequest?: boolean\r\n}) {\r\n if (shouldAbortRunningRequest) {\r\n abortRequest(key)\r\n }\r\n const controller = 'AbortController' in window ? new AbortController() : undefined\r\n if (controller) {\r\n requestsAbortControllersCache[key] = controller\r\n }\r\n return controller\r\n}\r\n","import { getIsSSr } from './helpers'\r\n\r\n// Extracted from isMobile, and modified to fit usage\r\nfunction isFirefoxDesktop() {\r\n const matchesAndroid = navigator.userAgent.match(/Android/i)\r\n const matchesWebOS = navigator.userAgent.match(/webOS/i)\r\n const matchesIPhone = navigator.userAgent.match(/iPhone/i)\r\n const matchesiPad = navigator.userAgent.match(/iPad/i)\r\n const matchesIPod = navigator.userAgent.match(/iPod/i)\r\n const matchesBlackBerry = navigator.userAgent.match(/BlackBerry/i)\r\n const matchesWindowsPhone = navigator.userAgent.match(/Windows Phone/i)\r\n const matchesIOSLike = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints > 0\r\n\r\n const isMobileDevice =\r\n matchesAndroid ||\r\n matchesWebOS ||\r\n matchesIPhone ||\r\n matchesiPad ||\r\n matchesIPod ||\r\n matchesBlackBerry ||\r\n matchesWindowsPhone ||\r\n matchesIOSLike\r\n\r\n const matchesFirefox = !!navigator.userAgent.match(/firefox/i)\r\n\r\n return matchesFirefox && !isMobileDevice\r\n}\r\n\r\n// Due bug in FireFox, when if HW acceleration is used canvas is blurry\r\n// we need to set canvas as CPU only\r\nconst shouldUseCPUOnly = getIsSSr() ? false : isFirefoxDesktop()\r\n\r\nexport function getContextWithCache(canvas: HTMLCanvasElement | null): CanvasRenderingContext2D | null {\r\n if (!canvas) {\r\n return null\r\n }\r\n\r\n const context = canvas.getContext('2d', shouldUseCPUOnly ? { willReadFrequently: true } : undefined)\r\n if (!context) {\r\n window.Sentry?.captureMessage('Context unavailable')\r\n return null\r\n }\r\n\r\n context._cache = {}\r\n\r\n const _restore = CanvasRenderingContext2D.prototype.restore\r\n context.restore = function () {\r\n this._cache = {}\r\n return _restore.apply(this)\r\n }\r\n\r\n context.set = function (key, value) {\r\n if (this._cache[key] !== value) {\r\n this[key] = value\r\n this._cache[key] = value\r\n }\r\n }\r\n\r\n return context\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { ChartConfigChartPane, Instrument, ObjectHash } from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport { chartsByType } from '../charts/charts'\r\nimport {\r\n CRYPTOS,\r\n ChartEditorEnum,\r\n ChartElementType,\r\n OFFSET,\r\n PADDING,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TIMEFRAME_SECONDS,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getPercentageFromValue } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport ChartLayoutModel from '../models/chart_layout'\r\nimport { IChartSettings } from '../models/chart_settings/interfaces'\r\nimport { Mouse } from '../models/mouse'\r\nimport Pane from '../models/pane'\r\nimport Quote, { QuoteGetParams } from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Utils, { dateFromUnixTimestamp } from '../utils'\r\nimport { captureException } from './helpers'\r\n\r\nconst DAY_IN_SECONDS = 86400\r\nconst TWO_MIN_IN_MS = 2 * 60 * 1000\r\nconst virtualDatesCache: ObjectHash<{\r\n fromSeconds: number\r\n toSeconds: number\r\n lastUsed: number\r\n virtualDates: number[]\r\n}> = {}\r\n\r\n// The reason to use this func instead of dateFns.isSameDay is performance as this is way faster\r\nfunction areTimestampsFromSameDay({ ts1, ts2 }: { ts1: number; ts2: number }) {\r\n const ts1Utc = ts1\r\n const ts2Utc = ts2\r\n return Math.floor(ts1Utc / DAY_IN_SECONDS) === Math.floor(ts2Utc / DAY_IN_SECONDS)\r\n}\r\n\r\nfunction getVirtualDatesCacheId({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n}) {\r\n return `${ticker}-${timeframe}-${idRevision}`\r\n}\r\n\r\nfunction getCachedVirtualDates({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n fromSeconds,\r\n toSeconds,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n fromSeconds: number\r\n toSeconds: number\r\n}) {\r\n const id = getVirtualDatesCacheId({ idRevision, ticker, timeframe })\r\n const cache = virtualDatesCache[id]\r\n if (cache?.fromSeconds <= fromSeconds && cache?.toSeconds >= toSeconds) {\r\n cache.lastUsed = Date.now()\r\n if (cache.fromSeconds === fromSeconds && cache.toSeconds === toSeconds) {\r\n return cache.virtualDates\r\n }\r\n return cache.virtualDates.filter(\r\n (virtualDateSeconds) => virtualDateSeconds >= fromSeconds && virtualDateSeconds <= toSeconds\r\n )\r\n }\r\n return null\r\n}\r\n\r\nfunction checkVirtualCacheSize() {\r\n const now = Date.now()\r\n Object.keys(virtualDatesCache).forEach((virtualDatesCacheId) => {\r\n if (virtualDatesCache[virtualDatesCacheId].lastUsed < now - TWO_MIN_IN_MS) {\r\n delete virtualDatesCache[virtualDatesCacheId]\r\n }\r\n })\r\n}\r\n\r\nfunction setCachedVirtualDates({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n fromSeconds,\r\n toSeconds,\r\n virtualDates,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n fromSeconds: number\r\n toSeconds: number\r\n virtualDates: number[]\r\n}) {\r\n const id = getVirtualDatesCacheId({ idRevision, ticker, timeframe })\r\n checkVirtualCacheSize()\r\n virtualDatesCache[id] = {\r\n fromSeconds,\r\n toSeconds,\r\n virtualDates,\r\n lastUsed: Date.now(),\r\n }\r\n}\r\n\r\nconst MAX_BAR_BORDER_WIDTH = 1\r\nconst MIN_BAR_MARGIN_WIDTH = 0\r\nconst MAX_BAR_MARGIN_WIDTH = 16\r\n\r\nexport function getBarWidthWithMarginByParts({\r\n zoomFactor = 1,\r\n chartLayout,\r\n}: {\r\n zoomFactor?: number\r\n chartLayout: ChartLayoutModel\r\n}) {\r\n const { ChartSettings } = chartLayout.settings\r\n const settingsCenter = ChartSettings.center\r\n const barMargin =\r\n zoomFactor > 1 && settingsCenter.barMargin === 0\r\n ? Math.min(settingsCenter.barWidth, 1 - 1 / zoomFactor)\r\n : settingsCenter.barMargin\r\n\r\n const barFillWidth = settingsCenter.barWidth * zoomFactor\r\n const barBorderWidth = Math.min(settingsCenter.border * zoomFactor, MAX_BAR_BORDER_WIDTH)\r\n const barMarginWidth = Math.max(MIN_BAR_MARGIN_WIDTH, Math.min(barMargin * zoomFactor, MAX_BAR_MARGIN_WIDTH))\r\n\r\n return {\r\n barFillWidth,\r\n barBorderWidth,\r\n barMarginWidth,\r\n }\r\n}\r\n\r\nexport function getBarWidthWithMargin({\r\n zoomFactor = 1,\r\n chartLayout,\r\n shouldRound = true,\r\n}: {\r\n zoomFactor?: number\r\n chartLayout: ChartLayoutModel\r\n shouldRound?: boolean\r\n}) {\r\n const { barFillWidth, barBorderWidth, barMarginWidth } = getBarWidthWithMarginByParts({ zoomFactor, chartLayout })\r\n\r\n const barWidth = barFillWidth + barBorderWidth * 2 + barMarginWidth\r\n if (!shouldRound) {\r\n return barWidth\r\n }\r\n const roundDecimalPlaces = barWidth > 100 ? 10 : 10000\r\n return Math.round(barWidth * roundDecimalPlaces) / roundDecimalPlaces\r\n}\r\n\r\nconst DEFAULT_ZOOM_GUESS_INCREMENT = 0.001\r\n\r\nconst zoomFactorForBarsToDisplayCache: ObjectHash = {}\r\nconst zoomFactorForBarsToDisplayCacheKeys: string[] = []\r\nconst NUMBER_OF_CACHED_ZOOM_FACTORS = 10\r\nconst getZoomFactorFromCache = (key: string) => zoomFactorForBarsToDisplayCache[key] ?? null\r\nconst setZoomFactorToCache = (key: string, value: number) => {\r\n if (!zoomFactorForBarsToDisplayCacheKeys.includes(key)) {\r\n zoomFactorForBarsToDisplayCacheKeys.unshift(key)\r\n if (zoomFactorForBarsToDisplayCacheKeys.length > NUMBER_OF_CACHED_ZOOM_FACTORS) {\r\n const poppedKey = zoomFactorForBarsToDisplayCacheKeys.pop()\r\n if (poppedKey) {\r\n delete zoomFactorForBarsToDisplayCache[poppedKey]\r\n }\r\n }\r\n }\r\n\r\n zoomFactorForBarsToDisplayCache[key] = value\r\n}\r\n\r\nexport function getZoomFactorForBarsToDisplay({\r\n chartVisibleWidth,\r\n numOfVisibleBars,\r\n chartLayout,\r\n}: {\r\n chartVisibleWidth: number\r\n numOfVisibleBars: number\r\n chartLayout: ChartLayoutModel\r\n}) {\r\n const defaultBarWidthWithMargin = getBarWidthWithMargin({ chartLayout })\r\n const barWidthWithMargin = chartVisibleWidth / numOfVisibleBars\r\n const cacheKey = `${defaultBarWidthWithMargin}-${barWidthWithMargin}`\r\n let zoomIncrement = 0\r\n let currentZoomFactor = 1\r\n let finalZoomFactor = getZoomFactorFromCache(cacheKey)\r\n let iteration = 0\r\n if (barWidthWithMargin <= defaultBarWidthWithMargin) {\r\n finalZoomFactor = barWidthWithMargin / defaultBarWidthWithMargin\r\n }\r\n while (finalZoomFactor === null) {\r\n iteration += 1\r\n const threshold = 0.01\r\n currentZoomFactor += zoomIncrement\r\n const barWidth = getBarWidthWithMargin({ zoomFactor: currentZoomFactor, chartLayout, shouldRound: false })\r\n const barWidthDiff = barWidthWithMargin - barWidth\r\n if (barWidthDiff > threshold) {\r\n zoomIncrement = zoomIncrement > 0 ? zoomIncrement * 2 : DEFAULT_ZOOM_GUESS_INCREMENT\r\n } else if (barWidthDiff < -threshold) {\r\n zoomIncrement = zoomIncrement < 0 ? zoomIncrement * 2 : -DEFAULT_ZOOM_GUESS_INCREMENT\r\n } else {\r\n finalZoomFactor = currentZoomFactor\r\n }\r\n\r\n if (iteration === 1000) {\r\n captureException(new Error('Invalid zoom factor from getZoomFactorForBarsToDisplay'), {\r\n extra: {\r\n iteration,\r\n zoomIncrement,\r\n barWidthWithMargin,\r\n barWidth,\r\n barWidthDiff,\r\n currentZoomFactor,\r\n chartLayout: chartLayout.toConfig(['colors', 'panes']),\r\n },\r\n })\r\n return currentZoomFactor\r\n }\r\n }\r\n\r\n setZoomFactorToCache(cacheKey, finalZoomFactor)\r\n\r\n return finalZoomFactor\r\n}\r\n\r\nexport function getTimeframeSeconds({\r\n lowerIndex,\r\n dates,\r\n timeframe,\r\n}: {\r\n lowerIndex: number\r\n dates: number[]\r\n timeframe: TIMEFRAME\r\n}) {\r\n const upperIndex = lowerIndex + 1\r\n const areBoundsDefined = ![dates[upperIndex], dates[lowerIndex]].some((index) => index === undefined)\r\n return areBoundsDefined ? dates[upperIndex] - dates[lowerIndex] : TIMEFRAME_SECONDS[timeframe]\r\n}\r\n\r\nfunction getVirtualTradedDays({\r\n dateStartSeconds,\r\n dateEndSeconds,\r\n datesSeconds,\r\n marketStartMinutes,\r\n}: {\r\n dateStartSeconds: number\r\n dateEndSeconds: number\r\n datesSeconds: number[]\r\n marketStartMinutes: number\r\n}) {\r\n const dateStart = dateFromUnixTimestamp(dateStartSeconds)\r\n const dateEnd = dateFromUnixTimestamp(dateEndSeconds)\r\n const isStartBeforeDates = dateStartSeconds < datesSeconds[0]\r\n const isEndAfterDates = datesSeconds.length > 0 && datesSeconds[datesSeconds.length - 1] < dateEndSeconds\r\n const firstDate = dateFromUnixTimestamp(datesSeconds[0])\r\n const lastDate = dateFromUnixTimestamp(datesSeconds[datesSeconds.length - 1])\r\n return dateFns\r\n .eachDayOfInterval({\r\n start:\r\n isStartBeforeDates && (dateFns.isWeekend(dateStart) || dateStart.getMinutes() < marketStartMinutes)\r\n ? dateFns.addBusinessDays(dateStart, -1)\r\n : dateStart,\r\n end: isEndAfterDates ? dateFns.addBusinessDays(dateEnd, 1) : dateEnd,\r\n })\r\n .filter((date) => {\r\n const ts2 = date.getTime() / 1000 - date.getTimezoneOffset() * 60\r\n return (\r\n !dateFns.isWithinInterval(date, { start: dateFns.startOfDay(firstDate), end: dateFns.endOfDay(lastDate) }) ||\r\n datesSeconds.some((dateTime) =>\r\n areTimestampsFromSameDay({\r\n ts1: dateTime - Utils.getQuoteDateTimestampOffsetInSeconds(new Date(dateTime * 1000)),\r\n ts2,\r\n })\r\n )\r\n )\r\n })\r\n}\r\n\r\nexport function getVirtualTimeframeTradedDates({\r\n dateStart,\r\n dateEnd,\r\n quote,\r\n}: {\r\n dateStart: number\r\n dateEnd: number\r\n quote: Quote\r\n}) {\r\n const { date: dates, ticker, timeframe, instrument, isIntraday, marketStartMinutes } = quote\r\n const barsInDay = quote.getBarsInDay() ?? 0\r\n\r\n // Currently we're passing first and last quote dates to dateStart / dateEnd so this is always true\r\n // but this function can be used on other places in the future where it will work with dates out of quote dates range\r\n const isWithinRangeOfQuoteDate = dateStart === dates[0] && dateEnd === dates[dates.length - 1]\r\n\r\n const commonVirtualCacheProps = {\r\n idRevision: dates.length,\r\n ticker,\r\n timeframe,\r\n fromSeconds: dateStart,\r\n toSeconds: dateEnd,\r\n }\r\n const cachedDates = getCachedVirtualDates(commonVirtualCacheProps)\r\n if (cachedDates) {\r\n return cachedDates\r\n }\r\n if (!isIntraday || instrument !== Instrument.Stock) {\r\n if (isWithinRangeOfQuoteDate) {\r\n return dates\r\n }\r\n const timeframeSeconds = TIMEFRAME_SECONDS[timeframe]\r\n const firstDate = dates[0]\r\n const lastDate = dates[dates.length - 1]\r\n const numOfDatesBefore = Math.ceil((firstDate - dateStart) / timeframeSeconds)\r\n const numOfDatesAfter = Math.ceil((dateEnd - lastDate) / timeframeSeconds)\r\n return [\r\n ...Array.from({ length: numOfDatesBefore })\r\n .map((_, index) => firstDate - (index + 1) * timeframeSeconds)\r\n .reverse(),\r\n ...dates,\r\n ...Array.from({ length: numOfDatesAfter }).map((_, index) => lastDate + (index + 1) * timeframeSeconds),\r\n ]\r\n }\r\n\r\n const virtualTradedDays = isWithinRangeOfQuoteDate\r\n ? quote.getDaysInQuote()\r\n : getVirtualTradedDays({\r\n dateStartSeconds: dateStart,\r\n dateEndSeconds: dateEnd,\r\n datesSeconds: dates,\r\n marketStartMinutes,\r\n })\r\n\r\n const marketStartSeconds = marketStartMinutes * 60\r\n const barTimeframeSeconds = Array.from({ length: barsInDay }).map((_, i) => i * TIMEFRAME_SECONDS[timeframe])\r\n const quoteDatesTimestampOffset = Utils.getQuoteDateTimestampOffsetInSeconds(new Date(dateStart * 1000))\r\n const virtualDates = virtualTradedDays.flatMap((date) => {\r\n const daySeconds =\r\n date.getTime() / 1000 + Utils.getQuoteDateTimestampOffsetInSeconds(date) - date.getTimezoneOffset() * 60\r\n const dayStartSeconds = daySeconds + marketStartSeconds\r\n return barTimeframeSeconds.map(\r\n // Hourly market starts at 9:30 but all other time ticks should be rounded down to :00 of the current hour\r\n (barSeconds, index) =>\r\n ([TIMEFRAME.h, TIMEFRAME.h2, TIMEFRAME.h4].includes(timeframe) && index > 0 ? -1800 : 0) +\r\n dayStartSeconds +\r\n barSeconds\r\n )\r\n })\r\n\r\n if (!isWithinRangeOfQuoteDate) {\r\n virtualDates.filter((date, index, virtualTimeframeTradedDates) => {\r\n const isLowerBounded =\r\n date >= dateStart ||\r\n areTimestampsFromSameDay({\r\n ts1: date - Utils.getQuoteDateTimestampOffsetInSeconds(new Date(date * 1000)),\r\n ts2: dateStart - quoteDatesTimestampOffset,\r\n })\r\n const isOneBeforeLowerBoundStarts = dateStart > date && dateStart < virtualTimeframeTradedDates[index + 1]\r\n return isLowerBounded || isOneBeforeLowerBoundStarts\r\n })\r\n }\r\n\r\n setCachedVirtualDates({\r\n ...commonVirtualCacheProps,\r\n virtualDates,\r\n })\r\n\r\n return virtualDates\r\n}\r\n\r\ninterface TimestampPositionGettersProps {\r\n quote: Quote\r\n}\r\n\r\nexport function getTimestampFromPositionX({ positionX, quote }: TimestampPositionGettersProps & { positionX: number }) {\r\n const { date, timeframe } = quote\r\n const dates = getVirtualTimeframeTradedDates({\r\n dateStart: date[0],\r\n dateEnd: date[date.length - 1],\r\n quote,\r\n })\r\n const dateStart = dates[0]\r\n const dateEnd = dates[dates.length - 1]\r\n const lastDateIndex = dates.length - 1\r\n if (positionX >= 0 && positionX <= lastDateIndex) {\r\n const lowerIndex = Math.floor(positionX)\r\n const timeframeSeconds = getTimeframeSeconds({ lowerIndex, dates, timeframe })\r\n return dates[lowerIndex] + (positionX - lowerIndex) * timeframeSeconds\r\n }\r\n const isLookingBack = positionX < 0\r\n const averageBarDate = (dateEnd - dateStart) / dates.length\r\n const numOfSecondsOutOfBounds = isLookingBack\r\n ? Math.abs(positionX) * averageBarDate\r\n : (positionX - lastDateIndex) * averageBarDate\r\n return Math.round(isLookingBack ? dateStart - numOfSecondsOutOfBounds : dateEnd + numOfSecondsOutOfBounds)\r\n}\r\n\r\nexport function getPositionXFromTimestamp({ timestamp, quote }: TimestampPositionGettersProps & { timestamp: number }) {\r\n const { date, timeframe } = quote\r\n const dates = getVirtualTimeframeTradedDates({\r\n dateStart: date[0],\r\n dateEnd: date[date.length - 1],\r\n quote,\r\n })\r\n const dateStart = dates[0]\r\n const dateEnd = dates[dates.length - 1]\r\n const lastDateIndex = dates.length - 1\r\n if (timestamp >= dates[0] && timestamp <= dates[dates.length - 1]) {\r\n const upperIndex = timestamp === dateEnd ? lastDateIndex : dates.findIndex((date) => date > timestamp)\r\n const timeframeSeconds = getTimeframeSeconds({ lowerIndex: upperIndex - 1, dates, timeframe })\r\n const positionDiffUpperTimestamp = (dates[upperIndex] - timestamp) / timeframeSeconds\r\n return upperIndex - positionDiffUpperTimestamp\r\n }\r\n const isLookingBack = timestamp < dateStart\r\n const averageBarDate = (dateEnd - dateStart) / dates.length\r\n return isLookingBack\r\n ? -((dateStart - timestamp) / averageBarDate)\r\n : lastDateIndex + (timestamp - dateEnd) / averageBarDate\r\n}\r\n\r\n// counterpart in Finviz-Website 'Finviz-Website/js/main/util.ts'\r\nexport function getInstrument(tickerRaw: string) {\r\n if (tickerRaw.indexOf('@') === 0) {\r\n const ticker = tickerRaw.substring(1) as keyof typeof CRYPTOS\r\n\r\n if (CRYPTOS[ticker]) {\r\n return Instrument.Crypto\r\n } else if (ticker.length === 6) {\r\n return Instrument.Forex\r\n } else {\r\n return Instrument.Futures\r\n }\r\n }\r\n return Instrument.Stock\r\n}\r\n\r\nexport function getPerfIndicatorTickerAndTimeframes({\r\n paneWithPerfIndicator,\r\n timeframe,\r\n}: {\r\n paneWithPerfIndicator: ChartConfigChartPane\r\n timeframe: TIMEFRAME\r\n}) {\r\n const { elements } = paneWithPerfIndicator\r\n const perfIndicatorElement = elements.find(({ type }) => type === 'indicators/perf')\r\n const tickers = perfIndicatorElement?.period?.split(',') ?? []\r\n return tickers.map((ticker) => ({\r\n ticker,\r\n instrument: getInstrument(ticker),\r\n timeframe,\r\n }))\r\n}\r\n\r\ninterface PrefetchPerfIndicatorAllQuotesProps extends Pick {\r\n paneWithPerfIndicator: ChartConfigChartPane\r\n chartUuid?: string\r\n}\r\n\r\nexport async function prefetchPerfIndicatorAllQuotes({\r\n paneWithPerfIndicator,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n}: PrefetchPerfIndicatorAllQuotesProps) {\r\n const tickersAndTimeframes = getPerfIndicatorTickerAndTimeframes({ paneWithPerfIndicator, timeframe })\r\n\r\n if (tickersAndTimeframes.length > 0) {\r\n const promises = tickersAndTimeframes.map(({ ticker, instrument, timeframe }) =>\r\n Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n })\r\n )\r\n return Promise.all(promises)\r\n }\r\n return Promise.resolve([])\r\n}\r\n\r\ninterface RenderCrossProps {\r\n context: CanvasRenderingContext2D\r\n mouseModel: Mouse\r\n paneModel: Pane\r\n quote: Quote\r\n contentWidth: number\r\n contentHeight: number\r\n onRenderCrossText?: (context: CanvasRenderingContext2D, crossIndex: number) => void\r\n getRoundDecimalPlaces?: (price?: number) => number | undefined\r\n isIndicator?: boolean\r\n isPerfIndicator?: boolean\r\n}\r\n\r\nexport function renderCross({\r\n context,\r\n mouseModel,\r\n paneModel,\r\n quote,\r\n contentWidth,\r\n contentHeight,\r\n onRenderCrossText,\r\n getRoundDecimalPlaces,\r\n isIndicator = false,\r\n isPerfIndicator = false,\r\n}: RenderCrossProps) {\r\n const crossIndex = mouseModel.getCrossIndexForPane(paneModel)\r\n const chartModel = paneModel.chart()\r\n const { ChartSettings, IndicatorSettings } = getChartLayoutSettings(chartModel.chart_layout())\r\n const settings = isIndicator ? IndicatorSettings : ChartSettings\r\n const { Colors } = ChartSettings.general\r\n\r\n if (!mouseModel.getShouldRenderCrossInPane(paneModel)) {\r\n return false\r\n }\r\n\r\n const price = mouseModel.getPriceForPane(paneModel)\r\n const middle = paneModel.scale.x(crossIndex) + chartModel.leftOffset\r\n const isXAxisInView = middle > 0 && middle <= contentWidth\r\n if (isXAxisInView) {\r\n const x = middle + settings.left.width\r\n new Line(\r\n {\r\n x1: x,\r\n x2: x,\r\n y1: settings.top.height,\r\n y2: settings.top.height + contentHeight,\r\n strokeStyle: Colors.cross,\r\n },\r\n paneModel\r\n ).render(context)\r\n\r\n onRenderCrossText?.(context, crossIndex)\r\n }\r\n\r\n const domainRange = paneModel.scale.y\r\n .domain()\r\n .slice()\r\n .sort((a, b) => a - b)\r\n\r\n if (price === null || !(domainRange[0] <= price && price <= domainRange[1])) {\r\n return isXAxisInView\r\n }\r\n\r\n const priceFy = paneModel.scale.y(price)\r\n const y = Math.round(priceFy + settings.top.height)\r\n new Line(\r\n {\r\n x1: settings.left.width,\r\n x2: settings.left.width + contentWidth,\r\n y1: y,\r\n y2: y,\r\n strokeStyle: Colors.cross,\r\n },\r\n paneModel\r\n ).render(context)\r\n const YAxisLeftMargin = quote.instrument === Instrument.Crypto && quote.lastClose <= 0.001 ? 3 : 8\r\n\r\n const getCrossText = () => {\r\n if (chartModel.scale === ScaleType.Percentage && !isIndicator) {\r\n return `${math.round({\r\n value: getPercentageFromValue({ number: price, base: chartModel.firstBarClose }),\r\n lastClose: quote.lastClose,\r\n instrument: quote.instrument,\r\n overridePlaces: 2,\r\n })}%`\r\n }\r\n return `${math.round({\r\n value: price,\r\n lastClose: quote.lastClose,\r\n instrument: quote.instrument,\r\n overridePlaces: getRoundDecimalPlaces?.(price) ?? (paneModel.getIsChartPane() ? undefined : 2),\r\n })}${isPerfIndicator ? '%' : ''}`\r\n }\r\n\r\n new Text(\r\n {\r\n text: getCrossText(),\r\n x:\r\n settings.left.width +\r\n settings.right.axis.margin.left! +\r\n contentWidth +\r\n (isIndicator ? OFFSET.S : YAxisLeftMargin - PADDING.XXS),\r\n padding: isIndicator\r\n ? Text.getMergedPropsWithDefaults('padding', IndicatorSettings.right.axis.font.padding)\r\n : {\r\n top: PADDING.XXS,\r\n right: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n },\r\n ...{\r\n y,\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.crossText,\r\n background: Colors.crossTextBackground,\r\n font: Text.getMergedPropsWithDefaults('font', { ...settings.right.axis.font, style: 'bold' }),\r\n lineHeight: settings.right.axis.font.lineHeight,\r\n },\r\n },\r\n paneModel\r\n ).render(context)\r\n\r\n return true\r\n}\r\n\r\n/**\r\n * Set canvas width and height to 0 which fixes Safari memory problems\r\n *\r\n * @see https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12\r\n */\r\nexport function unmountCanvas(canvas?: HTMLCanvasElement | null) {\r\n if (!canvas) return\r\n\r\n canvas.width = 0\r\n canvas.height = 0\r\n canvas.style.width = '0px'\r\n canvas.style.height = '0px'\r\n}\r\n\r\nexport function getChangeColor({ change, ChartSettings }: { change: number; ChartSettings: IChartSettings }) {\r\n const { Colors } = ChartSettings.general\r\n if (change === 0) {\r\n return Colors.zeroChange\r\n }\r\n return change > 0 ? Colors.positiveChange : Colors.negativeChange\r\n}\r\n\r\nexport function round({ data, num, overridePlaces }: { data: Quote; num: number; overridePlaces?: number }) {\r\n return math.round({\r\n value: num,\r\n lastClose: data.lastClose,\r\n instrument: data.instrument,\r\n overridePlaces: overridePlaces,\r\n })\r\n}\r\n\r\nexport interface ITickerChange {\r\n points: number\r\n string: string\r\n percentString: string\r\n}\r\ninterface ITickerChangeResult {\r\n tickerChange: ITickerChange | null\r\n tickerAfterChange: ITickerChange | null\r\n}\r\n\r\nexport function getTickerChangeFromCloseValues({\r\n anchorClose,\r\n prevClose,\r\n data,\r\n}: {\r\n anchorClose: number\r\n prevClose: number\r\n data: Quote\r\n}): ITickerChange {\r\n const changePoints = anchorClose - prevClose\r\n const changePercent = (anchorClose / prevClose - 1) * 100\r\n const sign = changePoints < 0 ? '-' : changePoints > 0 ? '+' : ''\r\n const changePercentString = `${round({\r\n data,\r\n num: Math.abs(changePercent),\r\n overridePlaces: 2,\r\n })}%`\r\n const changePointsString = `${sign}${round({\r\n data,\r\n num: Math.abs(changePoints),\r\n })} (${changePercentString})`\r\n\r\n return {\r\n points: changePoints,\r\n string: changePointsString,\r\n percentString: `${sign}${changePercentString}`,\r\n }\r\n}\r\nexport function getTickerChange({ data }: { data: Quote }) {\r\n const result: ITickerChangeResult = { tickerChange: null, tickerAfterChange: null }\r\n const isChange = Number.isFinite(data.prevClose) // if not new stock always present\r\n if (isChange) {\r\n result.tickerChange = getTickerChangeFromCloseValues({\r\n data,\r\n anchorClose: data.lastClose,\r\n prevClose: data.prevClose,\r\n })\r\n }\r\n\r\n const isAfterChange = Number.isFinite(data.afterClose) && data.afterClose !== data.lastClose\r\n if (isAfterChange) {\r\n const tickerAfterChange = getTickerChangeFromCloseValues({\r\n data,\r\n anchorClose: data.afterClose,\r\n prevClose: data.lastClose,\r\n })\r\n result.tickerAfterChange = {\r\n ...tickerAfterChange,\r\n string: `AH: ${tickerAfterChange.string}`,\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\nexport function isForexFuturesCryptoPage(specificChartFunctionality: SpecificChartFunctionality) {\r\n return [\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n SpecificChartFunctionality.futuresPage,\r\n ].includes(specificChartFunctionality)\r\n}\r\n\r\nexport function getShouldUseDarkerWickColors({\r\n specificChartFunctionality,\r\n totalBarWidth,\r\n}: {\r\n specificChartFunctionality: SpecificChartFunctionality\r\n timeFrame?: TIMEFRAME\r\n totalBarWidth: number\r\n}) {\r\n const isForexFuturesCrypto = isForexFuturesCryptoPage(specificChartFunctionality)\r\n const isOffscreenChartWithNarrowBars =\r\n specificChartFunctionality === SpecificChartFunctionality.offScreen && totalBarWidth < 5\r\n const isQuoteChartWithNarrowBars =\r\n specificChartFunctionality === SpecificChartFunctionality.quotePage && totalBarWidth < 5\r\n\r\n return isForexFuturesCrypto || isOffscreenChartWithNarrowBars || isQuoteChartWithNarrowBars\r\n}\r\n\r\nexport const DRAWING_COOKIE_NAME = 'charts-draw'\r\nexport function getIsDrawingEnabled() {\r\n return Utils.getCookie(DRAWING_COOKIE_NAME) === 'on'\r\n}\r\n\r\nexport function setIsDrawingEnabled(value: boolean) {\r\n const expires = new Date()\r\n expires.setMonth(expires.getMonth() + 1)\r\n Utils.setCookie(DRAWING_COOKIE_NAME, value ? 'on' : 'off', expires)\r\n}\r\n\r\nexport function getIsSidebarEnabled(specificChartFunctionality: SpecificChartFunctionality) {\r\n return (\r\n specificChartFunctionality === SpecificChartFunctionality.chartPage && !!window.FinvizSettings.hasSidebarEnabled\r\n )\r\n}\r\n\r\nexport const handleTypeChange = ({\r\n type,\r\n chartLayoutModel,\r\n}: {\r\n type: ChartElementType\r\n chartLayoutModel: ChartLayoutModel\r\n}) => {\r\n const elements = chartLayoutModel.getAllElements()\r\n elements.forEach((element) => {\r\n if (element.isChart() && element.instance.attrs.type !== type) {\r\n const pane = element.pane()\r\n const instance = chartsByType[type].fromObject(\r\n {\r\n ...element.instance.attrs,\r\n type,\r\n },\r\n pane\r\n )\r\n element.replace(instance)\r\n }\r\n })\r\n}\r\n\r\nexport const getIsPreserveDrawingsAndAutosaveAvailable = (args: {\r\n specificChartFunctionality: SpecificChartFunctionality\r\n editable: boolean\r\n editors: ChartEditorEnum[]\r\n}) => {\r\n const { specificChartFunctionality, editable, editors } = args\r\n\r\n return (\r\n editable &&\r\n editors?.includes(ChartEditorEnum.tools) &&\r\n specificChartFunctionality &&\r\n [\r\n SpecificChartFunctionality.chartPage,\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(specificChartFunctionality)\r\n )\r\n}\r\n","/**\r\n * Keep this file in sync with `Website/js/main/components/color-picker/util.ts` in website repo\r\n * */\r\n\r\nexport interface RGBA {\r\n r: number\r\n g: number\r\n b: number\r\n a: number\r\n}\r\n\r\nexport interface HSVA {\r\n h: number\r\n s: number\r\n v: number\r\n a: number\r\n}\r\n\r\nexport interface HSLA {\r\n h: number\r\n s: number\r\n l: number\r\n a: number\r\n}\r\n\r\n/**\r\n * Convert Hex string to RGBA object.\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hexStringToRGBA(hexString: string): RGBA {\r\n const hexColor = removeHashSymbol(hexString)\r\n let r: string | number = 0\r\n let g: string | number = 0\r\n let b: string | number = 0\r\n let a: string | number = 255\r\n\r\n // 3 digits\r\n if (hexColor.length === 3 || hexColor.length === 4) {\r\n r = '0x' + hexColor[0] + hexColor[0]\r\n g = '0x' + hexColor[1] + hexColor[1]\r\n b = '0x' + hexColor[2] + hexColor[2]\r\n // Get channel if defined\r\n a = hexColor.length === 4 ? '0x' + hexColor[3] + hexColor[3] : a\r\n\r\n // 6 digits\r\n } else if (hexColor.length === 6 || hexColor.length === 8) {\r\n r = '0x' + hexColor[0] + hexColor[1]\r\n g = '0x' + hexColor[2] + hexColor[3]\r\n b = '0x' + hexColor[4] + hexColor[5]\r\n // Get channel if defined\r\n a = hexColor.length === 8 ? '0x' + hexColor[6] + hexColor[7] : a\r\n }\r\n\r\n return { r: Number(r), g: Number(g), b: Number(b), a: Math.min(Math.round((Number(a) / 255) * 100) / 100, 1) }\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSVA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSVA(hexString: string) {\r\n return rgbaToHSVA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSLA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSLA(hexString: string) {\r\n return rgbaToHSLA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert alpha value to hex value\r\n *\r\n * Input: [0,1]\r\n *\r\n * Output: alpha in HEX format\r\n */\r\nexport function alphaToHex(alpha: number) {\r\n return Math.max(Math.min(Math.round(alpha * 255), 255), 0)\r\n .toString(16)\r\n .padStart(2, '0')\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HEX string.\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: color in hex6 or hex8 depending on whether or not alpha is enabled\r\n */\r\nexport function rgbaToHexString(color: RGBA, alpha = false) {\r\n const r = color.r.toString(16)\r\n const g = color.g.toString(16)\r\n const b = color.b.toString(16)\r\n const hexString = '#' + r.padStart(2, '0') + g.padStart(2, '0') + b.padStart(2, '0')\r\n\r\n if (!alpha || color.a === 1) {\r\n return hexString\r\n }\r\n\r\n return `${hexString}${alphaToHex(color.a)}`\r\n}\r\n\r\n/**\r\n * Convert HSVA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToHEXString(color: HSVA, alpha = false) {\r\n const rgbaColor = hsvaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert HSLA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToHexString(color: HSLA, alpha = false) {\r\n const rgbaColor = hslaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HSVA\r\n * @see https://stackoverflow.com/a/54070620/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSVA(color: RGBA): HSVA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: v ? c / v : 0,\r\n v: v,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA to HSLA\r\n * @see https://stackoverflow.com/a/54071699/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSLA(color: RGBA): HSLA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const f = 1 - Math.abs(v + v - c - 1)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: f ? c / f : 0,\r\n l: (v + v - c) / 2,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSVA color to RGBA\r\n * @see https://stackoverflow.com/a/54024653/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToRGBA(color: HSVA): RGBA {\r\n const f = (n: number, k = (n + color.h / 60) % 6) => color.v - color.v * color.s * Math.max(Math.min(k, 4 - k, 1), 0)\r\n\r\n return {\r\n r: Math.round(f(5) * 255),\r\n g: Math.round(f(3) * 255),\r\n b: Math.round(f(1) * 255),\r\n a: Math.round(color.a * 100) / 100,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to RGBA\r\n * @see https://stackoverflow.com/a/54014428/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToRGBA(color: HSLA): RGBA {\r\n const a = color.s * Math.min(color.l, 1 - color.l)\r\n const f = (n: number, k = (n + color.h / 30) % 12) => color.l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\r\n\r\n return {\r\n r: Math.round(f(0) * 255),\r\n g: Math.round(f(8) * 255),\r\n b: Math.round(f(4) * 255),\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA color to rgba() string\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: rgba(r, g, b, a)\r\n */\r\nexport function rgbaToRGBAString(color: RGBA) {\r\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`\r\n}\r\n\r\n/**\r\n * Convert rgba() string to RGBA color\r\n *\r\n * Input: rgba(r, g, b, a)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function rgbaStringToObject(color: string) {\r\n const colorParts = /^rgba?\\(([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]*([01].?[0-9]*)?\\)$/.exec(color)\r\n const [red, green, blue, alpha = '1'] = colorParts?.slice(1) || [0, 0, 0, 1].map(String)\r\n return {\r\n r: Number.parseInt(red),\r\n g: Number.parseInt(green),\r\n b: Number.parseInt(blue),\r\n a: Number.parseFloat(alpha),\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to hsla() string\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: hsla(h, s, l, a)\r\n */\r\nexport function hslaToHSLAString(color: HSLA) {\r\n return `hsla(${Math.round(color.h)}, ${Math.round(color.s * 10000) / 100}%, ${Math.round(color.l * 10000) / 100}%, ${\r\n color.a\r\n })`\r\n}\r\n\r\nexport function removeHashSymbol(strColor: string) {\r\n return strColor.replace(/#/g, '')\r\n}\r\n\r\n/**\r\n * Check if the param is a valid color by setting it as style\r\n */\r\nexport function isValidColor(strColor: string) {\r\n const isRgb = strColor.startsWith('rgba')\r\n const s = new Option().style\r\n\r\n s.color = isRgb ? strColor : `#${removeHashSymbol(strColor)}`\r\n\r\n return s.color !== ''\r\n}\r\n\r\n/**\r\n * Normalize color to be a hex value\r\n */\r\nexport function convertColorToHEX(strColor: string, allowAlpha = true) {\r\n const isRgb = getIsRgb(strColor)\r\n const hexColor = isRgb ? rgbaToHexString(rgbaStringToObject(strColor), allowAlpha) : strColor\r\n\r\n if (allowAlpha) {\r\n return hexColor\r\n }\r\n return hexColor.slice(0, 7)\r\n}\r\n\r\n/**\r\n * Returns true if color is rgb or rgba\r\n */\r\nexport function getIsRgb(strColor: string, isAlphaAllowed = true) {\r\n const rgbKeys = ['rgb']\r\n if (isAlphaAllowed) {\r\n rgbKeys.push('rgba')\r\n }\r\n return rgbKeys.some((startsWith) => strColor.startsWith(startsWith))\r\n}\r\n\r\n/**\r\n * Convert any color format to HSVA (internal color picker representation)\r\n */\r\nexport function getHSVAFromColor(strColor: string) {\r\n if (getIsRgb(strColor)) {\r\n return rgbaToHSVA(rgbaStringToObject(strColor))\r\n }\r\n\r\n return hexStringToHSVA(strColor)\r\n}\r\n\r\n/**\r\n * Stringify HSVA color representation into a output format\r\n */\r\nexport function stringifyHSVAColor(color: HSVA, output: 'rgba' | 'hex', canSelectAlpha?: boolean) {\r\n switch (output) {\r\n case 'rgba':\r\n return rgbaToRGBAString(hsvaToRGBA(color))\r\n default:\r\n return hsvaToHEXString(color, canSelectAlpha)\r\n }\r\n}\r\n\r\n/**\r\n * Get luma value from RGBA color using the Rec. 709 coefficients\r\n * @see https://en.wikipedia.org/wiki/Luma_%28video%29\r\n *\r\n * If luma is >= 165 the foreground color should be dark\r\n */\r\nexport function getLumaFromRGBA(color: RGBA) {\r\n return 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b\r\n}\r\n\r\n/**\r\n * Checks if luma is >= 165 or alpha < 0.3\r\n */\r\nexport function getIsColorTooLightOrTransparent(color: RGBA) {\r\n return getLumaFromRGBA(color) >= 165 || color.a < 0.5\r\n}\r\n\r\n/**\r\n * Set specific alpha for a hex color\r\n */\r\nexport function getHEXWithSpecificAplha(color: string, alpha = 1) {\r\n const rgbaColor = hexStringToRGBA(color)\r\n return rgbaToHexString({ ...rgbaColor, a: alpha }, true)\r\n}\r\n\r\n/**\r\n * Get rgba from valid color string\r\n */\r\nexport function getRGBAValueFromValidColorString(value: string) {\r\n if (getIsRgb(value)) return rgbaToRGBAString(rgbaStringToObject(value))\r\n return rgbaToRGBAString(hexStringToRGBA(value))\r\n}\r\n","import { ChartConfigChartPane, Position, RootChartConfigObject, TaConfigObject } from '../../types/shared'\r\nimport { ChartElementType, IndicatorType, OverlayType, PANE_HEIGHT_DEFAULT, ScaleType } from '../constants/common'\r\n\r\nfunction hasPaneWithCOTCode(panes: ChartConfigChartPane[], code: string) {\r\n return panes.some(({ elements }) =>\r\n elements.some((element) => element.type === IndicatorType.Cot && element.code === code)\r\n )\r\n}\r\nfunction pushIndicators(\r\n panes: ChartConfigChartPane[],\r\n indicator: { name: string; parameters: string },\r\n options?: { COTs?: string[] }\r\n) {\r\n if (indicator.name === 'cot') {\r\n const cotKeys = options?.COTs ?? []\r\n if (cotKeys.length === 0) {\r\n cotKeys.push('')\r\n }\r\n cotKeys.forEach(function (code: string) {\r\n if (!hasPaneWithCOTCode(panes, code)) {\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.indicator,\r\n elements: [\r\n {\r\n type: IndicatorType.Cot,\r\n code,\r\n },\r\n ],\r\n })\r\n }\r\n })\r\n } else {\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.indicator,\r\n elements: [\r\n {\r\n type: ('indicators/' + indicator.name) as IndicatorType,\r\n period: indicator.parameters,\r\n },\r\n ],\r\n })\r\n }\r\n}\r\n\r\nfunction getChartTypeByTaConfigStyle(style: string) {\r\n const chartTypeMap = {\r\n candlestick: ChartElementType.CandleStick,\r\n heikinashi: ChartElementType.HeikinAshi,\r\n hollowcandlestick: ChartElementType.HollowCandleStick,\r\n line: ChartElementType.LineChart,\r\n ohlc: ChartElementType.OhlcChart,\r\n }\r\n return chartTypeMap[style as keyof typeof chartTypeMap]\r\n}\r\n\r\nfunction getChartScaleByTaConfigScale(scale: string | undefined) {\r\n const chartScaleMap = {\r\n linear: ScaleType.Linear,\r\n percentage: ScaleType.Percentage,\r\n logarithmic: ScaleType.Logarithmic,\r\n }\r\n return chartScaleMap[scale as keyof typeof chartScaleMap] ?? ScaleType.Linear\r\n}\r\n\r\n/*\r\n * Merges chartConfig (in \"chart\" format) with taConfig (in format that TA is preserved in DB)\r\n */\r\nexport const mergeChartAndTAConfig = function convertTA(\r\n chartConfig: RootChartConfigObject,\r\n taConfig: TaConfigObject,\r\n options?: { COTs: string[] }\r\n) {\r\n const panes = chartConfig.charts[0].panes\r\n const chart = chartConfig.charts[0]\r\n\r\n chart.scale = getChartScaleByTaConfigScale(taConfig.scale)\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Above)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n const overlays = taConfig.overlays.map(function (overlay) {\r\n return {\r\n type: ('overlays/' + overlay.name) as OverlayType,\r\n period: overlay.parameters ?? '',\r\n color: overlay.color ?? '',\r\n }\r\n })\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.chart,\r\n elements: [\r\n {\r\n type: getChartTypeByTaConfigStyle(taConfig.style),\r\n overlays: overlays,\r\n },\r\n ],\r\n })\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Below)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n chartConfig.height = chart.height = PANE_HEIGHT_DEFAULT.chart + (panes.length - 1) * PANE_HEIGHT_DEFAULT.indicator\r\n}\r\n\r\nexport const getPanes = function getPanes(taConfig: TaConfigObject) {\r\n const options = {}\r\n const panes: ChartConfigChartPane[] = []\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Above)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n const overlays = taConfig.overlays.map(function (overlay) {\r\n return {\r\n type: ('overlays/' + overlay.name) as OverlayType,\r\n period: overlay.parameters ?? '',\r\n color: overlay.color ?? '',\r\n }\r\n })\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.chart,\r\n elements: [\r\n {\r\n type: getChartTypeByTaConfigStyle(taConfig.style),\r\n overlays: overlays,\r\n },\r\n ],\r\n })\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Below)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n return panes\r\n}\r\n","// if conditionalCursor provided, cursor is set only if current cursor !== conditionalCursor\r\n// otherwise cursor is set if element exists\r\nexport const setElementCursor = ({\r\n elementId,\r\n cursor,\r\n conditionalCursor,\r\n}: {\r\n elementId: string\r\n cursor: string\r\n conditionalCursor?: string\r\n}) => {\r\n const element = document.getElementById(elementId)\r\n if (element && (conditionalCursor ? element.style.cursor !== conditionalCursor : true)) {\r\n element.style.cursor = cursor\r\n }\r\n}\r\n","/*\r\n * We want to be able to render only bars/parts of line that are visible to users,\r\n * but without introducing visual artifacts like bars missing in front of users while scrolling\r\n * or lines that start in middle of chart for sparse intraday stock data.\r\n *\r\n * In general we want to start rendering lines one bar sooner than what is visible to user and stop rendering\r\n * one bar outside of visible area to create a continuous line.\r\n */\r\nimport { ScaleAxis } from '../models/pane'\r\nimport type Quote from '../models/quote'\r\n\r\nexport const drawInVisibleArea = ({\r\n quote,\r\n scale,\r\n fxOverride,\r\n fromIndexOffset = 0,\r\n toIndexOffset = 0,\r\n leftOffset,\r\n drawBarCallback,\r\n width,\r\n}: {\r\n quote: Quote\r\n scale: { x: ScaleAxis }\r\n fromIndexOffset?: number\r\n toIndexOffset?: number\r\n fxOverride?: (index: number) => number\r\n leftOffset: number\r\n width: number\r\n drawBarCallback: (i: number, x: number) => void\r\n}) => {\r\n const fx = fxOverride ?? ((index: number) => scale.x(quote.barIndex[index]))\r\n // We want to render one bar before first visible bar to fix disconnected lines on charts with missing data\r\n const firstBarToRender = Math.max(0, getFirstBarToRenderIndex({ quote, scale, leftOffset }) - 1, fromIndexOffset - 1)\r\n\r\n let lastBarToRender = -1\r\n for (let i = firstBarToRender; i < quote.close.length + toIndexOffset; i++) {\r\n const x = fx(i)\r\n if (x + leftOffset > width) {\r\n lastBarToRender = i\r\n break\r\n }\r\n drawBarCallback(i, x)\r\n }\r\n\r\n if (lastBarToRender > -1) {\r\n const x = fx(lastBarToRender)\r\n drawBarCallback(lastBarToRender, x)\r\n }\r\n}\r\n\r\nexport const getFirstBarToRenderIndex = ({\r\n leftOffset,\r\n quote,\r\n scale,\r\n}: {\r\n quote: Quote\r\n scale: { x: ScaleAxis }\r\n leftOffset: number\r\n}) => {\r\n const barIndex = Math.ceil(scale.x.invert(-leftOffset))\r\n return quote.barToDataIndex[Math.max(barIndex, 0)]\r\n}\r\n\r\nexport const getLastBarToRenderIndex = ({\r\n leftOffset,\r\n quote,\r\n scale,\r\n chartWidth,\r\n}: {\r\n quote: Quote\r\n scale: { x: ScaleAxis }\r\n leftOffset: number\r\n chartWidth: number\r\n}) => {\r\n const { barToDataIndex } = quote\r\n const barIndex = Math.ceil(scale.x.invert(-leftOffset + chartWidth))\r\n return barToDataIndex[Math.max(barIndex, 0)] ?? barToDataIndex[barToDataIndex.length - 1]\r\n}\r\n","import queryString from 'query-string'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\n\r\ninterface FetchApiProps {\r\n location: string\r\n queryParameters?: ObjectHash\r\n method?: string\r\n body?: RequestInit['body']\r\n contentType?: ContentType\r\n abortController?: null | AbortController\r\n throwOnStatusCodes?: number[]\r\n throwOnPredicate?: (response: Response) => boolean\r\n keepalive?: boolean\r\n}\r\n\r\nexport const getFormDataFromObject = (object: ObjectHash) =>\r\n Object.keys(object).reduce((formData, key) => {\r\n formData.append(key, object[key])\r\n return formData\r\n }, new FormData())\r\n\r\n// Keep in sync with ContentType in https://github.com/finvizhq/Finviz-Website/blob/master/Website/js/main/services/api.ts\r\n// START\r\nexport enum ContentType {\r\n ApplicationJson = 'application/json',\r\n ApplicationJsonUTF = 'application/json; charset=utf-8', // WriteAsJsonAsync\r\n FormUrlEncoded = 'application/x-www-form-urlencoded',\r\n Html = 'text/html; charset=utf-8',\r\n}\r\n\r\nfunction parseResponseForContentType(response: string, contentType: ContentType) {\r\n switch (contentType) {\r\n case ContentType.ApplicationJson:\r\n case ContentType.ApplicationJsonUTF:\r\n case ContentType.FormUrlEncoded:\r\n return JSON.parse(response)\r\n default:\r\n return response\r\n }\r\n}\r\n// END\r\n\r\nconst fetchApi = async ({\r\n location,\r\n queryParameters,\r\n method,\r\n body,\r\n contentType,\r\n abortController,\r\n throwOnStatusCodes,\r\n throwOnPredicate,\r\n keepalive = false,\r\n}: FetchApiProps) => {\r\n const url = `${location}${queryParameters ? `?${queryString.stringify(queryParameters)}` : ''}`\r\n const parameters: RequestInit = {\r\n method: method || 'GET',\r\n credentials: 'include',\r\n headers: contentType && {\r\n 'Content-Type': contentType,\r\n },\r\n signal: abortController?.signal,\r\n body: body,\r\n keepalive,\r\n }\r\n try {\r\n const response = await fetch(url, parameters)\r\n const responseContentType: ContentType = (response.headers.get('Content-Type') as any) ?? ContentType.Html\r\n const responseData = parseResponseForContentType(await response.text(), responseContentType)\r\n if (throwOnStatusCodes?.includes(response.status) || throwOnPredicate?.(response)) {\r\n const StatusCodeError = getStatusCodeError(response.status)\r\n throw new StatusCodeError(`${url} returned ${response.status}`, responseData as T, response.status)\r\n }\r\n return responseData as T\r\n } catch (err) {\r\n throw err\r\n }\r\n}\r\n\r\nfunction getStatusCodeError(statusCode: number): typeof GenericStatusCodeError {\r\n switch (statusCode) {\r\n case 403:\r\n return ForbiddenError\r\n case 404:\r\n return NotFoundError\r\n case 410:\r\n return GoneError\r\n case 500:\r\n return InternalServerError\r\n default:\r\n return GenericStatusCodeError\r\n }\r\n}\r\n\r\nexport class GenericStatusCodeError extends Error {\r\n response: ObjectHash | string\r\n statusCode: number\r\n\r\n constructor(message: string, response: ObjectHash | string, statusCode: number) {\r\n super(message)\r\n this.response = response\r\n this.statusCode = statusCode\r\n }\r\n}\r\nexport class ForbiddenError extends GenericStatusCodeError {}\r\nexport class NotFoundError extends GenericStatusCodeError {}\r\nexport class InternalServerError extends GenericStatusCodeError {}\r\nexport class GoneError extends GenericStatusCodeError {}\r\n\r\nexport default fetchApi\r\n","import { EmptyObject, ObjectHash } from '../../types/shared'\r\n\r\nexport function getRoundedString({ number, numOfDecimalPlaces }: { number: number; numOfDecimalPlaces: number }) {\r\n const precision = Math.pow(10, numOfDecimalPlaces)\r\n return String(Math.round(number * precision) / precision)\r\n}\r\n\r\nexport function getIsSSr() {\r\n return typeof process !== 'undefined' && !!process?.env.IS_OFFSCREEN_RENDERER\r\n}\r\n\r\nexport function isValidHexColor(color: string) {\r\n const regex = /^#([\\da-f]{3}){1,2}$|^#([\\da-f]{4}){1,2}$/i\r\n return !!color && regex.test(color)\r\n}\r\n\r\nexport function getParsedIntegersFromPeriodString(periodString: string) {\r\n const periodParts = periodString.split(',')\r\n return periodParts.map((part) => Number.parseInt(part, 10))\r\n}\r\n\r\nexport function captureException(exception: Error, captureContext?: { extra: ObjectHash }) {\r\n if (process.env.NODE_ENV === 'development' || process.env.IS_E2E_TESTING) {\r\n console.error(exception)\r\n } else if (process.env.IS_OFFSCREEN_RENDERER) {\r\n import('@sentry/node').then((client) => {\r\n client.captureException(exception, captureContext)\r\n })\r\n } else {\r\n window.Sentry.captureException(exception, captureContext)\r\n }\r\n}\r\n\r\nexport function isPositiveFloat(value: string | number) {\r\n const parsedNumber = Number.parseFloat(`${value}`)\r\n return !Number.isNaN(parsedNumber) && isFinite(parsedNumber) && parsedNumber > 0\r\n}\r\n\r\nexport function isPositiveInteger(value: string | number) {\r\n const string = `${value}`\r\n return isPositiveFloat(value) && Number.parseInt(string, 10) === Number.parseFloat(string)\r\n}\r\n\r\nexport function isInRange({\r\n value,\r\n min = Number.MIN_SAFE_INTEGER,\r\n max = Number.MAX_SAFE_INTEGER,\r\n}: {\r\n value: string | number\r\n min?: number\r\n max?: number\r\n}) {\r\n const parsedNumber = Number.parseFloat(`${value}`)\r\n return !Number.isNaN(parsedNumber) && parsedNumber >= min && parsedNumber <= max\r\n}\r\n\r\nexport function tryJsonParse(json: string | null = '') {\r\n try {\r\n return JSON.parse(json ?? '') as Result\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nexport function getValueInRange({ value, min, max }: { value: number; min: number; max: number }) {\r\n return Math.min(Math.max(value, min), max)\r\n}\r\n\r\nexport function isPrimaryClick(e: React.Touch | React.TouchEvent | React.MouseEvent) {\r\n // cypress trigger mouseevent has button: undefined if button option isn't explicitly specified\r\n // as cy.get('.target').trigger('mousedown', { button: 0 })\r\n if (e.hasOwnProperty('button') && (e as unknown as MouseEvent).button !== undefined) {\r\n return (e as unknown as MouseEvent).button === 0\r\n } else {\r\n return true\r\n }\r\n}\r\n\r\n// this function is used to fix the issue with circular reference when stringifying an object using JSON.stringify\r\nexport function getJSONReplacerFunc() {\r\n const visited = new WeakSet()\r\n return (key: string, value: any) => {\r\n if (typeof value === 'object' && value !== null) {\r\n if (visited.has(value)) {\r\n return\r\n }\r\n visited.add(value)\r\n }\r\n return value\r\n }\r\n}\r\n\r\n// This is a duplicate from Website repo which is accessible on window.FLibs but this doesn't work on SSR charts\r\nexport const formatDateToStringUS = (date: Date, options?: Intl.DateTimeFormatOptions | undefined) =>\r\n date.toLocaleDateString('en-US', {\r\n day: '2-digit',\r\n month: '2-digit',\r\n year: 'numeric',\r\n ...options,\r\n })\r\n\r\n// randomUUID source: https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid/2117523#2117523\r\nexport function randomUUID() {\r\n return `${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g, (substring) => {\r\n const c = Number(substring)\r\n return (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)\r\n })\r\n}\r\n\r\nexport function getUuid() {\r\n return window.crypto?.randomUUID?.() ?? randomUUID()\r\n}\r\n","import { CanvasRenderingContext2D as NodeCanvasRenderingContext2D } from 'skia-canvas'\r\n\r\nimport {\r\n CanvasElementType,\r\n ChartEditorEnum,\r\n ChartElementType,\r\n ChartEventType,\r\n IndicatorType,\r\n LayoutType,\r\n OverlayType,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../app/constants/common'\r\nimport ChartModel from '../app/models/chart'\r\nimport ChartLayout from '../app/models/chart_layout'\r\nimport { IChartThemeColors } from '../app/models/constants'\r\n\r\ninterface ISentry {\r\n captureException: (exception: any, captureContext?: { extra: ObjectHash }) => any\r\n captureMessage: (message: string, captureContext?: { extra: ObjectHash }) => any\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n Sentry: ISentry\r\n FinvizSettings: ObjectHash\r\n FinvizChartsSettings: ObjectHash\r\n globalChartConfig: RootChartConfigObject\r\n isRenderInProgress: boolean | number\r\n FinvizQuoteTypeCurrent: string\r\n handleScriptNotLoaded: () => void\r\n renderScriptNotLoaded: () => void\r\n gtag?: any\r\n }\r\n\r\n interface Document {\r\n fullscreenElement: any\r\n webkitFullscreenElement?: () => void\r\n mozFullScreenElement?: () => void\r\n msFullscreenElement?: () => void\r\n\r\n webkitExitFullscreen?: () => void\r\n mozExitFullScreen?: () => void\r\n msExitFullscreen?: () => void\r\n }\r\n\r\n interface HTMLElement {\r\n webkitRequestFullScreen?: () => void\r\n mozRequestFullScreen?: () => void\r\n msRequestFullscreen?: () => void\r\n }\r\n\r\n interface Navigator {\r\n msMaxTouchPoints: any\r\n }\r\n\r\n interface Array {\r\n last(): T | undefined\r\n }\r\n\r\n interface String {\r\n padLeft(paddingValue: string): string\r\n startsWith(str: string): boolean\r\n }\r\n\r\n type CanvasCache = Partial>\r\n\r\n interface CanvasRenderingContext2D {\r\n _cache: CanvasCache\r\n // We need to omit `canvas` because it is read only\r\n set>(\r\n key: Key,\r\n value: CanvasRenderingContext2D[Key]\r\n ): void\r\n }\r\n\r\n interface HTMLCanvasElement {\r\n _cache: CanvasCache\r\n }\r\n\r\n interface ImageBitmapRenderingContext {\r\n _cache: CanvasCache\r\n }\r\n\r\n type RenderingContext2DType = CanvasRenderingContext2D | NodeCanvasRenderingContext2D\r\n}\r\n\r\ndeclare module 'skia-canvas' {\r\n interface CanvasRenderingContext2D {\r\n _cache: CanvasCache\r\n\r\n set>(\r\n key: Key,\r\n value: CanvasRenderingContext2D[Key]\r\n ): void\r\n }\r\n}\r\n\r\nexport type TodoObjectHashAnyType = Record\r\nexport type TodoAreaObject = Record\r\nexport type ObjectHash = Record\r\nexport type EmptyObject = Record\r\n\r\nexport type TodoAnyType = any\r\n\r\nexport type ThumbType = string\r\n\r\nexport type PaneArea = {\r\n mouseDown?: boolean\r\n x: number\r\n y: number\r\n scaled: {\r\n x: number\r\n y: number\r\n }\r\n width: number\r\n height: number\r\n cursorX: number\r\n cursorY: number\r\n isCursorInChartWidthBoundaries: boolean\r\n} & T\r\n\r\nexport type Maybe = T | null | undefined\r\n\r\nexport interface DrawingBorder {\r\n color: string\r\n width: number\r\n}\r\n\r\nexport interface TextAttrs {\r\n text?: string\r\n background: string\r\n border?: { width: number; color: string }\r\n lineWidth?: number\r\n font: {\r\n size: number\r\n family?: string\r\n style?: string\r\n weight?: string\r\n }\r\n fillStyle?: string\r\n strokeStyle?: string\r\n angle?: number\r\n lineHeight: number\r\n textAlign?: TextAlign\r\n textBaseline: TextBaseline\r\n padding: {\r\n top: number\r\n right: number\r\n bottom: number\r\n left: number\r\n }\r\n}\r\n\r\nexport interface Point {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport type RequireByKey = Omit & Required>\r\n\r\nexport interface ResizeByThumbFuncProps {\r\n type: ThumbType\r\n difX: number\r\n difY: number\r\n area: PaneArea\r\n}\r\n\r\nexport type ResizeByThumbWithTypeAndDifs = RequireByKey\r\n\r\nexport interface ChartConfigChartPaneElement {\r\n type: ChartElementType | CanvasElementType | IndicatorType | OverlayType | ChartEventType\r\n overlays?: OverlayConfigObject[]\r\n period?: string\r\n code?: string\r\n elementId?: string | null\r\n zIndex?: number\r\n}\r\n\r\nexport interface RendererChartBarProps {\r\n index: number\r\n chartSettingsColors: IChartThemeColors\r\n hasFillAndBorder?: boolean\r\n}\r\n\r\nexport interface ChartConfigChartPane {\r\n elements: ChartConfigChartPaneElement[]\r\n height: number\r\n chart?: ChartConfigObject | ChartModel\r\n}\r\n\r\nexport interface IIdea {\r\n id?: number\r\n date?: string\r\n note: string\r\n}\r\n\r\nexport interface ChartConfigObjectExtended {\r\n editable: boolean\r\n canChangeTicker: boolean\r\n scrollable: boolean\r\n cross: boolean\r\n ideas: boolean\r\n editors: ChartEditorEnum[]\r\n specificChartFunctionality: SpecificChartFunctionality\r\n theme: Theme\r\n layout: LayoutType\r\n uuid?: string\r\n idea?: IIdea\r\n}\r\n\r\nexport interface ChartConfigObject {\r\n width: number\r\n height: number\r\n panes: ChartConfigChartPane[]\r\n premarket: boolean\r\n aftermarket: boolean\r\n dateRange: string | null\r\n hasChartEvents?: boolean\r\n stretch?: boolean\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n chart_layout: ChartLayout\r\n zoomFactor: number\r\n leftOffset: number | null\r\n refreshData: boolean | number\r\n isHideDrawingsActive: boolean\r\n isScrolled?: boolean\r\n scale: ScaleType\r\n}\r\n\r\nexport type RootChartConfigObjectChart = Omit<\r\n ChartConfigObject,\r\n 'chart_layout' | 'leftOffset' | 'zoomFactor' | 'isHideDrawingsActive'\r\n>\r\nexport interface RootChartConfigObject extends Partial {\r\n charts: Array\r\n width: number\r\n height: number\r\n newCharts?: boolean\r\n useGrid?: boolean\r\n}\r\n\r\nexport interface TaConfigObject {\r\n indicators: IndicatorConfigObject[]\r\n overlays: OverlayDatabaseRecordObject[]\r\n height: number\r\n style: string\r\n scale: string\r\n}\r\n\r\nexport interface IndicatorConfigObject {\r\n name: string\r\n parameters: string\r\n position: Position\r\n}\r\n\r\nexport interface OverlayConfigObject {\r\n color: string\r\n period: string\r\n type: OverlayType\r\n}\r\n\r\nexport interface OverlayDatabaseRecordObject {\r\n name: string\r\n parameters: string | null\r\n color: string | null\r\n}\r\n\r\nexport enum Instrument {\r\n Stock = 'stock',\r\n Crypto = 'crypto',\r\n MarketSentiment = 'market_sentiment',\r\n Futures = 'futures',\r\n Forex = 'forex',\r\n Group = 'group',\r\n}\r\n\r\nexport enum Theme {\r\n light = 'light',\r\n dark = 'dark',\r\n}\r\n\r\nexport interface IModalConfig {\r\n title: string\r\n inputs: IModalConfigInput[]\r\n inputsErrorMessages: ObjectHash\r\n}\r\nexport interface IOptionType {\r\n value: string | number\r\n label: string\r\n}\r\nexport interface IModalConfigInput {\r\n type: React.HTMLInputTypeAttribute\r\n label: string\r\n name: string\r\n value: number | string\r\n required?: boolean\r\n min?: number\r\n color?: string\r\n step?: number\r\n items?: IOptionType[]\r\n}\r\n\r\nexport enum Position {\r\n Above = 'above',\r\n Below = 'below',\r\n}\r\n\r\nexport enum DefaultSpineEvents {\r\n Change = 'change',\r\n Destroy = 'destroy',\r\n Refresh = 'refresh',\r\n Update = 'update',\r\n}\r\n\r\nexport enum CustomSpineEvents {\r\n IndicatorsChange = 'indicatorsChange',\r\n ManualChange = 'manualChange',\r\n}\r\n\r\nexport enum DrawingSpineOptionsEvent {\r\n Remove = 'remove',\r\n}\r\n\r\nexport interface DrawingSpineOptions {\r\n eventType: DrawingSpineOptionsEvent\r\n}\r\n\r\nexport type TodoButtonProps = ObjectHash\r\nexport type TodoButtonTheme = string\r\n"],"names":["module","exports","white","black","inherit","transparent","current","finviz","blue","gray","red","orange","amber","yellow","brightYellow","lime","green","emerald","teal","violet","purple","pink","MarketBadgeType","getMarketBadgeText","type","_date","Open","label","Closed","Premarket","Aftermarket","MarketBadge","_ref","badge","className","None","_jsx","classnames","includes","UPDATE_INTERVAL","TimeBreakpointMode","BREAKPOINTS","minWidth","Infinity","marketBadgeText","timeFormat","getTimeState","fixedTime","hasUserPremium","arguments","length","undefined","FinvizSettings","time","getDate","isHoliday","isPremarket","isAftermarket","getMarketBadgeType","TooltipBadge","props","state","useTooltipState","placement","_jsxs","_Fragment","children","TooltipTrigger","Tooltip","Heading","level","StaticBadge","findMatchingBreakpoint","compareWidth","breakpoints","filter","breakpoint","pop","getCurrentWidth","mode","element","window","innerWidth","clientWidth","Time","breakpointMode","ResizeObserver","useResizeObserver","rootRef","React","setState","currentBreakpoint","setBreakpoint","interval","setInterval","clearInterval","currentWidth","handleResize","throttle","foundBreakpoint","observer","entries","requestAnimationFrame","Array","isArray","observe","addEventListener","disconnect","removeEventListener","ref","getFormattedDateString","seed","date","Date","dateAsNY","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","isDst","dayNumber","monthIndex","getMonth","previousSunday","getDay","getIsDstInNy","setUTCHours","getWeekDay","toLocaleDateString","weekday","uppercase","name","month","toUpperCase","toString","padStart","getTime","toLocaleString","hour","minute","hour12","TimeFormat","long","getFullYear","short","dateOnly","timeOnly","formatDate","value","inputOrOutputFormat","outputFormat","dateFns","isPremium","dayOfWeek","min","getMinutes","hours","getHours","HOLIDAY_DATES","test","day","find","holiday","getHoliday","InputTheme","InputRounding","InputSize","getInputTheme","theme","isError","none","dark","input","icon","navigationBar","InputComponent","isHorizontalLabel","labelClassName","size","rounding","showNumberStepper","leftContent","rightContent","inputClass","error","caption","isMobileStyleEnabled","inputTheme","useMemo","isLeftStringIcon","isValidIconName","isRightStringIcon","inputSize","commonSideContentClassnames","Label","title","isHorizontal","small","regular","medium","large","Icon","width","ButtonPadding","InputCaption","_ref2","TextareaComponent","_ref3","textareaTheme","Input","forwardRef","Textarea","ListContext","useListState","options","Reakit","loop","unstable_virtual","ListItem","as","activeTheme","onSelectItem","onClick","onKeyPress","closeOnSelect","ev","currentTarget","id","itemProps","active","Boolean","Button","role","BUTTON_DEFAULT_ELEMENT","align","contentClass","List","selectedIndex","includeBaseStyles","onChange","prevSelected","items","move","closeParent","findIndex","item","Provider","map","child","DEFAULT_ELEMENT","ComboBoxItem","asComponent","selected","currentId","ComboBox","inputProps","popoverProps","inputTestId","ariaLabel","isFullyClosed","getExtendedDialogState","zIndex","useZIndex","autoFocus","unstable_referenceRef","focus","preventScroll","onKeyDown","key","inputValue","Portal","onTransitionEnd","onAnimationEnd","innerProps","Box","onMouseUp","INSTRUMENT_CATEGORIES","instrument","Instrument","Stock","Futures","Forex","Crypto","Centered","SearchError","Paragraph","href","link","toContact","resetErrorBoundary","Highlight","highlight","text","index","toLowerCase","indexOf","processedText","before","substring","after","SearchItem","ticker","chartIndex","company","exchange","getRedirectForTicker","tickerRaw","getSanitizedTicker","redirectLink","cleanTicker","getInstrumentForTicker","toQuote","toForexChartDetail","toFuturesChartDetail","toCryptoChartDetail","toSearch","quoteSearchExt","SearchList","data","isLoading","useQuery","searchApiRequest","enabled","keepPreviousData","cacheTime","staleTime","setAnimated","hide","animated","isShowAllVisible","COMPONENT_ANIMATION_DURATION","Spinner","isSearchItemLink","preventDefault","onTickerSelected","setInputValue","encodeURIComponent","currentValue","Search","isSearchIcon","reset","useQueryErrorResetBoundary","minValueLength","defaultValue","defaultPlacement","modal","inline","unstable_offset","listState","orientation","category","setCategory","changeCategory","first","onInputKeyDown","visible","stopPropagation","placeholder","autoComplete","autoCorrect","autoCapitalize","maxLength","onBlur","e","popoverClass","isMatchInputAndBoxWidth","style","getBoundingClientRect","maxWidth","location","allowCategorySwitching","ErrorBoundary","FallbackComponent","onReset","resetKeys","TooltipBox","color","tooltipColor","TooltipColor","isIos","tooltipProps","TooltipArrow","isBlurAfterClick","isHideOnClickOutside","onMouseEnter","onMouseLeave","document","activeElement","HTMLElement","blur","settings","transformMap","auto","top","right","bottom","left","positionMain","split","arrowColor","xmlns","viewBox","transform","d","ContentType","ThrowableError","Error","status","isServerError","body","extra","constructor","super","this","apiRequest","url","query","headers","throwOnAllErrors","controller","AbortController","requestUrl","URLSearchParams","requestOptions","ApplicationJson","cancelableRequest","fetch","signal","then","async","textResponse","response","responseContentType","get","Html","parsedResponse","contentType","ApplicationJsonUTF","FormUrlEncoded","JSON","parse","parseResponseForContentType","ok","statusText","rayId","message","catch","Sentry","scope","setContext","cancel","abort","portfoliosRequest","fields","lastCloseRequest","t","portfolioLimitRequest","portfolioId","pid","Element","Spine","static","CanvasElementType","fromObject","obj","model","getNumOfBarsBuffer","_","isCreator","isCreatorDialogOpen","attrs","_thumbs","activeThumb","isMouseDown","isSelected","isHovered","isEditInProgress","edgeXYValues","values","getDefaults","set","defaults","onMouseDown","bind","onMouseMove","getIsChartEvent","chartEvents","findByAttribute","elements","trigger","getThumbs","moveBy","__","setIsSelected","setIsHovered","getShouldRenderThumbs","getIsPaneSelection","paneModel","pane","selection","attrsSubset","Object","keys","reduce","acc","stringify","customizer","objValue","srcValue","getIsDrawing","mergewith","getIsCreator","cachePointPositionTimestamp","getBoundingPointKeys","fx","x","scale","fy","y","scaled","forEach","el","defineProperty","render","renderThumbs","context","globalAlpha","thumb","area","isInArea","startEditing","mouseDown","moveTo","quote","chart","xPointKeys","positionTimestamps","positionX","getTimestampFomPositionX","updateScales","pointPoitionsFromTimestamp","timestamp","getPositionXFromTimestamp","thumbsAreInArea","isDrawingElementLockedOrInvisible","chart_layout","isLockDrawingsActive","getIsVisible","getModalConfig","config","getModalConfigBase","merge","modalConfig","inputs","push","default","toObject","toConfig","getAutosaveOmittedProperties","toAutosaveConfig","omit","replaceMyself","setTimeout","replace","captureMessage","oldElement","newElement","getIsCreatorDialogOpen","release","unbind","getChartLayoutSettings","startsWith","micro","macro","MicroMacroTimeframe","timeframe","visibility","isInRange","from","max","to","setVisibilityTo","setTo","currentIndex","MacroTimeframe","timeframesToSet","attrsToSet","SetVisibilityTo","currentAndAbove","currentAndBelow","currentOnly","all","assign","getEdgeXYValues","xPoints","yPoints","minX","Math","maxX","positionY","minY","maxY","getIsInChartView","omitX","isMaxXInvalid","isNaN","isMinXInvalid","leftOffset","omitY","topBound","invert","bottomBound","height","Line","line","resize","Thumb","x1","y1","x2","y2","lineWidth","strokeStyle","ElementSettings","Colors","roundedXY","getRoundedObject","translateXY","getXYOffsetFromLine","translate","beginPath","dashLength","setLineDash","lineTo","stroke","difX","difY","math","distanceToSegment","DEFAULTS","font","family","weight","lineHeight","textAlign","TextAlign","textBaseline","TextBaseline","alphabetic","padding","Text","getMergedPropsWithDefaults","propKey","initClass","prototype","setupContext","measure","count","getLines","f","required","textWithoutBackground","fillStyle","angle","save","rotate","PI","fillText","restore","renderBackground","renderText","lines","measureText","testArea","convertArea","background","rawHight","rect","fill","renderBorder","closePath","border","borderWidth","ChartSettings","getHeight","lastX","lastY","ThumbSettings","borderColor","thumbWidth","getThumbWidth","offset","getOffsetFromLineWidth","canvas","createElement","callback","rendered","refresh","ratio","drawImage","cWidth","cHeight","sWidth","screen","sHeight","getScaleRatio","setSizeOnCanvasElement","canvasElement","OHLCType","ChartMinWidthBreakpoints","getChartBreakpoints","chartWidthInPx","isXs","xs","isS","s","isM","m","isL","l","getDateString","dateString","year","TIMEFRAME","i1","i2","i3","i5","i10","i15","i30","h","h2","h4","padLeft","MONTHS","w","getClosestDifferentMinMaxValueIndices","currentMinIndex","currentMaxIndex","high","low","hasPreviousIndex","hasNextIndex","minIndex","maxIndex","gray300","tailwindColors","BaseChart","_ref4","overlays","overlay","overlaysByType","specificChartFunctionality","tickerWidth","changeWidth","lastOhlc","isLargeChart","shouldRenderVolume","afterChange","chartLayoutModel","isMobile","utils","overlayDefinition","convertColorToHEX","addOverlay","renderYAxis","renderCrossText","setupCache","renderOverlaysLabels","CustomSpineEvents","IndicatorsChange","handleIndicatorsChange","mouseModelChangeHandler","mouseModel","unmountCanvas","baseCache","updateShouldRenderVolume","renderChart","close","renderChartNotAvailable","getIsRedesignedChart","renderTicker","clip","renderVolume","renderOverlays","renderPrevClose","renderFadeExtendedHours","renderGrid","renderXAxis","tickerText","getIsSmallIndexChart","general","margin","FONT_SIZE","XXS","OFFSET","baseline","renderTimeframe","volumeFY","range","Group","getTimeframeLabel","textSecondary","center","L","SpecificChartFunctionality","offScreen","XS","renderChange","getOHLC","directRender","_ref5","changePercentage","lastDate","renderOHLC","isSmallIndexChart","isNewestOHLC","open","volume","numberToStringWithUnitsSuffix","Number","afterHour","isFinite","afterClose","lastClose","roundOhlc","lastVolume","last","toLocaleTimeString","getRoundedLastData","lastOpen","lastHigh","lastLow","renderOverlaysLabelsChartsPage","renderOverlaysLabelsQuotePage","overlayLabel","isRenderedOverlaysLabel","labelSpacing","getLabelColor","getYAxisLeftMargin","getYAxisLastCloseLabel","_ref6","firstVisibleClose","ScaleType","Percentage","round","getPercentageFromValue","number","base","renderLabels","contentHeight","lineTicks","textTicks","lastCloseLabel","getTranslate","xOffset","yOffset","do","tickCount","floor","minMax","getMinMax","placesAxis","stepPrice","scaleRange","updateAttribute","minPerc","maxPerc","d3","domain","nice","ticks","tick","getValueFromPercentage","Logarithmic","pixelGap","negativeScale","previousNegativeTick","unshift","positiveScale","previousTick","positiveScaleY","abs","getYLineText","val","places","yTickText","axis","middle","yTickLine","getYLine","resetYTicksStyles","i","percentageZeroLineText","undo","renderYAxisLabel","yCoordinate","getSecondaryLabelBackgroundColor","stringifyHSVAColor","getHSVAFromColor","currentBackground","getYAxisSecondaryLabelYCoordinate","_ref7","mainLabelValue","secondaryLabelValue","direction","sign","LINE_HEIGHT","S","PADDING","mainLabelValuePosition","secondaryLabelValuePosition","offsetedY","_ref8","currentText","getDrawDays","MarketSentiment","textRenderer","startBarIndex","getFirstBarToRenderIndex","endBarIndex","getLastBarToRenderIndex","chartWidth","ChartElementType","LineChart","render15MinXAxis","renderIntradayXAxis","renderIntradayXAxisFutures","renderDailyXAxis","renderWeeklyXAxis","renderMonthlyXAxis","isXPointVisible","buffer","renderXAxisLabels","_ref9","labels","allowedOverflow","sortedLabels","renderedLabelRanges","reverse","textWidth","newLabel","hasPriority","_ref10","halfOfTextWidth","overflowLeft","overflowRight","labelX","some","getIsOverlapping","M","IntradayTimeframeInterval","marketStartHour","marketStartMinutes","marketEndHour","ceil","aftermarketLengthMinutes","xLine","getXLine","barWidth","getBarWidthWithMargin","zoomFactor","chartLayout","dayToOffset","getDayToOffset","dayIndex","dateFromDateString","drawMinutesPerDay","roundedX","premarketLengthMinutes","_ref11","lastDay","lastHours","NaN","_ref12","indexOffset","barIndex","getBarsInDay","_ref13","lastMonth","_ref14","gridSecondary","isYearLabel","_ref15","lastYear","isJanuary","getIsIndicatorPresent","IndicatorType","Vol","getVolumeTicks","maxHeight","fontHeight","renderVolumeAxis","relativeVolume","toFixed","grid","fillRect","strokeRect","rangeMax","volumeAxisFontSize","volumeAxis","format","tickFormat","domainFrom","domainTo","setupAxisTimeFrame","halfBarWidth","getHalfBarWidth","barWidthWithoutMargin","getBarWithoutMarginWidth","drawInVisibleArea","drawBarCallback","volumeTrendDown","volumeTrendUp","renderContent","renderCross","isRendered","contentWidth","getRoundDecimalPlaces","price","getPlacesLastClose","onRenderCrossText","getCrossIndexForPane","setElementCursor","elementId","getHTMLElementId","cursor","conditionalCursor","getDataByCrossIndex","crossIndex","shouldReturnRoundedString","n","getDataByBarIndex","getCrossIndexChange","crossDataIndex","getDataIndexByBarIndex","crossClose","previousClose","getTickerChangeFromCloseValues","anchorClose","prevClose","dateByBarIndex","virtualTradedDates","getVirtualTimeframeTradedDates","dateStart","dateEnd","_ref16","change","ohlc","tickerChange","tickerAfterChange","getTickerChange","isOffscreen","isGroupInstrument","changeText","percentString","string","getChangeColor","points","afterChangeText","afterChangeTextWidth","oneLineAHChangeWidth","parameters","renderOHLCChartsPage","renderOHLCQuotePage","_ref17","chartBreakpoints","OhlcText","getHEXWithSpecificAplha","canvasFill","dateElements","trendColor","oElements","hElements","lElements","cElements","volElements","changeElements","getFlatLineArrayWithSpaces","lineElements","flatMap","startX","lineElement","LabelsText","numberOfNewOhlcLines","_ref18","lineTopY","OHLCFontSize","centerXOffset","leftXOffset","OHLC","ohlcString","singleLine","OHLC_TEXT","getOHLCType","ohlcSettings","getOHLCSettings","CHART_MARGIN","XXL","alignTop","renderOHLCToCanvas","_ref19","ohlcSet","isSingleLineWithChange","period","parseInt","n0","n1","x0","premarketFade","aftermarketFade","shouldShowPrevClose","isStock","isIntradayWithPreMarket","TIMEFRAMES_WITH_PRE_MARKET","isIndexChart","smallIndex","Cache","getIsMobileChartPage","setupAxis","volumeHeight","volumes","addMarginBottom","marginBottom","setOverlays","removeOverlay","splice","MAX_VALUE","MIN_VALUE","start","end1","asc1","closestMinMaxIndices","dateRange","overridePlaces","num","placesLastClose","barFillWidth","barBorderWidth","getBarWidthWithMarginByParts","priceAbs","hasOverlay","chartPage","getCandleLikeChartsRenderingColors","colors","overwrittenColors","getColorOverwrites","overwrittenColorKeys","hasOverwrittenCandleColor","colorKey","Theme","light","getShouldUseDarkerWickColors","totalBarWidth","darkerWickColors","thinBarColorsOverride","isRedesignedPage","CandleStick","Chart","getRenderChartBarProps","chartSettingsColors","hasFillAndBorder","trendDown","trendUp","borderDown","borderUp","wickDown","wickUp","wickColor","barFillColor","shouldRenderFillAndBorder","HollowCandleStick","translateForWick","WICK_WIDTH","candleBodyHigh","candleBodyLow","candleWickHigh","candleWickLow","candleBodyHeight","candleBodyLeftX","halfBorderWidth","getIsSSr","isBodyHeightGreaterOrEqualBorders","isWickLineCandleLessThanOnePixel","hasBorder","fillHeight","hasFill","isHollow","generalTrendColor","ohlcTrendUp","ohlcTrendDown","zeroChange","HeikinAshi","haData","getHeikinAshiData","getLastValues","originalLatestClose","heikinLatestCloseLabel","originalLatestCloseLabel","redLine","greenLine","MarketSentimentSettings","arr","sum","_data","lastIndex","_dataLastIndex","renderLineBullBear","array","oversold","overbought","isRedesign","isRedesignEnabled","marketDown","marketUp","_compute","computeVisibleMinMax","yLine","fillUp","fillDown","percent","months","MultiLineChart","tickersDimensions","ColorsSettings","quotes","getQuotes","tickers","end","asc","maxTickerLength","isLastDate","XXXS","closeValue","_len","arrays","_key","q","Quote","select","isIdeaId","ideaID","OHLCChart","OhlcChart","barWithoutMarginWidth","lineThickness","handleLengthFromWick","lineOffset","barX","PerfChart","overlayLabelWidth","perf","shouldRenderDate","tickerData","MARGIN","hasData","percentageText","lastCrossIndex","fromDate","toDate","filteredQuotes","closes","daysCount","end2","asc2","monthsInData","availableTickSpots","monthsToAvail","renderMonth","chartsByType","freeze","candleStick","heikinAshi","hollowCandleStick","lineChart","marketSentiment","multiLineCharts","ohlcChart","perfChart","XXXL","XL","SETTINGS_HEIGHT","TICKER_TIMEFRAME_CHANGE_HEIGHT","ChartEditorEnum","LayoutType","OverlayType","ChartEventDbType","ChartEventType","ChartEventBadgeType","ChartEventLabels","Dividends","Split","EarningsPositive","EarningsNegative","EarningsNeutral","EarningsFuture","LAYOUTS","columns","rows","gridAreas","SORT_DIRECTION","ASC","DESC","DateRangeType","TIMEFRAME_SECONDS","CRYPTOS","BTCUSD","LTCUSD","ETHUSD","XRPUSD","BCHUSD","BTCEUR","LTCEUR","ETHEUR","XRPEUR","BCHEUR","LTCBTC","ETHBTC","XRPBTC","BCHBTC","QuotePollingIntervalInMs","EXTRA_MARKET_BUFFER_MINUTES","ScaleLabel","Linear","PANE_HEIGHT_DEFAULT","indicator","INDICATOR_LABEL_HEIGHT","MOBILE_BARS_TO_VIEW","MOBILE_VIEW_BREAKPOINT_WIDTH","FREE_DATE_RANGES","QuotePageQueryChartTypes","minutes","days","weeks","MicroTimeframeRange","prev","curr","QUOTE_FETCH_EVENT","PREMARKET_AFTERMARKET_HOURS","CustomDateRangePrefixEnum","DATE_RANGE_PREFIX_DELMITER","getParsedDateRange","getVisibleBarsNumber","startInSec","endInSec","lastQuoteDateIndex","lastVisibleBarIndex","numOfVisibleBars","d1","d5","firstVisibleBarIndex","quoteDate","isQuoteDateInRange","numOfBarsOffset","getChartZoomAndLeftOffset","chartVisibleWidth","chartModel","numOfBarsToRender","getZoomFactorForBarsToDisplay","getLeftOffset","numberOfBarsToDraw","getChartStartEndDates","daysInQuote","getDaysInQuote","dateFromUnixTimestamp","anchorDate","dateRangePrefix","dateRangeValue","Range","dateFromString","dateToString","dateFrom","dateTo","Prev","years","parseCustomDateRangeUrlParam","convertLocalToNyTime","setHours","startDateIndex","m1","m3","m6","ytd","y5","getMinMaxLeftOffset","newLeftOffset","numOfBarsInView","Utils","getIntradayChartConfig","timeframeMinutes","barWidthWithMargin","hasPremarket","hasAftermarket","fullChartWidth","marketMinutesLength","getFullChartWidth","offsetInPx","shouldCropChart","chartWidthWithOffset","offsetChartAfter","getBarIndex","shouldAlignDaysToLeftApplied","stretch","shouldAlignDaysToLeft","drawDaysInOneChart","premarket","aftermarket","lastQuoteDate","barsToOffset","offsetChartInPx","isStockIntraday","isIntraday","isQuoteOrOffscreen","quotePage","isChartPage","isChartsInradayDateRange","canvasCtx","Settings","getSettings","IndicatorSettings","isIndicator","getShouldOffsetChartDomain","elementModel","recountScale","getAllElements","getAllChartEvents","instance","isChart","scaleType","handleDomainOffset","currentScale","scaleCreator","protectedHeightPx","CHART_EVENT_BADGE_SIZE","minPx","extendedMin","rounded","fromEntries","updateZoomAndLeftOffsetByDateRange","parsedRange","startQuoteDate","endQuoteDate","numOfDaysToRender","reversedDaysInQuote","startQuoteDayIndex","endQuoteDayIndex","renderDateStart","renderDateEnd","getParsedDateRangeMetaData","updateAttributes","renderPane","shouldRenderCross","clearRect","elementInstance","isDrawing","isChartEvent","isHideDrawingsActive","add","tr","BigNumber","BIG_NUMBER_VALUES","Thousand","Million","Billion","Trillion","BIG_NUMBER_ZEROES","BIG_NUMBER_SUFFIX","dotProduct","p1","p2","crossProduct","distance","sqrt","pow","lineEquation","a","b","c","k","pointInPolygon","point","polygon","j","oddNodes","p","distanceToLine","l2","getInstrumentDecimalPlaces","formatBigNumber","minNumber","absNum","getString","suffix","zeroes","str","splitString","addZeroes","padEnd","numberByZeroesCount","result","isInteger","perpendicularPointToLine","yAxisCoeficient","xAxisCoeficient","radAngle","atan2","cos","sin","rotatedPointCoordinates","rotationAxisPoint","pointToRotate","sharedPointLinesAngle","sharedPoint","oldLinePoint","newLinePoint","atan","twoSegmentLinesIntersection","p3","p4","denominator","ua","ub","checkLineIntersection","line1_p1","line1_p2","line2_p1","line2_p2","onLine1","onLine2","numerator1","numerator2","getRayToLineSegmentIntersection","rayOrigin","rayEnd","segmentStart","segmentEnd","lineIntersection","subtractPoints","getMiddlePointOnLineSegment","P1","P2","normalizeVector","v","multiplyVectorByScalar","scalar","addPoints","ExponentialMovingAverage","multiplier","EMACalculation","MainCalculation","Ema","getDefaultCalculatedValues","ema","calculate","onValueCalculated","_calculatedValues","calculatedValues","Indicator","getAllCalculatedValues","lastNItems","getCalculatedValues","slice","getDbColumnName","sort","key1","key2","localeCompare","join","ChartSyncablePart","ChartPartToAttrsSyncMap","Ticker","Timeframe","ChartSyncableParts","Crosshair","normalizeHexAlpha","hexString","customColors","customColorKeys","defaultColors","chartLightTheme","chartDarkTheme","cross","crossText","crossTextBackground","indicatorCurrentBackground","indicatorCurrentText","negativeChange","overlayTransparentBackground","performanceIndicatorLabel","positiveChange","indicatorLightTheme","signalLine","indicatorDarkTheme","elementLightTheme","elementDarkTheme","generalColors","AutoSaveState","MARKET_START","END_OF_DAY","roundTimeForSyncedPane","sourceChart","targetChart","dateToReturn","sourceChartHasPremarket","targetChartHasPremarket","setDate","lastDayOfMonth","lastDayOfWeek","weekStartsOn","endOfDay","getIsDateBeforeMarketStart","Mouse","configure","belongsTo","Pane","getIsCrossSyncOn","getIsChartPartInSync","getIsMouseInChartOfPane","eql","getShouldRenderCrossInPane","position","paneOfMouse","mouseInChart","currentPaneChart","mousePositionTimestamp","currentPanePositionX","getPriceForPane","mousePaneIndex","getIndexInChart","mouse","create","CHART_EVENT_BADGE_TYPE_ORDER","chartEventElementModel","hasMany","destroyCascade","destroy","omitKeys","chartPanes","getAllPanes","chartPane","getIsIndicatorPane","targetPane","currentChartPaneRecords","records","chart_id","ohterChartPaneRecords","targetRecordIndex","record","arrayWithoutTargetRecord","chartRecordIndex","panesAbove","panesBelow","Position","Above","getNumericId","Below","concat","isSorted","getChartOrIndicatorElement","mainElement","getIsChartPane","resetHeight","getElementZIndexRange","getBelowAboveZeroElements","allPaneElements","elementsBelowZero","elementsAboveZero","normalizeZIndexes","rebuildElementZIndexes","elementsArray","isBelowZero","getQuoteRawTicker","updateChartEventsZIndexes","hasOwnProperty","hoveredChartEvent","chartEvent","openedChartEvent","isOpen","hoveredTypeChartEventElements","openedTypeChartEventElements","nonActiveChartEventElements","chartEventsOnSameXPoint","chartEvent_B","yIndex","isOpened","isHoveredType","isOpenType","getChartEvenBadgeType","quoteCache","getCachedQuote","cid","fetchedAt","cachedAt","setCachedQuote","emptyQuote","numberOfRefreshChecks","isFetching","is404","COTs","patterns","patternsMinRange","patternsMaxRange","dataId","abortController","shouldUseCache","chartUuid","doesQuoteAndFetchParamsMatch","uuid","isSameOrNoChartUuid","isNotEmptyQuote","cachePredicate","isCacheAllowed","hasPatterns","events","doesQuoteAndOptionsMatch","getResolvedFetchingPromise","fetchNewDataOnCachedQuote","fetchData","fetchType","QuoteFetchType","NewerData","newQuote","maxBars","Refetch","getAll","tickersAndTimeframes","Promise","accumulator","err","fetchRequest","QuoteFetchTypeUrlOption","New","wasFetchAborted","fetchingPromise","fetchApi","getUrl","throwOnStatusCodes","getIsAbortError","NotFoundError","shouldUseEmptyQuote","isPossibleToFetchSequentialData","Newer","noNewData","newQuoteData","lastTime","afterTime","now","AIndex","BIndex","mergeIndex","ADate","BDate","prevAIndex","prevDate","newDate","isSameWeek","isSameMonth","console","warn","thisDateLength","dataDateLength","fetchOlderData","load","atts","drawDays","getBarIndexes","barToDataIndex","eventType","Earnings","dateTimestamp","getChartEventsWithId","deleteCachedQuote","cachedHeikinAshiData","HAClose","heikAshiData","cachedDayToOffset","dateStringFromDate","yyyy","mm","dd","String","dataIndex","getDateToIndex","cachedDateToIndex","dateToIndex","getTimestampFromPositionX","host","process","env","BE_API_URL","queryString","rev","getRawTicker","getRawTickerForInstrument","clearData","largeChartFontSize","INTERACTIVE_CHART_SETTINGS","settingsHeight","tickerTimeframeChangeHeight","barMargin","indicatorLabel","touchSize","defaultFill","defaultTransparentFill","chartSettings","colorsOverride","settingColors","charts","updateSettings","isLight","handleRemoveIndicatorPane","paneIndex","getAllCharts","getNormalizedZIndex","newZIndex","changeElementZIndexes","addElement","oldZIndex","BbCalculation","Bb","sma","stdDev","upperBand","lowerBand","deviations","stdDevSum","Overlay","periodInt","getParsedIntegersFromPeriodString","getFreeColor","getIsValid","getIsNumberInputValid","integerOnly","isPositiveInteger","inputsErrorMessages","periods","getRGBAValueFromValidColorString","BB_COLORS","TOP","BOTTOM","MIDDLE","DEFAULT_PARAMETERS","BollingerBands","periodStr","parseFloat","parsePeriod","scaledTop","scaledBottom","firstBarToRender","lastBarToRender","bbCalculation","step","topColor","bottomColor","COLORS","DonchianChannels","Dch","medianBand","strokeColor","channelStrokeColor","fillColor","channelFillColor","medianBandColor","EMA","EMA2","Ema2","HighLow","Hilo","halfWidth","highColor","prevHigh","highestHigh","lowColor","prevLow","prevBar","lowestLow","HorizontalLine","Hline","isPositiveFloat","Stroke","Fill","Conversion","Base","SpanB","conversion","spanB","IchimokuCloud","Ic","renderFull","outsideBar","spanAFillColor","spanAStrokeColor","spanBFillColor","spanBStrokeColor","baseLineColor","conversionLineColor","laggingSpanColor","conversionLine","baseLine","senkouSpanA","senkouSpanB","conversionStartIndex","baseStartIndex","spanBIndex","highestHi","lowestLo","lastSpanAX","lastSpanBX","cloudStartingX","fxOverride","toIndexOffset","IchimokuCloudFull","Icf","KeltnerChannel","Kch","emaPeriod","atrPeriod","atr","AverageTrueRange","middleLine","Patterns","originalScale","barsInDay","scaleY","aboveBelow","textHS","above","below","supportColor","resistColor","pattern","x3","y3","kind","Calculation","PivotPeriod","PivotPoints","Pp","calculationType","getPeriodType","week","getIsEnoughData","startIndex","endIndex","periodType","dayGap","startDay","beforeDay","calculatedX","fromX","toX","currentDate","previousTradingDay","previousNYMidnightTimestamp","currentMidnight","currentNYMidnightTimestamp","ts","diff","isNonStockFullDay","isStockFullDay","MIN_SAFE_INTEGER","firstDayCurrentWeek","firstDayCurrentWeekTimestamp","firstDayPreviousWeek","firstDayPreviousWeekTimestamp","firstDayCurrentMonth","firstDayCurrentMonthTimestamp","firstDayPreviousMonth","firstDayPreviousMonthTimestamp","firstDayCurrentYear","firstDayCurrentYearTimestamp","firstDayPreviousYear","firstDayPreviousYearTimestamp","pivot","sup1","sup2","sup3","res1","res2","res3","previousHigh","previousLow","pivotPoint","currentX","toBars","nextDate","SAR","Sar","maxStep","deltaHigh","deltaLow","isLong","sar","ep","newHigh","newLow","af","sarToDraw","risingColor","fallingColor","customizable","SMACalculation","Sma","SMA","chartConfig","SMA2","Sma2","Supertrend","Str","finalUpperBand","finalLowerBand","supertrend","uptrendColor","avg","downtrendColor","VP_COLORS","applyOpacityToColor","opacity","VolumeProfile","Vp","upColor","downColor","minClose","maxClose","segment","segments","up","down","segmentIndex","isInSegment","volumeTrend","volumeFX","segmentHeightRaw","segmentHeight","upSegmentWidth","downSegmentWidth","VWapCalculation","Vwap","vwap","cumulativePV","cumulativeVolume","second","datesAreOnSameDay","VWAP","bb","dch","ema2","hilo","hline","ic","icf","kch","pp","sma2","vp","args","arg","_len2","_key2","_len3","_key3","devicePixelRatio","getQuoteDateTimestampOffsetInSeconds","referenceDate","addOffset","quoteDateTimeOffsetInMs","localTimeOffsetInMs","getTimezoneOffset","offsetDirectionCoefficient","setTime","isStockFastRefreshAvailable","bufferMinutes","currentDayMinutes","premarketMinutes","aftermarketMinutes","isWeekend","isClosed","setUTCSeconds","captureException","testTouchPoints","isMobileOs","navigator","userAgent","createEvent","match","msMaxTouchPoints","maxTouchPoints","isIPad","matchesIPad","matchesIPhone","matchesIPod","getCookie","re","RegExp","cookie","setCookie","expires","toUTCString","hostname","getFullscreenStatus","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","getRequestFullscreen","requestFullscreen","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen","getExitFullscreen","exitFullscreen","webkitExitFullscreen","mozExitFullScreen","msExitFullscreen","ready","fn","readyState","getChartsDimensions","chartElementId","containerElement","getElementById","box","getIsMobileScreenSize","getIsMobilePortrait","hasRedesignEnabled","matchingPages","forexPage","futuresPage","cryptoPage","requestsAbortControllersCache","removeFromAbortCache","createRequestAbortController","shouldAbortRunningRequest","abortRequest","shouldUseCPUOnly","matchesAndroid","matchesWebOS","matchesiPad","matchesBlackBerry","matchesWindowsPhone","matchesIOSLike","isMobileDevice","isFirefoxDesktop","getContextWithCache","getContext","willReadFrequently","_cache","_restore","CanvasRenderingContext2D","apply","DAY_IN_SECONDS","TWO_MIN_IN_MS","virtualDatesCache","areTimestampsFromSameDay","ts1","ts2","ts1Utc","ts2Utc","getVirtualDatesCacheId","idRevision","setCachedVirtualDates","fromSeconds","toSeconds","virtualDates","virtualDatesCacheId","lastUsed","checkVirtualCacheSize","MAX_BAR_BORDER_WIDTH","MIN_BAR_MARGIN_WIDTH","MAX_BAR_MARGIN_WIDTH","settingsCenter","barMarginWidth","shouldRound","roundDecimalPlaces","DEFAULT_ZOOM_GUESS_INCREMENT","zoomFactorForBarsToDisplayCache","zoomFactorForBarsToDisplayCacheKeys","getZoomFactorFromCache","setZoomFactorToCache","poppedKey","defaultBarWidthWithMargin","cacheKey","zoomIncrement","currentZoomFactor","finalZoomFactor","iteration","threshold","barWidthDiff","getTimeframeSeconds","lowerIndex","dates","upperIndex","isWithinRangeOfQuoteDate","commonVirtualCacheProps","cachedDates","cache","virtualDateSeconds","getCachedVirtualDates","timeframeSeconds","firstDate","numOfDatesBefore","numOfDatesAfter","virtualTradedDays","dateStartSeconds","dateEndSeconds","datesSeconds","isStartBeforeDates","isEndAfterDates","dateTime","getVirtualTradedDays","marketStartSeconds","barTimeframeSeconds","quoteDatesTimestampOffset","dayStartSeconds","barSeconds","virtualTimeframeTradedDates","isLowerBounded","isOneBeforeLowerBoundStarts","lastDateIndex","isLookingBack","averageBarDate","numOfSecondsOutOfBounds","getInstrument","prefetchPerfIndicatorAllQuotes","paneWithPerfIndicator","perfIndicatorElement","getPerfIndicatorTickerAndTimeframes","promises","resolve","isPerfIndicator","isXAxisInView","domainRange","priceFy","YAxisLeftMargin","firstBarClose","_ref20","changePoints","changePercent","changePercentString","_ref21","isForexFuturesCryptoPage","_ref22","isForexFuturesCrypto","isOffscreenChartWithNarrowBars","isQuoteChartWithNarrowBars","DRAWING_COOKIE_NAME","getIsDrawingEnabled","getIsSidebarEnabled","hasSidebarEnabled","handleTypeChange","_ref23","getIsPreserveDrawingsAndAutosaveAvailable","editable","editors","tools","hexStringToRGBA","hexColor","removeHashSymbol","r","g","rgbaToHexString","alpha","alphaToHex","rgbaToHSVA","hsvaToRGBA","rgbaToRGBAString","rgbaStringToObject","colorParts","exec","strColor","allowAlpha","getIsRgb","rgbKeys","output","canSelectAlpha","hsvaToHEXString","pushIndicators","panes","cotKeys","code","Cot","hasPaneWithCOTCode","getChartTypeByTaConfigStyle","candlestick","heikinashi","hollowcandlestick","mergeChartAndTAConfig","taConfig","linear","percentage","logarithmic","indicators","getPanes","fromIndexOffset","getFormDataFromObject","object","formData","append","FormData","GenericStatusCodeError","statusCode","ForbiddenError","InternalServerError","GoneError","queryParameters","method","throwOnPredicate","keepalive","credentials","responseData","getStatusCodeError","getRoundedString","numOfDecimalPlaces","precision","periodString","part","exception","captureContext","parsedNumber","MAX_SAFE_INTEGER","getValueInRange","isPrimaryClick","button","getJSONReplacerFunc","visited","WeakSet","has","formatDateToStringUS","getUuid","crypto","randomUUID","getRandomValues","Uint8Array","DefaultSpineEvents","DrawingSpineOptionsEvent"],"sourceRoot":""}