add repeated flow
This commit is contained in:
parent
2471ce872a
commit
2026bb5ed0
@ -95,6 +95,11 @@
|
||||
step: ["ITM", "OTM"],
|
||||
defaultValue: "any",
|
||||
},
|
||||
flowType: {
|
||||
label: "Flow Type",
|
||||
step: ["Repeated Flow"],
|
||||
defaultValue: "any",
|
||||
},
|
||||
put_call: {
|
||||
label: "Contract Type",
|
||||
step: ["Calls", "Puts"],
|
||||
@ -128,6 +133,16 @@
|
||||
},
|
||||
};
|
||||
|
||||
const categoricalRules = [
|
||||
"moneyness",
|
||||
"flowType",
|
||||
"put_call",
|
||||
"sentiment",
|
||||
"execution_estimate",
|
||||
"option_activity_type",
|
||||
"underlying_type",
|
||||
];
|
||||
|
||||
// Generate allRows from allRules
|
||||
$: allRows = Object?.entries(allRules)
|
||||
?.sort(([, a], [, b]) => a.label.localeCompare(b.label)) // Sort by label
|
||||
@ -218,6 +233,7 @@
|
||||
|
||||
switch (ruleName) {
|
||||
case "moneyness":
|
||||
case "flowType":
|
||||
case "put_call":
|
||||
case "sentiment":
|
||||
case "execution_estimate":
|
||||
@ -347,16 +363,7 @@
|
||||
}
|
||||
|
||||
// Specific rule handling for options-related rules
|
||||
if (
|
||||
[
|
||||
"moneyness",
|
||||
"put_call",
|
||||
"sentiment",
|
||||
"execution_estimate",
|
||||
"option_activity_type",
|
||||
"underlying_type",
|
||||
]?.includes(ruleName)
|
||||
) {
|
||||
if (categoricalRules?.includes(ruleName)) {
|
||||
// Ensure valueMappings[ruleName] is initialized as an array
|
||||
if (!Array.isArray(valueMappings[ruleName])) {
|
||||
valueMappings[ruleName] = [];
|
||||
@ -1130,7 +1137,7 @@
|
||||
<DropdownMenu.Content
|
||||
class="w-64 min-h-auto max-h-72 overflow-y-auto scroller"
|
||||
>
|
||||
{#if !["moneyness", "put_call", "sentiment", "execution_estimate", "option_activity_type", "underlying_type"]?.includes(row?.rule)}
|
||||
{#if !categoricalRules?.includes(row?.rule)}
|
||||
<DropdownMenu.Label
|
||||
class="absolute mt-2 h-11 border-gray-800 border-b -top-1 z-20 fixed sticky bg-[#09090B]"
|
||||
>
|
||||
@ -1290,7 +1297,7 @@
|
||||
></div>
|
||||
{/if}
|
||||
<DropdownMenu.Group class="min-h-10 mt-2">
|
||||
{#if !["moneyness", "put_call", "sentiment", "execution_estimate", "option_activity_type", "underlying_type"]?.includes(row?.rule)}
|
||||
{#if !categoricalRules?.includes(row?.rule)}
|
||||
{#each row?.step as newValue, index}
|
||||
{#if ruleCondition[row?.rule] === "between"}
|
||||
{#if newValue && row?.step[index + 1]}
|
||||
@ -1334,7 +1341,7 @@
|
||||
</DropdownMenu.Item>
|
||||
{/if}
|
||||
{/each}
|
||||
{:else if ["moneyness", "put_call", "sentiment", "execution_estimate", "option_activity_type", "underlying_type"]?.includes(row?.rule)}
|
||||
{:else if categoricalRules?.includes(row?.rule)}
|
||||
{#each row?.step as item}
|
||||
<DropdownMenu.Item
|
||||
class="sm:hover:bg-[#2A2E39]"
|
||||
|
||||
@ -1,4 +1,8 @@
|
||||
|
||||
interface FilterContext {
|
||||
flowTypeCache?: Map<string, number>;
|
||||
}
|
||||
|
||||
const categoricalFields = [
|
||||
'put_call',
|
||||
'sentiment',
|
||||
@ -36,6 +40,7 @@ function convertUnitToValue(
|
||||
"etf",
|
||||
"itm",
|
||||
"otm",
|
||||
"repeated flow"
|
||||
]);
|
||||
if (nonNumericValues.has(lowerInput)) return input;
|
||||
if (input.endsWith("%")) {
|
||||
@ -72,10 +77,38 @@ function createRuleCheck(rule, ruleName, ruleValue) {
|
||||
const now = new Date(new Date().toLocaleString("en-US", { timeZone: "America/New_York" }));
|
||||
|
||||
|
||||
if (ruleName === 'flowtype') {
|
||||
return (item: any, context: FilterContext = {}) => {
|
||||
// Check for 'any' rule or other non-repeated flow conditions
|
||||
if (ruleValue === 'any' || ruleValue?.includes("any")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle Repeated Flow logic
|
||||
if (ruleValue?.includes('Repeated Flow')) {
|
||||
// Initialize flowTypeCache if it doesn't exist
|
||||
context.flowTypeCache = context.flowTypeCache || new Map();
|
||||
|
||||
// Create a unique key for repeated flow based on item characteristics
|
||||
const key = `${item.ticker}-${item.put_call}-${item.strike_price}-${item.date_expiration}`;
|
||||
|
||||
// Increment the count for the key in the flowTypeCache
|
||||
const currentCount = (context.flowTypeCache.get(key) || 0) + 1;
|
||||
context.flowTypeCache.set(key, currentCount);
|
||||
|
||||
// Return true if this flow appears more than N times (3 in this case)
|
||||
return currentCount > 3;
|
||||
}
|
||||
|
||||
// Fallback for other flow type conditions (i.e., non-repeated flow)
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
if (ruleName === 'moneyness') {
|
||||
return (item) => {
|
||||
|
||||
if (ruleValue === 'any') return true;
|
||||
if (ruleValue === 'any' || ruleValue?.includes("any")) return true;
|
||||
|
||||
const currentPrice = parseFloat(item?.underlying_price);
|
||||
const strikePrice = parseFloat(item?.strike_price);
|
||||
@ -274,17 +307,22 @@ return (item) => {
|
||||
|
||||
async function filterRawData(rawData, ruleOfList, filterQuery) {
|
||||
// Early return for empty inputs
|
||||
if (!rawData?.length ) {
|
||||
if (!rawData?.length) {
|
||||
return rawData || [];
|
||||
}
|
||||
|
||||
// Preprocess filter tickers
|
||||
const filterTickers = filterQuery
|
||||
? filterQuery.split(",").map((ticker) => ticker.trim().toUpperCase())
|
||||
? filterQuery?.split(",").map((ticker) => ticker.trim().toUpperCase())
|
||||
: [];
|
||||
|
||||
// Initialize context with optional flowTypeCache
|
||||
const context: FilterContext = {
|
||||
flowTypeCache: new Map()
|
||||
};
|
||||
|
||||
// Precompile rules for more efficient filtering
|
||||
const compiledRules = ruleOfList.map(rule => {
|
||||
const compiledRules = ruleOfList?.map(rule => {
|
||||
const ruleName = rule?.name?.toLowerCase();
|
||||
const ruleValue = convertUnitToValue(rule.value);
|
||||
|
||||
@ -302,12 +340,12 @@ async function filterRawData(rawData, ruleOfList, filterQuery) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply all precompiled rules
|
||||
return compiledRules.every(rule => rule?.compiledCheck(item));
|
||||
// Apply all precompiled rules, passing the context
|
||||
return compiledRules?.every(rule => rule?.compiledCheck(item, context));
|
||||
});
|
||||
}
|
||||
|
||||
// Web Worker message handler
|
||||
// Web Worker message handler remains the same
|
||||
onmessage = async (event: MessageEvent) => {
|
||||
const { rawData, ruleOfList, filterQuery } = event.data || {};
|
||||
// Filter the data
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user