From 2660c0b82215aed6f392e701ccec4b745793d1cf Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Sun, 22 Dec 2024 11:09:42 +0100 Subject: [PATCH] add top analyst rule --- src/lib/components/Table/Table.svelte | 8 +- src/routes/analysts/top-stocks/+page.svelte | 80 +++---------------- src/routes/stock-screener/+page.svelte | 54 ++++++++++--- .../stock-screener/workers/filterWorker.ts | 2 +- .../[tickerID]/forecast/analyst/+page.svelte | 15 ++-- 5 files changed, 70 insertions(+), 89 deletions(-) diff --git a/src/lib/components/Table/Table.svelte b/src/lib/components/Table/Table.svelte index 3e7daeaa..44c1cdb3 100644 --- a/src/lib/components/Table/Table.svelte +++ b/src/lib/components/Table/Table.svelte @@ -146,6 +146,10 @@ rule: "institutionalOwnership", type: "percent", }, + { name: "Top Analyst Rating", rule: "topAnalystRating", type: "rating" }, + { name: "Top Analyst Count", rule: "topAnalystCounter", type: "int" }, + { name: "Top Analyst Price Target", rule: "topAnalystPriceTarget", type: "float" }, + { name: "Top Analyst PT Upside", rule: "topAnalystUpside", type: "percentSign" }, ]; allRows = [...allRows, ...specificRows]; @@ -543,8 +547,8 @@ const preferredOrder = ["rank", "symbol", "name"]; // Create a mapping of rule to name and type from allRows - const ruleToMetadataMap = Object.fromEntries( - allRows.map((row) => [row.rule, { name: row.name, type: row.type }]), + const ruleToMetadataMap = Object?.fromEntries( + allRows?.map((row) => [row.rule, { name: row.name, type: row.type }]), ); // Separate preferred keys and other keys, excluding "type" diff --git a/src/routes/analysts/top-stocks/+page.svelte b/src/routes/analysts/top-stocks/+page.svelte index 5d10343a..57b12a23 100644 --- a/src/routes/analysts/top-stocks/+page.svelte +++ b/src/routes/analysts/top-stocks/+page.svelte @@ -8,19 +8,19 @@ const rawData = data?.getTopAnalystStocks; const excludedRules = new Set([ - "upside", - "priceTarget", + "topAnalystUpside", + "topAnalystPriceTarget", + "topAnalystCounter", "marketCap", - "analystCounter", - "analystRating" + "topAnalystRating" ]); const defaultList = [ - { name: "Analyst Count", rule: "analystCounter" }, - { name: "Upside", rule: "upside" }, - { name: "Price Target", rule: "priceTarget" }, - { name: "Market Cap", rule: "marketCap" }, - {name: 'Analyst Rating', rule: 'analystRating'} + { name: "Top Analyst Count", rule: "topAnalystCounter" }, + { name: "Top Analyst PT Upside", rule: "topAnalystUpside" }, + { name: "Top Analyst Price Target", rule: "topAnalystPriceTarget" }, + {name: 'Top Analyst Rating', rule: 'topAnalystRating'}, + {name: 'Market Cap', rule: 'marketCap'} ]; const hideLastRow = true; @@ -74,7 +74,7 @@
-
+

Top Strong Buy Stocks @@ -255,66 +255,6 @@

