Features
Discovers search terms that just started converting to identify expansion opportunities.
Export for Review: Weekly or Daily schedule | Export qualified terms, evaluate for manual keyword addition or negative matching
The template splits your search term history into two periods: recent (default 7 days) and historical (everything before that). It identifies search terms with at least one order in the recent period AND zero orders historically, representing genuinely new converting queries. For terms with 3+ recent orders, it validates ACOS is within 150% of target to ensure quality. Results are categorized by order volume (Emerging/Solid/Strong) to help prioritize which new winners warrant immediate keyword addition versus continued monitoring.
The critical distinction is zero historical orders, not just "no recent orders before this period." A search term that sold 20 times last year but had a dry spell isn't a new winner - it's an established term that just converted again. By requiring historical orders = 0, the template only surfaces search terms that represent genuinely new traffic patterns, seasonal shifts, or emerging market trends worth investigating.
The recent and historical periods must not overlap or gap. With default settings (recent: 0d..7d, historical: 8d..), day 7 is the most recent full day in "recent," and day 8 starts "historical." This creates a clean split of your entire search term history. If you change recent to 0d..14d, you must change historical to 15d.. to maintain the boundary. Overlapping periods would incorrectly classify terms, while gaps would miss data entirely.
For terms with 1-2 orders, ACOS is highly variable and unreliable - a single high-AOV order can show 15% ACOS while a single low-AOV order shows 60% ACOS from the same underlying profitability. The template skips ACOS validation below 3 orders (configurable) to avoid rejecting potentially good terms due to small sample noise. Above this threshold, ACOS must be within 150% of target to qualify, ensuring you don't expand into consistently unprofitable queries.
Strong New Winner (5+ orders): High confidence - multiple conversions in short window indicate real demand and likely profitability. Add as exact or phrase match keywords immediately.
Solid New Winner (3-4 orders): Medium confidence - meaningful conversion signal but less certain. Good candidates for exact match testing or continued auto campaign exposure.
Emerging New Winner (1-2 orders): Lower confidence - could be random variance or genuine new trend. Monitor for additional conversions before keyword addition, or add as broad match if very relevant to product.
Shorter recent periods (3-5 days) catch trends faster but surface more noise - you'll see many single-order terms that may not repeat. Longer periods (14-21 days) provide more reliable signals but you discover opportunities later, potentially missing early trend adoption advantages. The 7-day default balances these tradeoffs for most accounts. High-velocity businesses (daily deal sites, trending products) benefit from shorter windows. Stable catalog businesses benefit from longer windows.
The 150% threshold creates different selection pressures based on your target ACOS. With aggressive 20% target ACOS, 150% threshold = 30% acceptable - you're only seeing very efficient new terms. With conservative 40% target ACOS, 150% threshold = 60% acceptable - you'll discover more terms but need to validate their long-term viability. Match threshold tightness to your profit margins and willingness to test marginal terms.
This setting determines when ACOS filtering activates. At 3 orders (default), terms with 1-2 orders bypass ACOS check entirely - you see all low-volume new winners regardless of efficiency. Lowering to 2 orders means ACOS filtering starts at 2-order terms, reducing false positives from lucky single high-margin orders. Raising to 5 orders means you see all new winners with 1-4 orders, only filtering those with 5+ orders - useful when you want to manually evaluate all emerging trends.
Using "8d.." (day 8 through earliest available data) means the template looks at your entire search term history before the recent window. This is intentional - even if a term sold once 18 months ago, it's not a "new" winner today. If you only want to flag terms that are new within a specific lookback (e.g., terms that didn't sell in last 90 days), you could adjust to "8d..97d" but this misses the core use case of finding genuinely novel search patterns.
Strong New Winner (5+ orders) - Highest priority for keyword addition. Multiple conversions in recent window represent reliable demand signal. Action: Add as exact match keywords immediately in manual campaigns. Consider phrase match if search term shows clear intent variations (e.g., "red running shoes" could become phrase "red running shoes").
Solid New Winner (3-4 orders) - Good candidates for testing. Meaningful conversion signal but not yet proven at scale. Action: Add as exact match in dedicated testing campaign with controlled budget, or continue monitoring in auto campaigns for one more period. If ACOS is excellent (<50% of target), promote to immediate keyword addition.
Emerging New Winner (1-2 orders) - Early signals requiring validation. Could be random variance or genuine new trend. Action: Monitor for one more review period. If term appears again with additional orders, promote to keyword addition. If highly relevant to product (exact product name variation, clear purchase intent), consider immediate broad match addition for exposure control.
New Sales - Poor ACOS - Converting but unprofitable. These passed the new winner test but failed ACOS validation. Action: Review for relevance - if search term is off-target (wrong product category, informational intent), add as negative keyword. If relevant but expensive, monitor to see if efficiency improves with scale, or accept that this query isn't profitable for your product.
"New winner identified" - Qualified term meeting all criteria. Most common scenario during active discovery periods. Indicates healthy auto campaign performance generating new converting traffic.
"Already has historical sales" - Term converted in recent period but has prior order history. This is normal behavior for established terms and not a concern - these are filtered out to focus your attention on genuinely new opportunities.
"Recent ACOS too high" - Term is converting for first time but inefficiently. Evaluate relevance: if term is off-target, negate it. If relevant, the product may not be competitive for this query (check organic rank, competitor pricing, review quality).
"Insufficient recent orders" - Very rare with default 1-order minimum. Only appears if you've raised the minimum recent orders setting above 1. Indicates you have strict discovery criteria and are waiting for stronger signals.
Expect higher volumes of new winners at season starts (back-to-school in July, holiday in October, summer in April). These represent seasonal search pattern shifts as customers begin researching category needs. Process these batches systematically - don't add all terms at once. Prioritize Strong/Solid categories first, monitor Emerging terms for follow-up conversions before committing budget.
New product listings typically show 10-30 new converting search terms in first 2-4 weeks as Amazon's algorithm tests different placements and customers find various search paths to your product. This is healthy and expected. Focus on terms that appear in Strong/Solid categories - these represent your product's core search relevance. Emerging terms may be exploratory placements that won't sustain.
Sudden clusters of new winners on established products may indicate competitor stock-outs or price increases driving their traffic to your listings. These opportunities can be temporary - if you see 5-10 new winners in a single week on a mature product, check top competitors' availability and pricing. Add the most relevant terms quickly to capture shifted demand before competitors return to market.
Consistent weekly discovery of 2-5 new winners indicates healthy auto campaign performance. Zero new winners for multiple consecutive weeks suggests: auto campaign budgets too constrained (not getting enough exposure for discovery), bids too low (not winning auctions on new terms), or market saturation (you've already captured all relevant search terms for your niche).
Daily reviews will show many Emerging (1-2 order) terms that may not repeat. Weekly reviews show fewer total terms but higher proportion of Solid/Strong signals. Monthly reviews miss fast-moving trends but show only the most sustained new traffic patterns. Match review frequency to your business velocity and available time for keyword management.
Small accounts ($5-10k/month spend): 2-5 new winners per week is healthy. More suggests very broad targeting, fewer suggests over-reliance on manual campaigns.
Medium accounts ($10-30k/month spend): 5-15 new winners per week typical. Should include mix of Strong/Solid/Emerging.
Large accounts ($30k+/month spend): 15-30+ new winners per week common, especially with diverse product catalogs. Requires systematic processing workflow to avoid overwhelming keyword management.
/*
=== Newly Sold Search Terms ===
Purpose: Find search terms with recent orders that have never sold before.
Dataset: Search Terms
Recommended: Export for review | Daily or Weekly
*/
// === Core Settings ===
let $recent_period = 0d..7d; // CORE: Recent period for new sales [Change both periods together: 7d recent = 8d.. historical]
let $historical_period = 8d..; // CORE: Historical period - must start day after recent ends
let $orders_min_recent = 1; // CORE: Minimum orders in recent period to qualify
// === Strategy Settings ===
let $t_acos_threshold = 150%; // STRATEGY: Only flag if ACOS ≤ (Target ACOS × 150%) [e.g., 30% target = 45% threshold]
let $orders_min_for_acos_eval = 3; // STRATEGY: Minimum orders needed for ACOS reliability check
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms
// ============================================================================
// === Segment Logic ===
// ============================================================================
// Define time periods for comparison
let $recent_orders = orders($recent_period);
let $historical_orders = orders($historical_period);
// Check if this is truly a "new winner"
let $is_new_winner = case(
$recent_orders >= $orders_min_recent and $historical_orders = 0 => 1,
else 0
);
// Performance validation for new winners
let $recent_acos = acos($recent_period);
let $performance_acceptable = case(
target acos <= 0 => 1, // No target set = accept
$recent_orders < $orders_min_for_acos_eval => 1, // Not enough data for ACOS check
$recent_acos <= (target acos * $t_acos_threshold) => 1, // ACOS acceptable
else 0
);
// Final qualification
let $qualified = case(
$is_new_winner = 1 and $performance_acceptable = 1 => 1,
else 0
);
// Diagnostic properties
let $reason = case(
$recent_orders = 0 => "No recent orders",
$historical_orders > 0 => "Already has historical sales",
$recent_orders < $orders_min_recent => "Insufficient recent orders",
$performance_acceptable = 0 => "Recent ACOS too high",
$qualified = 1 => "New winner identified",
else "Not qualified"
);
let $result = case(
$qualified = 1 and $recent_orders >= 5 => "Strong New Winner",
$qualified = 1 and $recent_orders >= 3 => "Solid New Winner",
$qualified = 1 => "Emerging New Winner",
$is_new_winner = 1 and $performance_acceptable = 0 => "New Sales - Poor ACOS",
$historical_orders > 0 => "Established Performer",
else "No Action"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $qualified = 1
/*
=== Newly Sold Search Terms ===
Purpose: Find search terms with recent orders that have never sold before.
Dataset: Search Terms
Recommended: Export for review | Daily or Weekly
*/
// === Core Settings ===
let $recent_period = 0d..7d; // CORE: Recent period for new sales [Change both periods together: 7d recent = 8d.. historical]
let $historical_period = 8d..; // CORE: Historical period - must start day after recent ends
let $orders_min_recent = 1; // CORE: Minimum orders in recent period to qualify
// === Strategy Settings ===
let $t_acos_threshold = 150%; // STRATEGY: Only flag if ACOS ≤ (Target ACOS × 150%) [e.g., 30% target = 45% threshold]
let $orders_min_for_acos_eval = 3; // STRATEGY: Minimum orders needed for ACOS reliability check
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms
// ============================================================================
// === Segment Logic ===
// ============================================================================
// Define time periods for comparison
let $recent_orders = orders($recent_period);
let $historical_orders = orders($historical_period);
// Check if this is truly a "new winner"
let $is_new_winner = case(
$recent_orders >= $orders_min_recent and $historical_orders = 0 => 1,
else 0
);
// Performance validation for new winners
let $recent_acos = acos($recent_period);
let $performance_acceptable = case(
target acos <= 0 => 1, // No target set = accept
$recent_orders < $orders_min_for_acos_eval => 1, // Not enough data for ACOS check
$recent_acos <= (target acos * $t_acos_threshold) => 1, // ACOS acceptable
else 0
);
// Final qualification
let $qualified = case(
$is_new_winner = 1 and $performance_acceptable = 1 => 1,
else 0
);
// Diagnostic properties
let $reason = case(
$recent_orders = 0 => "No recent orders",
$historical_orders > 0 => "Already has historical sales",
$recent_orders < $orders_min_recent => "Insufficient recent orders",
$performance_acceptable = 0 => "Recent ACOS too high",
$qualified = 1 => "New winner identified",
else "Not qualified"
);
let $result = case(
$qualified = 1 and $recent_orders >= 5 => "Strong New Winner",
$qualified = 1 and $recent_orders >= 3 => "Solid New Winner",
$qualified = 1 => "Emerging New Winner",
$is_new_winner = 1 and $performance_acceptable = 0 => "New Sales - Poor ACOS",
$historical_orders > 0 => "Established Performer",
else "No Action"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $qualified = 1
Drills down from account-level spend changes to identify specific entities driving increases or decreases.
Multi-Level Investigation: Review-only | Start at Campaign level, drill to Keywords & Targets for root cause analysis
The template compares recent 7-day spend against a 28-day baseline to detect percentage changes, then decomposes spend into its mathematical components (Clicks × CPC) to identify root causes. When entities show 30%+ spend shifts, it evaluates recent ACOS against target to determine if increases represent problems or healthy scaling. Results are categorized into Problems, Scaling, or Opportunities based on spend direction and performance context. The identical logic works across all datasets (Campaigns, Ad Groups, Keywords & Targets, Product Ads), enabling multi-level drill-down investigation from account to entity level.
The template uses only universal properties available across all datasets (spend, clicks, impressions, CPC, ACOS, orders, state). This enables a consistent investigation workflow: start at Campaign level to identify which campaigns are driving account problems, then switch dataset to Keywords & Targets to drill into specific root causes within those campaigns. The logic, thresholds, and categorization work identically at every level - only the granularity of analysis changes. For complex account structures, Ad Groups provide an intermediate analysis layer between campaigns and individual targets.
Since spend is mathematically defined as Clicks × CPC, the blueprint analyzes both components separately to identify which drove the change. A 50% spend increase could be from 50% more clicks (traffic growth), 50% higher CPC (cost escalation), or a combination. This attribution immediately directs investigation - click-driven changes point to traffic/impression issues, while CPC-driven changes point to competition or Quality Score factors.
Raw spend changes without performance context create false alarms. A 100% spend increase is concerning if ACOS went from 25% to 55%, but perfectly fine if ACOS stayed at 25% - that's just successful scaling. The blueprint applies ACOS thresholds (120% acceptable, 150% problem) to recent performance, categorizing spend increases as either problematic or healthy based on efficiency maintenance.
Problems: Spend increases paired with poor ACOS (>150% of target). These are the entities actively hurting account performance and should be addressed first through bid reductions, budget adjustments, or pausing.
Scaling: Spend increases with good ACOS (≤100% of target). These represent successful growth and typically don't need intervention - they're just context for why total account spend increased.
Opportunities: Spend decreases on entities with good ACOS. These represent high-performing campaigns or targets losing volume, often due to budget constraints or reduced bids, and may benefit from increased investment.
Not all entities matter equally. A 100% increase on a $5/week entity is less important than a 30% increase on a $200/week entity. The [High $] tag identifies entities with $50+ recent spend, ensuring you prioritize changes that meaningfully affect account totals rather than getting distracted by percentage changes on low-volume entities. This is particularly valuable at keyword/target level where spend can be widely distributed, but also useful at campaign level for large accounts.
The moderate (30%) and severe (75%) thresholds create a two-tier sensitivity system. Moderate catches meaningful but not urgent changes for awareness, while severe flags dramatic shifts requiring immediate investigation. In volatile markets (seasonal products, new launches), raise thresholds 10-15 percentage points to avoid alert fatigue. In stable mature markets, lower thresholds 5-10 points to catch problems earlier.
The 120% acceptable and 150% problem thresholds work together to categorize spend changes. With a 30% target ACOS: 36% is acceptable (scaling territory), 45% is a problem (reduce spend territory). The gap between thresholds creates a middle zone for moderate efficiency degradation. Narrow this gap (110%/130%) for thin margins where you can't tolerate efficiency loss. Widen it (130%/175%) for high margins where volume matters more.
The 7-day recent window balances responsiveness with stability - long enough to filter daily noise but short enough to catch current problems. The 28-day baseline provides reliable comparison without being so long that market shifts make it irrelevant. Extending recent to 14 days smooths weekend/weekday variations but reduces responsiveness to new problems. Shortening baseline to 14 days makes the tool more reactive to market changes but less reliable in distinguishing true anomalies from normal variance.
The 25% component threshold determines when the blueprint attributes spend changes to clicks vs. CPC. If clicks increased 30% and CPC increased 5%, clicks are identified as the driver. If both increased 30%, both are identified. Lowering this threshold (15-20%) provides more granular attribution but may over-identify drivers during normal market noise. Raising it (30-35%) ensures you only see attribution for truly meaningful component shifts.
Problem: Severe Increase + Poor ACOS [High $] - Highest priority. Entity is spending significantly more (75%+ increase) with ACOS above 150% of target, and represents $50+ weekly spend. These are actively damaging account performance. At Campaign level, investigate campaign settings and recent changes. At Keywords & Targets level, check if recent bid increases caused this, verify listing quality hasn't declined, consider reducing bids or pausing.
Problem: Moderate Increase + Poor ACOS - Medium priority. Spending 30-75% more with poor efficiency. These contribute to account-level ACOS problems but less urgently than severe cases. Review performance trends to determine if deterioration is accelerating or stabilizing.
Scaling: Severe Increase (Clicks) + Good ACOS - Positive signal, no action needed. Entity is successfully scaling with maintained efficiency. This is healthy growth - the ACOS context confirms the increased spend is justified by strong performance.
Opportunity: Severe Decrease (Clicks) + Good ACOS - Missed revenue potential. High-performing entity losing click volume. At Campaign level, likely hitting budget constraints - consider raising daily budget. At Keywords & Targets level, may be due to parent campaign budget caps or reduced bids - consider raising campaign budget or increasing bids to recapture lost volume from proven performers.
Increase: Severe (CPC Spike) - Neutral but investigate cause. Spending 75%+ more due to CPC increases without clear performance context. Check for: competitor bid increases in auction, Quality Score declines affecting ad rank, recent bid changes you made. Determine if the higher cost is sustainable given current conversion rates.
Decrease: Moderate (Click Loss) - Context-dependent. Spending 30-50% less due to reduced clicks. If performance was poor, this is natural wind-down. If performance was good, investigate: campaign budget constraints, reduced bids, impression loss from competition, dayparting or placement restrictions.
"Severe spend increase from click volume growth with poor ACOS" - You're getting more traffic but it's converting poorly. Check if: new placements activated with different traffic quality, expanded targeting brought in less relevant traffic, organic ranking changed affecting who clicks your ads. The problem isn't the spend increase per se, it's that the additional traffic quality is subpar.
"Severe spend increase driven by CPC escalation" - Same traffic volume but paying more per click. Check: competitor activity in shared keywords, your Quality Score changes, recent bid adjustments. If your bid hasn't changed but CPC rose, competitors are bidding more aggressively. Evaluate whether maintaining position at higher costs makes sense given current conversion rates.
"Moderate spend drop from reduced clicks despite good ACOS" - Proven performer losing volume. Most common causes: campaign budget hitting daily cap earlier in day (check campaign budget utilization), bids becoming less competitive as market evolved (check impression share lost to rank), seasonality reducing overall search volume. Consider raising investment since efficiency is good.
The [High $] suffix appears when recent spend ≥$50/week. These targets should be prioritized because their changes materially affect account totals. A 100% increase on a $5 target adds $5 weekly, while a 30% increase on a $100 target adds $30 weekly - the latter matters more despite the smaller percentage change.
Most effective use case: Account dashboard shows "Spend +40%, ACOS degraded from 30% to 42%." Step 1: Deploy template on Campaigns dataset, sort by $result. Identify 2-3 campaigns showing "Problem" status. Step 2: Note which campaigns, then switch dataset to Keywords & Targets. Filter segment to those problematic campaigns. Step 3: Sort by $result to identify the 5-10 specific targets within those campaigns driving the degradation. This multi-level approach quickly narrows from account problem to actionable entity-level fixes.
Secondary pattern: Use at keyword/target level when you've already identified problematic campaigns. Open template with Keywords & Targets dataset, filter to known problem campaigns, sort by $result. Problems sort to top, immediately identifying the 3-5 targets driving campaign-level degradation. Most commonly these are targets where bids were recently raised or new high-volume but poor-efficiency targets recently enabled.
Pattern across datasets: Account performance is good but total orders are flat. At Campaign level, filter to $result contains "Opportunity" to find campaigns with good ACOS losing spend. At Keywords & Targets level within those campaigns, find specific high-performers losing volume. These often cluster where parent campaigns are hitting budget caps. Raising budget in those campaigns typically shows immediate ROI since the constrained entities have proven efficiency.
Expect higher volumes of "Scaling" results during peak seasons when overall account spend naturally increases. If you see many "Problem" results during peak season, this indicates you're not scaling efficiently - increased demand is bringing lower-quality traffic rather than just more volume of good traffic. This suggests bid optimization or targeting refinement is needed.
Clusters of "Increase: Severe (CPC Spike)" results without corresponding click increases indicate competitive pressure. At Campaign level, this suggests market-wide competition increases. At Keywords & Targets level, multiple targets in same campaign showing this pattern suggests a competitor entered your primary keywords. You'll need to decide whether to match their bids (increasing spend to maintain volume) or accept reduced impression share (maintaining spend but losing volume).
If segment shows few results (<5 entities) despite account-level spend changes, the issue may be at a different level than currently analyzed. At Campaign level with sparse results, spend changes might be distributed across many campaigns rather than concentrated. Switch to Keywords & Targets to see if specific targets are driving changes. At Keywords & Targets level with sparse results, check for: campaign budget changes, campaign pauses/enables, bid strategy switches, bulk bid adjustments across many targets (each small, but cumulative large impact). This template focuses on individual entity anomalies, not structural account changes.
/*
=== Anomaly Detection: Spend ===
Purpose: Identifies entities driving spend changes for account-level investigation.
Datasets: Campaigns | Ad Groups | Keywords & Targets | Keywords | Targets | Ads | Search Terms
Recommended: Ad-hoc investigation tool | Change dataset based on investigation depth needed
*/
// === Time Periods ===
let $period_recent = 0d..7d; // TIME: Recent spend window (7 days)
let $period_baseline = 8d..35d; // TIME: Baseline comparison (28 days)
// === Reliability Thresholds ===
let $spend_min = 5.00; // CORE: Minimum baseline spend for reliable analysis [e.g., $5+ spend]
let $impressions_min = 50; // CORE: Minimum baseline impressions for meaningful context [e.g., 50+ impressions]
let $clicks_min = 5; // CORE: Minimum baseline clicks for reliable spend attribution [e.g., 5+ clicks]
// === Shift Detection ===
let $spend_moderate = 30%; // STRATEGY: Moderate spend shift threshold [e.g., 30% = $100 to $130 or $70]
let $spend_severe = 75%; // STRATEGY: Severe spend shift threshold [e.g., 75% = $100 to $175 or $25]
let $component_threshold = 25%; // STRATEGY: Click/CPC shift to attribute root cause [e.g., 25% shift = meaningful driver]
// === Performance Context ===
let $acos_acceptable_threshold = 120%; // STRATEGY: ACOS threshold for performance assessment [e.g., 120% = 30% target → 36% acceptable]
let $acos_problem_threshold = 150%; // STRATEGY: ACOS threshold for problem identification [e.g., 150% = 30% target → 45% problem]
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Segment Logic ===
// ============================================================================
// === Baseline & Recent Metrics ===
let $spend_recent = spend($period_recent);
let $spend_baseline = spend($period_baseline);
let $impressions_recent = impressions($period_recent);
let $impressions_baseline = impressions($period_baseline);
let $clicks_recent = clicks($period_recent);
let $clicks_baseline = clicks($period_baseline);
let $cpc_recent = cpc($period_recent);
let $cpc_baseline = cpc($period_baseline);
let $acos_recent = acos($period_recent);
let $acos_baseline = acos($period_baseline);
let $orders_recent = orders($period_recent);
let $orders_baseline = orders($period_baseline);
// === Data Reliability ===
let $sufficient_data = case(
$spend_baseline >= $spend_min and $impressions_baseline >= $impressions_min and $clicks_baseline >= $clicks_min => 1,
else 0
);
let $sufficient_for_acos = case(
$orders_recent >= 1 and $orders_baseline >= 1 => 1,
else 0
);
// === Calculate Changes ===
// Spend = Clicks × CPC, so analyze these components
let $spend_change = case(
$spend_baseline > 0 => ($spend_recent - $spend_baseline) / $spend_baseline,
else 0
);
let $clicks_change = case(
$clicks_baseline > 0 => ($clicks_recent - $clicks_baseline) / $clicks_baseline,
else 0
);
let $cpc_change = case(
$cpc_baseline > 0 => ($cpc_recent - $cpc_baseline) / $cpc_baseline,
else 0
);
let $acos_change = case(
$sufficient_for_acos = 1 and $acos_baseline > 0 => ($acos_recent - $acos_baseline) / $acos_baseline,
else 0
);
// === Severity Assessment ===
let $spend_severity = case(
$spend_change >= $spend_severe => "severe_increase",
$spend_change >= $spend_moderate => "moderate_increase",
$spend_change <= -1 * $spend_severe => "severe_decrease",
$spend_change <= -1 * $spend_moderate => "moderate_decrease",
else "normal"
);
let $has_anomaly = case(
$spend_severity != "normal" => 1,
else 0
);
// === Root Cause Analysis ===
// Determine if spend change is driven by click volume or cost per click
let $driven_by_clicks = case(
$clicks_change >= $component_threshold or $clicks_change <= -1 * $component_threshold => 1,
else 0
);
let $driven_by_cpc = case(
$cpc_change >= $component_threshold or $cpc_change <= -1 * $component_threshold => 1,
else 0
);
let $change_driver = case(
$driven_by_clicks = 1 and $driven_by_cpc = 1 => "clicks_and_cpc",
$driven_by_clicks = 1 => "click_volume",
$driven_by_cpc = 1 => "cost_per_click",
else "minor_shifts"
);
// === Performance Assessment ===
let $performance_status = case(
$sufficient_for_acos = 0 => "insufficient_data",
target acos <= 0 => "no_target",
$acos_recent > target acos * $acos_problem_threshold => "poor_efficiency",
$acos_recent > target acos * $acos_acceptable_threshold => "acceptable_efficiency",
$acos_recent > target acos => "near_target",
else "good_efficiency"
);
// === Spend Impact Assessment ===
let $spend_impact = case(
$spend_recent >= 50.00 => "high_impact",
$spend_recent >= 20.00 => "medium_impact",
$spend_recent >= 5.00 => "low_impact",
else "minimal_impact"
);
// === Diagnostic Properties ===
let $reason = case(
$sufficient_data = 0 => "Insufficient spend history",
$has_anomaly = 0 => "No significant spend shift detected",
// Severe increases with performance context
$spend_severity = "severe_increase" and $performance_status = "poor_efficiency" and $change_driver = "click_volume" => "Severe spend increase from click volume growth with poor ACOS",
$spend_severity = "severe_increase" and $performance_status = "poor_efficiency" and $change_driver = "cost_per_click" => "Severe spend increase from CPC escalation with poor ACOS",
$spend_severity = "severe_increase" and $performance_status = "poor_efficiency" => "Severe spend increase with poor efficiency",
$spend_severity = "severe_increase" and $change_driver = "click_volume" => "Severe spend increase driven by click volume growth",
$spend_severity = "severe_increase" and $change_driver = "cost_per_click" => "Severe spend increase driven by CPC escalation",
$spend_severity = "severe_increase" and $change_driver = "clicks_and_cpc" => "Severe spend increase from both click volume and CPC rises",
$spend_severity = "severe_increase" => "Severe spend increase detected",
// Moderate increases with performance context
$spend_severity = "moderate_increase" and $performance_status = "poor_efficiency" and $change_driver = "click_volume" => "Moderate spend increase from click volume with poor ACOS",
$spend_severity = "moderate_increase" and $performance_status = "poor_efficiency" and $change_driver = "cost_per_click" => "Moderate spend increase from CPC rise with poor ACOS",
$spend_severity = "moderate_increase" and $performance_status = "poor_efficiency" => "Moderate spend increase with poor efficiency",
$spend_severity = "moderate_increase" and $change_driver = "click_volume" => "Moderate spend increase from click volume growth",
$spend_severity = "moderate_increase" and $change_driver = "cost_per_click" => "Moderate spend increase from CPC rise",
$spend_severity = "moderate_increase" and $change_driver = "clicks_and_cpc" => "Moderate spend increase from click volume and CPC",
$spend_severity = "moderate_increase" => "Moderate spend increase detected",
// Decreases with performance context
$spend_severity = "severe_decrease" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Severe spend drop from lost clicks despite good ACOS",
$spend_severity = "severe_decrease" and $change_driver = "click_volume" => "Severe spend drop due to lost clicks",
$spend_severity = "severe_decrease" and $change_driver = "cost_per_click" => "Severe spend drop due to CPC decrease",
$spend_severity = "severe_decrease" and $change_driver = "clicks_and_cpc" => "Severe spend drop from both click and CPC declines",
$spend_severity = "severe_decrease" => "Severe spend decrease detected",
$spend_severity = "moderate_decrease" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Moderate spend drop from reduced clicks despite good ACOS",
$spend_severity = "moderate_decrease" and $change_driver = "click_volume" => "Moderate spend drop from reduced clicks",
$spend_severity = "moderate_decrease" and $change_driver = "cost_per_click" => "Moderate spend drop from CPC decrease",
$spend_severity = "moderate_decrease" and $change_driver = "clicks_and_cpc" => "Moderate spend drop from click and CPC declines",
$spend_severity = "moderate_decrease" => "Moderate spend decrease detected",
else "No significant spend pattern change"
);
let $result = case(
$sufficient_data = 0 => "insufficient_data",
$has_anomaly = 0 => "insufficient_data",
// Problem increases (high spend + poor efficiency) - sort to top
$spend_severity = "severe_increase" and $performance_status = "poor_efficiency" and $spend_impact = "high_impact" => "Problem: Severe Increase + Poor ACOS [High $]",
$spend_severity = "severe_increase" and $performance_status = "poor_efficiency" => "Problem: Severe Increase + Poor ACOS",
$spend_severity = "moderate_increase" and $performance_status = "poor_efficiency" and $spend_impact = "high_impact" => "Problem: Moderate Increase + Poor ACOS [High $]",
$spend_severity = "moderate_increase" and $performance_status = "poor_efficiency" => "Problem: Moderate Increase + Poor ACOS",
// Neutral/good increases
$spend_severity = "severe_increase" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Scaling: Severe Increase (Clicks) + Good ACOS",
$spend_severity = "severe_increase" and $change_driver = "click_volume" => "Increase: Severe (Click Volume)",
$spend_severity = "severe_increase" and $change_driver = "cost_per_click" => "Increase: Severe (CPC Spike)",
$spend_severity = "severe_increase" and $change_driver = "clicks_and_cpc" => "Increase: Severe (Clicks + CPC)",
$spend_severity = "severe_increase" => "Increase: Severe",
$spend_severity = "moderate_increase" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Scaling: Moderate Increase (Clicks) + Good ACOS",
$spend_severity = "moderate_increase" and $change_driver = "click_volume" => "Increase: Moderate (Click Volume)",
$spend_severity = "moderate_increase" and $change_driver = "cost_per_click" => "Increase: Moderate (CPC)",
$spend_severity = "moderate_increase" and $change_driver = "clicks_and_cpc" => "Increase: Moderate (Clicks + CPC)",
$spend_severity = "moderate_increase" => "Increase: Moderate",
// Opportunity decreases (good performers losing volume)
$spend_severity = "severe_decrease" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Opportunity: Severe Decrease (Clicks) + Good ACOS",
$spend_severity = "moderate_decrease" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Opportunity: Moderate Decrease (Clicks) + Good ACOS",
// Normal decreases
$spend_severity = "severe_decrease" and $change_driver = "click_volume" => "Decrease: Severe (Click Loss)",
$spend_severity = "severe_decrease" and $change_driver = "cost_per_click" => "Decrease: Severe (CPC Drop)",
$spend_severity = "severe_decrease" and $change_driver = "clicks_and_cpc" => "Decrease: Severe (Clicks + CPC)",
$spend_severity = "severe_decrease" => "Decrease: Severe",
$spend_severity = "moderate_decrease" and $change_driver = "click_volume" => "Decrease: Moderate (Click Loss)",
$spend_severity = "moderate_decrease" and $change_driver = "cost_per_click" => "Decrease: Moderate (CPC Drop)",
$spend_severity = "moderate_decrease" and $change_driver = "clicks_and_cpc" => "Decrease: Moderate (Clicks + CPC)",
$spend_severity = "moderate_decrease" => "Decrease: Moderate",
// Catch-all for any edge cases
else "insufficient_data"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $sufficient_data = 1
and $has_anomaly = 1
and $result != "insufficient_data"
/*
=== Anomaly Detection: Spend ===
Purpose: Identifies entities driving spend changes for account-level investigation.
Datasets: Campaigns | Ad Groups | Keywords & Targets | Keywords | Targets | Ads | Search Terms
Recommended: Ad-hoc investigation tool | Change dataset based on investigation depth needed
*/
// === Time Periods ===
let $period_recent = 0d..7d; // TIME: Recent spend window (7 days)
let $period_baseline = 8d..35d; // TIME: Baseline comparison (28 days)
// === Reliability Thresholds ===
let $spend_min = 5.00; // CORE: Minimum baseline spend for reliable analysis [e.g., $5+ spend]
let $impressions_min = 50; // CORE: Minimum baseline impressions for meaningful context [e.g., 50+ impressions]
let $clicks_min = 5; // CORE: Minimum baseline clicks for reliable spend attribution [e.g., 5+ clicks]
// === Shift Detection ===
let $spend_moderate = 30%; // STRATEGY: Moderate spend shift threshold [e.g., 30% = $100 to $130 or $70]
let $spend_severe = 75%; // STRATEGY: Severe spend shift threshold [e.g., 75% = $100 to $175 or $25]
let $component_threshold = 25%; // STRATEGY: Click/CPC shift to attribute root cause [e.g., 25% shift = meaningful driver]
// === Performance Context ===
let $acos_acceptable_threshold = 120%; // STRATEGY: ACOS threshold for performance assessment [e.g., 120% = 30% target → 36% acceptable]
let $acos_problem_threshold = 150%; // STRATEGY: ACOS threshold for problem identification [e.g., 150% = 30% target → 45% problem]
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Segment Logic ===
// ============================================================================
// === Baseline & Recent Metrics ===
let $spend_recent = spend($period_recent);
let $spend_baseline = spend($period_baseline);
let $impressions_recent = impressions($period_recent);
let $impressions_baseline = impressions($period_baseline);
let $clicks_recent = clicks($period_recent);
let $clicks_baseline = clicks($period_baseline);
let $cpc_recent = cpc($period_recent);
let $cpc_baseline = cpc($period_baseline);
let $acos_recent = acos($period_recent);
let $acos_baseline = acos($period_baseline);
let $orders_recent = orders($period_recent);
let $orders_baseline = orders($period_baseline);
// === Data Reliability ===
let $sufficient_data = case(
$spend_baseline >= $spend_min and $impressions_baseline >= $impressions_min and $clicks_baseline >= $clicks_min => 1,
else 0
);
let $sufficient_for_acos = case(
$orders_recent >= 1 and $orders_baseline >= 1 => 1,
else 0
);
// === Calculate Changes ===
// Spend = Clicks × CPC, so analyze these components
let $spend_change = case(
$spend_baseline > 0 => ($spend_recent - $spend_baseline) / $spend_baseline,
else 0
);
let $clicks_change = case(
$clicks_baseline > 0 => ($clicks_recent - $clicks_baseline) / $clicks_baseline,
else 0
);
let $cpc_change = case(
$cpc_baseline > 0 => ($cpc_recent - $cpc_baseline) / $cpc_baseline,
else 0
);
let $acos_change = case(
$sufficient_for_acos = 1 and $acos_baseline > 0 => ($acos_recent - $acos_baseline) / $acos_baseline,
else 0
);
// === Severity Assessment ===
let $spend_severity = case(
$spend_change >= $spend_severe => "severe_increase",
$spend_change >= $spend_moderate => "moderate_increase",
$spend_change <= -1 * $spend_severe => "severe_decrease",
$spend_change <= -1 * $spend_moderate => "moderate_decrease",
else "normal"
);
let $has_anomaly = case(
$spend_severity != "normal" => 1,
else 0
);
// === Root Cause Analysis ===
// Determine if spend change is driven by click volume or cost per click
let $driven_by_clicks = case(
$clicks_change >= $component_threshold or $clicks_change <= -1 * $component_threshold => 1,
else 0
);
let $driven_by_cpc = case(
$cpc_change >= $component_threshold or $cpc_change <= -1 * $component_threshold => 1,
else 0
);
let $change_driver = case(
$driven_by_clicks = 1 and $driven_by_cpc = 1 => "clicks_and_cpc",
$driven_by_clicks = 1 => "click_volume",
$driven_by_cpc = 1 => "cost_per_click",
else "minor_shifts"
);
// === Performance Assessment ===
let $performance_status = case(
$sufficient_for_acos = 0 => "insufficient_data",
target acos <= 0 => "no_target",
$acos_recent > target acos * $acos_problem_threshold => "poor_efficiency",
$acos_recent > target acos * $acos_acceptable_threshold => "acceptable_efficiency",
$acos_recent > target acos => "near_target",
else "good_efficiency"
);
// === Spend Impact Assessment ===
let $spend_impact = case(
$spend_recent >= 50.00 => "high_impact",
$spend_recent >= 20.00 => "medium_impact",
$spend_recent >= 5.00 => "low_impact",
else "minimal_impact"
);
// === Diagnostic Properties ===
let $reason = case(
$sufficient_data = 0 => "Insufficient spend history",
$has_anomaly = 0 => "No significant spend shift detected",
// Severe increases with performance context
$spend_severity = "severe_increase" and $performance_status = "poor_efficiency" and $change_driver = "click_volume" => "Severe spend increase from click volume growth with poor ACOS",
$spend_severity = "severe_increase" and $performance_status = "poor_efficiency" and $change_driver = "cost_per_click" => "Severe spend increase from CPC escalation with poor ACOS",
$spend_severity = "severe_increase" and $performance_status = "poor_efficiency" => "Severe spend increase with poor efficiency",
$spend_severity = "severe_increase" and $change_driver = "click_volume" => "Severe spend increase driven by click volume growth",
$spend_severity = "severe_increase" and $change_driver = "cost_per_click" => "Severe spend increase driven by CPC escalation",
$spend_severity = "severe_increase" and $change_driver = "clicks_and_cpc" => "Severe spend increase from both click volume and CPC rises",
$spend_severity = "severe_increase" => "Severe spend increase detected",
// Moderate increases with performance context
$spend_severity = "moderate_increase" and $performance_status = "poor_efficiency" and $change_driver = "click_volume" => "Moderate spend increase from click volume with poor ACOS",
$spend_severity = "moderate_increase" and $performance_status = "poor_efficiency" and $change_driver = "cost_per_click" => "Moderate spend increase from CPC rise with poor ACOS",
$spend_severity = "moderate_increase" and $performance_status = "poor_efficiency" => "Moderate spend increase with poor efficiency",
$spend_severity = "moderate_increase" and $change_driver = "click_volume" => "Moderate spend increase from click volume growth",
$spend_severity = "moderate_increase" and $change_driver = "cost_per_click" => "Moderate spend increase from CPC rise",
$spend_severity = "moderate_increase" and $change_driver = "clicks_and_cpc" => "Moderate spend increase from click volume and CPC",
$spend_severity = "moderate_increase" => "Moderate spend increase detected",
// Decreases with performance context
$spend_severity = "severe_decrease" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Severe spend drop from lost clicks despite good ACOS",
$spend_severity = "severe_decrease" and $change_driver = "click_volume" => "Severe spend drop due to lost clicks",
$spend_severity = "severe_decrease" and $change_driver = "cost_per_click" => "Severe spend drop due to CPC decrease",
$spend_severity = "severe_decrease" and $change_driver = "clicks_and_cpc" => "Severe spend drop from both click and CPC declines",
$spend_severity = "severe_decrease" => "Severe spend decrease detected",
$spend_severity = "moderate_decrease" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Moderate spend drop from reduced clicks despite good ACOS",
$spend_severity = "moderate_decrease" and $change_driver = "click_volume" => "Moderate spend drop from reduced clicks",
$spend_severity = "moderate_decrease" and $change_driver = "cost_per_click" => "Moderate spend drop from CPC decrease",
$spend_severity = "moderate_decrease" and $change_driver = "clicks_and_cpc" => "Moderate spend drop from click and CPC declines",
$spend_severity = "moderate_decrease" => "Moderate spend decrease detected",
else "No significant spend pattern change"
);
let $result = case(
$sufficient_data = 0 => "insufficient_data",
$has_anomaly = 0 => "insufficient_data",
// Problem increases (high spend + poor efficiency) - sort to top
$spend_severity = "severe_increase" and $performance_status = "poor_efficiency" and $spend_impact = "high_impact" => "Problem: Severe Increase + Poor ACOS [High $]",
$spend_severity = "severe_increase" and $performance_status = "poor_efficiency" => "Problem: Severe Increase + Poor ACOS",
$spend_severity = "moderate_increase" and $performance_status = "poor_efficiency" and $spend_impact = "high_impact" => "Problem: Moderate Increase + Poor ACOS [High $]",
$spend_severity = "moderate_increase" and $performance_status = "poor_efficiency" => "Problem: Moderate Increase + Poor ACOS",
// Neutral/good increases
$spend_severity = "severe_increase" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Scaling: Severe Increase (Clicks) + Good ACOS",
$spend_severity = "severe_increase" and $change_driver = "click_volume" => "Increase: Severe (Click Volume)",
$spend_severity = "severe_increase" and $change_driver = "cost_per_click" => "Increase: Severe (CPC Spike)",
$spend_severity = "severe_increase" and $change_driver = "clicks_and_cpc" => "Increase: Severe (Clicks + CPC)",
$spend_severity = "severe_increase" => "Increase: Severe",
$spend_severity = "moderate_increase" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Scaling: Moderate Increase (Clicks) + Good ACOS",
$spend_severity = "moderate_increase" and $change_driver = "click_volume" => "Increase: Moderate (Click Volume)",
$spend_severity = "moderate_increase" and $change_driver = "cost_per_click" => "Increase: Moderate (CPC)",
$spend_severity = "moderate_increase" and $change_driver = "clicks_and_cpc" => "Increase: Moderate (Clicks + CPC)",
$spend_severity = "moderate_increase" => "Increase: Moderate",
// Opportunity decreases (good performers losing volume)
$spend_severity = "severe_decrease" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Opportunity: Severe Decrease (Clicks) + Good ACOS",
$spend_severity = "moderate_decrease" and $performance_status = "good_efficiency" and $change_driver = "click_volume" => "Opportunity: Moderate Decrease (Clicks) + Good ACOS",
// Normal decreases
$spend_severity = "severe_decrease" and $change_driver = "click_volume" => "Decrease: Severe (Click Loss)",
$spend_severity = "severe_decrease" and $change_driver = "cost_per_click" => "Decrease: Severe (CPC Drop)",
$spend_severity = "severe_decrease" and $change_driver = "clicks_and_cpc" => "Decrease: Severe (Clicks + CPC)",
$spend_severity = "severe_decrease" => "Decrease: Severe",
$spend_severity = "moderate_decrease" and $change_driver = "click_volume" => "Decrease: Moderate (Click Loss)",
$spend_severity = "moderate_decrease" and $change_driver = "cost_per_click" => "Decrease: Moderate (CPC Drop)",
$spend_severity = "moderate_decrease" and $change_driver = "clicks_and_cpc" => "Decrease: Moderate (Clicks + CPC)",
$spend_severity = "moderate_decrease" => "Decrease: Moderate",
// Catch-all for any edge cases
else "insufficient_data"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $sufficient_data = 1
and $has_anomaly = 1
and $result != "insufficient_data"
Adjusts bids based on proven historical CPC from the same seasonal period last year.
✓ Seasonal businesses preparing for upcoming high-demand periods (holidays, back-to-school, summer, etc.)
✓ Accounts with at least one year of advertising history to reference previous seasonal performance
✓ Keywords and targets that performed well last season (within 125% of Target ACOS with conversion history)
✓ Manual seasonal optimization sessions where you want to leverage historical success rather than current performance alone
Manual Execution: Change Bid: Set ($) using $suggested_seasonal_bid
This template sets bids based on historical CPC from the corresponding seasonal period one year ago, but only when that historical period showed acceptable ACOS performance. The core logic: if a keyword performed well at a certain CPC last season, it's likely to perform similarly at that CPC this season.
The historical window looks at a 45-day period starting exactly one year ago. For example, if you run this on January 15th, it examines January 15th through February 28th of last year. This forward-looking window captures not just the exact date match, but the seasonal trend that was building during that period.
Unlike simple year-over-year comparisons that only look at the exact same date, this template captures a 45-day forward window starting from one year ago. This approach recognizes that seasonal patterns build over time rather than appearing on a single date. If preparing for Valentine's Day on January 15th, you see not just January 15th last year, but the entire ramp-up period through late February.
Multiple requirements must be met before a bid adjustment is suggested:
This prevents adjusting bids based on insufficient data or poor historical performance.
Two independent caps protect against extreme changes:
Both caps are applied, with the most restrictive limit winning. This prevents the template from, for example, jumping a $0.50 bid to $3.00 even if that was the historical CPC.
The bid safety factor (default 100%) lets you apply a percentage adjustment to the historical CPC. Set to 95% to bid slightly below historical levels for added safety, or 105% to bid slightly above if you want to be more aggressive than last year.
The default 320d..365d setting (45-day window starting 1 year ago) works for most seasonal patterns. Consider adjusting based on your business:
Shorter windows provide more precise seasonal matching but require concentrated historical activity. Longer windows are more forgiving for keywords with sporadic conversion patterns.
The 125% default means historical ACOS ≤ 1.25 × Target ACOS qualifies:
Lower thresholds are safer but may exclude profitable keywords that ran slightly above target. Higher thresholds include more keywords but increase risk of replicating marginally profitable periods.
Percentage cap ($bid_max_change_pct): 50% default prevents doubling or halving bids in one adjustment. Increase to 75% for more aggressive seasonal adjustments, or decrease to 25-30% for more conservative changes.
Absolute maximum ($bid_absolute_max): $2.00 default should be set based on your business economics. Calculate as: Average Order Value × Target ACOS × Typical Conversion Rate × 2-3. This ensures the absolute cap is grounded in your profitability model rather than an arbitrary number.
Four properties show the historical data used for calculations:
Compare $calculated_bid_value to $suggested_seasonal_bid to see when safety caps activated.
Use these to identify keywords with dramatic suggested changes that may warrant manual review before applying.
When $calculated_bid_value is significantly higher than $suggested_seasonal_bid, the safety caps activated. This often indicates:
Review these manually - you may want to increase caps for specific high-value keywords or maintain current lower bids if current performance is acceptable.
Keywords showing "Insufficient historical orders" despite good historical ACOS are edge cases. They converted during that period but not enough times to be statistically reliable. Consider:
When current bid is $0.25 and suggested is $1.00+, review carefully. This pattern suggests:
Check current year-to-date performance before applying large increases to ensure the keyword is still relevant.
If few or no keywords qualify, common causes:
Adjust thresholds incrementally and review diagnostic properties to understand why keywords are being excluded.
/*
=== Seasonal Bid Tuner ===
Purpose: Set bids to historical CPC from the same seasonal period when ACOS performance was within safe limits.
Dataset: Keywords & Targets
Recommended: Change Bid → Set ($) using $suggested_seasonal_bid | Manual Execution
*/
// === Core Settings ===
let $min_orders = 2; // CORE: Minimum historical orders required for reliable data
let $acos_threshold = 125%; // CORE: Only use historical CPC if ACOS ≤ (Target ACOS × 125%) [e.g., 30% target = 37.5% threshold]
// === Strategy Settings ===
let $historical_period = 320d..365d; // STRATEGY: Historical evaluation period [1 year ago through 320 days ago - captures same season with forward context]
let $bid_safety_factor = 100%; // STRATEGY: Percentage of historical CPC to use [e.g., 95% = bid at 95% of historical CPC for safety margin]
// === Safeguards ===
let $bid_max_change_pct = 50%; // SAFEGUARD: Maximum bid change percentage [e.g., 50% = can increase/decrease by up to 50%]
let $bid_absolute_max = 2.00; // SAFEGUARD: Never set bids above this amount [$2.00 maximum]
let $protected_terms = ["test", "experiment"]; // SAFEGUARD: Never adjust keywords/targets containing these terms
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms
// ============================================================================
// === Segment Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// === Historical Data ===
let $hist_orders = orders($historical_period);
let $hist_acos = acos($historical_period);
let $hist_cpc = cpc($historical_period);
// === Protection Check ===
let $protected_term_check = case(
campaign name contains any $protected_terms => 0,
else 1
);
// === Performance Qualification ===
let $performance_ok = case(
target acos <= 0 => 0, // No target set
$hist_orders < $min_orders => 0, // Insufficient orders
$hist_cpc <= 0 => 0, // No CPC data
$hist_acos <= target acos * $acos_threshold => 1, // Performance acceptable
else 0
);
// === Calculate Bid Change Limits ===
let $max_allowed_bid = bid * (1 + $bid_max_change_pct);
let $min_allowed_bid = bid * (1 - $bid_max_change_pct);
// === Suggested Bid Calculation with Safety Caps ===
let $calculated_seasonal_bid = $hist_cpc * $bid_safety_factor;
let $suggested_seasonal_bid = case(
$performance_ok = 0 => bid, // Keep current if not qualified
// Apply maximum change percentage cap
$calculated_seasonal_bid > $max_allowed_bid => $max_allowed_bid,
$calculated_seasonal_bid < $min_allowed_bid => $min_allowed_bid,
// Apply absolute maximum cap
$calculated_seasonal_bid > $bid_absolute_max => $bid_absolute_max,
// Otherwise use calculated seasonal bid
else $calculated_seasonal_bid
);
// === Diagnostic Properties ===
let $historical_cpc_value = $hist_cpc;
let $historical_acos_value = $hist_acos;
let $historical_orders_count = $hist_orders;
let $calculated_bid_value = $calculated_seasonal_bid;
let $bid_change_amount = $suggested_seasonal_bid - bid;
let $bid_change_percent = case(
bid > 0 => (($suggested_seasonal_bid - bid) / bid) * 100,
else 0
);
let $reason = case(
target acos <= 0 => "No target ACOS set - cannot evaluate performance",
$protected_term_check = 0 => "Protected term - excluded from adjustments",
$hist_orders < $min_orders => "Insufficient historical orders for reliable data",
$hist_cpc <= 0 => "No historical CPC data available",
$hist_acos > target acos * $acos_threshold => "Historical ACOS too high for safe adjustment",
$calculated_seasonal_bid > $bid_absolute_max => "Bid capped at absolute maximum",
$calculated_seasonal_bid > $max_allowed_bid => "Bid capped at maximum change percentage",
$calculated_seasonal_bid < $min_allowed_bid => "Bid capped at minimum change percentage",
$performance_ok = 1 => "Historical performance acceptable - bid set to seasonal CPC",
else "Insufficient data for adjustment"
);
let $result = case(
$protected_term_check = 0 => "No Action - Protected Term",
$performance_ok = 0 => "No Action - Historical Performance Insufficient",
$suggested_seasonal_bid = bid => "No Change - Already at Target",
$calculated_seasonal_bid > $bid_absolute_max => "Bid Set - Absolute Maximum Applied",
$calculated_seasonal_bid > $max_allowed_bid => "Bid Increase - Maximum Change Cap Applied",
$calculated_seasonal_bid < $min_allowed_bid => "Bid Decrease - Minimum Change Cap Applied",
$suggested_seasonal_bid > bid => "Bid Increase - Using Historical CPC",
$suggested_seasonal_bid < bid => "Bid Decrease - Using Historical CPC",
else "No Action"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $protected_term_check = 1
and $performance_ok = 1
and $suggested_seasonal_bid != bid
/*
=== Seasonal Bid Tuner ===
Purpose: Set bids to historical CPC from the same seasonal period when ACOS performance was within safe limits.
Dataset: Keywords & Targets
Recommended: Change Bid → Set ($) using $suggested_seasonal_bid | Manual Execution
*/
// === Core Settings ===
let $min_orders = 2; // CORE: Minimum historical orders required for reliable data
let $acos_threshold = 125%; // CORE: Only use historical CPC if ACOS ≤ (Target ACOS × 125%) [e.g., 30% target = 37.5% threshold]
// === Strategy Settings ===
let $historical_period = 320d..365d; // STRATEGY: Historical evaluation period [1 year ago through 320 days ago - captures same season with forward context]
let $bid_safety_factor = 100%; // STRATEGY: Percentage of historical CPC to use [e.g., 95% = bid at 95% of historical CPC for safety margin]
// === Safeguards ===
let $bid_max_change_pct = 50%; // SAFEGUARD: Maximum bid change percentage [e.g., 50% = can increase/decrease by up to 50%]
let $bid_absolute_max = 2.00; // SAFEGUARD: Never set bids above this amount [$2.00 maximum]
let $protected_terms = ["test", "experiment"]; // SAFEGUARD: Never adjust keywords/targets containing these terms
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms
// ============================================================================
// === Segment Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// === Historical Data ===
let $hist_orders = orders($historical_period);
let $hist_acos = acos($historical_period);
let $hist_cpc = cpc($historical_period);
// === Protection Check ===
let $protected_term_check = case(
campaign name contains any $protected_terms => 0,
else 1
);
// === Performance Qualification ===
let $performance_ok = case(
target acos <= 0 => 0, // No target set
$hist_orders < $min_orders => 0, // Insufficient orders
$hist_cpc <= 0 => 0, // No CPC data
$hist_acos <= target acos * $acos_threshold => 1, // Performance acceptable
else 0
);
// === Calculate Bid Change Limits ===
let $max_allowed_bid = bid * (1 + $bid_max_change_pct);
let $min_allowed_bid = bid * (1 - $bid_max_change_pct);
// === Suggested Bid Calculation with Safety Caps ===
let $calculated_seasonal_bid = $hist_cpc * $bid_safety_factor;
let $suggested_seasonal_bid = case(
$performance_ok = 0 => bid, // Keep current if not qualified
// Apply maximum change percentage cap
$calculated_seasonal_bid > $max_allowed_bid => $max_allowed_bid,
$calculated_seasonal_bid < $min_allowed_bid => $min_allowed_bid,
// Apply absolute maximum cap
$calculated_seasonal_bid > $bid_absolute_max => $bid_absolute_max,
// Otherwise use calculated seasonal bid
else $calculated_seasonal_bid
);
// === Diagnostic Properties ===
let $historical_cpc_value = $hist_cpc;
let $historical_acos_value = $hist_acos;
let $historical_orders_count = $hist_orders;
let $calculated_bid_value = $calculated_seasonal_bid;
let $bid_change_amount = $suggested_seasonal_bid - bid;
let $bid_change_percent = case(
bid > 0 => (($suggested_seasonal_bid - bid) / bid) * 100,
else 0
);
let $reason = case(
target acos <= 0 => "No target ACOS set - cannot evaluate performance",
$protected_term_check = 0 => "Protected term - excluded from adjustments",
$hist_orders < $min_orders => "Insufficient historical orders for reliable data",
$hist_cpc <= 0 => "No historical CPC data available",
$hist_acos > target acos * $acos_threshold => "Historical ACOS too high for safe adjustment",
$calculated_seasonal_bid > $bid_absolute_max => "Bid capped at absolute maximum",
$calculated_seasonal_bid > $max_allowed_bid => "Bid capped at maximum change percentage",
$calculated_seasonal_bid < $min_allowed_bid => "Bid capped at minimum change percentage",
$performance_ok = 1 => "Historical performance acceptable - bid set to seasonal CPC",
else "Insufficient data for adjustment"
);
let $result = case(
$protected_term_check = 0 => "No Action - Protected Term",
$performance_ok = 0 => "No Action - Historical Performance Insufficient",
$suggested_seasonal_bid = bid => "No Change - Already at Target",
$calculated_seasonal_bid > $bid_absolute_max => "Bid Set - Absolute Maximum Applied",
$calculated_seasonal_bid > $max_allowed_bid => "Bid Increase - Maximum Change Cap Applied",
$calculated_seasonal_bid < $min_allowed_bid => "Bid Decrease - Minimum Change Cap Applied",
$suggested_seasonal_bid > bid => "Bid Increase - Using Historical CPC",
$suggested_seasonal_bid < bid => "Bid Decrease - Using Historical CPC",
else "No Action"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $protected_term_check = 1
and $performance_ok = 1
and $suggested_seasonal_bid != bid
Recovers lost impression share for proven high-performers when visibility suddenly drops.
Daily Automation: Change Bid: Set ($) using $target_bid
The blueprint calculates daily impression averages over two time periods (recent 7 days vs. baseline 30 days) and detects percentage drops from baseline. When qualified targets show drops of 40%+ and meet performance criteria (15+ lifetime orders, ACOS within 120% of target, 2+ baseline orders), it applies a 10% bid increase with CPC-based safety limits. A 3-day cooldown prevents over-adjustment while allowing the market to respond to bid changes.
Rather than reacting to single-day impression changes, the algorithm compares daily averages across time periods. Recent period (7 days) captures current state. Baseline period (30 days) represents normal performance. This approach filters out daily noise and identifies sustained traffic loss requiring intervention.
The impression drop ratio is calculated as: (Baseline Daily Avg - Recent Daily Avg) / Baseline Daily Avg. For example, if baseline is 1000 impressions/day and recent is 600/day, the drop ratio is 0.40 (40%). The algorithm only acts when this ratio exceeds your configured threshold, ensuring you're responding to material changes.
Multiple conditions must be met simultaneously: proven performer status (15+ lifetime orders), acceptable baseline performance (ACOS ≤ 120% of target with 2+ orders), sufficient baseline volume (50+ daily impressions), and cooldown clearance (3+ days since last change). This layered approach ensures bid increases only happen for established winners experiencing genuine traffic loss.
The final bid is capped at 2× your 90-day average CPC. If the 10% increase would push your bid above this limit, it gets reduced to the cap. This prevents expensive recovery attempts in markets where competitors have significantly higher bids, protecting you from unprofitable visibility recovery.
The impression drop threshold creates a tradeoff: lower values (25-30%) respond faster to traffic loss but act more frequently, while higher values (50%+) wait for severe drops but act less often. Consider your market dynamics - highly competitive markets benefit from faster response, while stable markets need patience to avoid chasing normal fluctuations.
The 15-order requirement ensures you're only recovering traffic for genuinely proven performers. Lowering this threshold allows faster recovery for newer winners but increases risk of boosting marginally profitable targets. If you lower it below 10 orders, tighten the ACOS threshold (110% vs. 120%) to maintain safety.
The 120% ACOS threshold means a 30% target allows increases up to 36% baseline ACOS. For high-margin products (50%+ profit margins), loosening to 130-140% recovers more volume. For thin-margin products (20-30% profit margins), tighten to 110% to avoid recovering unprofitable traffic. This setting directly impacts which performers qualify for recovery.
The 7-day recent period vs. 30-day baseline balance responsiveness with stability. Shortening recent to 3-5 days responds faster but risks reacting to weekend/weekday patterns. Extending baseline to 60 days smooths seasonal fluctuations but may miss market shifts. Maintain at least a 3:1 ratio (baseline 3× longer than recent) for reliable comparisons.
Bid Increase: Major Drop (75%+) - Severe traffic loss requiring immediate attention. Verify if this is due to competitors, budget constraints in parent campaigns, or Amazon algorithm changes.
Bid Increase: Significant Drop (50-75%) - Substantial traffic loss indicating market shift. Most common scenario for competitive keywords where recovery is warranted.
Bid Increase: Moderate Drop (25-50%) - Meaningful but not extreme. Typical when new competitors enter the auction or your Quality Score decreases slightly.
Bid Increase: CPC Limited - Attempted recovery but capped by 2× CPC limit. Indicates highly competitive auction where full recovery may be unprofitable. Consider whether this target is still worth pursuing.
Major/Significant/Moderate Drop - No Action - Traffic dropped but didn't meet qualification criteria (lifetime orders, ACOS performance, or cooldown). Review $reason to understand blocking factor.
"Insufficient lifetime orders" - Target hasn't proven itself yet. Let it accumulate more conversion history before recovery attempts.
"ACOS too high for increase" - Baseline ACOS exceeds 120% of target. This target may be declining in profitability - consider whether it's worth recovering or should be allowed to phase out naturally.
"Low baseline impression volume" - Less than 50 daily impressions in baseline period. Traffic is too low for reliable drop detection. May indicate dying keyword or very niche target.
"Cooldown active" - Changed within last 3 days. Be patient - Amazon needs time to adjust ad positioning after bid changes.
Best results occur with established winners (20-30+ lifetime orders) showing 50-75% impression drops while maintaining strong ACOS (90-110% of target). These typically indicate competitor bid increases or temporary Quality Score dips where recovery is highly effective.
Targets with 15-20 lifetime orders showing 40-50% drops and 110-120% baseline ACOS. Recovery often works but requires monitoring - if ACOS deteriorates further after increase, the market dynamics may have permanently shifted against this target.
The blueprint intentionally won't act on: targets with inconsistent baseline performance (fewer than 2 orders in 30 days), targets recently adjusted (within 3 days), or targets where the calculated increase would exceed 2× average CPC. These protective measures prevent wasteful spending on declining performers or markets where you can't compete profitably.
With default settings, expect 5-15% of your proven performers to qualify for increases on any given day. If you're seeing higher rates (25%+), your impression drop threshold may be too sensitive. If you're seeing lower rates (<5%), either your proven performers are maintaining visibility well, or your thresholds are too conservative for your competitive market.
/*
=== Core: Impression Recovery Boost ===
Purpose: Increases bids for proven performers when impression volume drops significantly.
Recommended: Change Bid: Set ($) using $target_bid | Daily
*/
// === Core Settings ===
let $orders_min_lifetime = 10; // CORE: Minimum lifetime orders to qualify as proven performer [e.g., 15+ orders = established winner]
let $orders_min_baseline = 0; // CORE: Minimum orders in baseline period for reliable ACOS evaluation [e.g., 2+ orders in 30 days]
let $impression_drop_threshold = 40%; // CORE: Act when impressions drop at least 40% from baseline [e.g., 40% = from 1000 to 600 daily impressions]
let $bid_change_increase = 10%; // CORE: Bid increase amount when conditions are met [e.g., 10% = $1.00 bid increases to $1.10]
// === Strategy Settings ===
let $t_acos_threshold_increase = 120%; // STRATEGY: Only increase if ACOS ≤ (Target ACOS × 120%) [e.g., 30% target = 36% threshold]
let $impressions_min_daily = 50; // STRATEGY: Minimum daily impressions for reliable baseline [e.g., 50+ impressions/day = meaningful traffic]
let $cooldown_period = 3d; // TIME: Wait 3 days after bid change before adjusting again
// === Time Periods ===
let $period_recent = 7d; // TIME: Recent period for drop detection (7 days including today)
let $period_baseline = 90d; // TIME: Baseline comparison period (30 days including today)
// === Advanced Settings ===
let $bid_limit_cpc_multiplier = 2.0; // SAFEGUARD: Max bid = Avg CPC × 2.0 [e.g., $0.50 CPC = $1.00 max]
let $bid_limit_cpc_period = 90d; // SAFEGUARD: Period for calculating CPC-based bid limits (90 days)
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Segment Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// === Impression Analysis ===
let $recent_impressions = impressions($period_recent);
let $baseline_impressions = impressions($period_baseline);
let $recent_days = interval($period_recent) / 86400;
let $baseline_days = interval($period_baseline) / 86400;
let $recent_daily_avg = $recent_impressions / $recent_days;
let $baseline_daily_avg = $baseline_impressions / $baseline_days;
let $impression_drop_ratio = case(
$baseline_daily_avg > 0 => ($baseline_daily_avg - $recent_daily_avg) / $baseline_daily_avg,
else 0 // No baseline data = no drop detected
);
// === Performance Protection ===
let $baseline_orders = orders($period_baseline);
let $baseline_acos = acos($period_baseline);
let $acos_acceptable = case(
target acos > 0 and $baseline_orders >= $orders_min_baseline and $baseline_acos <= (target acos * $t_acos_threshold_increase) => 1,
else 0
);
// === Bid Calculation ===
let $calculated_target_bid = bid * (1 + $bid_change_increase);
// === Dynamic Bid Cap ===
let $avg_cpc = cpc($bid_limit_cpc_period);
let $dynamic_cap = case(
$avg_cpc > 0 => $avg_cpc * $bid_limit_cpc_multiplier,
else 999 // No cap if no CPC history
);
let $target_bid = case(
$calculated_target_bid > $dynamic_cap => $dynamic_cap,
$calculated_target_bid < 0.02 => 0.02,
else $calculated_target_bid
);
// === Cooldown Check ===
let $cooldown_cutoff = now() - interval($cooldown_period);
let $timing_ready = case(
is_null(last bid change) => 1,
last bid change < $cooldown_cutoff => 1,
else 0
);
// === Qualification Logic ===
let $impression_drop_detected = case(
$impression_drop_ratio >= $impression_drop_threshold => 1,
else 0
);
let $action_needed = case(
target acos <= 0 => 0, // Invalid target
orders(lifetime) < $orders_min_lifetime => 0, // Not proven performer
$baseline_daily_avg < $impressions_min_daily => 0, // Insufficient baseline data
$impression_drop_detected = 0 => 0, // No drop detected
$acos_acceptable = 0 => 0, // Poor baseline performance
$timing_ready = 0 => 0, // Cooldown active
$target_bid <= bid => 0, // No increase calculated
else 1
);
// === Diagnostic Properties ===
let $reason = case(
target acos <= 0 => "No target ACOS set",
orders(lifetime) < $orders_min_lifetime => "Insufficient lifetime orders",
$baseline_daily_avg < $impressions_min_daily => "Low baseline impression volume",
$impression_drop_detected = 0 => "No qualifying drop detected",
$acos_acceptable = 0 => "ACOS too high for increase",
$timing_ready = 0 => "Cooldown active",
$target_bid <= bid => "No bid increase calculated",
$action_needed = 1 => "Drop detected - increasing bid",
else "Stable impression volume"
);
let $result = case(
$action_needed = 1 => case(
$impression_drop_ratio >= 0.75 => "Bid Increase: Major Drop (75%+)",
$impression_drop_ratio >= 0.50 => "Bid Increase: Significant Drop (50-75%)",
$impression_drop_ratio >= 0.25 => "Bid Increase: Moderate Drop (25-50%)",
$calculated_target_bid > $dynamic_cap => "Bid Increase: CPC Limited",
else "Bid Increase: Minor Drop (<25%)"
),
$impression_drop_ratio >= 0.75 => "Major Drop (75%+) - No Action",
$impression_drop_ratio >= 0.50 => "Significant Drop (50-75%) - No Action",
$impression_drop_ratio >= 0.25 => "Moderate Drop (25-50%) - No Action",
$impression_drop_ratio > 0 => "Minor Drop (<25%) - No Action",
$impression_drop_ratio < 0 => "Impressions Increased",
else "No Change Detected"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $action_needed = 1
/*
=== Core: Impression Recovery Boost ===
Purpose: Increases bids for proven performers when impression volume drops significantly.
Recommended: Change Bid: Set ($) using $target_bid | Daily
*/
// === Core Settings ===
let $orders_min_lifetime = 10; // CORE: Minimum lifetime orders to qualify as proven performer [e.g., 15+ orders = established winner]
let $orders_min_baseline = 0; // CORE: Minimum orders in baseline period for reliable ACOS evaluation [e.g., 2+ orders in 30 days]
let $impression_drop_threshold = 40%; // CORE: Act when impressions drop at least 40% from baseline [e.g., 40% = from 1000 to 600 daily impressions]
let $bid_change_increase = 10%; // CORE: Bid increase amount when conditions are met [e.g., 10% = $1.00 bid increases to $1.10]
// === Strategy Settings ===
let $t_acos_threshold_increase = 120%; // STRATEGY: Only increase if ACOS ≤ (Target ACOS × 120%) [e.g., 30% target = 36% threshold]
let $impressions_min_daily = 50; // STRATEGY: Minimum daily impressions for reliable baseline [e.g., 50+ impressions/day = meaningful traffic]
let $cooldown_period = 3d; // TIME: Wait 3 days after bid change before adjusting again
// === Time Periods ===
let $period_recent = 7d; // TIME: Recent period for drop detection (7 days including today)
let $period_baseline = 90d; // TIME: Baseline comparison period (30 days including today)
// === Advanced Settings ===
let $bid_limit_cpc_multiplier = 2.0; // SAFEGUARD: Max bid = Avg CPC × 2.0 [e.g., $0.50 CPC = $1.00 max]
let $bid_limit_cpc_period = 90d; // SAFEGUARD: Period for calculating CPC-based bid limits (90 days)
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Segment Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// === Impression Analysis ===
let $recent_impressions = impressions($period_recent);
let $baseline_impressions = impressions($period_baseline);
let $recent_days = interval($period_recent) / 86400;
let $baseline_days = interval($period_baseline) / 86400;
let $recent_daily_avg = $recent_impressions / $recent_days;
let $baseline_daily_avg = $baseline_impressions / $baseline_days;
let $impression_drop_ratio = case(
$baseline_daily_avg > 0 => ($baseline_daily_avg - $recent_daily_avg) / $baseline_daily_avg,
else 0 // No baseline data = no drop detected
);
// === Performance Protection ===
let $baseline_orders = orders($period_baseline);
let $baseline_acos = acos($period_baseline);
let $acos_acceptable = case(
target acos > 0 and $baseline_orders >= $orders_min_baseline and $baseline_acos <= (target acos * $t_acos_threshold_increase) => 1,
else 0
);
// === Bid Calculation ===
let $calculated_target_bid = bid * (1 + $bid_change_increase);
// === Dynamic Bid Cap ===
let $avg_cpc = cpc($bid_limit_cpc_period);
let $dynamic_cap = case(
$avg_cpc > 0 => $avg_cpc * $bid_limit_cpc_multiplier,
else 999 // No cap if no CPC history
);
let $target_bid = case(
$calculated_target_bid > $dynamic_cap => $dynamic_cap,
$calculated_target_bid < 0.02 => 0.02,
else $calculated_target_bid
);
// === Cooldown Check ===
let $cooldown_cutoff = now() - interval($cooldown_period);
let $timing_ready = case(
is_null(last bid change) => 1,
last bid change < $cooldown_cutoff => 1,
else 0
);
// === Qualification Logic ===
let $impression_drop_detected = case(
$impression_drop_ratio >= $impression_drop_threshold => 1,
else 0
);
let $action_needed = case(
target acos <= 0 => 0, // Invalid target
orders(lifetime) < $orders_min_lifetime => 0, // Not proven performer
$baseline_daily_avg < $impressions_min_daily => 0, // Insufficient baseline data
$impression_drop_detected = 0 => 0, // No drop detected
$acos_acceptable = 0 => 0, // Poor baseline performance
$timing_ready = 0 => 0, // Cooldown active
$target_bid <= bid => 0, // No increase calculated
else 1
);
// === Diagnostic Properties ===
let $reason = case(
target acos <= 0 => "No target ACOS set",
orders(lifetime) < $orders_min_lifetime => "Insufficient lifetime orders",
$baseline_daily_avg < $impressions_min_daily => "Low baseline impression volume",
$impression_drop_detected = 0 => "No qualifying drop detected",
$acos_acceptable = 0 => "ACOS too high for increase",
$timing_ready = 0 => "Cooldown active",
$target_bid <= bid => "No bid increase calculated",
$action_needed = 1 => "Drop detected - increasing bid",
else "Stable impression volume"
);
let $result = case(
$action_needed = 1 => case(
$impression_drop_ratio >= 0.75 => "Bid Increase: Major Drop (75%+)",
$impression_drop_ratio >= 0.50 => "Bid Increase: Significant Drop (50-75%)",
$impression_drop_ratio >= 0.25 => "Bid Increase: Moderate Drop (25-50%)",
$calculated_target_bid > $dynamic_cap => "Bid Increase: CPC Limited",
else "Bid Increase: Minor Drop (<25%)"
),
$impression_drop_ratio >= 0.75 => "Major Drop (75%+) - No Action",
$impression_drop_ratio >= 0.50 => "Significant Drop (50-75%) - No Action",
$impression_drop_ratio >= 0.25 => "Moderate Drop (25-50%) - No Action",
$impression_drop_ratio > 0 => "Minor Drop (<25%) - No Action",
$impression_drop_ratio < 0 => "Impressions Increased",
else "No Change Detected"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $action_needed = 1
Calculates optimal bids from actual conversion performance to hit Target ACOS goals.
✓ Manual bid optimization sessions where you want data-driven bid recommendations
✓ Accounts with Target ACOS configured at account, campaign, ad group, or keyword level
✓ Keywords and targets with conversion history (minimum 2 orders and 20 clicks in evaluation period)
✓ Sellers who want to understand the math behind bid-to-performance relationships
Manual Execution: Change Bid: Set ($) using $target_bid
/*
=== Utility: Target CPC Calculator ===
Purpose: Calculate target bids from performance efficiency metrics (ACOS, AOV, CVR) for manual bid optimization.
Dataset: Keywords & Targets
Recommended: Change Bid → Set ($) using $target_bid | Manual Execution
Note: Run on-demand after reviewing performance - not intended for automated daily execution
*/
// === Core Settings ===
let $orders_min = 2; // CORE: Minimum orders required for reliable calculation
let $clicks_min = 20; // CORE: Minimum clicks required for reliable calculation
let $period_eval = 30d; // CORE: Performance evaluation period [30 days including today]
// === Safeguards ===
let $bid_limit_cpc_multiplier = 2.0; // SAFEGUARD: Max bid = Avg CPC × 2.0 [e.g., $0.50 CPC = $1.00 max]
let $bid_limit_cpc_period = 90d; // SAFEGUARD: Period for calculating CPC-based limits
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms
// ============================================================================
// === Segment Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// === Target CPC Calculation Method ===
// Formula: Target CPC = Target ACOS × Average Order Value × Conversion Rate
//
// Example: If targeting 30% ACOS with $50 AOV and 5% CVR:
// Target CPC = 0.30 × $50 × 0.05 = $0.75
//
// This ensures each click costs the right amount to hit your profit target
// given your actual conversion performance and order values.
// === Performance Metrics ===
let $recent_cpc = cpc($period_eval);
let $recent_acos = acos($period_eval);
let $recent_aov = aov($period_eval);
let $recent_orders = orders($period_eval);
let $recent_clicks = clicks($period_eval);
// Calculate conversion rate
let $recent_cvr = case(
$recent_clicks > 0 => $recent_orders / $recent_clicks,
else 0
);
// === Calculate Target CPC ===
let $calculated_target_cpc = case(
target acos <= 0 => $recent_cpc, // No target set - keep current bid
$recent_cvr > 0 and $recent_aov > 0 => target acos * $recent_aov * $recent_cvr,
else $recent_cpc // Insufficient data - keep current bid
);
// === Apply Dynamic Bid Cap ===
let $avg_cpc_for_cap = cpc($bid_limit_cpc_period);
let $dynamic_max_bid = case(
$avg_cpc_for_cap > 0 => $avg_cpc_for_cap * $bid_limit_cpc_multiplier,
else 999 // No cap if no CPC data
);
let $target_bid = case(
$calculated_target_cpc > $dynamic_max_bid => $dynamic_max_bid,
else $calculated_target_cpc
);
// === Data Sufficiency Check ===
let $sufficient_data = case(
$recent_orders >= $orders_min and $recent_clicks >= $clicks_min => 1,
else 0
);
// === Diagnostic Properties ===
// Show calculation inputs for transparency
let $aov_used = $recent_aov;
let $cvr_used = $recent_cvr;
let $target_acos_used = target acos;
let $uncapped_target_cpc = $calculated_target_cpc;
let $reason = case(
target acos <= 0 => "No target ACOS set - cannot calculate",
$recent_orders < $orders_min => "Insufficient orders for reliable calculation",
$recent_clicks < $clicks_min => "Insufficient clicks for reliable calculation",
$calculated_target_cpc > $dynamic_max_bid => "Target CPC exceeds dynamic cap",
$recent_cvr <= 0 or $recent_aov <= 0 => "Missing conversion or AOV data",
else "Target CPC calculated from performance metrics"
);
let $result = case(
target acos <= 0 => "No Target ACOS - Cannot Calculate",
$sufficient_data = 0 => "Insufficient Data - Review Manually",
$target_bid = bid => "No Change - Already at Target CPC",
$calculated_target_cpc > $dynamic_max_bid => "Bid Set - Capped at Dynamic Maximum",
$recent_cvr <= 0 or $recent_aov <= 0 => "Cannot Calculate - Missing Data",
else "Target CPC Calculated Successfully"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and target acos > 0
and $target_bid != bid
and $sufficient_data = 1
/*
=== Utility: Target CPC Calculator ===
Purpose: Calculate target bids from performance efficiency metrics (ACOS, AOV, CVR) for manual bid optimization.
Dataset: Keywords & Targets
Recommended: Change Bid → Set ($) using $target_bid | Manual Execution
Note: Run on-demand after reviewing performance - not intended for automated daily execution
*/
// === Core Settings ===
let $orders_min = 2; // CORE: Minimum orders required for reliable calculation
let $clicks_min = 20; // CORE: Minimum clicks required for reliable calculation
let $period_eval = 30d; // CORE: Performance evaluation period [30 days including today]
// === Safeguards ===
let $bid_limit_cpc_multiplier = 2.0; // SAFEGUARD: Max bid = Avg CPC × 2.0 [e.g., $0.50 CPC = $1.00 max]
let $bid_limit_cpc_period = 90d; // SAFEGUARD: Period for calculating CPC-based limits
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms
// ============================================================================
// === Segment Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// === Target CPC Calculation Method ===
// Formula: Target CPC = Target ACOS × Average Order Value × Conversion Rate
//
// Example: If targeting 30% ACOS with $50 AOV and 5% CVR:
// Target CPC = 0.30 × $50 × 0.05 = $0.75
//
// This ensures each click costs the right amount to hit your profit target
// given your actual conversion performance and order values.
// === Performance Metrics ===
let $recent_cpc = cpc($period_eval);
let $recent_acos = acos($period_eval);
let $recent_aov = aov($period_eval);
let $recent_orders = orders($period_eval);
let $recent_clicks = clicks($period_eval);
// Calculate conversion rate
let $recent_cvr = case(
$recent_clicks > 0 => $recent_orders / $recent_clicks,
else 0
);
// === Calculate Target CPC ===
let $calculated_target_cpc = case(
target acos <= 0 => $recent_cpc, // No target set - keep current bid
$recent_cvr > 0 and $recent_aov > 0 => target acos * $recent_aov * $recent_cvr,
else $recent_cpc // Insufficient data - keep current bid
);
// === Apply Dynamic Bid Cap ===
let $avg_cpc_for_cap = cpc($bid_limit_cpc_period);
let $dynamic_max_bid = case(
$avg_cpc_for_cap > 0 => $avg_cpc_for_cap * $bid_limit_cpc_multiplier,
else 999 // No cap if no CPC data
);
let $target_bid = case(
$calculated_target_cpc > $dynamic_max_bid => $dynamic_max_bid,
else $calculated_target_cpc
);
// === Data Sufficiency Check ===
let $sufficient_data = case(
$recent_orders >= $orders_min and $recent_clicks >= $clicks_min => 1,
else 0
);
// === Diagnostic Properties ===
// Show calculation inputs for transparency
let $aov_used = $recent_aov;
let $cvr_used = $recent_cvr;
let $target_acos_used = target acos;
let $uncapped_target_cpc = $calculated_target_cpc;
let $reason = case(
target acos <= 0 => "No target ACOS set - cannot calculate",
$recent_orders < $orders_min => "Insufficient orders for reliable calculation",
$recent_clicks < $clicks_min => "Insufficient clicks for reliable calculation",
$calculated_target_cpc > $dynamic_max_bid => "Target CPC exceeds dynamic cap",
$recent_cvr <= 0 or $recent_aov <= 0 => "Missing conversion or AOV data",
else "Target CPC calculated from performance metrics"
);
let $result = case(
target acos <= 0 => "No Target ACOS - Cannot Calculate",
$sufficient_data = 0 => "Insufficient Data - Review Manually",
$target_bid = bid => "No Change - Already at Target CPC",
$calculated_target_cpc > $dynamic_max_bid => "Bid Set - Capped at Dynamic Maximum",
$recent_cvr <= 0 or $recent_aov <= 0 => "Cannot Calculate - Missing Data",
else "Target CPC Calculated Successfully"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and target acos > 0
and $target_bid != bid
and $sufficient_data = 1
Prevents budget waste on underutilized campaigns while scaling spend for constrained high-performers.
✓ Campaigns hitting daily budget caps that need automated scaling when performance justifies increased spend
✓ Overbudgeted campaigns wasting potential by having daily budgets far above actual spend patterns
✓ Data-starved campaigns with budgets too low to generate the minimum clicks needed for optimization decisions
✓ Accounts wanting hands-off budget management that adapts to both growth opportunities and efficiency improvements
Daily or Multiple Times Daily | Automation: Change Daily Budget: Set ($) using $new_budget
Run multiple times daily during high-traffic periods to catch budget constraints quickly, or daily for standard monitoring.
The blueprint operates two independent decision paths that never conflict. The increase path examines the last four individual days to detect budget-capping behavior, then verifies performance is acceptable before scaling up by a fixed percentage. The rightsizing path analyzes sustained 14-day average utilization to identify campaigns consistently spending well below budget, then calculates a new budget based on actual usage patterns plus a buffer. A third "data starvation" path increases budgets that fall below CPC-based minimums regardless of utilization, ensuring all campaigns can generate enough clicks for reliable optimization.
Individual Daily Budget Cap Detection
Most budget management tools look at average utilization, which can hide intermittent constraints. This blueprint checks each of the last four days individually - if ANY single day hit 90%+ utilization and ACOS is acceptable, it triggers an increase. This catches scenarios like weekend budget caps that disappear into weekday averages, or campaigns that only hit caps on high-traffic days. One capped day in the last four is treated as evidence of constraint.
CPC-Based Data Minimum System
The blueprint calculates a dynamic minimum budget using your average CPC × minimum daily clicks (default 5). A campaign averaging $0.50 CPC needs at least $2.50 daily budget to support data collection. This minimum applies to both rightsizing decreases and data-starvation increases, creating a floor that ensures campaigns remain optimizable. Campaigns below this floor trigger immediate increases regardless of utilization or performance.
Sustained Utilization for Rightsizing
Unlike the increase path which reacts to single-day caps, rightsizing requires sustained 14-day average utilization below 50%. This asymmetry is intentional - increases should be reactive (quick response to constraints) while decreases should be conservative (only act on persistent underutilization). A campaign spending $8/day against a $20 budget for two full weeks triggers rightsizing, but two low-spend days mixed with normal days won't.
Performance-Gated Increases with Data Tolerance
Budget increases require ACOS ≤ 130% of target across three cascading periods (7d → 14d → 30d). However, if no period has sufficient orders for reliable ACOS ($orders_min = 4), the blueprint allows the increase anyway. This "innocent until proven guilty" approach recognizes that budget constraints themselves may be preventing the order volume needed for ACOS evaluation. If you're capped and can't evaluate performance, the blueprint gives you room to generate data.
Dual Minimum Logic
The blueprint uses different minimum floors for increases vs decreases:
This ensures rightsizing never creates data starvation, while still allowing performance-based increases to start from the platform floor.
Utilization Threshold Interaction
The 90% high and 50% low thresholds create three zones:
Narrowing this acceptable range (e.g., 70-85%) increases budget turnover - more frequent increases and decreases as campaigns move in/out of the target zone. Widening it (e.g., 40-95%) creates more stability but may leave efficiency on the table. Consider your management bandwidth and campaign predictability when tuning.
Orders Minimum for ACOS Evaluation
The $orders_min = 4 setting determines when ACOS is considered reliable for gating increases. This is intentionally higher than typical ACOS evaluation minimums (usually 2) because you're making spending decisions, not just bid adjustments. Lower values (2-3) make the ACOS gate easier to pass, enabling more budget increases. Higher values (5-6) require more proof of efficiency before scaling spend. If you're seeing too many increases on questionable performers, increase this threshold.
Spend Buffer for Rightsizing
When rightsizing, the new budget is set to average daily spend × $spend_buffer (default 130%). This 30% cushion prevents setting budgets so tight that campaigns immediately hit caps again due to natural daily variance. Reducing to 110-120% creates tighter budgets that maximize efficiency but risk constraint on above-average days. Increasing to 150%+ provides more breathing room but may leave excess budget unused. The 130% default is designed for typical daily spend variance of ±20%.
Budget Increase Percentage Scaling
The fixed 20% increase ($budget_increase_pct) is conservative by design - it takes 4-5 iterations to double a budget. Increase to 30-50% if you want faster scaling on proven performers (useful during launch periods or seasonal ramps). Decrease to 10-15% if you want more gradual, cautious scaling. Avoid increases above 50% as this can create budget shock if ACOS subsequently degrades.
Cooldown Period Strategy
The 14-day cooldown between rightsizing actions prevents thrashing on campaigns with variable spend. Campaigns that occasionally spike above the low utilization threshold won't immediately trigger re-increases after being rightsized. If your campaigns have predictable, stable spend patterns, you can safely shorten to 7 days. If you see rightsizing → increase → rightsizing cycles, extend to 21-30 days or raise the low utilization threshold.
$reason Utilization Ranges:
The diagnostic includes actual average utilization ranges in brackets:
These ranges help you understand not just that action is/isn't being taken, but how far from thresholds each campaign sits.
Reason Categories:
$result Action Types:
Rapid Budget-Capping Increases
Campaigns consistently showing "Budget Increase: High Utilization" across consecutive days are successfully scaling but may be hitting caps again immediately after each increase. This is normal during high-performance periods - the 20% increases are intentionally conservative. If you want faster scaling on these proven winners, increase $budget_increase_pct to 30-40%. Alternatively, manually set budgets higher on your top performers and let automation manage the rest.
Data-Starved Campaign Recovery
Campaigns showing "Budget Increase: CPC Minimum" had budgets below what's needed for basic data collection. After increase, watch for them to transition to utilization-based decisions within 1-2 weeks. If campaigns remain stuck on CPC minimums long-term (still showing 0-10% utilization after increases), they may have fundamental performance issues preventing any meaningful spend. Consider pausing these rather than continuing to maintain minimum budgets.
Rightsizing Followed by Stability
Campaigns showing "Budget Decrease: Rightsizing" should then show "Within acceptable utilization" after the decrease. If you see a campaign rightsize, then immediately trigger "Budget Increase: High Utilization" within a few days, your thresholds are too close together (50% low and 90% high might be creating boundary cases). Either raise the low threshold to 60% or lower the high threshold to 85% to create more separation.
Cooldown Blocking Obvious Rightsizing
Campaigns showing "[0-30%] Below low utilization threshold, cooldown active" for extended periods suggest the 14-day cooldown is too long for your account's spend patterns. These campaigns are clearly underutilizing budget but waiting on cooldown. If this is common, reduce $cooldown_period to 7 days, or if you're confident in the stability of these campaigns, manually reduce their budgets and let automation take over after cooldown.
ACOS Blocking Scale Opportunities
Campaigns showing "[90%+] Above high utilization threshold, ACOS too high" are budget-capped but performing poorly. This is the blueprint correctly preventing bad spend scaling. However, if you see this frequently and believe the campaigns deserve scale opportunities, either: (1) loosen $t_acos_threshold_increase to 150-200% to allow scaling on less efficient campaigns, or (2) use bid management automation to improve ACOS first, then let budget scaling follow.
Minimum Floor Preventing Rightsizing
Campaigns showing "Budget below rightsizing minimum" at 0-30% utilization are already at the calculated minimum (either $budget_min = $5.00 or CPC-based minimum). If you have many campaigns stuck here, consider whether you actually need them active. Campaigns that can't productively spend even $5/day may be better candidates for pausing rather than maintaining minimum budgets indefinitely. Alternatively, if you want more aggressive rightsizing, lower $budget_min to $3.00 or disable CPC minimums (though this risks data starvation).
/*
=== Core: Adaptive Budget Management ===
Purpose: Prevents budget waste while ensuring adequate spend for data collection and performance scaling.
Recommended: Change Daily Budget | Set ($) using $new_budget | Daily or Multiple Times Daily
*/
// === Core Settings ===
let $high_utilization = 90%; // CORE: Daily spend % that indicates budget constraint
let $low_utilization = 50%; // CORE: Daily budget utilization % that triggers rightsizing
let $enable_cpc_minimums = 1; // ADVANCED: Enable CPC-based budget minimums (1=yes, 0=no)
// === Budget Increases (High Utilization) ===
let $t_acos_threshold_increase = 130%; // STRATEGY: Increase budget when ACOS ≤ (Target ACOS × 130%) [e.g., 30% target = 39% threshold]
let $budget_increase_pct = 20%; // STRATEGY: Percentage increase when scaling up
let $orders_min = 4; // STRATEGY: Minimum orders needed for reliable ACOS evaluation
let $acos_eval_short = 7d; // TIME: Recent performance period
let $acos_eval_medium = 14d; // TIME: Medium-term performance period
let $acos_eval_long = 30d; // TIME: Long-term performance period
// === Budget Rightsizing (Low Utilization) ===
let $spend_buffer = 130%; // STRATEGY: Buffer above avg daily spend when rightsizing (budget set to 130% avg daily spend)
let $budget_min = 5.00; // STRATEGY: Absolute minimum budget floor for rightsizing
let $cooldown_eval_period = 14d; // TIME: Period for sustained utilization evaluation
let $cooldown_period = 14d; // TIME: Wait period between rightsizing actions
// === CPC-Based Budget Minimums ===
let $min_daily_clicks = 5; // ADVANCED: Minimum clicks per day budget should support
let $cpc_eval_period = 60d; // ADVANCED: Period for calculating average CPC for minimum budget
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Increase Path: Individual daily budget cap analysis
let $today_spend = spend(0d..0d);
let $yesterday_spend = spend(1d..1d);
let $day2_spend = spend(2d..2d);
let $day3_spend = spend(3d..3d);
let $today_capped = case($today_spend >= budget * $high_utilization => 1, else 0);
let $yesterday_capped = case($yesterday_spend >= budget * $high_utilization => 1, else 0);
let $day2_capped = case($day2_spend >= budget * $high_utilization => 1, else 0);
let $day3_capped = case($day3_spend >= budget * $high_utilization => 1, else 0);
let $any_day_budget_capped = case(
$today_capped = 1 or $yesterday_capped = 1 or $day2_capped = 1 or $day3_capped = 1 => 1,
else 0
);
// Increase Path: CPC-based data sufficiency check
let $avg_cpc = cpc($cpc_eval_period);
let $min_budget_for_data = case(
$enable_cpc_minimums = 1 and $avg_cpc > 0 => $avg_cpc * $min_daily_clicks,
else 0 // Data minimums disabled or no CPC data
);
let $budget_too_small = case(
$enable_cpc_minimums = 1 and $avg_cpc > 0 and budget < $min_budget_for_data => 1,
else 0
);
// Increase Path: Performance evaluation for increases (prioritize recent data)
let $orders_short = orders($acos_eval_short);
let $orders_medium = orders($acos_eval_medium);
let $orders_long = orders($acos_eval_long);
let $performance_acos = case(
$orders_short >= $orders_min => acos($acos_eval_short),
$orders_medium >= $orders_min => acos($acos_eval_medium),
$orders_long >= $orders_min => acos($acos_eval_long),
else 99999 // No reliable ACOS data
);
let $acos_good_for_increase = case(
$performance_acos = 99999 => 1, // No ACOS data = allow increase
target acos <= 0 => 0, // Invalid target
$performance_acos <= (target acos * $t_acos_threshold_increase) => 1,
else 0
);
// Rightsizing Path: Sustained utilization analysis
let $total_spend = spend($cooldown_eval_period);
let $days_in_eval = 14; // Days in 14d period
let $avg_daily_spend = $total_spend / $days_in_eval;
let $avg_utilization_rate = case(
budget > 0 => $avg_daily_spend / budget,
else 0
);
// Calculate effective minimum for decreases early
let $effective_min_for_decreases = case(
$min_budget_for_data > $budget_min => $min_budget_for_data, // Use CPC minimum if higher
else $budget_min // Otherwise use absolute minimum
);
let $rightsizing_cooldown_passed = case(
is_null(last budget change) => 1,
last budget change < now() - interval($cooldown_period) => 1,
else 0
);
// Decision logic by path
let $should_increase = case(
$budget_too_small = 1 => 1, // Data-starved campaign
$any_day_budget_capped = 1 and $acos_good_for_increase = 1 => 1, // Budget-capped + good performance
else 0
);
let $should_rightsize = case(
$rightsizing_cooldown_passed = 0 => 0, // Cooldown period active
budget <= $effective_min_for_decreases => 0, // Already at or below minimum - don't rightsize
$avg_utilization_rate < $low_utilization => 1, // Sustained low utilization (including 0% from no spend)
else 0
);
// Calculate new budget
let $increase_budget = budget * (1 + $budget_increase_pct);
// For rightsizing, calculate based on actual usage plus buffer
let $rightsized_budget = case(
$avg_daily_spend > 0 => $avg_daily_spend * $spend_buffer,
else $budget_min // No spend = use minimum budget
);
let $calculated_budget = case(
$should_increase = 1 => $increase_budget,
$should_rightsize = 1 => $rightsized_budget,
else budget
);
// Apply minimums - different rules for increases vs decreases
let $final_minimum = case(
$should_rightsize = 1 => case(
$effective_min_for_decreases > 1.00 => $effective_min_for_decreases, // Use effective minimum if higher than platform
else 1.00 // Otherwise platform minimum
),
$should_increase = 1 and $budget_too_small = 1 => case(
$min_budget_for_data > 1.00 => $min_budget_for_data, // Use CPC minimum for data generation increases
else 1.00 // Platform minimum
),
else 1.00 // Platform minimum for budget-capping increases
);
let $new_budget = case(
$calculated_budget < $final_minimum => $final_minimum,
else $calculated_budget
);
// Diagnostic properties
let $reason = case(
target acos <= 0 => "No target ACOS set",
$should_increase = 1 and $budget_too_small = 1 => case(
$avg_utilization_rate <= 0.10 => "[0-10%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.30 => "[10-30%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.50 => "[30-50%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.70 => "[50-70%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.90 => "[70-90%] Below CPC minimum threshold",
else "[90%+] Below CPC minimum threshold"
),
$should_increase = 1 => case(
$avg_utilization_rate <= 0.70 => "[50-70%] Above high utilization threshold, ACOS acceptable",
$avg_utilization_rate <= 0.90 => "[70-90%] Above high utilization threshold, ACOS acceptable",
else "[90%+] Above high utilization threshold, ACOS acceptable"
),
$rightsizing_cooldown_passed = 0 => case(
$avg_utilization_rate = 0 => "[0%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.10 => "[0-10%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.30 => "[10-30%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.50 => "[30-50%] Below low utilization threshold, cooldown active",
else "[50%+] Below low utilization threshold, cooldown active"
),
$should_rightsize = 1 => case(
$avg_utilization_rate = 0 => "[0%] Below low utilization threshold",
$avg_utilization_rate <= 0.10 => "[0-10%] Below low utilization threshold",
$avg_utilization_rate <= 0.30 => "[10-30%] Below low utilization threshold",
$avg_utilization_rate <= 0.50 => "[30-50%] Below low utilization threshold",
else "[50-70%] Below low utilization threshold"
),
$any_day_budget_capped = 1 and $acos_good_for_increase = 0 => case(
$avg_utilization_rate <= 0.70 => "[50-70%] Above high utilization threshold, ACOS too high",
$avg_utilization_rate <= 0.90 => "[70-90%] Above high utilization threshold, ACOS too high",
else "[90%+] Above high utilization threshold, ACOS too high"
),
budget <= $effective_min_for_decreases => case(
$avg_utilization_rate = 0 => "[0%] Budget below rightsizing minimum",
$avg_utilization_rate <= 0.30 => "[0-30%] Budget below rightsizing minimum",
else "[30-50%] Budget below rightsizing minimum"
),
else case(
$avg_utilization_rate = 0 => "[0%] Within acceptable utilization",
$avg_utilization_rate <= 0.10 => "[0-10%] Within acceptable utilization",
$avg_utilization_rate <= 0.30 => "[10-30%] Within acceptable utilization",
$avg_utilization_rate <= 0.50 => "[30-50%] Within acceptable utilization",
$avg_utilization_rate <= 0.70 => "[50-70%] Within acceptable utilization",
$avg_utilization_rate <= 0.90 => "[70-90%] Within acceptable utilization",
else "[90%+] Within acceptable utilization"
)
);
let $result = case(
$should_increase = 1 and $budget_too_small = 1 => "Budget Increase: CPC Minimum",
$should_increase = 1 => "Budget Increase: High Utilization",
$should_rightsize = 1 => "Budget Decrease: Rightsizing",
else "No Action"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and ($should_increase = 1 or $should_rightsize = 1)
and $new_budget != budget
/*
=== Core: Adaptive Budget Management ===
Purpose: Prevents budget waste while ensuring adequate spend for data collection and performance scaling.
Recommended: Change Daily Budget | Set ($) using $new_budget | Daily or Multiple Times Daily
*/
// === Core Settings ===
let $high_utilization = 90%; // CORE: Daily spend % that indicates budget constraint
let $low_utilization = 50%; // CORE: Daily budget utilization % that triggers rightsizing
let $enable_cpc_minimums = 1; // ADVANCED: Enable CPC-based budget minimums (1=yes, 0=no)
// === Budget Increases (High Utilization) ===
let $t_acos_threshold_increase = 130%; // STRATEGY: Increase budget when ACOS ≤ (Target ACOS × 130%) [e.g., 30% target = 39% threshold]
let $budget_increase_pct = 20%; // STRATEGY: Percentage increase when scaling up
let $orders_min = 4; // STRATEGY: Minimum orders needed for reliable ACOS evaluation
let $acos_eval_short = 7d; // TIME: Recent performance period
let $acos_eval_medium = 14d; // TIME: Medium-term performance period
let $acos_eval_long = 30d; // TIME: Long-term performance period
// === Budget Rightsizing (Low Utilization) ===
let $spend_buffer = 130%; // STRATEGY: Buffer above avg daily spend when rightsizing (budget set to 130% avg daily spend)
let $budget_min = 5.00; // STRATEGY: Absolute minimum budget floor for rightsizing
let $cooldown_eval_period = 14d; // TIME: Period for sustained utilization evaluation
let $cooldown_period = 14d; // TIME: Wait period between rightsizing actions
// === CPC-Based Budget Minimums ===
let $min_daily_clicks = 5; // ADVANCED: Minimum clicks per day budget should support
let $cpc_eval_period = 60d; // ADVANCED: Period for calculating average CPC for minimum budget
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Increase Path: Individual daily budget cap analysis
let $today_spend = spend(0d..0d);
let $yesterday_spend = spend(1d..1d);
let $day2_spend = spend(2d..2d);
let $day3_spend = spend(3d..3d);
let $today_capped = case($today_spend >= budget * $high_utilization => 1, else 0);
let $yesterday_capped = case($yesterday_spend >= budget * $high_utilization => 1, else 0);
let $day2_capped = case($day2_spend >= budget * $high_utilization => 1, else 0);
let $day3_capped = case($day3_spend >= budget * $high_utilization => 1, else 0);
let $any_day_budget_capped = case(
$today_capped = 1 or $yesterday_capped = 1 or $day2_capped = 1 or $day3_capped = 1 => 1,
else 0
);
// Increase Path: CPC-based data sufficiency check
let $avg_cpc = cpc($cpc_eval_period);
let $min_budget_for_data = case(
$enable_cpc_minimums = 1 and $avg_cpc > 0 => $avg_cpc * $min_daily_clicks,
else 0 // Data minimums disabled or no CPC data
);
let $budget_too_small = case(
$enable_cpc_minimums = 1 and $avg_cpc > 0 and budget < $min_budget_for_data => 1,
else 0
);
// Increase Path: Performance evaluation for increases (prioritize recent data)
let $orders_short = orders($acos_eval_short);
let $orders_medium = orders($acos_eval_medium);
let $orders_long = orders($acos_eval_long);
let $performance_acos = case(
$orders_short >= $orders_min => acos($acos_eval_short),
$orders_medium >= $orders_min => acos($acos_eval_medium),
$orders_long >= $orders_min => acos($acos_eval_long),
else 99999 // No reliable ACOS data
);
let $acos_good_for_increase = case(
$performance_acos = 99999 => 1, // No ACOS data = allow increase
target acos <= 0 => 0, // Invalid target
$performance_acos <= (target acos * $t_acos_threshold_increase) => 1,
else 0
);
// Rightsizing Path: Sustained utilization analysis
let $total_spend = spend($cooldown_eval_period);
let $days_in_eval = 14; // Days in 14d period
let $avg_daily_spend = $total_spend / $days_in_eval;
let $avg_utilization_rate = case(
budget > 0 => $avg_daily_spend / budget,
else 0
);
// Calculate effective minimum for decreases early
let $effective_min_for_decreases = case(
$min_budget_for_data > $budget_min => $min_budget_for_data, // Use CPC minimum if higher
else $budget_min // Otherwise use absolute minimum
);
let $rightsizing_cooldown_passed = case(
is_null(last budget change) => 1,
last budget change < now() - interval($cooldown_period) => 1,
else 0
);
// Decision logic by path
let $should_increase = case(
$budget_too_small = 1 => 1, // Data-starved campaign
$any_day_budget_capped = 1 and $acos_good_for_increase = 1 => 1, // Budget-capped + good performance
else 0
);
let $should_rightsize = case(
$rightsizing_cooldown_passed = 0 => 0, // Cooldown period active
budget <= $effective_min_for_decreases => 0, // Already at or below minimum - don't rightsize
$avg_utilization_rate < $low_utilization => 1, // Sustained low utilization (including 0% from no spend)
else 0
);
// Calculate new budget
let $increase_budget = budget * (1 + $budget_increase_pct);
// For rightsizing, calculate based on actual usage plus buffer
let $rightsized_budget = case(
$avg_daily_spend > 0 => $avg_daily_spend * $spend_buffer,
else $budget_min // No spend = use minimum budget
);
let $calculated_budget = case(
$should_increase = 1 => $increase_budget,
$should_rightsize = 1 => $rightsized_budget,
else budget
);
// Apply minimums - different rules for increases vs decreases
let $final_minimum = case(
$should_rightsize = 1 => case(
$effective_min_for_decreases > 1.00 => $effective_min_for_decreases, // Use effective minimum if higher than platform
else 1.00 // Otherwise platform minimum
),
$should_increase = 1 and $budget_too_small = 1 => case(
$min_budget_for_data > 1.00 => $min_budget_for_data, // Use CPC minimum for data generation increases
else 1.00 // Platform minimum
),
else 1.00 // Platform minimum for budget-capping increases
);
let $new_budget = case(
$calculated_budget < $final_minimum => $final_minimum,
else $calculated_budget
);
// Diagnostic properties
let $reason = case(
target acos <= 0 => "No target ACOS set",
$should_increase = 1 and $budget_too_small = 1 => case(
$avg_utilization_rate <= 0.10 => "[0-10%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.30 => "[10-30%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.50 => "[30-50%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.70 => "[50-70%] Below CPC minimum threshold",
$avg_utilization_rate <= 0.90 => "[70-90%] Below CPC minimum threshold",
else "[90%+] Below CPC minimum threshold"
),
$should_increase = 1 => case(
$avg_utilization_rate <= 0.70 => "[50-70%] Above high utilization threshold, ACOS acceptable",
$avg_utilization_rate <= 0.90 => "[70-90%] Above high utilization threshold, ACOS acceptable",
else "[90%+] Above high utilization threshold, ACOS acceptable"
),
$rightsizing_cooldown_passed = 0 => case(
$avg_utilization_rate = 0 => "[0%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.10 => "[0-10%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.30 => "[10-30%] Below low utilization threshold, cooldown active",
$avg_utilization_rate <= 0.50 => "[30-50%] Below low utilization threshold, cooldown active",
else "[50%+] Below low utilization threshold, cooldown active"
),
$should_rightsize = 1 => case(
$avg_utilization_rate = 0 => "[0%] Below low utilization threshold",
$avg_utilization_rate <= 0.10 => "[0-10%] Below low utilization threshold",
$avg_utilization_rate <= 0.30 => "[10-30%] Below low utilization threshold",
$avg_utilization_rate <= 0.50 => "[30-50%] Below low utilization threshold",
else "[50-70%] Below low utilization threshold"
),
$any_day_budget_capped = 1 and $acos_good_for_increase = 0 => case(
$avg_utilization_rate <= 0.70 => "[50-70%] Above high utilization threshold, ACOS too high",
$avg_utilization_rate <= 0.90 => "[70-90%] Above high utilization threshold, ACOS too high",
else "[90%+] Above high utilization threshold, ACOS too high"
),
budget <= $effective_min_for_decreases => case(
$avg_utilization_rate = 0 => "[0%] Budget below rightsizing minimum",
$avg_utilization_rate <= 0.30 => "[0-30%] Budget below rightsizing minimum",
else "[30-50%] Budget below rightsizing minimum"
),
else case(
$avg_utilization_rate = 0 => "[0%] Within acceptable utilization",
$avg_utilization_rate <= 0.10 => "[0-10%] Within acceptable utilization",
$avg_utilization_rate <= 0.30 => "[10-30%] Within acceptable utilization",
$avg_utilization_rate <= 0.50 => "[30-50%] Within acceptable utilization",
$avg_utilization_rate <= 0.70 => "[50-70%] Within acceptable utilization",
$avg_utilization_rate <= 0.90 => "[70-90%] Within acceptable utilization",
else "[90%+] Within acceptable utilization"
)
);
let $result = case(
$should_increase = 1 and $budget_too_small = 1 => "Budget Increase: CPC Minimum",
$should_increase = 1 => "Budget Increase: High Utilization",
$should_rightsize = 1 => "Budget Decrease: Rightsizing",
else "No Action"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and ($should_increase = 1 or $should_rightsize = 1)
and $new_budget != budget
Scales bid adjustments proportionally based on distance from target ACOS using adaptive timing controls.
✓ Accounts wanting intelligent bid optimization that adjusts more aggressively when performance is far from target and more cautiously when close
✓ Keywords and targets with varying data reliability where some have daily orders while others need weeks to generate meaningful signals
✓ Sellers who want proportional responses rather than binary "increase or decrease" logic that treats all performance gaps the same
✓ Accounts ready for sophisticated automation that adapts cooldown periods based on data freshness and volume
Daily | Automation: Change Bid: Set ($) using $target_bid
Scales bid adjustments proportionally based on distance from target ACOS using adaptive timing controls.
✓ Accounts wanting intelligent bid optimization that adjusts more aggressively when performance is far from target and more cautiously when close
✓ Keywords and targets with varying data reliability where some have daily orders while others need weeks to generate meaningful signals
✓ Sellers who want proportional responses rather than binary "increase or decrease" logic that treats all performance gaps the same
✓ Accounts ready for sophisticated automation that adapts cooldown periods based on data freshness and volume
Daily | Automation: Change Bid: Set ($) using $target_bid
The blueprint evaluates performance across four cascading time periods to find the freshest data with sufficient orders, then calculates how far current ACOS is from target ACOS. This distance determines both the magnitude of bid adjustment (closer = smaller changes, farther = larger changes) and the cooldown period before the next change (fresher data = shorter cooldowns). The proportional scaling system creates smooth, graduated responses rather than binary reactions, while buffer zones prevent adjustment churn on keywords performing near target.
Proportional Performance Gap Calculation
The blueprint doesn't treat a keyword at 15% ACOS the same as one at 25% when target is 30%. It calculates exactly how far performance is from the relevant threshold, then scales the adjustment percentage proportionally within your configured min/max range. A keyword barely outside the buffer zone gets close to $bid_min_change (3%), while a keyword at or beyond the max threshold gets the full $bid_max_change (10%). This creates nuanced responses that match the severity of the performance gap.
Four-Tier Data Cascade with Adaptive Cooldowns
The blueprint evaluates four periods in order: 7-day → 14-day → 30-day → 60-day, stopping at the first period with sufficient orders ($orders_min = 2). But it doesn't just use different data - it also adapts the cooldown period based on which tier is used. Fresh 7-day data gets a 2-day cooldown, while old 60-day data gets a 7-day cooldown. This prevents over-optimization when forced to use stale data due to low order volume.
Dual-Threshold Asymmetric System
The blueprint uses different threshold distances for increases vs decreases:
This asymmetry reflects different risk profiles - being very efficient (50% of target) justifies aggressive scaling, while being very inefficient (200% of target) requires aggressive cuts. The buffer zone (90-110% of target by default) sits in the middle, creating a stability zone where no changes occur.
Buffer Zone vs Threshold Logic
Understanding the three zones is critical:
This creates five distinct response regions: max increase, scaled increase, no change, scaled decrease, max decrease.
Buffer and Threshold Interaction
The buffer (tacosbufferminchange)andthresholds(t_acos_buffer_min_change) and thresholds (tacosbufferminchange)andthresholds(t_acos_threshold_max_increase, $t_acos_threshold_max_decrease) work together to create the adjustment curve. If you widen the buffer to 15%, you're creating a 85-115% no-change zone, which means adjustments only start when performance is more significantly different from target. This is paired with threshold distances - if your max increase threshold is 50%, the scaling region runs from 85% down to 50% of target ACOS. Narrower buffers + distant thresholds = more gradual scaling. Wider buffers + close thresholds = more aggressive scaling once outside the buffer.
Data Reliability vs Coverage Tradeoff
Setting $orders_min higher (3-4) means you'll rely on longer lookback periods more often, which increases cooldowns and reduces adjustment frequency but improves confidence in each decision. Setting it lower (2 or even 1) means you'll use fresher data more often, enabling more frequent adjustments but with higher risk of reacting to statistical noise. For accounts with high order volume, consider $orders_min = 3-4. For lower volume accounts where most keywords rarely hit 2 orders in 7 days, keeping it at 2 maximizes coverage.
Adjustment Range Philosophy
The min/max range creates bounds for the proportional scaling. A 3-10% range means:
Narrower ranges (2-7%) create more predictable, conservative automation. Wider ranges (5-15%) create more dramatic responses to performance extremes. Avoid ranges where min is too close to max (like 8-10%) as this eliminates the benefits of proportional scaling.
CPC Limit Period Selection
The $bid_limit_cpc_period = 90d uses a long period to smooth out CPC volatility and establish a stable benchmark. Shortening this to 30-60 days makes the limit more responsive to recent CPC changes (useful if your category sees seasonal CPC shifts), but also makes it more volatile. Lengthening to 180+ days creates extreme stability but may lag behind market changes. The 90-day default balances stability with reasonable responsiveness.
$data_quality Values:
These tags appear in the $reason diagnostic to show both why action is/isn't being taken AND which data quality tier is driving decisions.
$reason Patterns:
$result Magnitude Categories:
High-Volume Keywords with Short Lookback
Keywords consistently showing "High Volume: Short Lookback" are your most actively managed terms. They generate enough orders weekly to use fresh 7-day data with 2-day cooldowns, meaning they can be adjusted multiple times per week if performance shifts. These should show the most responsive bid optimization and are where the proportional scaling system shines most - small performance deviations get small adjustments, large deviations get large adjustments, all happening quickly.
Low-Volume Keywords Stuck on Extended Lookback
Keywords consistently showing "Very Low Volume: Extended Lookback" generate fewer than 2 orders in 30 days, forcing the system to use 60-day data with 7-day cooldowns. These will adjust infrequently (maximum once per week), and when they do adjust, the changes are based on very old data. This is working as designed - low-order keywords should change cautiously. If you're seeing too many keywords stuck here and want more frequent adjustments, lower $orders_min to 1 (but expect more noise).
Buffer Zone Stability vs Constant Adjustments
Keywords bouncing between "Within target buffer zone" and "ACOS below/above target threshold" indicate you're near the buffer boundaries. If you're seeing excessive adjustment churn (adjust up, then down, then up again), widen the buffer to 15% to create more stability. If you're seeing too many keywords sitting in "Within target buffer zone" while you think they should be adjusted, narrow the buffer to 5% to reduce the no-change zone.
CPC Limit Constraints
If many keywords show "Limited by CPC-based maximum" frequently, your bid calculations are trying to exceed 2× average CPC regularly. This suggests either: (1) Your ACOS targets are very aggressive relative to current CPC reality, requiring unrealistic bids to achieve them, or (2) The multiplier is too conservative for your category. Review actual performance of keywords hitting this limit - if they're delivering good ACOS even at the capped bid, consider increasing the multiplier to 2.5 or 3.0.
Cooldown Blocking High-Opportunity Keywords
Keywords showing "[High Volume: Short Lookback] Recently changed - cooldown active" with excellent ACOS (far below target) are in a scenario where you'd like to increase bids more aggressively but the adaptive cooldown is holding you back. This is intentional safety - even with fresh data, some cooldown prevents over-reaction to short-term spikes. However, if you're consistently seeing opportunities blocked by cooldowns, you can shorten the tier-specific cooldown periods ($cooldown_short, $cooldown_medium, etc.) to enable more frequent adjustments.
/*
=== Core: Dynamic Bid Management ===
Purpose: Intelligent bid optimization that adjusts more aggressively when further from target ACOS, with adaptive timing controls.
Recommended: Change Bid: Set ($) using $target_bid | Daily
*/
// === Core Settings ===
let $orders_min = 2; // CORE: Minimum orders required for reliable ACOS evaluation
let $bid_min_change = 3%; // CORE: Minimum bid adjustment when change is warranted
let $bid_max_change = 10%; // CORE: Maximum bid adjustment when ACOS is at or beyond target ACOS thresholds
// === Target ACOS Thresholds ===
// Between buffer and thresholds: bid adjustments scale linearly from min to max change percent
let $t_acos_buffer_min_change = 10%; // STRATEGY: No-change buffer around target ACOS - min changes start outside this zone (Target ACOS ± 10%) [e.g., 30% target = 27-33% no-change zone]
let $t_acos_threshold_max_increase = 50%; // STRATEGY: Max increase when ACOS ≤ (Target ACOS × 50%) [e.g., 30% target = 15% max increase threshold]
let $t_acos_threshold_max_decrease = 200%; // STRATEGY: Max decrease when ACOS ≥ (Target ACOS × 200%) [e.g., 30% target = 60% max decrease threshold]
// === Time Periods ===
let $period_short = 0d..7d; // TIME: Primary evaluation period (7 days including today)
let $cooldown_short = 2d; // TIME: Wait period after bid change for short data periods
let $period_medium = 0d..14d; // TIME: Secondary evaluation period (14 days including today)
let $cooldown_medium = 3d; // TIME: Wait period after bid change for medium data periods
let $period_long = 0d..30d; // TIME: Tertiary evaluation period (30 days including today)
let $cooldown_long = 5d; // TIME: Wait period after bid change for long data periods
let $period_extended = 0d..60d; // TIME: Final fallback evaluation period (60 days including today)
let $cooldown_extended = 7d; // TIME: Wait period after bid change for extended data periods
// === Advanced Settings ===
let $bid_limit_cpc_multiplier = 2.0; // SAFEGUARD: Max bid = Avg CPC × 2.0 [e.g., $0.50 CPC = $1.00 max]
let $bid_limit_cpc_period = 90d; // SAFEGUARD: Period for calculating CPC-based bid limits
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Multi-period data selection with extended coverage
let $orders_short = orders($period_short);
let $orders_medium = orders($period_medium);
let $orders_long = orders($period_long);
let $orders_extended = orders($period_extended);
let $evaluation_acos = case(
$orders_short >= $orders_min => acos($period_short),
$orders_medium >= $orders_min => acos($period_medium),
$orders_long >= $orders_min => acos($period_long),
$orders_extended >= $orders_min => acos($period_extended),
else 99999 // No reliable data
);
// Track which period was used for diagnostics
let $data_quality = case(
$orders_short >= $orders_min => "High Volume: Short Lookback",
$orders_medium >= $orders_min => "Med Volume: Medium Lookback",
$orders_long >= $orders_min => "Low Volume: Long Lookback",
$orders_extended >= $orders_min => "Very Low Volume: Extended Lookback",
else "insufficient"
);
// Adaptive cooldown periods based on data source
let $cooldown_cutoff = case(
$orders_short >= $orders_min => now() - interval($cooldown_short),
$orders_medium >= $orders_min => now() - interval($cooldown_medium),
$orders_long >= $orders_min => now() - interval($cooldown_long),
else now() - interval($cooldown_extended)
);
// Calculate performance ratio with Target ACOS validation
let $acos_ratio = case(
$evaluation_acos = 99999 => -1, // No reliable data
target acos <= 0 => -1, // Invalid target ACOS
else $evaluation_acos / target acos // Performance ratio
);
// Check if within no-change buffer zone
let $within_buffer = case(
$acos_ratio < 0 => 1, // No change if no data or invalid target
$acos_ratio >= (1 - $t_acos_buffer_min_change) and $acos_ratio <= (1 + $t_acos_buffer_min_change) => 1,
else 0
);
// Proportional scaling for bid adjustments
let $performance_gap = case(
$acos_ratio < 0 => 0, // No gap if no data
// Max increase region: ACOS at 50% of target or better
$acos_ratio <= $t_acos_threshold_max_increase => 1,
// Scaled increase region: ACOS between 50% and buffer zone (90% of target)
$acos_ratio < (1 - $t_acos_buffer_min_change) =>
((1 - $t_acos_buffer_min_change) - $acos_ratio) /
((1 - $t_acos_buffer_min_change) - $t_acos_threshold_max_increase),
// Max decrease region: ACOS at 200% of target or worse
$acos_ratio >= $t_acos_threshold_max_decrease => 1,
// Scaled decrease region: ACOS between buffer zone (110%) and 200% of target
$acos_ratio > (1 + $t_acos_buffer_min_change) =>
($acos_ratio - (1 + $t_acos_buffer_min_change)) /
($t_acos_threshold_max_decrease - (1 + $t_acos_buffer_min_change)),
else 0 // Within buffer zone - no adjustment
);
let $adjustment_percent = case(
$within_buffer = 1 => 0%, // No change within buffer zone
// Increase adjustments for ACOS below target
$acos_ratio <= $t_acos_threshold_max_increase =>
$bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change)),
$acos_ratio < (1 - $t_acos_buffer_min_change) =>
$bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change)),
// Decrease adjustments for ACOS above target
$acos_ratio > (1 + $t_acos_buffer_min_change) =>
-1 * ($bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change))),
else 0%
);
// Calculate target bid with CPC-based limits
let $initial_target_bid = bid * (1 + $adjustment_percent);
let $avg_cpc = cpc($bid_limit_cpc_period);
let $dynamic_max = case(
$avg_cpc > 0 => $avg_cpc * $bid_limit_cpc_multiplier,
else 999 // No CPC data = no dynamic limit
);
let $target_bid = case(
$avg_cpc > 0 and $initial_target_bid > $dynamic_max => $dynamic_max,
else $initial_target_bid
);
// Cooldown validation
let $cooldown_ready = case(
is_null(last bid change) => 1,
last bid change < $cooldown_cutoff => 1,
else 0
);
// Diagnostic properties
let $reason = case(
target acos <= 0 => "No target ACOS set",
$evaluation_acos = 99999 => "Insufficient order data across all lookback periods",
$within_buffer = 1 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] Within target buffer zone",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] Within target buffer zone",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] Within target buffer zone",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] Within target buffer zone",
else "Performance within target buffer zone"
),
$cooldown_ready = 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] Recently changed - cooldown active",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] Recently changed - cooldown active",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] Recently changed - cooldown active",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] Recently changed - cooldown active",
else "Recently changed - cooldown active"
),
$target_bid = bid => "No bid change calculated",
$avg_cpc > 0 and $initial_target_bid > $dynamic_max => "Limited by CPC-based maximum",
$adjustment_percent > 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] ACOS below target threshold",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] ACOS below target threshold",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] ACOS below target threshold",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] ACOS below target threshold",
else "ACOS below target threshold"
),
$adjustment_percent < 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] ACOS above target threshold",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] ACOS above target threshold",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] ACOS above target threshold",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] ACOS above target threshold",
else "ACOS above target threshold"
),
else "Performance at target"
);
let $result = case(
$within_buffer = 0 and $cooldown_ready = 1 and $target_bid != bid => case(
$adjustment_percent >= $bid_max_change => "Bid Increase: Max",
$adjustment_percent >= $bid_max_change * 0.5 => "Bid Increase: Upper Range",
$adjustment_percent > 0 => "Bid Increase: Lower Range",
$adjustment_percent <= -1 * $bid_max_change => "Bid Decrease: Max",
$adjustment_percent <= -1 * $bid_max_change * 0.5 => "Bid Decrease: Upper Range",
$adjustment_percent < 0 => "Bid Decrease: Lower Range",
else "No action needed"
),
else "No action needed"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $within_buffer = 0
and $target_bid != bid
and $cooldown_ready = 1
/*
=== Core: Dynamic Bid Management ===
Purpose: Intelligent bid optimization that adjusts more aggressively when further from target ACOS, with adaptive timing controls.
Recommended: Change Bid: Set ($) using $target_bid | Daily
*/
// === Core Settings ===
let $orders_min = 2; // CORE: Minimum orders required for reliable ACOS evaluation
let $bid_min_change = 3%; // CORE: Minimum bid adjustment when change is warranted
let $bid_max_change = 10%; // CORE: Maximum bid adjustment when ACOS is at or beyond target ACOS thresholds
// === Target ACOS Thresholds ===
// Between buffer and thresholds: bid adjustments scale linearly from min to max change percent
let $t_acos_buffer_min_change = 10%; // STRATEGY: No-change buffer around target ACOS - min changes start outside this zone (Target ACOS ± 10%) [e.g., 30% target = 27-33% no-change zone]
let $t_acos_threshold_max_increase = 50%; // STRATEGY: Max increase when ACOS ≤ (Target ACOS × 50%) [e.g., 30% target = 15% max increase threshold]
let $t_acos_threshold_max_decrease = 200%; // STRATEGY: Max decrease when ACOS ≥ (Target ACOS × 200%) [e.g., 30% target = 60% max decrease threshold]
// === Time Periods ===
let $period_short = 0d..7d; // TIME: Primary evaluation period (7 days including today)
let $cooldown_short = 2d; // TIME: Wait period after bid change for short data periods
let $period_medium = 0d..14d; // TIME: Secondary evaluation period (14 days including today)
let $cooldown_medium = 3d; // TIME: Wait period after bid change for medium data periods
let $period_long = 0d..30d; // TIME: Tertiary evaluation period (30 days including today)
let $cooldown_long = 5d; // TIME: Wait period after bid change for long data periods
let $period_extended = 0d..60d; // TIME: Final fallback evaluation period (60 days including today)
let $cooldown_extended = 7d; // TIME: Wait period after bid change for extended data periods
// === Advanced Settings ===
let $bid_limit_cpc_multiplier = 2.0; // SAFEGUARD: Max bid = Avg CPC × 2.0 [e.g., $0.50 CPC = $1.00 max]
let $bid_limit_cpc_period = 90d; // SAFEGUARD: Period for calculating CPC-based bid limits
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Multi-period data selection with extended coverage
let $orders_short = orders($period_short);
let $orders_medium = orders($period_medium);
let $orders_long = orders($period_long);
let $orders_extended = orders($period_extended);
let $evaluation_acos = case(
$orders_short >= $orders_min => acos($period_short),
$orders_medium >= $orders_min => acos($period_medium),
$orders_long >= $orders_min => acos($period_long),
$orders_extended >= $orders_min => acos($period_extended),
else 99999 // No reliable data
);
// Track which period was used for diagnostics
let $data_quality = case(
$orders_short >= $orders_min => "High Volume: Short Lookback",
$orders_medium >= $orders_min => "Med Volume: Medium Lookback",
$orders_long >= $orders_min => "Low Volume: Long Lookback",
$orders_extended >= $orders_min => "Very Low Volume: Extended Lookback",
else "insufficient"
);
// Adaptive cooldown periods based on data source
let $cooldown_cutoff = case(
$orders_short >= $orders_min => now() - interval($cooldown_short),
$orders_medium >= $orders_min => now() - interval($cooldown_medium),
$orders_long >= $orders_min => now() - interval($cooldown_long),
else now() - interval($cooldown_extended)
);
// Calculate performance ratio with Target ACOS validation
let $acos_ratio = case(
$evaluation_acos = 99999 => -1, // No reliable data
target acos <= 0 => -1, // Invalid target ACOS
else $evaluation_acos / target acos // Performance ratio
);
// Check if within no-change buffer zone
let $within_buffer = case(
$acos_ratio < 0 => 1, // No change if no data or invalid target
$acos_ratio >= (1 - $t_acos_buffer_min_change) and $acos_ratio <= (1 + $t_acos_buffer_min_change) => 1,
else 0
);
// Proportional scaling for bid adjustments
let $performance_gap = case(
$acos_ratio < 0 => 0, // No gap if no data
// Max increase region: ACOS at 50% of target or better
$acos_ratio <= $t_acos_threshold_max_increase => 1,
// Scaled increase region: ACOS between 50% and buffer zone (90% of target)
$acos_ratio < (1 - $t_acos_buffer_min_change) =>
((1 - $t_acos_buffer_min_change) - $acos_ratio) /
((1 - $t_acos_buffer_min_change) - $t_acos_threshold_max_increase),
// Max decrease region: ACOS at 200% of target or worse
$acos_ratio >= $t_acos_threshold_max_decrease => 1,
// Scaled decrease region: ACOS between buffer zone (110%) and 200% of target
$acos_ratio > (1 + $t_acos_buffer_min_change) =>
($acos_ratio - (1 + $t_acos_buffer_min_change)) /
($t_acos_threshold_max_decrease - (1 + $t_acos_buffer_min_change)),
else 0 // Within buffer zone - no adjustment
);
let $adjustment_percent = case(
$within_buffer = 1 => 0%, // No change within buffer zone
// Increase adjustments for ACOS below target
$acos_ratio <= $t_acos_threshold_max_increase =>
$bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change)),
$acos_ratio < (1 - $t_acos_buffer_min_change) =>
$bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change)),
// Decrease adjustments for ACOS above target
$acos_ratio > (1 + $t_acos_buffer_min_change) =>
-1 * ($bid_min_change + ($performance_gap * ($bid_max_change - $bid_min_change))),
else 0%
);
// Calculate target bid with CPC-based limits
let $initial_target_bid = bid * (1 + $adjustment_percent);
let $avg_cpc = cpc($bid_limit_cpc_period);
let $dynamic_max = case(
$avg_cpc > 0 => $avg_cpc * $bid_limit_cpc_multiplier,
else 999 // No CPC data = no dynamic limit
);
let $target_bid = case(
$avg_cpc > 0 and $initial_target_bid > $dynamic_max => $dynamic_max,
else $initial_target_bid
);
// Cooldown validation
let $cooldown_ready = case(
is_null(last bid change) => 1,
last bid change < $cooldown_cutoff => 1,
else 0
);
// Diagnostic properties
let $reason = case(
target acos <= 0 => "No target ACOS set",
$evaluation_acos = 99999 => "Insufficient order data across all lookback periods",
$within_buffer = 1 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] Within target buffer zone",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] Within target buffer zone",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] Within target buffer zone",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] Within target buffer zone",
else "Performance within target buffer zone"
),
$cooldown_ready = 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] Recently changed - cooldown active",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] Recently changed - cooldown active",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] Recently changed - cooldown active",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] Recently changed - cooldown active",
else "Recently changed - cooldown active"
),
$target_bid = bid => "No bid change calculated",
$avg_cpc > 0 and $initial_target_bid > $dynamic_max => "Limited by CPC-based maximum",
$adjustment_percent > 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] ACOS below target threshold",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] ACOS below target threshold",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] ACOS below target threshold",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] ACOS below target threshold",
else "ACOS below target threshold"
),
$adjustment_percent < 0 => case(
$data_quality = "High Volume: Short Lookback" => "[High Volume: Short Lookback] ACOS above target threshold",
$data_quality = "Med Volume: Medium Lookback" => "[Med Volume: Medium Lookback] ACOS above target threshold",
$data_quality = "Low Volume: Long Lookback" => "[Low Volume: Long Lookback] ACOS above target threshold",
$data_quality = "Very Low Volume: Extended Lookback" => "[Very Low Volume: Extended Lookback] ACOS above target threshold",
else "ACOS above target threshold"
),
else "Performance at target"
);
let $result = case(
$within_buffer = 0 and $cooldown_ready = 1 and $target_bid != bid => case(
$adjustment_percent >= $bid_max_change => "Bid Increase: Max",
$adjustment_percent >= $bid_max_change * 0.5 => "Bid Increase: Upper Range",
$adjustment_percent > 0 => "Bid Increase: Lower Range",
$adjustment_percent <= -1 * $bid_max_change => "Bid Decrease: Max",
$adjustment_percent <= -1 * $bid_max_change * 0.5 => "Bid Decrease: Upper Range",
$adjustment_percent < 0 => "Bid Decrease: Lower Range",
else "No action needed"
),
else "No action needed"
);
// === Final Filter ===
state = "effectively enabled"
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $within_buffer = 0
and $target_bid != bid
and $cooldown_ready = 1
Automatically negate zero-converting search terms to stop budget waste.
✓ Accounts with obvious search term waste - zero-order terms burning through clicks
✓ Conservative automation approach - only targets the most clear-cut waste
✓ First-time negative keyword automation - simple, safe starting point
✓ Accounts wanting budget protection without complex performance analysis
Daily Automation: Create Negative Exact Match using $action
This blueprint uses the simplest possible waste detection: zero orders + high clicks = clear waste. It evaluates each search term's lifetime performance and negates terms that have generated 20+ clicks without a single order. No complex calculations, no performance ratios - just pure waste elimination.
Conservative Targeting Philosophy: Only acts on terms with zero orders, eliminating any risk of accidentally negating valuable converting terms. This makes it ideal for first-time automation users or accounts wanting maximum safety.
Lifetime Performance Analysis: Uses complete historical data rather than recent periods, ensuring terms get adequate opportunity to convert before negation. A term needs to accumulate the full click threshold over its entire lifetime.
Binary Decision Logic: No gray areas or complex scoring - terms either qualify for negation (zero orders + sufficient clicks) or they don't. This transparency makes the automation predictable and trustworthy.
Click Threshold Selection: The 20-click default provides conservative waste removal suitable for most accounts. Increase to 30-40 clicks for accounts with higher average order values or longer consideration cycles. Decrease to 15 clicks only for very budget-conscious accounts with clear waste patterns.
Campaign Filtering Strategy: Use include/exclude filters to target specific campaign types rather than running separate blueprints. For example, set include_campaigns to ["Auto"] to focus on automatic targeting waste, or exclude_campaigns to ["Brand"] to protect brand campaigns.
Action Results: Simple "Negate" or "Keep" output makes it easy to audit automation decisions. "Negate" indicates the term met both criteria (zero orders + click threshold). "Keep" covers all other scenarios including converting terms and terms below the click threshold.
Expected Volume: In healthy accounts, expect 5-15% of search terms to qualify for negation. Higher percentages may indicate targeting issues, while very low percentages suggest the click threshold might be too conservative.
High-Waste Scenarios: Accounts with broad keyword targeting or automatic campaigns often see significant waste elimination in the first weeks of deployment. This is normal and indicates the automation is working effectively.
Low-Activity Periods: During slower seasons or after campaign restructuring, fewer terms will qualify for negation. This doesn't indicate a problem - the automation naturally adapts to activity levels.
Upgrade Considerations: This blueprint focuses only on zero-order waste. Accounts wanting to address converting but inefficient terms, or terms with poor ACOS performance, should consider the Core-level Search Term Waste Elimination blueprint for more sophisticated analysis.
/*
=== Basics: Search Term Waste Elimination ===
Purpose: Automatically negate zero-converting search terms to stop budget waste.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $base_clicks = 20; // CORE: Clicks required to negate zero-order terms (0 orders + 20 clicks = negated)
// === Campaign Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_orders = orders(lifetime);
let $lifetime_clicks = clicks(lifetime);
// Simple waste removal: zero orders with sufficient clicks
let $waste_candidate = case(
$lifetime_orders = 0 and $lifetime_clicks >= $base_clicks => 1,
else 0
);
// Diagnostic properties
let $action = case(
$waste_candidate = 1 => "Negate",
else "Keep"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $waste_candidate = 1
/*
=== Basics: Search Term Waste Elimination ===
Purpose: Automatically negate zero-converting search terms to stop budget waste.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $base_clicks = 20; // CORE: Clicks required to negate zero-order terms (0 orders + 20 clicks = negated)
// === Campaign Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_orders = orders(lifetime);
let $lifetime_clicks = clicks(lifetime);
// Simple waste removal: zero orders with sufficient clicks
let $waste_candidate = case(
$lifetime_orders = 0 and $lifetime_clicks >= $base_clicks => 1,
else 0
);
// Diagnostic properties
let $action = case(
$waste_candidate = 1 => "Negate",
else "Keep"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $waste_candidate = 1
Intelligently negate wasteful search terms using KDP performance data and relevance analysis.
✓ KDP accounts wanting sophisticated waste analysis beyond just zero-conversion terms
✓ Authors with blended profit data from both sales and page reads for reliable analysis
✓ Campaigns mixing fiction and non-fiction requiring profit-scaled efficiency thresholds
✓ Accounts needing KENP-aware optimization that considers page read engagement patterns
Daily Automation: Create Negative Exact Match using automatic detection
This blueprint uses four distinct negation paths to identify wasteful search terms in KDP campaigns. It combines profit-scaled efficiency analysis with KDP-specific blended metrics to account for both immediate sales and page read engagement. The system automatically adjusts click thresholds based on the blended profit generated, allowing higher-value terms more opportunity to convert while quickly identifying true waste.
Profit-Scaled Click Thresholds: Base threshold (20 clicks) increases by 4 clicks per dollar of blended profit generated. A term generating $5 in blended profit gets 40 total clicks before evaluation (20 + 5×4). This prevents negating terms that show profitability but need more volume to optimize.
Blended Performance Analysis: Uses KDP-specific metrics that combine sales revenue and estimated KENP royalties. This captures terms that drive page reads but not immediate sales, or vice versa, providing complete performance visibility for subscription-based reading.
Four-Path Negation Logic: Irrelevant terms (fast negation with minimal data), zero-profit waste (no engagement after sufficient testing), efficiency violations (converting but requiring too many clicks), and performance failures (converting well but poor blended ACOS).
Blended ROAS Protection: Prevents negating profitable terms by calculating target blended ROAS from target blended ACOS and protecting terms achieving 50% of that threshold. This safeguards against accidentally removing terms with acceptable profitability ratios.
Profit Scaling Strategy: The 4.0 clicks per dollar works well for mixed-genre accounts. Increase to 6.0+ for high-value non-fiction or business books where longer consideration cycles are normal. Decrease to 2.5-3.0 for quick-decision romance or thriller genres.
Target Blended ACOS Context: KDP campaigns typically target 100% blended ACOS (break-even) rather than 30% profit margins common in physical products. This reflects the different economics of digital content and subscription reading models.
Threshold Multiplier Applications: Use 1.5x for conservative accounts wanting more data before decisions, or 0.8x for aggressive waste removal in budget-constrained campaigns. This scales all thresholds proportionally while maintaining relative relationships.
Safeguard Balance: The $50 blended profit safeguard protects established performers while allowing aggressive optimization of low-value terms. Adjust based on your typical book price points and engagement patterns.
Efficiency vs Performance Negations: "Over Click Limit" indicates converting terms that require too many clicks per dollar of profit generated. "High Blended ACOS" indicates terms converting efficiently but with poor profitability ratios.
Protection Classifications: "Blended ROAS protection" means the term shows acceptable profitability even if other metrics suggest negation. "Too much blended profit" indicates established revenue streams that warrant protection regardless of efficiency.
Data Sufficiency Signals: "Insufficient clicks for profit level" means the term hasn't reached its profit-scaled threshold yet. This helps distinguish between terms needing more time versus clear non-performers.
Genre-Specific Behavior: Romance and thriller terms tend to convert quickly or fail clearly, leading to faster negation decisions. Business and self-help terms often show gradual profit accumulation, benefiting from profit-scaled thresholds.
Page Read Dynamics: Terms driving significant page reads but few sales will show in efficiency rather than zero-profit categories. The blended profit calculation captures this engagement and adjusts thresholds accordingly.
Seasonal Adaptation: During high-traffic periods (holidays, back-to-school), the profit scaling naturally accommodates increased engagement without premature negation. The system becomes more selective as terms generate more blended profit.
Volume Expectations: Expect 15-25% of search terms to qualify for negation in mature KDP campaigns, with higher percentages in the first weeks of deployment. The multi-path approach captures waste that simple zero-conversion analysis might miss.
/*
=== KDP Core: Search Term Waste Elimination ===
Purpose: Intelligently negate wasteful search terms using performance data and relevance analysis.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $clicks_threshold = 20; // CORE: Base click threshold for zero-profit terms
let $spend_threshold = 5.00; // CORE: Minimum lifetime spend required for evaluation
// === Strategy Settings ===
let $blend_profit_min_for_acos_eval = 20.00; // STRATEGY: Blended profit required for ACOS-based evaluation ($20.00 threshold)
let $clicks_min_for_acos_eval = 100; // STRATEGY: Clicks required for ACOS-based evaluation
let $t_blend_acos_threshold_negate = 500%; // STRATEGY: Negate if blended ACOS ≥ (Target Blended ACOS × 500%) when min clicks & profit are met [e.g., 100% target = 500% threshold]
// === Advanced Settings ===
let $clicks_scaling_per_dollar = 4.0; // ADVANCED: Additional clicks allowed per $1.00 blended profit [e.g., $5 profit = 20 + (5 × 4) = 40 clicks]
let $threshold_multiplier = 1.0; // ADVANCED: Scales testing thresholds for clicks and spend [e.g., 1.5 = 50% higher requirements]
let $spend_scaling_enabled = 0; // ADVANCED: Scale spend requirement with profit using threshold multiplier (1=yes, 0=no) [e.g., 0 profit = $5, $5 profit = $10]
let $irrelevant_terms = ["NEVER_MATCH"]; // ADVANCED: Aggressively negate search terms containing these keywords (unrelated terms)
let $irrelevant_clicks_threshold = 10; // ADVANCED: Clicks required to negate irrelevant terms (ignores all scaling and spend requirements)
// === Safeguards ===
let $safeguard_blend_profit = 50.00; // SAFEGUARD: Never negate terms with this much blended profit or more
let $safeguard_min_blended_roas_ratio = 50%; // SAFEGUARD: Protect terms with blended ROAS ≥ (Target Blended ROAS × 50%) [e.g., 1.0 target ROAS = 0.5 protection]
let $protected_terms = ["NEVER_MATCH"]; // SAFEGUARD: Never negate search terms containing these keywords (your brand, product names, strategic terms)
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_blended_profit = blended profit(lifetime);
let $lifetime_clicks = clicks(lifetime);
let $lifetime_spend = spend(lifetime);
let $lifetime_blended_acos = blended acos(lifetime);
let $lifetime_blended_roas = blended roas(lifetime);
// Calculate scaled click threshold based on blended profit
let $base_clicks_threshold = $clicks_threshold * $threshold_multiplier;
let $allowed_clicks = $base_clicks_threshold + ($lifetime_blended_profit * $clicks_scaling_per_dollar * $threshold_multiplier);
let $spend_required = case(
$spend_scaling_enabled = 1 => $spend_threshold + (($lifetime_blended_profit / 5.0) * $threshold_multiplier * $spend_threshold),
else $spend_threshold
);
// Data sufficiency check (both clicks and spend)
let $sufficient_data = case(
$lifetime_clicks >= $allowed_clicks and $lifetime_spend >= $spend_required => 1,
else 0
);
// Blended ROAS-based protection calculation
let $target_blended_roas = case(
target acos > 0 => 1 / target acos,
else 0
);
let $blended_roas_protection_threshold = case(
$target_blended_roas > 0 => $target_blended_roas * $safeguard_min_blended_roas_ratio,
else 0
);
let $blended_roas_protected = case(
$lifetime_blended_profit > 0 and $target_blended_roas > 0 and $lifetime_blended_roas >= $blended_roas_protection_threshold => 1,
else 0
);
// Search term relevance analysis
let $protected_term = case(
search term contains any $protected_terms => 1,
else 0
);
let $irrelevant_term = case(
search term contains any $irrelevant_terms => 1,
else 0
);
// Protection safeguards
let $high_profit_protection = case(
$lifetime_blended_profit >= $safeguard_blend_profit => 1,
else 0
);
let $protected_overall = case(
$high_profit_protection = 1 => 1,
$protected_term = 1 => 1,
$blended_roas_protected = 1 => 1,
else 0
);
// Four negation paths: irrelevant, zero-profit waste, efficiency, and ACOS performance
let $irrelevant_candidate = case(
$irrelevant_term = 1 and $lifetime_clicks >= $irrelevant_clicks_threshold => 1,
else 0
);
let $zero_profit_waste_candidate = case(
$lifetime_blended_profit = 0 and $sufficient_data = 1 => 1,
else 0
);
let $efficiency_candidate = case(
$lifetime_blended_profit > 0 and ($lifetime_blended_profit < $blend_profit_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => case(
$sufficient_data = 1 => 1,
else 0
),
else 0
);
let $performance_candidate = case(
$lifetime_blended_profit >= $blend_profit_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => case(
target acos > 0 and $lifetime_blended_acos > target acos * $t_blend_acos_threshold_negate => 1,
else 0
),
else 0
);
let $negation_candidate = case(
$irrelevant_candidate = 1 => 1,
$zero_profit_waste_candidate = 1 => 1,
$efficiency_candidate = 1 => 1,
$performance_candidate = 1 => 1,
else 0
);
// Diagnostic properties
let $reason = case(
$high_profit_protection = 1 => "Protected - too much blended profit to negate",
$protected_term = 1 => "Protected - contains protected keyword",
$blended_roas_protected = 1 => "Protected - blended ROAS above safeguard threshold",
$irrelevant_candidate = 1 => "Contains irrelevant terms, met click threshold",
$irrelevant_term = 1 and $lifetime_clicks < $irrelevant_clicks_threshold => "Contains irrelevant terms, needs more clicks",
$zero_profit_waste_candidate = 1 => "Zero blended profit, met click threshold",
$efficiency_candidate = 1 and $lifetime_clicks >= $allowed_clicks * 1.5 => "Greatly exceeds profit-scaled click limit",
$efficiency_candidate = 1 => "Exceeds profit-scaled click limit",
$performance_candidate = 1 => "Blended ACOS far above target threshold",
$sufficient_data = 0 and $lifetime_spend < $spend_required and $lifetime_clicks < $allowed_clicks => "Insufficient spend and clicks",
$sufficient_data = 0 and $lifetime_spend < $spend_required => "Insufficient spend",
$sufficient_data = 0 => "Insufficient clicks for profit level",
$lifetime_blended_profit > 0 and ($lifetime_blended_profit < $blend_profit_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => "Converting within profit-scaled click limit",
$lifetime_blended_profit >= $blend_profit_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => "Blended ACOS below negation threshold",
else "Zero blended profit, needs more clicks"
);
let $result = case(
$zero_profit_waste_candidate = 1 => "Negate - Zero Profit, High Clicks",
$irrelevant_candidate = 1 => "Negate - Irrelevant Term",
$efficiency_candidate = 1 => case(
$lifetime_blended_profit <= 5.00 => "Negate - Low Profit, High Clicks",
$lifetime_blended_profit >= 15.00 => "Negate - Converting but Inefficient",\
else "Negate - Over Click Limit"
),
$performance_candidate = 1 => "Negate - High Blended ACOS",
$high_profit_protection = 1 or $protected_term = 1 or $blended_roas_protected = 1 => "Protected - No Action",
else "No Action"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $negation_candidate = 1
and $protected_overall = 0
/*
=== KDP Core: Search Term Waste Elimination ===
Purpose: Intelligently negate wasteful search terms using performance data and relevance analysis.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $clicks_threshold = 20; // CORE: Base click threshold for zero-profit terms
let $spend_threshold = 5.00; // CORE: Minimum lifetime spend required for evaluation
// === Strategy Settings ===
let $blend_profit_min_for_acos_eval = 20.00; // STRATEGY: Blended profit required for ACOS-based evaluation ($20.00 threshold)
let $clicks_min_for_acos_eval = 100; // STRATEGY: Clicks required for ACOS-based evaluation
let $t_blend_acos_threshold_negate = 500%; // STRATEGY: Negate if blended ACOS ≥ (Target Blended ACOS × 500%) when min clicks & profit are met [e.g., 100% target = 500% threshold]
// === Advanced Settings ===
let $clicks_scaling_per_dollar = 4.0; // ADVANCED: Additional clicks allowed per $1.00 blended profit [e.g., $5 profit = 20 + (5 × 4) = 40 clicks]
let $threshold_multiplier = 1.0; // ADVANCED: Scales testing thresholds for clicks and spend [e.g., 1.5 = 50% higher requirements]
let $spend_scaling_enabled = 0; // ADVANCED: Scale spend requirement with profit using threshold multiplier (1=yes, 0=no) [e.g., 0 profit = $5, $5 profit = $10]
let $irrelevant_terms = ["NEVER_MATCH"]; // ADVANCED: Aggressively negate search terms containing these keywords (unrelated terms)
let $irrelevant_clicks_threshold = 10; // ADVANCED: Clicks required to negate irrelevant terms (ignores all scaling and spend requirements)
// === Safeguards ===
let $safeguard_blend_profit = 50.00; // SAFEGUARD: Never negate terms with this much blended profit or more
let $safeguard_min_blended_roas_ratio = 50%; // SAFEGUARD: Protect terms with blended ROAS ≥ (Target Blended ROAS × 50%) [e.g., 1.0 target ROAS = 0.5 protection]
let $protected_terms = ["NEVER_MATCH"]; // SAFEGUARD: Never negate search terms containing these keywords (your brand, product names, strategic terms)
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_blended_profit = blended profit(lifetime);
let $lifetime_clicks = clicks(lifetime);
let $lifetime_spend = spend(lifetime);
let $lifetime_blended_acos = blended acos(lifetime);
let $lifetime_blended_roas = blended roas(lifetime);
// Calculate scaled click threshold based on blended profit
let $base_clicks_threshold = $clicks_threshold * $threshold_multiplier;
let $allowed_clicks = $base_clicks_threshold + ($lifetime_blended_profit * $clicks_scaling_per_dollar * $threshold_multiplier);
let $spend_required = case(
$spend_scaling_enabled = 1 => $spend_threshold + (($lifetime_blended_profit / 5.0) * $threshold_multiplier * $spend_threshold),
else $spend_threshold
);
// Data sufficiency check (both clicks and spend)
let $sufficient_data = case(
$lifetime_clicks >= $allowed_clicks and $lifetime_spend >= $spend_required => 1,
else 0
);
// Blended ROAS-based protection calculation
let $target_blended_roas = case(
target acos > 0 => 1 / target acos,
else 0
);
let $blended_roas_protection_threshold = case(
$target_blended_roas > 0 => $target_blended_roas * $safeguard_min_blended_roas_ratio,
else 0
);
let $blended_roas_protected = case(
$lifetime_blended_profit > 0 and $target_blended_roas > 0 and $lifetime_blended_roas >= $blended_roas_protection_threshold => 1,
else 0
);
// Search term relevance analysis
let $protected_term = case(
search term contains any $protected_terms => 1,
else 0
);
let $irrelevant_term = case(
search term contains any $irrelevant_terms => 1,
else 0
);
// Protection safeguards
let $high_profit_protection = case(
$lifetime_blended_profit >= $safeguard_blend_profit => 1,
else 0
);
let $protected_overall = case(
$high_profit_protection = 1 => 1,
$protected_term = 1 => 1,
$blended_roas_protected = 1 => 1,
else 0
);
// Four negation paths: irrelevant, zero-profit waste, efficiency, and ACOS performance
let $irrelevant_candidate = case(
$irrelevant_term = 1 and $lifetime_clicks >= $irrelevant_clicks_threshold => 1,
else 0
);
let $zero_profit_waste_candidate = case(
$lifetime_blended_profit = 0 and $sufficient_data = 1 => 1,
else 0
);
let $efficiency_candidate = case(
$lifetime_blended_profit > 0 and ($lifetime_blended_profit < $blend_profit_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => case(
$sufficient_data = 1 => 1,
else 0
),
else 0
);
let $performance_candidate = case(
$lifetime_blended_profit >= $blend_profit_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => case(
target acos > 0 and $lifetime_blended_acos > target acos * $t_blend_acos_threshold_negate => 1,
else 0
),
else 0
);
let $negation_candidate = case(
$irrelevant_candidate = 1 => 1,
$zero_profit_waste_candidate = 1 => 1,
$efficiency_candidate = 1 => 1,
$performance_candidate = 1 => 1,
else 0
);
// Diagnostic properties
let $reason = case(
$high_profit_protection = 1 => "Protected - too much blended profit to negate",
$protected_term = 1 => "Protected - contains protected keyword",
$blended_roas_protected = 1 => "Protected - blended ROAS above safeguard threshold",
$irrelevant_candidate = 1 => "Contains irrelevant terms, met click threshold",
$irrelevant_term = 1 and $lifetime_clicks < $irrelevant_clicks_threshold => "Contains irrelevant terms, needs more clicks",
$zero_profit_waste_candidate = 1 => "Zero blended profit, met click threshold",
$efficiency_candidate = 1 and $lifetime_clicks >= $allowed_clicks * 1.5 => "Greatly exceeds profit-scaled click limit",
$efficiency_candidate = 1 => "Exceeds profit-scaled click limit",
$performance_candidate = 1 => "Blended ACOS far above target threshold",
$sufficient_data = 0 and $lifetime_spend < $spend_required and $lifetime_clicks < $allowed_clicks => "Insufficient spend and clicks",
$sufficient_data = 0 and $lifetime_spend < $spend_required => "Insufficient spend",
$sufficient_data = 0 => "Insufficient clicks for profit level",
$lifetime_blended_profit > 0 and ($lifetime_blended_profit < $blend_profit_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => "Converting within profit-scaled click limit",
$lifetime_blended_profit >= $blend_profit_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => "Blended ACOS below negation threshold",
else "Zero blended profit, needs more clicks"
);
let $result = case(
$zero_profit_waste_candidate = 1 => "Negate - Zero Profit, High Clicks",
$irrelevant_candidate = 1 => "Negate - Irrelevant Term",
$efficiency_candidate = 1 => case(
$lifetime_blended_profit <= 5.00 => "Negate - Low Profit, High Clicks",
$lifetime_blended_profit >= 15.00 => "Negate - Converting but Inefficient",\
else "Negate - Over Click Limit"
),
$performance_candidate = 1 => "Negate - High Blended ACOS",
$high_profit_protection = 1 or $protected_term = 1 or $blended_roas_protected = 1 => "Protected - No Action",
else "No Action"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $negation_candidate = 1
and $protected_overall = 0
Stop ad spend waste by automatically negating inefficient search terms across all campaigns.
Daily Automation: Create Negative Exact Match using built-in logic
The blueprint uses four distinct evaluation paths to identify wasteful search terms while protecting valuable converters. Zero-order terms are evaluated on click efficiency, converting terms are assessed on both efficiency and ACOS performance, with dynamic thresholds that scale based on conversion history.
/*
=== Core: Search Term Waste Elimination ===
Purpose: Intelligently negate wasteful search terms using efficiency targets and performance analysis.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $clicks_threshold = 20; // CORE: Base click threshold for zero-order terms
let $spend_threshold = 5.00; // CORE: Base spend requirement for zero-order terms
// === Strategy Settings ===
let $orders_min_for_acos_eval = 5; // STRATEGY: Orders required for ACOS-based evaluation
let $clicks_min_for_acos_eval = 100; // STRATEGY: Clicks required for ACOS-based evaluation
let $t_acos_threshold_negate = 400%; // STRATEGY: Negate if ACOS ≥ (Target ACOS × 400%) when min clicks & orders are met [e.g., 30% target = 120% threshold]
// === Advanced Settings ===
let $clicks_scaling_per_order = 20; // ADVANCED: Additional clicks allowed per order [e.g., 2 orders = 20 + (2 × 20) = 60 clicks]
let $spend_scaling_per_order = 5.00; // ADVANCED: Additional spend required per order [e.g., 2 orders = $5 + (2 × $5) = $15 spend]
let $irrelevant_terms = ["NEVER_MATCH"]; // ADVANCED: Aggressively negate search terms containing these keywords (unrelated terms)
let $irrelevant_clicks_threshold = 10; // ADVANCED: Clicks required to negate irrelevant terms (ignores all scaling and spend requirements)
// === Safeguards ===
let $safeguard_orders = 10; // SAFEGUARD: Never negate terms with this many orders or more
let $safeguard_min_roas_ratio = 50%; // SAFEGUARD: Protect terms with ROAS ≥ (Target ROAS × 50%) [e.g., 3.33 target ROAS = 1.67 protection]
let $protected_terms = ["NEVER_MATCH"]; // SAFEGUARD: Never negate search terms containing these keywords (your brand, product names, strategic terms)
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_orders = orders(lifetime);
let $lifetime_clicks = clicks(lifetime);
let $lifetime_spend = spend(lifetime);
let $lifetime_acos = acos(lifetime);
let $lifetime_roas = roas(lifetime);
// Calculate scaled thresholds based on order history
let $allowed_clicks = $clicks_threshold + ($lifetime_orders * $clicks_scaling_per_order);
let $spend_required = $spend_threshold + ($lifetime_orders * $spend_scaling_per_order);
// Data sufficiency check (both clicks and spend)
let $sufficient_data = case(
$lifetime_clicks >= $allowed_clicks and $lifetime_spend >= $spend_required => 1,
else 0
);
// Calculate efficiency for converting terms\
let $actual_clicks_per_order = case(
$lifetime_orders > 0 => $lifetime_clicks / $lifetime_orders,
else 999 // Treat zero-order terms as infinitely inefficient
);
// ROAS-based protection calculation
let $target_roas = case(
target acos > 0 => 1 / target acos,
else 0
);
let $roas_protection_threshold = case(
$target_roas > 0 => $target_roas * $safeguard_min_roas_ratio,
else 0
);
let $roas_protected = case(
$lifetime_orders > 0 and $target_roas > 0 and $lifetime_roas >= $roas_protection_threshold => 1,
else 0
);
// Search term relevance analysis
let $protected_term = case(
search term contains any $protected_terms => 1,
else 0
);
let $irrelevant_term = case(
search term contains any $irrelevant_terms => 1,
else 0
);
// Protection safeguards
let $high_order_protection = case(
$lifetime_orders >= $safeguard_orders => 1,
else 0
);
let $protected_overall = case(
$high_order_protection = 1 => 1,
$protected_term = 1 => 1,
$roas_protected = 1 => 1,
else 0
);
// Four negation paths: irrelevant, zero-order waste, efficiency, and ACOS performance
let $irrelevant_candidate = case(
$irrelevant_term = 1 and $lifetime_clicks >= $irrelevant_clicks_threshold => 1,
else 0
);
let $zero_order_waste_candidate = case(
$lifetime_orders = 0 and $sufficient_data = 1 => 1,
else 0
);
let $efficiency_candidate = case(
$lifetime_orders > 0 and ($lifetime_orders < $orders_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => case(
$actual_clicks_per_order > $clicks_scaling_per_order and $sufficient_data = 1 => 1,
else 0
),
else 0
);
let $performance_candidate = case(
$lifetime_orders >= $orders_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => case(
target acos > 0 and $lifetime_acos > target acos * $t_acos_threshold_negate => 1,
else 0
),
else 0
);
let $negation_candidate = case(
$irrelevant_candidate = 1 => 1,
$zero_order_waste_candidate = 1 => 1,
$efficiency_candidate = 1 => 1,
$performance_candidate = 1 => 1,
else 0
);
// Diagnostic properties
let $reason = case(
$high_order_protection = 1 => "Protected - too many orders to negate",
$protected_term = 1 => "Protected - contains protected keyword",
$roas_protected = 1 => "Protected - ROAS above safeguard threshold",
$irrelevant_candidate = 1 => "Contains irrelevant terms, met click threshold",
$irrelevant_term = 1 and $lifetime_clicks < $irrelevant_clicks_threshold => "Contains irrelevant terms, needs more clicks",
$zero_order_waste_candidate = 1 => "Zero orders, met click threshold",
$efficiency_candidate = 1 and $actual_clicks_per_order >= $clicks_scaling_per_order * 2 => "Greatly exceeds click-per-order limit",
$efficiency_candidate = 1 => "Exceeds click-per-order limit",
$performance_candidate = 1 => "ACOS far above target threshold",
$sufficient_data = 0 and $lifetime_spend < $spend_required and $lifetime_clicks < $allowed_clicks => "Insufficient spend and clicks",
$sufficient_data = 0 and $lifetime_spend < $spend_required => "Insufficient spend",
$sufficient_data = 0 => "Insufficient clicks for order level",
$lifetime_orders > 0 and ($lifetime_orders < $orders_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => "Converting within click-per-order limit",
$lifetime_orders >= $orders_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => "ACOS below negation threshold",
else "Zero orders, needs more clicks"
);
let $result = case(
$zero_order_waste_candidate = 1 => "Negate - Zero Orders, High Clicks",
$irrelevant_candidate = 1 => "Negate - Irrelevant Term",
$efficiency_candidate = 1 => case(
$lifetime_orders = 1 => "Negate - Single Order, High Clicks",
$lifetime_orders >= 2 => "Negate - Converting but Inefficient",
else "Negate - Over Click Limit"
),
$performance_candidate = 1 => "Negate - High ACOS (Converting Well)",
$high_order_protection = 1 or $protected_term = 1 or $roas_protected = 1 => "Protected - No Action",
else "No Action"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $negation_candidate = 1
and $protected_overall = 0
/*
=== Core: Search Term Waste Elimination ===
Purpose: Intelligently negate wasteful search terms using efficiency targets and performance analysis.
Recommended: Create Negative Exact Match | Daily
*/
// === Core Settings ===
let $clicks_threshold = 20; // CORE: Base click threshold for zero-order terms
let $spend_threshold = 5.00; // CORE: Base spend requirement for zero-order terms
// === Strategy Settings ===
let $orders_min_for_acos_eval = 5; // STRATEGY: Orders required for ACOS-based evaluation
let $clicks_min_for_acos_eval = 100; // STRATEGY: Clicks required for ACOS-based evaluation
let $t_acos_threshold_negate = 400%; // STRATEGY: Negate if ACOS ≥ (Target ACOS × 400%) when min clicks & orders are met [e.g., 30% target = 120% threshold]
// === Advanced Settings ===
let $clicks_scaling_per_order = 20; // ADVANCED: Additional clicks allowed per order [e.g., 2 orders = 20 + (2 × 20) = 60 clicks]
let $spend_scaling_per_order = 5.00; // ADVANCED: Additional spend required per order [e.g., 2 orders = $5 + (2 × $5) = $15 spend]
let $irrelevant_terms = ["NEVER_MATCH"]; // ADVANCED: Aggressively negate search terms containing these keywords (unrelated terms)
let $irrelevant_clicks_threshold = 10; // ADVANCED: Clicks required to negate irrelevant terms (ignores all scaling and spend requirements)
// === Safeguards ===
let $safeguard_orders = 10; // SAFEGUARD: Never negate terms with this many orders or more
let $safeguard_min_roas_ratio = 50%; // SAFEGUARD: Protect terms with ROAS ≥ (Target ROAS × 50%) [e.g., 3.33 target ROAS = 1.67 protection]
let $protected_terms = ["NEVER_MATCH"]; // SAFEGUARD: Never negate search terms containing these keywords (your brand, product names, strategic terms)
// === Segment Filters ===
let $include_campaigns = [""]; // FILTER: Apply to all campaigns, or specify terms like ["SP-", "Auto", "Research"]
let $exclude_campaigns = ["NEVER_MATCH"]; // FILTER: Exclude campaigns containing these terms, e.g., ["Brand", "Test", "Archive"]
// ============================================================================
// === Blueprint Logic ===
// ============================================================================
// Advanced logic below - modify carefully
// Pre-calculate performance metrics
let $lifetime_orders = orders(lifetime);
let $lifetime_clicks = clicks(lifetime);
let $lifetime_spend = spend(lifetime);
let $lifetime_acos = acos(lifetime);
let $lifetime_roas = roas(lifetime);
// Calculate scaled thresholds based on order history
let $allowed_clicks = $clicks_threshold + ($lifetime_orders * $clicks_scaling_per_order);
let $spend_required = $spend_threshold + ($lifetime_orders * $spend_scaling_per_order);
// Data sufficiency check (both clicks and spend)
let $sufficient_data = case(
$lifetime_clicks >= $allowed_clicks and $lifetime_spend >= $spend_required => 1,
else 0
);
// Calculate efficiency for converting terms\
let $actual_clicks_per_order = case(
$lifetime_orders > 0 => $lifetime_clicks / $lifetime_orders,
else 999 // Treat zero-order terms as infinitely inefficient
);
// ROAS-based protection calculation
let $target_roas = case(
target acos > 0 => 1 / target acos,
else 0
);
let $roas_protection_threshold = case(
$target_roas > 0 => $target_roas * $safeguard_min_roas_ratio,
else 0
);
let $roas_protected = case(
$lifetime_orders > 0 and $target_roas > 0 and $lifetime_roas >= $roas_protection_threshold => 1,
else 0
);
// Search term relevance analysis
let $protected_term = case(
search term contains any $protected_terms => 1,
else 0
);
let $irrelevant_term = case(
search term contains any $irrelevant_terms => 1,
else 0
);
// Protection safeguards
let $high_order_protection = case(
$lifetime_orders >= $safeguard_orders => 1,
else 0
);
let $protected_overall = case(
$high_order_protection = 1 => 1,
$protected_term = 1 => 1,
$roas_protected = 1 => 1,
else 0
);
// Four negation paths: irrelevant, zero-order waste, efficiency, and ACOS performance
let $irrelevant_candidate = case(
$irrelevant_term = 1 and $lifetime_clicks >= $irrelevant_clicks_threshold => 1,
else 0
);
let $zero_order_waste_candidate = case(
$lifetime_orders = 0 and $sufficient_data = 1 => 1,
else 0
);
let $efficiency_candidate = case(
$lifetime_orders > 0 and ($lifetime_orders < $orders_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => case(
$actual_clicks_per_order > $clicks_scaling_per_order and $sufficient_data = 1 => 1,
else 0
),
else 0
);
let $performance_candidate = case(
$lifetime_orders >= $orders_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => case(
target acos > 0 and $lifetime_acos > target acos * $t_acos_threshold_negate => 1,
else 0
),
else 0
);
let $negation_candidate = case(
$irrelevant_candidate = 1 => 1,
$zero_order_waste_candidate = 1 => 1,
$efficiency_candidate = 1 => 1,
$performance_candidate = 1 => 1,
else 0
);
// Diagnostic properties
let $reason = case(
$high_order_protection = 1 => "Protected - too many orders to negate",
$protected_term = 1 => "Protected - contains protected keyword",
$roas_protected = 1 => "Protected - ROAS above safeguard threshold",
$irrelevant_candidate = 1 => "Contains irrelevant terms, met click threshold",
$irrelevant_term = 1 and $lifetime_clicks < $irrelevant_clicks_threshold => "Contains irrelevant terms, needs more clicks",
$zero_order_waste_candidate = 1 => "Zero orders, met click threshold",
$efficiency_candidate = 1 and $actual_clicks_per_order >= $clicks_scaling_per_order * 2 => "Greatly exceeds click-per-order limit",
$efficiency_candidate = 1 => "Exceeds click-per-order limit",
$performance_candidate = 1 => "ACOS far above target threshold",
$sufficient_data = 0 and $lifetime_spend < $spend_required and $lifetime_clicks < $allowed_clicks => "Insufficient spend and clicks",
$sufficient_data = 0 and $lifetime_spend < $spend_required => "Insufficient spend",
$sufficient_data = 0 => "Insufficient clicks for order level",
$lifetime_orders > 0 and ($lifetime_orders < $orders_min_for_acos_eval or $lifetime_clicks < $clicks_min_for_acos_eval) => "Converting within click-per-order limit",
$lifetime_orders >= $orders_min_for_acos_eval and $lifetime_clicks >= $clicks_min_for_acos_eval => "ACOS below negation threshold",
else "Zero orders, needs more clicks"
);
let $result = case(
$zero_order_waste_candidate = 1 => "Negate - Zero Orders, High Clicks",
$irrelevant_candidate = 1 => "Negate - Irrelevant Term",
$efficiency_candidate = 1 => case(
$lifetime_orders = 1 => "Negate - Single Order, High Clicks",
$lifetime_orders >= 2 => "Negate - Converting but Inefficient",
else "Negate - Over Click Limit"
),
$performance_candidate = 1 => "Negate - High ACOS (Converting Well)",
$high_order_protection = 1 or $protected_term = 1 or $roas_protected = 1 => "Protected - No Action",
else "No Action"
);
// === Final Filter ===
negated = false
and (campaign name contains any $include_campaigns)
and (campaign name does not contain any $exclude_campaigns)
and $negation_candidate = 1
and $protected_overall = 0
© Merch Jar LLC