Merch Jar
Log in Start free trial
← Template Library Download Template ↗

Automation template

Seasonal Bid Tuner

Set bids to historical CPC from the same seasonal period when ACOS performance was within safe limits.

Ready to use Merch Jar workflow
Version
1.1
Type
ca77192dee2c581d08f8e97bee971076
Last updated
2026-01-15T00:00:00.000Z
Active
No

Download this template

Description

Purpose

Adjusts bids based on proven historical CPC from the same seasonal period last year.

This Template is for:

✓ 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

Key Features

  • Historical seasonal intelligence uses proven CPC from same period last year when performance was acceptable
  • Safety caps prevent extreme bid changes with both percentage limits (50% max change) and absolute maximums
  • Forward-looking seasonal window captures 45 days starting from one year ago to identify emerging trends
  • Performance qualification ensures only keywords with safe historical ACOS are adjusted

Configuration Guidance

  • Historical Period: Default 45-day window (1 year ago forward) captures seasonal patterns with forward context. Adjust to 30 days for tighter seasonal matching or 60 days for broader trend capture.
  • ACOS Threshold: 125% default means historical ACOS must have been within 125% of Target ACOS. Lower to 110% for stricter safety or increase to 150% to include more keywords.
  • Bid Safety Caps: 50% maximum change prevents dramatic adjustments. The $2.00 absolute maximum should be adjusted based on your typical bid range - set to 2-3x your average successful bid.
  • Timing: Run this manually 2-4 weeks before your peak season starts. Review diagnostic properties (historical CPC, ACOS, order counts) before applying to verify data quality.

Manual Execution: Change Bid: Set ($) using $suggested_seasonal_bid

How it works

How the Logic Works

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.

Key Technical Concepts

Forward-Looking Seasonal Window

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.

Performance Qualification Gates

Multiple requirements must be met before a bid adjustment is suggested:

  • Minimum order threshold (2 orders) ensures statistical reliability
  • Historical ACOS must be within 125% of Target ACOS (configurable)
  • Historical CPC must exist and be positive
  • Target ACOS must be configured

This prevents adjusting bids based on insufficient data or poor historical performance.

Dual Safety Cap System

Two independent caps protect against extreme changes:

  • Percentage cap: Limits change to 50% increase or decrease from current bid
  • Absolute cap: Never exceeds $2.00 regardless of historical CPC

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.

Safety Factor Application

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.

Configuration Deep Dive

Historical Period Adjustment ($historical_period)

The default 320d..365d setting (45-day window starting 1 year ago) works for most seasonal patterns. Consider adjusting based on your business:

  • 335d..365d (30 days): Tighter seasonal matching for sharp, well-defined seasons (e.g., Black Friday week)
  • 305d..365d (60 days): Broader trend capture for gradual seasonal buildups (e.g., holiday shopping season)
  • 290d..365d (75 days): Extended seasonal analysis for long-tail seasonal effects

Shorter windows provide more precise seasonal matching but require concentrated historical activity. Longer windows are more forgiving for keywords with sporadic conversion patterns.

ACOS Threshold Tuning ($acos_threshold)

The 125% default means historical ACOS ≤ 1.25 × Target ACOS qualifies:

  • 110-115%: Strict - only uses periods that were very close to target (safest, fewer keywords adjusted)
  • 125-130%: Balanced - allows some variance while maintaining safety (recommended default)
  • 140-150%: Permissive - includes more keywords but with higher historical ACOS (higher risk)

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.

Bid Cap Configuration

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.

Safety Factor Strategy ($bid_safety_factor)

  • 95-98%: Conservative approach - bid below historical levels to guard against market changes
  • 100%: Neutral - match historical CPC exactly
  • 102-105%: Aggressive - bid above historical levels if you expect increased competition or want to capture more volume

Diagnostic Property Interpretation

Historical Data Diagnostics

Four properties show the historical data used for calculations:

  • $historical_cpc_value: The CPC from same season last year
  • $historical_acos_value: The ACOS performance during that period
  • $historical_orders_count: Number of orders to validate data reliability
  • $calculated_bid_value: Historical CPC × safety factor (before caps applied)

Compare $calculated_bid_value to $suggested_seasonal_bid to see when safety caps activated.

Bid Change Metrics

  • $bid_change_amount: Dollar difference between suggested and current bid
  • $bid_change_percent: Percentage change being proposed

Use these to identify keywords with dramatic suggested changes that may warrant manual review before applying.

$reason Values

  • "No target ACOS set" → Configure Target ACOS before running
  • "Insufficient historical orders" → Less than 2 orders during historical period
  • "No historical CPC data" → Keyword didn't have impressions/clicks during that period
  • "Historical ACOS too high" → Performance during that period exceeded threshold
  • "Bid capped at absolute maximum" → Historical CPC would exceed $2.00 (or configured max)
  • "Bid capped at maximum change percentage" → Change would exceed 50% (or configured limit)
  • "Historical performance acceptable" → Qualified for adjustment, bid calculated from seasonal data

$result Values

  • "No Action - Protected Term" → Contains protected keyword, excluded from changes
  • "No Action - Historical Performance Insufficient" → Failed one or more qualification gates
  • "No Change - Already at Target" → Current bid matches calculated seasonal bid
  • "Bid Increase/Decrease - Maximum Change Cap Applied" → Safety percentage cap limited the adjustment
  • "Bid Set - Absolute Maximum Applied" → Dollar cap limited the adjustment
  • "Bid Increase/Decrease - Using Historical CPC" → Normal adjustment based on seasonal data

Common Performance Patterns

Keywords with High Historical CPC Hit Caps

When $calculated_bid_value is significantly higher than $suggested_seasonal_bid, the safety caps activated. This often indicates:

  • You were in a more competitive bidding position last year
  • Market conditions may have changed (fewer competitors, different strategies)
  • Your current bids are already optimized lower than last year

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 with Low Historical Orders but Good ACOS

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:

  • Lowering $min_orders to 1 if you want to include these (increases variance risk)
  • Leaving them excluded and letting current optimization handle them
  • Manually reviewing if they're strategically important terms

Large Suggested Increases from Low Current Bids

When current bid is $0.25 and suggested is $1.00+, review carefully. This pattern suggests:

  • Keyword was much more valuable last season
  • Current bid may have been lowered due to poor recent performance
  • Seasonal demand may justify the increase

Check current year-to-date performance before applying large increases to ensure the keyword is still relevant.

No Qualified Keywords

If few or no keywords qualify, common causes:

  • First year advertising (no historical data)
  • ACOS threshold too strict for your historical performance
  • Historical period had poor overall performance
  • Minimum order threshold too high for your conversion volume

Adjust thresholds incrementally and review diagnostic properties to understand why keywords are being excluded.

‍

Syntax

/*
=== 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 = 5;                       // CORE: Minimum historical orders required for reliable data
let $acos_threshold = 200%;                // CORE: Only use historical CPC if ACOS ≤ (Target ACOS × 125%) [e.g., 30% target = 37.5% threshold]
 
// === Strategy Settings ===
let $historical_period = 2024-11-29..2024-12-17;       // 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