Bid to Impression Share - Single Account

Bidding icon

Some advertisers want their ads to show up as often as possible in the search results, no matter the cost. Others choose a more modest impression share that costs less but provides sufficient visibility for their ads nonetheless.

Bid To Impression Share script allows you to incrementally reach your impression share goals. The script is looking through your keywords, finds the one most in need of adjustment, and raises or lowers their bids in order to affect how often they show in search results.

Scheduling

The script is considering the last 7 days of statistics. Schedule it to run Weekly.

How it works

The script does two things:

  • First, it finds keywords whose impression share is too low, and increases their bids.
  • Then the script finds all keywords whose Ctr is better than 1% and impression share is too high, and decreases their bids

Note that a single iterator can only fetch 50,000 keywords. Consequently, at most 50,000 bids will be increased, and 50,000 bids will get decreased per script execution.

You should carefully adjust the bid to your account's situation. You may want to keep factors other than just Ctr when deciding to adjust your keywords' bids.

Parameters

Update the following parameters in the script:

  • TARGET_IMPRESSION_SHARE specifies the impression share you intend to achieve.
  • Once the keyword's impression share is within TOLERANCE of TARGET_IMPRESSION_SHARE, its bids are no longer updated. We don't want a keyword's bid to keep changing up and down because its impression share is 49 vs. 51.
  • BID_ADJUSTMENT_COEFFICIENT specifies the multiplier to use when adjusting keyword bids. The larger the multiplier, the more aggressive the bid changes

Setup

  • Create a new script with the source code below.
  • Don't forget to update TARGET_IMPRESSION_SHARE, TOLERANCE, and BID_ADJUSTMENT_COEFFICIENT in the code below.
  • Take a careful look at the conditions used to fetch the keywords.
  • Schedule the script Weekly.

Source code

// Copyright 2015, Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @name Bid To Impression Share
 *
 * @overview The Bid To Impression Share script adjusts your bids and allows you
 *     to steer ads in an advertiser account into a desired impression share in
 *     the search results. See
 *     https://developers.google.com/google-ads/scripts/docs/solutions/bid-to-impression-share
 *     for more details.
 *
 * @author Google Ads Scripts Team [adwords-scripts@googlegroups.com]
 *
 * @version 3.0
 *
 * @changelog
 * - version 3.0
 *   - Updated to use new Google Ads Scripts features.
 * - version 2.0.1
 *   - Fixed logic when determining which keywords to raise and lower.
 * - version 2.0.0
 *   - Refactored to target impression share rather than position.
 * - version 1.0.1
 *   - Refactored to improve readability. Added documentation.
 * - version 1.0
 *   - Released initial version.
 */

// Ad impression share you are trying to achieve, representated as a percentage.
const TARGET_IMPRESSION_SHARE = 0.5;

// Once the keywords fall within TOLERANCE of TARGET_IMPRESSION_SHARE,
// their bids will no longer be adjusted. Represented as a percentage.
const TOLERANCE = 0.05;

// How much to adjust the bids.
const BID_ADJUSTMENT_COEFFICIENT = 1.05;

/**
 * Main function that lowers and raises keywords' CPC to move closer to
 * target impression share.
 */
function main() {
  raiseKeywordBids();
  lowerKeywordBids();
}

/**
 * Increases the CPC of keywords that are below the target impression share.
 */
function raiseKeywordBids() {
  const keywordsToRaise = getKeywordsToRaise();
  for (const keyword of keywordsToRaise) {
    keyword.bidding().setCpc(getIncreasedCpc(keyword.bidding().getCpc()));
  }
 }

/**
 * Decreases the CPC of keywords that are above the target impression share.
 */
function lowerKeywordBids() {
 const keywordsToLower = getKeywordsToLower();
 for (const keyword of keywordsToLower) {
   keyword.bidding().setCpc(getDecreasedCpc(keyword.bidding().getCpc()));
 }
}

/**
 * Increases a given CPC using the bid adjustment coefficient.
 * @param {number} cpc - the CPC to increase
 * @return {number} the new CPC
 */
function getIncreasedCpc(cpc) {
  return cpc * BID_ADJUSTMENT_COEFFICIENT;
}

/**
 * Decreases a given CPC using the bid adjustment coefficient.
 * @param {number} cpc - the CPC to decrease
 * @return {number} the new CPC
 */
function getDecreasedCpc(cpc) {
  return cpc / BID_ADJUSTMENT_COEFFICIENT;
}

/**
 * Gets an iterator of the keywords that need to have their CPC raised.
 * @return {!Iterator} an iterator of the keywords
 */
function getKeywordsToRaise() {
  // Condition to raise bid: Average impression share is worse (less) than
  // target - tolerance
  return AdsApp.keywords()
      .withCondition(`ad_group_criterion.status = ENABLED`)
      .withCondition(
          `metrics.search_impression_share < ${TARGET_IMPRESSION_SHARE - TOLERANCE}`)
      .orderBy(`metrics.search_impression_share ASC`)
      .forDateRange(`LAST_7_DAYS`)
      .get();
}

/**
 * Gets an iterator of the keywords that need to have their CPC lowered.
 * @return {!Iterator} an iterator of the keywords
 */
function getKeywordsToLower() {
  // Conditions to lower bid: Ctr greater than 1% AND
  // average impression share better (greater) than target + tolerance
  return AdsApp.keywords()
      .withCondition(`metrics.ctr > 0.01`)
      .withCondition(
          `metrics.search_impression_share > ${TARGET_IMPRESSION_SHARE + TOLERANCE}`)
      .withCondition(`ad_group_criterion.status = ENABLED`)
      .orderBy(`metrics.search_impression_share DESC`)
      .forDateRange(`LAST_7_DAYS`)
      .get();
}