diff --git a/src/lib/components/Indicator.svelte b/src/lib/components/Indicator.svelte new file mode 100644 index 00000000..553db080 --- /dev/null +++ b/src/lib/components/Indicator.svelte @@ -0,0 +1,278 @@ + + + + + + + + + +
+
+ + + + + {#if searchQuery?.length > 0} + + {/if} +
+
+ + + + {#each searchQuery?.length !== 0 ? testList : allRows as item} + +
+ {#if data?.user?.tier === "Pro" || excludedRules?.has(item?.rule)} + + {:else} + + + + + {item?.name} + + {/if} +
+
+ {/each} +
+ +
+ +
+
+
diff --git a/src/lib/workers/downloadWorker.ts b/src/lib/workers/downloadWorker.ts new file mode 100644 index 00000000..074a0818 --- /dev/null +++ b/src/lib/workers/downloadWorker.ts @@ -0,0 +1,42 @@ +// Cache to store previous requests +let cache = new Map(); + +const getData = async (rules, tickerList) => { + console.log("Checking cache and fetching new data if needed"); + + // Extract the rule names + let getRuleOfList = rules?.map((rule) => rule.rule) || []; + // Convert the rule set into a string key for the cache + const ruleKey = JSON.stringify(getRuleOfList); + + // Check if data for this rule set is already in the cache + if (cache.has(ruleKey)) { + console.log("Returning cached data"); + return cache.get(ruleKey); + } + + // Fetch new data if it's not in the cache + const postData = { ruleOfList: getRuleOfList, tickerList: tickerList }; + const response = await fetch("/api/indicator-data", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(postData), + }); + + const output = await response.json(); + // Store the new data in the cache + cache.set(ruleKey, output); + + return output; +}; + +onmessage = async (event) => { + const { ruleOfList, tickerList } = event.data || {}; + const rawData = await getData(ruleOfList, tickerList); + + postMessage({ message: "success", rawData }); +}; + +export {}; diff --git a/src/routes/stock-screener/+page.svelte b/src/routes/stock-screener/+page.svelte index 4f93242c..997cb072 100644 --- a/src/routes/stock-screener/+page.svelte +++ b/src/routes/stock-screener/+page.svelte @@ -347,6 +347,13 @@ defaultCondition: "over", defaultValue: "10M", }, + revenueGrowthYears: { + label: "Revenue Growth Years", + step: ["10", "5", "3", "1"], + category: "fund", + defaultCondition: "over", + defaultValue: "any", + }, growthRevenue: { label: "Revenue Growth", step: ["200%", "100%", "50%", "20%", "10%", "5%", "1%"], diff --git a/src/routes/stocks/[tickerID]/+layout.svelte b/src/routes/stocks/[tickerID]/+layout.svelte index 06163bec..206f2e0a 100644 --- a/src/routes/stocks/[tickerID]/+layout.svelte +++ b/src/routes/stocks/[tickerID]/+layout.svelte @@ -211,15 +211,15 @@ function handleTypeOfTrade(state:string) const { type, lp, time, bp, ap } = parsedData || {}; if (type === "T") { - $realtimePrice = lp; + $realtimePrice = typeof lp !== "undefined" ? lp : null; $priceChartData = { - time: time, - price: Number(lp), + time: typeof time !== "undefined" ? time : null, + price: typeof lp !== "undefined" ? Number(lp) : null, }; shouldUpdatePriceChart.set(true); } else if (type === "Q") { - $wsBidPrice = bp; - $wsAskPrice = ap; + $wsBidPrice = typeof bp !== "undefined" ? bp : null; + $wsAskPrice = typeof ap !== "undefined" ? ap : null; } // Update price increase state