diff --git a/src/routes/etf/[tickerID]/+page.svelte b/src/routes/etf/[tickerID]/+page.svelte index 3a160914..feb6fd79 100644 --- a/src/routes/etf/[tickerID]/+page.svelte +++ b/src/routes/etf/[tickerID]/+page.svelte @@ -1,1162 +1,1397 @@ - - - - - - - - {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ''} {$displayCompanyName} ({$etfTicker}) Statistics & Valuation Metrics · stocknear - - - - - - - + + + +let displayData; +let colorChange; +let topColorChange; +let bottomColorChange; + +let lastValue; +async function changeData(state) { - - - - - + switch (state) { + case '1D': + displayData = '1D'; + if(oneDayPrice?.length !== 0) + { + displayLastLogicalRangeValue = oneDayPrice?.at(0)?.close; //previousClose + const length = oneDayPrice?.length; + for (let i = length - 1; i >= 0; i--) { + if (!isNaN(oneDayPrice[i]?.close)) { + lastValue = oneDayPrice[i]?.close; + break; + } + } + + } + else { + displayLastLogicalRangeValue = null; + lastValue = null; + + } + + + break; + case '1W': + displayData = '1W'; + await historicalPrice('one-week'); + if(oneWeekPrice?.length !== 0) + { + displayLastLogicalRangeValue = oneWeekPrice?.at(0)?.close; + lastValue = oneWeekPrice?.slice(-1)?.at(0)?.close; + + } + else { + displayLastLogicalRangeValue = null; + lastValue = null; + + } + + + break; + case '1M': + displayData = '1M'; + await historicalPrice('one-month'); + if(oneMonthPrice?.length !== 0) + { + displayLastLogicalRangeValue = oneMonthPrice?.at(0)?.close; + lastValue = oneMonthPrice.slice(-1)?.at(0)?.close; + + } + else { + displayLastLogicalRangeValue = null; + lastValue = null; + + } + break; + + case '6M': + displayData = '6M'; + await historicalPrice('six-months'); + if(sixMonthPrice?.length !== 0) + { + displayLastLogicalRangeValue = sixMonthPrice?.at(0)?.close; + lastValue = sixMonthPrice?.slice(-1)?.at(0)?.close; + + } + else { + displayLastLogicalRangeValue = null; + lastValue = null; + + } + break; + case '1Y': + displayData = '1Y'; + await historicalPrice('one-year'); + if(oneYearPrice?.length !== 0) + { + displayLastLogicalRangeValue = oneYearPrice?.at(0)?.close; + lastValue = oneYearPrice.slice(-1)?.at(0)?.close; + } + else { + displayLastLogicalRangeValue = null; + lastValue = null; + } + + break; + case 'MAX': + displayData = 'MAX'; + await historicalPrice('max'); + if(threeYearPrice?.length !== 0) + { + displayLastLogicalRangeValue = threeYearPrice?.at(0)?.close; + lastValue = threeYearPrice.slice(-1)?.at(0)?.close; + + } + else { + displayLastLogicalRangeValue = null; + lastValue = null; + + } + + break; + default: + return; + } + colorChange = lastValue < displayLastLogicalRangeValue ? "#FF2F1F" : "#10DB06"; + topColorChange = lastValue < displayLastLogicalRangeValue ? "rgb(255, 47, 31, 0.2)" : "rgb(16, 219, 6, 0.2)"; + bottomColorChange = lastValue < displayLastLogicalRangeValue ? "rgb(255, 47, 31, 0.001)" : "rgb(16, 219, 6, 0.001)"; - + fitContentChart(); + + + //trackButtonClick('Time Period: '+ state) +} + + + + +async function historicalPrice(timePeriod:string) { + + const cachedData = getCache($etfTicker, 'historicalPrice'+timePeriod); + if (cachedData) { + switch (timePeriod) { + case 'one-week': + oneWeekPrice = cachedData + break; + case 'one-month': + oneMonthPrice = cachedData + break; + case 'six-months': + sixMonthPrice = cachedData + break; + case 'one-year': + oneYearPrice = cachedData + break; + case 'max': + threeYearPrice = cachedData + break; + default: + console.log(`Unsupported time period: ${timePeriod}`); + } + } else { + output = null; + + const postData = { + ticker: $etfTicker, + timePeriod: timePeriod, + }; + + const response = await fetch(data?.apiURL+'/historical-price', { + method: 'POST', + headers: { + "Content-Type": "application/json", "X-API-KEY": data?.apiKey + }, + body: JSON.stringify(postData) + }); + + output = await response?.json() ?? []; + + const mapData = (data) => data?.map(({ time, open, high, low, close }) => ({ + time: Date.parse(time), + open, + high, + low, + close + })); + + const mappedData = mapData(output); + try { + switch (timePeriod) { + case 'one-week': + oneWeekPrice = mappedData + break; + case 'one-month': + oneMonthPrice = mappedData + break; + case 'six-months': + sixMonthPrice = mappedData + break; + case 'one-year': + oneYearPrice = mappedData + break; + case 'max': + threeYearPrice = mappedData + break; + default: + console.log(`Unsupported time period: ${timePeriod}`); + } + setCache($etfTicker, mappedData, 'historicalPrice'+timePeriod); + + } catch (e) { + console.log(e); + } + + } +} + +async function initializePrice() { -
-
-
-

- Fundamental Data -

+ output = null; + if (intervalId) { + clearInterval(intervalId); + } + intervalId = setInterval(checkChart, 0); + try { + + output = [...data?.getOneDayPrice] ?? []; + oneDayPrice = output?.map(item => ({ time: Date.parse(item?.time), open: item?.open !== null ? item?.open : NaN, high: item?.high !== null ? item?.high : NaN, low: item?.low !== null ? item?.low : NaN, close: item?.close !== null ? item?.close : NaN})); + + displayData = oneDayPrice?.length === 0 && sixMonthPrice?.length !== 0 ? '6M' : '1D'; + //lastValue = oneDayPrice[oneDayPrice?.length - 1]?.value; + if (displayData === '1D') + { + const length = oneDayPrice?.length; + for (let i = length - 1; i >= 0; i--) { + if (!isNaN(oneDayPrice[i]?.close)) { + lastValue = oneDayPrice[i]?.close; + break; + } + } + } + else if (displayData === '6M') { + lastValue = sixMonthPrice?.slice(-1)?.at(0)?.close + } + + + displayLastLogicalRangeValue = oneDayPrice?.length === 0 && sixMonthPrice?.length !== 0 ? sixMonthPrice?.at(0)?.close : oneDayPrice?.at(0)?.close //previousClose; + + //colorChange = lastValue < displayLastLogicalRangeValue ? "#CC3636" : "#367E18"; + + colorChange = lastValue < displayLastLogicalRangeValue ? "#FF2F1F" : "#10DB06"; + topColorChange = lastValue < displayLastLogicalRangeValue ? "rgb(255, 47, 31, 0.2)" : "rgb(16, 219, 6, 0.2)"; + bottomColorChange = lastValue < displayLastLogicalRangeValue ? "rgb(255, 47, 31, 0.001)" : "rgb(16, 219, 6, 0.001)"; + } catch(e) { + console.log(e) + } +}; + + + + + + async function getPrePostQuote() { -
- - Get detailed Fundamental insights of {$displayCompanyName} and compare it to the S&P500. -
+ if(!$isOpen) { + const postData = { ticker: $etfTicker}; + const response = await fetch(data?.apiURL+'/pre-post-quote', { + method: 'POST', + headers: { + "Content-Type": "application/json", "X-API-KEY": data?.apiKey + }, + body: JSON.stringify(postData) + }); - {#if Object?.keys(quantStats)?.length !== 0} -
+ prePostData = await response.json(); + + } + }; + + + + + + let currentDataRow = {'value': '-', 'date': '-'}; + + let lineLegend = null; + let displayLegend = {'close': '-', 'date': '-'}; + + + + + function handleSeriesReference(ref) { + try { + lineLegend = ref; + } + catch (error) + { + console.log(error); + } + -
- - - - - {#if $screenWidth <= 550} - - - {:else} - - - - - {/if} - - - - {#if $screenWidth < 640} - - - {:else} - - - - - {/if} - - -
- 1-Day Range - -
-
- {dayLow} - {dayHigh} -
-
- -
-
-
- 1-Day Range - - {dayLow} - - - - - {dayHigh} -
- 1-Year Range - -
-
- {yearLow} - {yearHigh} -
-
- -
-
-
- 1-Year Range - - {yearLow} - - - - {yearHigh} -
-
- - + }; + + + + + + + + + async function handleCrosshairMove({detail: param}) { + + if (param?.time && !isNaN(param?.seriesData?.get(lineLegend)?.close ?? param?.seriesData?.get(lineLegend)?.value)) + { + $isCrosshairMoveActive = true; + try { + let graphData; + graphData = param?.seriesData?.get(lineLegend); -

- Company Stats -

- - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Mkt Cap ${marketCap}Volume{volume}
Price${currentPrice}Prev. Close${previousClose}
Alpha - {typeof alpha !== 'undefined' ? alpha : '-'} - Beta - {typeof beta !== 'undefined' && !isNaN(beta) ? beta?.toFixed(2) : '-'} -
EPS{eps}PE{pe}
-
+ const price = graphData?.close ?? graphData?.value + const dateObj = graphData?.time + const date = new Date(dateObj); + const options = { + day: '2-digit', + month: '2-digit', + year: 'numeric', + hour: '2-digit', + minute: '2-digit', + }; - {#if $etfTicker in quantStats && Object.keys(quantStats[$etfTicker]).length > 0} - -

- Worst 10 Drawdowns of {$etfTicker} -

-
- - - - - - - - - - - {#each quantStats[$etfTicker?.toUpperCase()]['Worst 10 Drawdowns'] as item} - - - - - - - {/each} - -
StartedRecoveredDrawdownDays
- {new Date(item['Started']).toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })} - - {#if ongoingDD(item['Recovered']) === true} - continuing - {:else} - {new Date(item['Recovered']).toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })} - {/if} - - {item['Drawdown']?.toFixed(2)}% - - {item['Days']} -
-
- - -

- {$etfTicker} vs. - S&P500 -

- -

- Comparison of company stats against the S&P500 Index. -

- - - Time Period between {new Date(quantStats[$etfTicker?.toUpperCase()]["Start Period"]).toLocaleString('en-US', { month: 'long', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })} - - - {new Date(quantStats[$etfTicker?.toUpperCase()]["End Period"]).toLocaleString('en-US', { month: 'long', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })} - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Metric - - {$etfTicker} - - S&P500 -
- Cumulative Return - - {#if quantStats[$etfTicker?.toUpperCase()]["Cumulative Return %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Cumulative Return %"]}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Cumulative Return %"]}% - {/if} - - {#if quantStats['SPY']["Cumulative Return %"] >=0} - +{quantStats['SPY']["Cumulative Return %"]}% - {:else} - {quantStats['SPY']["Cumulative Return %"]}% - {/if} -
- Compound Annual Growth Rate (CAGR) - - {#if quantStats[$etfTicker?.toUpperCase()]["CAGR %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["CAGR %"]}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["CAGR %"]}% - {/if} - - {#if quantStats['SPY']["CAGR %"] >=0} - +{quantStats['SPY']["CAGR %"]}% - {:else} - {quantStats['SPY']["CAGR %"]}% - {/if} -
- Sharpe - - {quantStats[$etfTicker?.toUpperCase()]["Sharpe"]?.toFixed(2)} - - {quantStats['SPY']["Sharpe"]?.toFixed(2)} -
- Sortino - - {quantStats[$etfTicker?.toUpperCase()]["Sortino"]?.toFixed(2)} - - {quantStats['SPY']["Sortino"]?.toFixed(2)} -
- Max Drawdown - - {#if quantStats[$etfTicker?.toUpperCase()]["Max Drawdown"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Max Drawdown"]}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Max Drawdown"]}% - {/if} - - {#if quantStats['SPY']["Max Drawdown"] >=0} - +{quantStats['SPY']["Max Drawdown"]}% - {:else} - {quantStats['SPY']["Max Drawdown"]}% - {/if} -
- Longest Drawdown Days - - {quantStats[$etfTicker?.toUpperCase()]["Longest DD Days"]} - - {quantStats['SPY']["Longest DD Days"]} -
- Volatility (ann.) - - {quantStats[$etfTicker?.toUpperCase()]["Volatility (ann.) %"]}% - - {quantStats['SPY']["Volatility (ann.) %"]}% -
- Correlation - - {quantStats[$etfTicker?.toUpperCase()]["Correlation"]}% - - {quantStats['SPY']["Correlation"]} -
- R^2 - - {quantStats[$etfTicker?.toUpperCase()]["R^2"]} - - {quantStats['SPY']["R^2"]} -
- Calmar - - {quantStats[$etfTicker?.toUpperCase()]["Calmar"]} - - {quantStats['SPY']["Calmar"]} -
- Skew - - {quantStats[$etfTicker?.toUpperCase()]["Skew"]?.toFixed(2)} - - {quantStats['SPY']["Skew"]?.toFixed(2)} -
- Kurtosis - - {quantStats[$etfTicker?.toUpperCase()]["Kurtosis"]?.toFixed(2)} - - {quantStats['SPY']["Kurtosis"]?.toFixed(2)} -
- Expected Daily - - {#if quantStats[$etfTicker?.toUpperCase()]["Expected Daily %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Expected Daily %"]}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Expected Daily %"]}% - {/if} - - {#if quantStats['SPY']["Expected Daily %"] >=0} - +{quantStats['SPY']["Expected Daily %"]}% - {:else} - {quantStats['SPY']["Expected Daily %"]}% - {/if} -
- Expected Monthly - - {#if quantStats[$etfTicker?.toUpperCase()]["Expected Monthly %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Expected Monthly %"]}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Expected Monthly %"]}% - {/if} - - {#if quantStats['SPY']["Expected Monthly %"] >=0} - +{quantStats['SPY']["Expected Monthly %"]}% - {:else} - {quantStats['SPY']["Expected Monthly %"]}% - {/if} -
- Expected Yearly - - {#if quantStats[$etfTicker?.toUpperCase()]["Expected Yearly %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Expected Yearly %"]}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Expected Yearly %"]}% - {/if} - - {#if quantStats['SPY']["Expected Yearly %"] >=0} - +{quantStats['SPY']["Expected Yearly %"]}% - {:else} - {quantStats['SPY']["Expected Yearly %"]}% - {/if} -
- Kelly Criterion - - {quantStats[$etfTicker?.toUpperCase()]["Kelly Criterion %"]}% - - {quantStats['SPY']["Kelly Criterion %"]}% -
- Risk of Ruin - - {quantStats[$etfTicker?.toUpperCase()]["Risk of Ruin %"]}% - - {quantStats['SPY']["Risk of Ruin %"]}% -
- Daily Value-at-Risk - - {#if quantStats[$etfTicker?.toUpperCase()]["Daily Value-at-Risk %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Daily Value-at-Risk %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Daily Value-at-Risk %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Daily Value-at-Risk %"] >=0} - +{quantStats['SPY']["Daily Value-at-Risk %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Daily Value-at-Risk %"]?.toFixed(2)}% - {/if} -
- Expected Shortfall (cVaR) - - {#if quantStats[$etfTicker?.toUpperCase()]["Expected Shortfall (cVaR) %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Expected Shortfall (cVaR) %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Expected Shortfall (cVaR) %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Expected Shortfall (cVaR) %"] >=0} - +{quantStats['SPY']["Expected Shortfall (cVaR) %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Expected Shortfall (cVaR) %"]?.toFixed(2)}% - {/if} -
- Max Consecutive Wins - - {quantStats[$etfTicker?.toUpperCase()]["Max Consecutive Wins"]} - - {quantStats['SPY']["Max Consecutive Wins"]} -
- Max Consecutive Losses - - {quantStats[$etfTicker?.toUpperCase()]["Max Consecutive Losses"]} - - {quantStats['SPY']["Max Consecutive Losses"]} -
- Gain/Pain Ratio - - {quantStats[$etfTicker?.toUpperCase()]["Gain/Pain Ratio"]?.toFixed(2)} - - {quantStats['SPY']["Gain/Pain Ratio"]?.toFixed(2)} -
- Gain/Pain (1M) - - {quantStats[$etfTicker?.toUpperCase()]["Gain/Pain (1M)"]?.toFixed(2)} - - {quantStats['SPY']["Gain/Pain (1M)"]?.toFixed(2)} -
- Payoff Ratio - - {quantStats[$etfTicker?.toUpperCase()]["Payoff Ratio"]?.toFixed(2)} - - {quantStats['SPY']["Payoff Ratio"]?.toFixed(2)} -
- Profit Factor - - {quantStats[$etfTicker?.toUpperCase()]["Profit Factor"]?.toFixed(2)} - - {quantStats['SPY']["Profit Factor"]?.toFixed(2)} -
- Outlier Win Ratio - - {quantStats[$etfTicker?.toUpperCase()]["Outlier Win Ratio"]?.toFixed(2)} - - {quantStats['SPY']["Outlier Win Ratio"]?.toFixed(2)} -
- Outlier Loss Ratio - - {quantStats[$etfTicker?.toUpperCase()]["Outlier Loss Ratio"]?.toFixed(2)} - - {quantStats['SPY']["Outlier Loss Ratio"]?.toFixed(2)} -
- MTD - - {#if quantStats[$etfTicker?.toUpperCase()]["MTD %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["MTD %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["MTD %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["MTD %"] >=0} - +{quantStats['SPY']["MTD %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["MTD %"]?.toFixed(2)}% - {/if} -
- 3M - - {#if quantStats[$etfTicker?.toUpperCase()]["3M %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["3M %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["3M %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["3M %"] >=0} - +{quantStats['SPY']["3M %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["3M %"]?.toFixed(2)}% - {/if} -
- 6M - - {#if quantStats[$etfTicker?.toUpperCase()]["6M %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["6M %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["6M %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["6M %"] >=0} - +{quantStats['SPY']["6M %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["6M %"]?.toFixed(2)}% - {/if} -
- YTD - - {#if quantStats[$etfTicker?.toUpperCase()]["YTD %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["YTD %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["YTD %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["YTD %"] >=0} - +{quantStats['SPY']["YTD %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["YTD %"]?.toFixed(2)}% - {/if} -
- 1Y - - {#if quantStats[$etfTicker?.toUpperCase()]["1Y %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["1Y %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["1Y %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["1Y %"] >=0} - +{quantStats['SPY']["1Y %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["1Y %"]?.toFixed(2)}% - {/if} -
- 3Y (ann.) - - {#if quantStats[$etfTicker?.toUpperCase()]["3Y (ann.) %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["3Y (ann.) %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["3Y (ann.) %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["3Y (ann.) %"] >=0} - +{quantStats['SPY']["3Y (ann.) %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["3Y (ann.) %"]?.toFixed(2)}% - {/if} -
- Best Day - - {#if quantStats[$etfTicker?.toUpperCase()]["Best Day %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Best Day %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Best Day %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Best Day %"] >=0} - +{quantStats['SPY']["Best Day %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Best Day %"]?.toFixed(2)}% - {/if} -
- Worst Day - - {#if quantStats[$etfTicker?.toUpperCase()]["Worst Day %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Worst Day %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Worst Day %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Worst Day %"] >=0} - +{quantStats['SPY']["Worst Day %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Worst Day %"]?.toFixed(2)}% - {/if} -
- Best Month - - {#if quantStats[$etfTicker?.toUpperCase()]["Worst Day %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Worst Day %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Worst Day %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Worst Day %"] >=0} - +{quantStats['SPY']["Worst Day %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Worst Day %"]?.toFixed(2)}% - {/if} -
- Worst Month - - {#if quantStats[$etfTicker?.toUpperCase()]["Worst Month %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Worst Month %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Worst Month %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Worst Month %"] >=0} - +{quantStats['SPY']["Worst Month %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Worst Month %"]?.toFixed(2)}% - {/if} -
- Best Year - - {#if quantStats[$etfTicker?.toUpperCase()]["Best Year %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Best Year %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Best Year %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Best Year %"] >=0} - +{quantStats['SPY']["Best Year %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Best Year %"]?.toFixed(2)}% - {/if} -
- Worst Year - - {#if quantStats[$etfTicker?.toUpperCase()]["Worst Year %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Worst Year %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Worst Year %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Worst Year %"] >=0} - +{quantStats['SPY']["Worst Year %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Worst Year %"]?.toFixed(2)}% - {/if} -
- Avg. Drawdown - - {#if quantStats[$etfTicker?.toUpperCase()]["Avg. Drawdown"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Avg. Drawdown"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Avg. Drawdown"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Avg. Drawdown"] >=0} - +{quantStats['SPY']["Avg. Drawdown"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Avg. Drawdown"]?.toFixed(2)}% - {/if} -
- Avg. Drawdown Days - - {quantStats[$etfTicker?.toUpperCase()]["Avg. Drawdown Days"]} - - {quantStats['SPY']["Avg. Drawdown Days"]} -
- Recovery Factor - - {quantStats[$etfTicker?.toUpperCase()]["Recovery Factor"]?.toFixed(2)} - - {quantStats['SPY']["Recovery Factor"]?.toFixed(2)} -
- Ulcer Index - - {quantStats[$etfTicker?.toUpperCase()]["Ulcer Index"]?.toFixed(2)} - - {quantStats['SPY']["Ulcer Index"]?.toFixed(2)} -
- Avg. Up Month - - {#if quantStats[$etfTicker?.toUpperCase()]["Avg. Up Month %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Avg. Up Month %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Avg. Up Month %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Avg. Up Month %"] >=0} - +{quantStats['SPY']["Avg. Up Month %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Avg. Up Month %"]?.toFixed(2)}% - {/if} -
- Avg. Down Month - - {#if quantStats[$etfTicker?.toUpperCase()]["Avg. Down Month %"] >=0} - +{quantStats[$etfTicker?.toUpperCase()]["Avg. Down Month %"]?.toFixed(2)}% - {:else} - {quantStats[$etfTicker?.toUpperCase()]["Avg. Down Month %"]?.toFixed(2)}% - {/if} - - {#if quantStats['SPY']["Avg. Down Month %"] >=0} - +{quantStats['SPY']["Avg. Down Month %"]?.toFixed(2)}% - {:else} - {quantStats['SPY']["Avg. Down Month %"]?.toFixed(2)}% - {/if} -
- Win Days - - {quantStats[$etfTicker?.toUpperCase()]["Win Days %"]?.toFixed(2)}% - - {quantStats['SPY']["Win Days %"]?.toFixed(2)}% -
- Win Month - - {quantStats[$etfTicker?.toUpperCase()]["Win Month %"]?.toFixed(2)}% - - {quantStats['SPY']["Win Month %"]?.toFixed(2)}% -
- Win Quarter - - {quantStats[$etfTicker?.toUpperCase()]["Win Quarter %"]?.toFixed(2)}% - - {quantStats['SPY']["Win Quarter %"]?.toFixed(2)}% -
- Win Year - - {quantStats[$etfTicker?.toUpperCase()]["Win Year %"]?.toFixed(2)}% - - {quantStats['SPY']["Win Year %"]?.toFixed(2)}% -
- -
- + //const formattedDate = ( displayData === '1W' || displayData === '1M' ) ? date.toLocaleDateString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric',hour: '2-digit', minute: '2-digit' }).replace(/\//g, '.') : date.toLocaleDateString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric' }).replace(/\//g, '.'); - {:else} + const formattedDate = (displayData === '1D' || displayData === '1W' || displayData === '1M') ? date.toLocaleString('en-GB', options).replace(/\//g, '.') : date.toLocaleDateString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric' })?.replace(/\//g, '.'); + + const change = ((price/displayLastLogicalRangeValue -1 )*100)?.toFixed(2); -

- -

- {/if} - -
- {:else} -

- No data available -

- {/if} + displayLegend = {"close": price?.toFixed(2), 'date': formattedDate, 'change': change}; + + + + } + + catch(error) + { + //pass; + } + + } + else + { + + //currentDataRow = oneDayPrice[oneDayPrice?.length - 1]; + const length = oneDayPrice?.length; + for (let i = length - 1; i >= 0; i--) { + if (!isNaN(oneDayPrice[i]?.close ?? oneDayPrice[i]?.value )) { + currentDataRow = oneDayPrice[i]; + break; + } + } + + + } + + }; + + + + + let displayLastLogicalRangeValue; + + + const fitContentChart = async () => { + + if(displayData === '1Y' && oneYearPrice?.length === 0) + { + + } + else if (chart !== null) { + + chart?.timeScale().fitContent(); + + chart?.applyOptions({ + trackingMode: { + exitMode: TrackingModeExitMode.OnTouchEnd + }, + }); + + } + + -
-
\ No newline at end of file + }; + + + + let width = 500; + //Initial height of graph + let height = 350; + + let observer; + let ref; + + ref = (element) => { + if (observer) { + observer.disconnect(); + } + if (!element) { + return; + } + + observer = new ResizeObserver(([entry]) => { + width = entry.contentRect.width; + height = entry.contentRect.height; + }); + observer.observe(element); + } + + + + //===============================================// + + + + + + + + + + + const options = { + width: width, + height: height, + layout: { + background: { + color: '#09090B', + }, + + }, + grid: { + vertLines: { + color: '#09090B', + visible: false, + }, + horzLines: { + color: '#09090B', + visible: false, + }, + }, + crosshair: { + // hide the horizontal crosshair line + horzLine: { + visible: false, + labelVisible: false, + }, + // hide the vertical crosshair label + vertLine: { + labelVisible: false, + style: 0, + }, + }, + rightPriceScale: { + visible: false, + borderColor: 'rgba(197, 203, 206, 0.8)', + }, + leftPriceScale: { + visible: false, + borderColor: 'rgba(197, 203, 206, 0.8)', + }, + handleScale: { + mouseWheel: false, + }, + handleScroll: { + mouseWheel: false, + horzTouchDrag: false, + vertTouchDrag: false, + pressedMouseMove: false, + }, + timeScale: { + borderColor: '#FFFFFF', + textColor: '#FFFFFF', + visible: false, + fixLeftEdge: true, + fixRightEdge: true, + }, + }; + + + + onDestroy(async() => { + $priceIncrease = null; + }) + + function changeChartType() { + if(displayChartType === 'line') { + displayChartType = 'candlestick'; + } + else { + displayChartType = 'line'; + } + } + + $: { + + if ($etfTicker && typeof window !== 'undefined') // add a check to see if running on client-side + { + + oneDayPrice = []; + oneWeekPrice = []; + oneMonthPrice = []; + oneYearPrice = []; + threeYearPrice = []; + + geographicList = []; + sectorList = []; + prePostData = {}; + output = null; + + + geographicList = data?.getCountryWeighting; + sectorList = data?.getETFProfile[0]?.sectorsList; + sectorList = sectorList?.sort(function(a,b) { + return b?.exposure - a?.exposure; + }) + etfProfile = data?.getETFProfile; + topHoldingList = data?.getETFHoldings; + dividendList = data?.getStockDividend; + similarTicker = data?.getSimilarETFs; + previousClose = data?.getStockQuote?.previousClose + + //stockDeck = data?.getStockDeckData; + + + + const asyncFunctions = [ + getPrePostQuote(), + ]; + + + + Promise.all(asyncFunctions) + .then((results) => { + initializePrice() + }) + .catch((error) => { + console.error('An error occurred:', error); + }); + + + } + + } + + + + $: { + if(form) + { + $globalForm = form; + } + } + + + + + + + + + + + {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ''} {$displayCompanyName} ({$etfTicker}) Stock Price, Quote & News · stocknear + + + + + + + + + + + + + + + + + + +
+ +
+ + +
+ +
+
+ + + + + +
+
+ +
+ {#if $isCrosshairMoveActive } + {$etfTicker?.includes('.DE') || $etfTicker?.includes('.F') ? `${displayLegend?.close}€` : ` $${displayLegend?.close}`} + {:else if !$isCrosshairMoveActive && $realtimePrice !== null} + {$etfTicker?.includes('.DE') || $etfTicker?.includes('.F') ? `${$realtimePrice}€` : ` $${$realtimePrice}`} + {:else} + {$etfTicker?.includes('.DE') || $etfTicker?.includes('.F') ? `${displayLegend?.close}€` : ` $${displayLegend?.close}`} + + {/if} + + {#if $priceIncrease === true} +
+ {:else if $priceIncrease === false} +
+ {/if} + +
+ + + + +
+ + {#if displayLegend?.change >= 0} + + +{displayLegend?.change}% + {:else if displayLegend?.change < 0} + + {displayLegend?.change}% + {/if} + + {displayLegend?.date} + + + +
+ +
+ + {#if Object?.keys(prePostData)?.length !== 0 && prePostData?.price !== 0} +
+
+ + ${prePostData?.price} + + {#if prePostData?.changesPercentage >= 0} + ({prePostData?.changesPercentage}%) + {:else if prePostData?.changesPercentage < 0} + ({prePostData?.changesPercentage}%) + {/if} +
+ {#if $isBeforeMarketOpen && !$isOpen && !$isWeekend} +
+ Pre-market: + +
+ {:else} +
+ Post-market: + +
+ {/if} + +
+ {/if} + + +
+ + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/src/routes/stocks/[tickerID]/+page.svelte b/src/routes/stocks/[tickerID]/+page.svelte index d20fc3e3..b2fbf604 100644 --- a/src/routes/stocks/[tickerID]/+page.svelte +++ b/src/routes/stocks/[tickerID]/+page.svelte @@ -3,7 +3,7 @@ import {AreaSeries, Chart, PriceLine, CandlestickSeries} from 'svelte-lightweight-charts'; import { TrackingModeExitMode } from 'lightweight-charts'; - import {getCache, setCache, corporateLobbyingComponent, taRatingComponent, swapComponent, analystInsightComponent, governmentContractComponent, optionsNetFlowComponent, impliedVolatilityComponent, borrowedShareComponent, clinicalTrialComponent, optionComponent, failToDeliverComponent, marketMakerComponent, analystEstimateComponent, sentimentComponent, screenWidth, displayCompanyName, numberOfUnreadNotification, globalForm, varComponent, shareStatisticsComponent, enterpriseComponent, darkPoolComponent, retailVolumeComponent, shareholderComponent, trendAnalysisComponent, revenueSegmentationComponent, priceAnalysisComponent, fundamentalAnalysisComponent, isCrosshairMoveActive, realtimePrice, priceIncrease, currentPortfolioPrice, stockTicker, isOpen, isBeforeMarketOpen, isWeekend} from '$lib/store'; + import {getCache, setCache, corporateLobbyingComponent, taRatingComponent, swapComponent, analystInsightComponent, governmentContractComponent, optionsNetFlowComponent, borrowedShareComponent, clinicalTrialComponent, optionComponent, failToDeliverComponent, marketMakerComponent, analystEstimateComponent, sentimentComponent, screenWidth, displayCompanyName, numberOfUnreadNotification, globalForm, varComponent, shareStatisticsComponent, enterpriseComponent, darkPoolComponent, retailVolumeComponent, shareholderComponent, trendAnalysisComponent, revenueSegmentationComponent, priceAnalysisComponent, fundamentalAnalysisComponent, isCrosshairMoveActive, realtimePrice, priceIncrease, currentPortfolioPrice, stockTicker, isOpen, isBeforeMarketOpen, isWeekend} from '$lib/store'; import { onDestroy, onMount } from 'svelte'; import BullBearSay from '$lib/components/BullBearSay.svelte'; import CommunitySentiment from '$lib/components/CommunitySentiment.svelte'; @@ -1308,6 +1308,7 @@ function changeChartType() { +