-
diff --git a/src/routes/stock-screener/+page.svelte b/src/routes/stock-screener/+page.svelte index 4e1655d2..f3e72a4e 100644 --- a/src/routes/stock-screener/+page.svelte +++ b/src/routes/stock-screener/+page.svelte @@ -1296,14 +1296,43 @@ category: "Forecasts, Analysts & Price Targets", }, upside: { - label: "Price Target Upside [%]", + label: "Price Target Upside", step: ["100%", "50%", "20%", "10%", "5%", "0%"], defaultCondition: "over", defaultValue: "any", category: "Forecasts, Analysts & Price Targets", }, + topAnalystRating: { + label: "Top Analyst Rating", + step: ["Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"], + defaultCondition: "", + defaultValue: "any", + category: "Forecasts, Analysts & Price Targets", + }, + topAnalystCounter: { + label: "Top Analyst Count", + step: ["10", "5", "3", "1"], + defaultCondition: "over", + defaultValue: "any", + category: "Forecasts, Analysts & Price Targets", + }, + topAnalystUpside: { + label: "Top Analyst Price Target Upside", + step: ["100%", "50%", "20%", "10%", "5%", "0%"], + + defaultCondition: "over", + defaultValue: "any", + category: "Forecasts, Analysts & Price Targets", + }, + topAnalystPriceTarget: { + label: "Top Analyst Price Target", + step: ["1000", "500", "100", "10", "5", "1"], + defaultCondition: "over", + defaultValue: "any", + category: "Forecasts, Analysts & Price Targets", + }, halalStocks: { label: "Halal Stocks", step: ["Compliant", "Non-Compliant"], @@ -1452,6 +1481,7 @@ ?.filter((rule) => [ "analystRating", + "topAnalystRating", "halalStocks", "sector", "country", @@ -1555,6 +1585,7 @@ ?.filter((rule) => [ "analystRating", + "topAnalystRating", "halalStocks", "sector", "country", @@ -1569,7 +1600,7 @@ } function changeRule(state: string) { - if (data?.user?.tier !== "Pro" && state === "score") { + if (data?.user?.tier !== "Pro" && ['topAnalystRating','topAnalystCounter','topAnalystPriceTarget','topAnalystUpside','score']?.includes(state)) { goto("/pricing"); } else { selectedPopularStrategy = ""; @@ -1628,6 +1659,7 @@ switch (ruleName) { case "analystRating": + case "topAnalystRating": case "halalStocks": case "score": case "sector": @@ -1862,6 +1894,7 @@ const handleKeyDown = (event) => { ?.filter((rule) => [ "analystRating", + "topAnalystRating", "halalStocks", "sector", "country", @@ -1949,6 +1982,7 @@ const handleKeyDown = (event) => { "ema200", "grahamNumber", "analystRating", + "topAnalystRating", "halalStocks", "score", "sector", @@ -2112,7 +2146,7 @@ const handleKeyDown = (event) => { ? sectorList : ruleName === "industry" ? industryList - : ruleName === "analystRating" || ruleName === "score" + : ['analystRating','topAnalystRating','score']?.includes(ruleName) ? ["Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"] : ["Compliant", "Non-Compliant"]; testList = @@ -2213,6 +2247,7 @@ const handleKeyDown = (event) => { "score", "sector", "analystRating", + "topAnalystRating", "halalStocks", ]; @@ -2797,7 +2832,7 @@ const handleKeyDown = (event) => { - {#if !["sma20", "sma50", "sma100", "sma200", "ema20", "ema50", "ema100", "ema200", "grahamNumber", "analystRating", "halalStocks", "score", "sector", "industry", "country"]?.includes(row?.rule)} + {#if !["sma20", "sma50", "sma100", "sma200", "ema20", "ema50", "ema100", "ema200", "grahamNumber", "analystRating", "topAnalystRating", "halalStocks", "score", "sector", "industry", "country"]?.includes(row?.rule)} @@ -2960,6 +2995,7 @@ const handleKeyDown = (event) => { autocomplete="off" class="{![ 'analystRating', + "topAnalystRating", 'halalStocks', 'score', 'sector', @@ -2975,7 +3011,7 @@ const handleKeyDown = (event) => { {/if} - {#if !["sma20", "sma50", "sma100", "sma200", "ema20", "ema50", "ema100", "ema200", "grahamNumber", "analystRating", "halalStocks", "score", "sector", "industry", "country"]?.includes(row?.rule)} + {#if !["sma20", "sma50", "sma100", "sma200", "ema20", "ema50", "ema100", "ema200", "grahamNumber", "analystRating", "topAnalystRating","halalStocks", "score", "sector", "industry", "country"]?.includes(row?.rule)} {#each row?.step as newValue, index} {#if ruleCondition[row?.rule] === "between"} {#if newValue && row?.step[index + 1]} @@ -3044,7 +3080,7 @@ const handleKeyDown = (event) => { {/each} {:else} - {#each testList.length > 0 && searchQuery?.length > 0 ? testList : searchQuery?.length > 0 && testList?.length === 0 ? [] : row?.rule === "country" ? listOfRelevantCountries : row?.rule === "sector" ? sectorList : row?.rule === "industry" ? industryList : ruleName === "analystRating" || ruleName === "score" ? ["Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"] : ["Compliant", "Non-Compliant"] as item} + {#each testList.length > 0 && searchQuery?.length > 0 ? testList : searchQuery?.length > 0 && testList?.length === 0 ? [] : row?.rule === "country" ? listOfRelevantCountries : row?.rule === "sector" ? sectorList : row?.rule === "industry" ? industryList : ['analystRating','topAnalystRating','score']?.includes(ruleName) ? ["Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"] : ["Compliant", "Non-Compliant"] as item}
{ - {#if ["ema20", "ema50", "ema100", "ema200", "analystRating", "halalStocks", "score", "sector", "industry", "country"]?.includes(row?.rule)} + {#if ["ema20", "ema50", "ema100", "ema200", "analystRating", "topAnalystRating", "halalStocks", "score", "sector", "industry", "country"]?.includes(row?.rule)} {item[row?.rule]} {:else} {abbreviateNumber(item[row?.rule])} @@ -3413,7 +3449,7 @@ const handleKeyDown = (event) => { > {/if} - {:else if row?.rule === 'analystRating'} + {:else if ['analystRating','topAnalystRating']?.includes(row?.rule)} {#if ["Strong Buy", "Buy"].includes(item[row?.rule])} {item[row?.rule]} {:else if ["Strong Sell", "Sell"].includes(item[row?.rule])} @@ -3593,7 +3629,7 @@ const handleKeyDown = (event) => {
- {#if row?.rule === "score" && data?.user?.tier !== "Pro"} + {#if ['topAnalystRating','topAnalystCounter','topAnalystPriceTarget','topAnalystUpside','score']?.includes(row?.rule) && data?.user?.tier !== "Pro"}