add analyst section to screener
This commit is contained in:
parent
f2f2319da6
commit
a8ae4ed633
@ -1272,11 +1272,9 @@
|
||||
defaultCondition: "over",
|
||||
defaultValue: "any",
|
||||
},
|
||||
|
||||
analystRating: {
|
||||
label: "Analyst Rating",
|
||||
step: ["Strong Buy", "Buy", "Hold", "Sell", "Strong Sell"],
|
||||
|
||||
defaultCondition: "",
|
||||
defaultValue: "any",
|
||||
category: ["Most Popular", "Forecasts, Analysts & Price Targets"],
|
||||
@ -1537,13 +1535,16 @@
|
||||
ruleName = "";
|
||||
selectedPopularStrategy = "";
|
||||
selectedStrategy = item?.id ?? "";
|
||||
|
||||
ruleOfList =
|
||||
strategyList?.find((item) => item.id === selectedStrategy)?.rules ?? [];
|
||||
ruleOfList.forEach((rule) => {
|
||||
|
||||
ruleOfList.forEach((rule) => {
|
||||
ruleCondition[rule.name] =
|
||||
rule.condition || allRules[rule.name].defaultCondition;
|
||||
valueMappings[rule.name] = rule.value || allRules[rule.name].defaultValue;
|
||||
});
|
||||
|
||||
if (ruleOfList?.length === 0) {
|
||||
filteredData = [];
|
||||
displayResults = [];
|
||||
@ -1564,6 +1565,7 @@
|
||||
) // Only include specific rules
|
||||
?.map((rule) => [rule.name, new Set(rule.value)]), // Create Map from filtered rules
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function changeRule(state: string) {
|
||||
@ -1591,7 +1593,7 @@
|
||||
};
|
||||
|
||||
const loadWorker = async () => {
|
||||
if (displayTableTab === "performance" || hoverStatus) {
|
||||
if (['performance', 'analysts']?.includes(displayTableTab) || hoverStatus) {
|
||||
syncWorker.postMessage({
|
||||
stockScreenerData,
|
||||
ruleOfList: [...ruleOfList, ...otherTabRules],
|
||||
@ -1605,7 +1607,7 @@
|
||||
};
|
||||
|
||||
const updateStockScreenerData = async () => {
|
||||
if (displayTableTab === "performance" || hoverStatus) {
|
||||
if (["performance","analysts"]?.includes(displayTableTab) || hoverStatus) {
|
||||
downloadWorker.postMessage({
|
||||
ruleOfList: [...ruleOfList, ...otherTabRules],
|
||||
});
|
||||
@ -1789,7 +1791,7 @@ const handleKeyDown = (event) => {
|
||||
strategyList.find((item) => item.id === selectedStrategy).rules =
|
||||
ruleOfList;
|
||||
|
||||
const postData = {
|
||||
const postData = {
|
||||
strategyId: selectedStrategy,
|
||||
rules: ruleOfList,
|
||||
};
|
||||
@ -1814,7 +1816,7 @@ const handleKeyDown = (event) => {
|
||||
}
|
||||
|
||||
$: {
|
||||
if (ruleOfList) {
|
||||
if (ruleOfList ) {
|
||||
const ruleToUpdate = ruleOfList?.find((rule) => rule.name === ruleName);
|
||||
if (ruleToUpdate) {
|
||||
ruleToUpdate.value = valueMappings[ruleToUpdate.name];
|
||||
@ -2226,6 +2228,11 @@ const handleKeyDown = (event) => {
|
||||
{ key: "name", label: "Name", align: "left" },
|
||||
{ key: "marketCap", label: "Market Cap", align: "right" },
|
||||
],
|
||||
analysts: [
|
||||
{ key: "symbol", label: "Symbol", align: "left" },
|
||||
{ key: "name", label: "Name", align: "left" },
|
||||
{ key: "marketCap", label: "Market Cap", align: "right" },
|
||||
],
|
||||
filters: [
|
||||
{ key: "symbol", label: "Symbol", align: "left" },
|
||||
{ key: "name", label: "Name", align: "left" },
|
||||
@ -2239,6 +2246,11 @@ const handleKeyDown = (event) => {
|
||||
name: { order: "none", type: "string" },
|
||||
marketCap: { order: "none", type: "number" },
|
||||
},
|
||||
analysts: {
|
||||
symbol: { order: "none", type: "string" },
|
||||
name: { order: "none", type: "string" },
|
||||
marketCap: { order: "none", type: "number" },
|
||||
},
|
||||
filters: {
|
||||
symbol: { order: "none", type: "string" },
|
||||
name: { order: "none", type: "string" },
|
||||
@ -2254,7 +2266,7 @@ const handleKeyDown = (event) => {
|
||||
sortOrders = { ...(baseSortOrdersMap[displayTableTab] || {}) };
|
||||
|
||||
const rulesList =
|
||||
displayTableTab === "performance" ? tabRuleList : displayRules;
|
||||
["performance","analysts"]?.includes(displayTableTab) ? tabRuleList : displayRules;
|
||||
rulesList?.forEach((rule) => {
|
||||
if (rule.rule !== "marketCap") {
|
||||
columns.push({
|
||||
@ -2287,10 +2299,24 @@ const handleKeyDown = (event) => {
|
||||
.map((rule) => allRows.find((row) => row.rule === rule.name))
|
||||
.filter(Boolean);
|
||||
|
||||
await updateStockScreenerData();
|
||||
} else if (displayTableTab === "analysts") {
|
||||
hoverStatus = false;
|
||||
otherTabRules = [
|
||||
{ name: "marketCap", value: "any" },
|
||||
{ name: "analystRating", value: "any" },
|
||||
{ name: "analystCounter", value: "any" },
|
||||
{ name: "priceTarget", value: "any" },
|
||||
{ name: "upside", value: "any" },
|
||||
];
|
||||
tabRuleList = otherTabRules
|
||||
.map((rule) => allRows.find((row) => row.rule === rule.name))
|
||||
.filter(Boolean);
|
||||
|
||||
await updateStockScreenerData();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
async function handleMouseOver() {
|
||||
if (displayTableTab !== "performance") {
|
||||
hoverStatus = true;
|
||||
@ -2305,9 +2331,24 @@ const handleKeyDown = (event) => {
|
||||
?.map((rule) => allRows.find((row) => row.rule === rule.name))
|
||||
?.filter(Boolean);
|
||||
|
||||
await updateStockScreenerData();
|
||||
} else if (displayTableTab !== "analysts") {
|
||||
hoverStatus = true;
|
||||
otherTabRules = [
|
||||
{ name: "marketCap", value: "any" },
|
||||
{ name: "analystRating", value: "any" },
|
||||
{ name: "analystCounter", value: "any" },
|
||||
{ name: "priceTarget", value: "any" },
|
||||
{ name: "upside", value: "any" },
|
||||
];
|
||||
tabRuleList = otherTabRules
|
||||
?.map((rule) => allRows.find((row) => row.rule === rule.name))
|
||||
?.filter(Boolean);
|
||||
|
||||
await updateStockScreenerData();
|
||||
}
|
||||
}
|
||||
*/
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@ -3058,7 +3099,7 @@ const handleKeyDown = (event) => {
|
||||
>
|
||||
<nav class="w-full flex flex-row items-center py-2.5 sm:py-3 lg:py-1">
|
||||
<ul
|
||||
class="flex flex-row items-center space-x-2 whitespace-nowrap text-base"
|
||||
class="flex flex-row overflow-x-auto items-center space-x-2 whitespace-nowrap text-base"
|
||||
>
|
||||
<li>
|
||||
<button
|
||||
@ -3093,7 +3134,7 @@ const handleKeyDown = (event) => {
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
on:mouseover={handleMouseOver}
|
||||
|
||||
on:click={() => changeTab("performance")}
|
||||
class="text-[1rem] sm:text-lg block text-white rounded-md px-2 py-1 focus:outline-none sm:hover:bg-primary {displayTableTab ===
|
||||
'performance'
|
||||
@ -3103,6 +3144,17 @@ const handleKeyDown = (event) => {
|
||||
Performance
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
on:click={() => changeTab("analysts")}
|
||||
class="text-[1rem] sm:text-lg block text-white rounded-md px-2 py-1 focus:outline-none sm:hover:bg-primary {displayTableTab ===
|
||||
'analysts'
|
||||
? 'font-semibold bg-primary'
|
||||
: ''}"
|
||||
>
|
||||
Analysts
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="w-fit ml-auto hidden sm:inline-block">
|
||||
<DownloadData
|
||||
@ -3206,9 +3258,7 @@ const handleKeyDown = (event) => {
|
||||
<tbody>
|
||||
{#each displayResults as item (item?.symbol)}
|
||||
<tr
|
||||
on:click={() => {
|
||||
handleSave(false);
|
||||
}}
|
||||
|
||||
class="sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-[#09090B] border-b-[#09090B] odd:bg-secondary"
|
||||
>
|
||||
<td class="border-b-[#09090B] whitespace-nowrap">
|
||||
@ -3259,9 +3309,7 @@ const handleKeyDown = (event) => {
|
||||
<tbody>
|
||||
{#each displayResults as item (item?.symbol)}
|
||||
<tr
|
||||
on:click={() => {
|
||||
handleSave(false);
|
||||
}}
|
||||
|
||||
class="sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-[#09090B] border-b-[#09090B] odd:bg-secondary"
|
||||
>
|
||||
<td class="border-b-[#09090B] whitespace-nowrap">
|
||||
@ -3307,6 +3355,82 @@ const handleKeyDown = (event) => {
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{:else if displayTableTab === "analysts"}
|
||||
<div class="w-full rounded-md overflow-x-scroll">
|
||||
<table
|
||||
class="table table-sm table-compact w-full bg-[#09090B] border-bg-[#09090B]"
|
||||
>
|
||||
<thead>
|
||||
<TableHeader {columns} {sortOrders} {sortData} />
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each displayResults as item (item?.symbol)}
|
||||
<tr
|
||||
|
||||
class="sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-[#09090B] border-b-[#09090B] odd:bg-secondary"
|
||||
>
|
||||
<td class="border-b-[#09090B] whitespace-nowrap">
|
||||
<a
|
||||
href={"/stocks/" + item?.symbol}
|
||||
class="sm:hover:text-white text-blue-400 text-sm sm:text-[1rem]"
|
||||
>{item?.symbol}</a
|
||||
>
|
||||
</td>
|
||||
<td
|
||||
class="whitespace-nowrap text-[1rem] text-white border-b-[#09090B]"
|
||||
>
|
||||
{item?.name?.length > charNumber
|
||||
? item?.name?.slice(0, charNumber) + "..."
|
||||
: item?.name}
|
||||
</td>
|
||||
|
||||
{#each tabRuleList as row (row?.rule)}
|
||||
<td
|
||||
class="whitespace-nowrap text-sm sm:text-[1rem] text-end text-white border-b-[#09090B]"
|
||||
>
|
||||
{#if row?.rule === "marketCap"}
|
||||
{abbreviateNumber(item[row?.rule])}
|
||||
|
||||
{:else if ['analystCounter','priceTarget']?.includes(row?.rule)}
|
||||
<span class="text-white"
|
||||
>{abbreviateNumber(
|
||||
item[row?.rule],
|
||||
)}</span
|
||||
>
|
||||
|
||||
{:else if row?.rule === 'upside'}
|
||||
{#if item[row?.rule] > 0}
|
||||
<span class="text-[#00FC50]"
|
||||
>+{item[row?.rule]?.toFixed(2)}%</span
|
||||
>
|
||||
{:else if item[row?.rule] < 0}
|
||||
<span class="text-[#FF2F1F]"
|
||||
>{item[row?.rule]?.toFixed(2)}%</span
|
||||
>
|
||||
{:else}
|
||||
<span class="text-[#fff]"
|
||||
>n/a</span
|
||||
>
|
||||
{/if}
|
||||
|
||||
{:else if row?.rule === 'analystRating'}
|
||||
{#if ["Strong Buy", "Buy"].includes(item[row?.rule])}
|
||||
<span class="text-[#00FC50]">{item[row?.rule]}</span>
|
||||
{:else if ["Strong Sell", "Sell"].includes(item[row?.rule])}
|
||||
<span class="text-[#FF2F1F]">{item[row?.rule]}</span>
|
||||
{:else if item[row?.rule] === "Hold"}
|
||||
<span class="text-[#FFA838]">{item[row?.rule]}</span>
|
||||
{:else}
|
||||
-
|
||||
{/if}
|
||||
{/if}
|
||||
</td>
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div
|
||||
|
||||
@ -1133,7 +1133,7 @@
|
||||
class="flex flex-col border-b border-gray-600 py-1 sm:table-row sm:py-0"
|
||||
><td
|
||||
class="whitespace-nowrap px-0.5 py-[1px] xs:px-1 sm:py-2 text-[1rem]"
|
||||
>Market Cap</td
|
||||
><a href={`/stocks/${$stockTicker}/statistics/market-cap`} class="sm:hover:text-blue-400 text-white underline underline-offset-4">Market Cap</a></td
|
||||
>
|
||||
<td
|
||||
class="whitespace-nowrap px-0.5 py-[1px] text-left text-sm font-semibold xs:px-1 sm:py-2 sm:text-right sm:text-[1rem]"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user