add more rules
This commit is contained in:
parent
1982c18cb6
commit
60da7e4eff
@ -14,7 +14,7 @@
|
|||||||
<DropdownMenuPrimitive.CheckboxItem
|
<DropdownMenuPrimitive.CheckboxItem
|
||||||
bind:checked
|
bind:checked
|
||||||
class={cn(
|
class={cn(
|
||||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
|
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...$$restProps}
|
{...$$restProps}
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<DropdownMenuPrimitive.Item
|
<DropdownMenuPrimitive.Item
|
||||||
class={cn(
|
class={cn(
|
||||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[disabled]:opacity-50",
|
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none ",
|
||||||
inset && "pl-8",
|
inset && "pl-8",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -124,14 +124,10 @@ const getStockScreenerData = async (rules) => {
|
|||||||
shortRatio: (ruleOfList?.find(item => item.name === "shortRatio") || { condition: 'over' }).condition,
|
shortRatio: (ruleOfList?.find(item => item.name === "shortRatio") || { condition: 'over' }).condition,
|
||||||
shortFloatPercent: (ruleOfList?.find(item => item.name === "shortFloatPercent") || { condition: 'over' }).condition,
|
shortFloatPercent: (ruleOfList?.find(item => item.name === "shortFloatPercent") || { condition: 'over' }).condition,
|
||||||
shortOutStandingPercent: (ruleOfList?.find(item => item.name === "shortOutStandingPercent") || { condition: 'over' }).condition,
|
shortOutStandingPercent: (ruleOfList?.find(item => item.name === "shortOutStandingPercent") || { condition: 'over' }).condition,
|
||||||
|
failToDeliver: (ruleOfList?.find(item => item.name === "failToDeliver") || { condition: 'over' }).condition,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let ruleTrend = {
|
|
||||||
ratingRecommendation: 'Hold',
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let allRows = [
|
let allRows = [
|
||||||
{ rule: 'avgVolume', label: 'Avg Volume', step: [100,50,20,10,5,1], unit: 'M', category: 'fund' },
|
{ rule: 'avgVolume', label: 'Avg Volume', step: [100,50,20,10,5,1], unit: 'M', category: 'fund' },
|
||||||
@ -186,7 +182,7 @@ const getStockScreenerData = async (rules) => {
|
|||||||
{ rule: 'var', label: 'Value at Risk', step: [-1,-5,-10,-15,-20], unit: '%', category: 'fund' },
|
{ rule: 'var', label: 'Value at Risk', step: [-1,-5,-10,-15,-20], unit: '%', category: 'fund' },
|
||||||
{ rule: 'trendAnalysis', label: 'AI Trend Analysis (Bullish)', step: [90,80,70,60,50], unit: '%', category: 'ai' },
|
{ rule: 'trendAnalysis', label: 'AI Trend Analysis (Bullish)', step: [90,80,70,60,50], unit: '%', category: 'ai' },
|
||||||
{ rule: 'fundamentalAnalysis', label: 'AI Fundamental Analysis (Bullish)', step: [90,80,70,60,50], unit: '%', category: 'ai' },
|
{ rule: 'fundamentalAnalysis', label: 'AI Fundamental Analysis (Bullish)', step: [90,80,70,60,50], unit: '%', category: 'ai' },
|
||||||
//{ rule: 'ratingRecommendation', label: 'Analyst Rating', max: "2", min:"0", step:"1", category: 'fund'},
|
{ rule: 'analystRating', label: 'Analyst Rating', step: ['Buy', 'Hold', 'Sell'], unit:'', category: 'fund'},
|
||||||
{ rule: 'currentRatio', label: 'Current Ratio', step: [50,40,30,20,10,5,1], unit: '', category: 'fund' },
|
{ rule: 'currentRatio', label: 'Current Ratio', step: [50,40,30,20,10,5,1], unit: '', category: 'fund' },
|
||||||
{ rule: 'quickRatio', label: 'Quick Ratio', step: [50,40,30,20,10,5,1], unit: '', category: 'fund' },
|
{ rule: 'quickRatio', label: 'Quick Ratio', step: [50,40,30,20,10,5,1], unit: '', category: 'fund' },
|
||||||
{ rule: 'debtEquityRatio', label: 'Debt / Equity', step: [50,40,30,20,10,5,1], unit: '', category: 'fund' },
|
{ rule: 'debtEquityRatio', label: 'Debt / Equity', step: [50,40,30,20,10,5,1], unit: '', category: 'fund' },
|
||||||
@ -201,6 +197,7 @@ const getStockScreenerData = async (rules) => {
|
|||||||
{ rule: 'shortRatio', label: 'Short Ratio', step: [10,5,3,2,1,0], unit: '',category: 'fund' },
|
{ rule: 'shortRatio', label: 'Short Ratio', step: [10,5,3,2,1,0], unit: '',category: 'fund' },
|
||||||
{ rule: 'shortFloatPercent', label: 'Short % Float', step: [50,30,20,10,5,1,0], unit: '%',category: 'fund' },
|
{ rule: 'shortFloatPercent', label: 'Short % Float', step: [50,30,20,10,5,1,0], unit: '%',category: 'fund' },
|
||||||
{ rule: 'shortOutStandingPercent', label: 'Short % Shares', step: [50,30,20,10,5,1,0], unit: '%',category: 'fund' },
|
{ rule: 'shortOutStandingPercent', label: 'Short % Shares', step: [50,30,20,10,5,1,0], unit: '%',category: 'fund' },
|
||||||
|
{ rule: 'failToDeliver', label: 'Fail to Deliver', step: [500,200,100,50,20,10,5], unit: 'K',category: 'fund' },
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -264,7 +261,7 @@ const getStockScreenerData = async (rules) => {
|
|||||||
let valuePriceToSalesRatio = (ruleOfList?.find(item => item.name === "priceToSalesRatio") || { value: 'any'}).value;
|
let valuePriceToSalesRatio = (ruleOfList?.find(item => item.name === "priceToSalesRatio") || { value: 'any'}).value;
|
||||||
let valueBeta = (ruleOfList?.find(item => item.name === "beta") || { value: 'any' }).value;
|
let valueBeta = (ruleOfList?.find(item => item.name === "beta") || { value: 'any' }).value;
|
||||||
let valueMarketCap = (ruleOfList?.find(item => item.name === "marketCap") || { value: 'any' }).value;
|
let valueMarketCap = (ruleOfList?.find(item => item.name === "marketCap") || { value: 'any' }).value;
|
||||||
let valueAnalyst = (ruleOfList?.find(item => item.name === "ratingRecommendation") || { value: 'any'}).value;
|
let valueAnalystRating = (ruleOfList?.find(item => item.name === "analystRating") || { value: 'any'}).value;
|
||||||
let valueRSI = (ruleOfList?.find(item => item.name === "rsi") || { value: 'any' }).value;
|
let valueRSI = (ruleOfList?.find(item => item.name === "rsi") || { value: 'any' }).value;
|
||||||
let valueStochRSI = (ruleOfList?.find(item => item.name === "stochRSI") || { value: 'any'}).value;
|
let valueStochRSI = (ruleOfList?.find(item => item.name === "stochRSI") || { value: 'any'}).value;
|
||||||
let valueMFI = (ruleOfList?.find(item => item.name === "mfi") || { value: 'any'}).value;
|
let valueMFI = (ruleOfList?.find(item => item.name === "mfi") || { value: 'any'}).value;
|
||||||
@ -292,20 +289,9 @@ const getStockScreenerData = async (rules) => {
|
|||||||
let valueShortRatio = (ruleOfList?.find(item => item.name === "shortRatio") || { value: 'any'}).value;
|
let valueShortRatio = (ruleOfList?.find(item => item.name === "shortRatio") || { value: 'any'}).value;
|
||||||
let valueShortFloatPercent = (ruleOfList?.find(item => item.name === "shortFloatPercent") || { value: 'any'}).value;
|
let valueShortFloatPercent = (ruleOfList?.find(item => item.name === "shortFloatPercent") || { value: 'any'}).value;
|
||||||
let valueShortOutStandingPercent = (ruleOfList?.find(item => item.name === "shortOutStandingPercent") || { value: 'any'}).value;
|
let valueShortOutStandingPercent = (ruleOfList?.find(item => item.name === "shortOutStandingPercent") || { value: 'any'}).value;
|
||||||
|
let valueFailToDeliver = (ruleOfList?.find(item => item.name === "failToDeliver") || { value: 'any'}).value;
|
||||||
|
|
||||||
|
|
||||||
const ratingRecommendations = [
|
|
||||||
'Sell',
|
|
||||||
'Hold',
|
|
||||||
'Buy',
|
|
||||||
];
|
|
||||||
|
|
||||||
$: {
|
|
||||||
if (ruleTrend['ratingRecommendation'])
|
|
||||||
{
|
|
||||||
ruleTrend['ratingRecommendation'] = ratingRecommendations[valueAnalyst];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function changeRule(state: string)
|
function changeRule(state: string)
|
||||||
@ -386,6 +372,8 @@ const valueMappings = {
|
|||||||
shortRatio: valueShortRatio,
|
shortRatio: valueShortRatio,
|
||||||
shortFloatPercent: valueShortFloatPercent,
|
shortFloatPercent: valueShortFloatPercent,
|
||||||
shortOutStandingPercent: valueShortOutStandingPercent,
|
shortOutStandingPercent: valueShortOutStandingPercent,
|
||||||
|
analystRating: valueAnalystRating,
|
||||||
|
failToDeliver: valueFailToDeliver,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -456,6 +444,7 @@ const conditions = {
|
|||||||
shortRatio: ruleCondition.shortRatio,
|
shortRatio: ruleCondition.shortRatio,
|
||||||
shortFloatPercent: ruleCondition.shortFloatPercent,
|
shortFloatPercent: ruleCondition.shortFloatPercent,
|
||||||
shortOutStandingPercent: ruleCondition.shortOutStandingPercent,
|
shortOutStandingPercent: ruleCondition.shortOutStandingPercent,
|
||||||
|
failToDeliver: ruleCondition.failToDeliver,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -472,8 +461,8 @@ function handleAddRule() {
|
|||||||
let newRule;
|
let newRule;
|
||||||
|
|
||||||
switch (ruleName) {
|
switch (ruleName) {
|
||||||
case 'ratingRecommendation':
|
case 'analystRating':
|
||||||
newRule = { name: ruleName, value: valueAnalyst }; //ruleTrend[ruleName]
|
newRule = { name: ruleName, value: valueAnalystRating }; //ruleTrend[ruleName]
|
||||||
handleRule(newRule);
|
handleRule(newRule);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -659,7 +648,7 @@ $: {
|
|||||||
priceToBookRatio: valuePriceToBookRatio,
|
priceToBookRatio: valuePriceToBookRatio,
|
||||||
priceToSalesRatio: valuePriceToSalesRatio,
|
priceToSalesRatio: valuePriceToSalesRatio,
|
||||||
interestIncome: valueInterestIncome,
|
interestIncome: valueInterestIncome,
|
||||||
ratingRecommendation: valueAnalyst,
|
analystRating: valueAnalystRating,
|
||||||
revenue: valueRevenue,
|
revenue: valueRevenue,
|
||||||
growthRevenue: valueGrowthRevenue,
|
growthRevenue: valueGrowthRevenue,
|
||||||
ebitda: valueEBITDA,
|
ebitda: valueEBITDA,
|
||||||
@ -713,6 +702,7 @@ $: {
|
|||||||
shortRatio: valueShortRatio,
|
shortRatio: valueShortRatio,
|
||||||
shortFloatPercent: valueShortFloatPercent,
|
shortFloatPercent: valueShortFloatPercent,
|
||||||
shortOutStandingPercent: valueShortOutStandingPercent,
|
shortOutStandingPercent: valueShortOutStandingPercent,
|
||||||
|
failToDeliver: valueFailToDeliver,
|
||||||
|
|
||||||
};
|
};
|
||||||
ruleToUpdate.value = valueMap[ruleToUpdate.name] ?? ruleToUpdate.value;
|
ruleToUpdate.value = valueMap[ruleToUpdate.name] ?? ruleToUpdate.value;
|
||||||
@ -724,8 +714,8 @@ $: {
|
|||||||
displayRules = allRows?.filter(row => ruleOfList.some(rule => rule.name === row.rule));
|
displayRules = allRows?.filter(row => ruleOfList.some(rule => rule.name === row.rule));
|
||||||
filteredData = filterStockScreenerData();
|
filteredData = filterStockScreenerData();
|
||||||
|
|
||||||
if (ruleOfList?.some(item => item?.name === 'ratingRecommendation')) {
|
if (ruleOfList?.some(item => item?.name === 'analystRating')) {
|
||||||
filteredData = filteredData?.filter(item => item?.ratingRecommendation === valueAnalyst);
|
filteredData = filteredData?.filter(item => item?.analystRating === valueAnalystRating);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -765,6 +755,12 @@ function filterStockScreenerData() {
|
|||||||
} else if (rule.condition === "under" && item[rule.name] > rule.value * 10**(6)) {
|
} else if (rule.condition === "under" && item[rule.name] > rule.value * 10**(6)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (['failToDeliver']?.includes(rule.name)) {
|
||||||
|
if (rule.condition === "over" && item[rule.name] <= rule.value * 10**(3)) {
|
||||||
|
return false;
|
||||||
|
} else if (rule.condition === "under" && item[rule.name] > rule.value * 10**(3)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else if (rule.name === 'trendAnalysis') {
|
} else if (rule.name === 'trendAnalysis') {
|
||||||
if (rule.condition === "over" && item[rule.name]?.accuracy <= rule.value) {
|
if (rule.condition === "over" && item[rule.name]?.accuracy <= rule.value) {
|
||||||
return false;
|
return false;
|
||||||
@ -912,8 +908,8 @@ function handleChangeValue(value) {
|
|||||||
case 'interestIncome':
|
case 'interestIncome':
|
||||||
valueInterestIncome = value;
|
valueInterestIncome = value;
|
||||||
break;
|
break;
|
||||||
case 'ratingRecommendation':
|
case 'analystRating':
|
||||||
valueAnalyst = value;
|
valueAnalystRating = value;
|
||||||
break;
|
break;
|
||||||
case 'revenue':
|
case 'revenue':
|
||||||
valueRevenue = value;
|
valueRevenue = value;
|
||||||
@ -1067,6 +1063,8 @@ function handleChangeValue(value) {
|
|||||||
valueShortFloatPercent = value;
|
valueShortFloatPercent = value;
|
||||||
case 'shortOutStandingPercent':
|
case 'shortOutStandingPercent':
|
||||||
valueShortOutStandingPercent = value;
|
valueShortOutStandingPercent = value;
|
||||||
|
case 'failToDeliver':
|
||||||
|
valueFailToDeliver = value;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Unhandled rule: ${rule}`);
|
console.warn(`Unhandled rule: ${rule}`);
|
||||||
@ -1320,12 +1318,12 @@ async function popularStrategy(state: string) {
|
|||||||
<div on:click={() => ruleName = row?.rule}>
|
<div on:click={() => ruleName = row?.rule}>
|
||||||
<DropdownMenu.Root>
|
<DropdownMenu.Root>
|
||||||
<DropdownMenu.Trigger asChild let:builder>
|
<DropdownMenu.Trigger asChild let:builder>
|
||||||
<Button builders={[builder]} class="bg-[#000] h-[33px] flex flex-row justify-between items-center w-[150px] xs:w-[140px] sm:w-[150px] px-3 text-white rounded-lg truncate">
|
<Button builders={[builder]} class="bg-[#000] h-[40px] flex flex-row justify-between items-center w-[150px] xs:w-[140px] sm:w-[150px] px-3 text-white rounded-lg truncate">
|
||||||
<span class="truncate ml-2 text-sm sm:text-[1rem]">
|
<span class="truncate ml-2 text-sm sm:text-[1rem]">
|
||||||
{#if valueMappings[row?.rule] === 'any'}
|
{#if valueMappings[row?.rule] === 'any'}
|
||||||
Any
|
Any
|
||||||
{:else}
|
{:else}
|
||||||
{ruleCondition[row?.rule]} {valueMappings[row?.rule]}{row?.unit}
|
{ruleCondition[row?.rule] !== undefined ? ruleCondition[row?.rule] : ''} {valueMappings[row?.rule]}{row?.unit}
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
<svg class=" ml-1 h-6 w-6 xs:ml-2 inline-block" viewBox="0 0 20 20" fill="currentColor" style="max-width:40px" aria-hidden="true">
|
<svg class=" ml-1 h-6 w-6 xs:ml-2 inline-block" viewBox="0 0 20 20" fill="currentColor" style="max-width:40px" aria-hidden="true">
|
||||||
@ -1334,6 +1332,7 @@ async function popularStrategy(state: string) {
|
|||||||
</Button>
|
</Button>
|
||||||
</DropdownMenu.Trigger>
|
</DropdownMenu.Trigger>
|
||||||
<DropdownMenu.Content class="w-56 h-fit max-h-72 overflow-y-auto scroller">
|
<DropdownMenu.Content class="w-56 h-fit max-h-72 overflow-y-auto scroller">
|
||||||
|
{#if row?.rule !== 'analystRating'}
|
||||||
<DropdownMenu.Label>
|
<DropdownMenu.Label>
|
||||||
<div class="flex items-center justify-start gap-x-1">
|
<div class="flex items-center justify-start gap-x-1">
|
||||||
<div class="relative inline-block flex flex-row items-center justify-center">
|
<div class="relative inline-block flex flex-row items-center justify-center">
|
||||||
@ -1350,14 +1349,15 @@ async function popularStrategy(state: string) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DropdownMenu.Label>
|
</DropdownMenu.Label>
|
||||||
|
{/if}
|
||||||
<DropdownMenu.Separator />
|
<DropdownMenu.Separator />
|
||||||
<DropdownMenu.Group>
|
<DropdownMenu.Group>
|
||||||
{#each row?.step as newValue}
|
{#each row?.step as newValue}
|
||||||
<DropdownMenu.Item>
|
<DropdownMenu.Item>
|
||||||
|
|
||||||
<button on:click={() => {handleChangeValue(newValue)}} class="block w-full border-b border-gray-600 px-4 py-2 text-left text-sm text-white last:border-0 sm:hover:bg-gray-100 sm:hover:text-gray-900
|
<button on:click={() => {handleChangeValue(newValue)}} class="block w-full border-b border-gray-600 px-4 py-2 text-left text-sm sm:text-[1rem] text-white last:border-0 sm:hover:bg-gray-100 sm:hover:text-gray-900
|
||||||
focus:bg-blue-100 focus:text-gray-900 focus:outline-none">
|
focus:bg-blue-100 focus:text-gray-900 focus:outline-none">
|
||||||
{ruleCondition[row?.rule]} {newValue}{row?.unit}
|
{ruleCondition[row?.rule] !== undefined ? ruleCondition[row?.rule] : ''} {newValue}{row?.unit}
|
||||||
</button>
|
</button>
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user