Presupuestos flexibles para una sola cuenta

Ícono de herramientas

Google Ads te permite establecer un importe de presupuesto diario para cada campaña. Sin embargo, algunas iniciativas de marketing tendrán un costo fijo asociado; por ejemplo, “Quiero invertir USD 5,000 antes de nuestra venta de otoño”. La estrategia de ofertas te brinda cierto control sobre cómo se invierte el presupuesto diario, pero no sobre cómo se consume durante la campaña.

Por ejemplo, si queremos invertir solo USD 5,000 para anunciar nuestras ofertas de otoño y publicar anuncios durante 10 días, podríamos establecer un presupuesto diario de USD 500 para utilizar todo el presupuesto. Sin embargo, se supone que gastaremos todo el importe cada día Y queremos gastarlo de manera uniforme. No es posible indicarle a Google Ads que desea invertir la mayor parte de su presupuesto durante los últimos días.

Esta secuencia de comandos ajustará el presupuesto de tu campaña de forma dinámica todos los días con un esquema de distribución de presupuesto personalizado.

Cómo funciona

Prueba estrategias de presupuesto

La secuencia de comandos incluye código de prueba para simular los efectos de ejecutarla durante varios días. Esto te da una mejor idea de lo que puede suceder cuando la secuencia de comandos está programada para ejecutarse a diario durante un período determinado.

De forma predeterminada, la secuencia de comandos simula una distribución del presupuesto uniforme de $500 invertidos durante 10 días.

function main() {
  testBudgetStrategy(calculateBudgetEvenly, 10, 500);
  // setNewBudget(calculateBudgetEvenly, CAMPAIGN_NAME, TOTAL_BUDGET, START_DATE, END_DATE);
}

La llamada a la función setNewBudget está marcada como comentario, lo que indica que solo ejecutará el código de prueba. Este es el resultado del ejemplo:

Day 1.0 of 10.0, new budget 50.0, cost so far 0.0
Day 2.0 of 10.0, new budget 50.0, cost so far 50.0
Day 3.0 of 10.0, new budget 50.0, cost so far 100.0
Day 4.0 of 10.0, new budget 50.0, cost so far 150.0
Day 5.0 of 10.0, new budget 50.0, cost so far 200.0
Day 6.0 of 10.0, new budget 50.0, cost so far 250.0
Day 7.0 of 10.0, new budget 50.0, cost so far 300.0
Day 8.0 of 10.0, new budget 50.0, cost so far 350.0
Day 9.0 of 10.0, new budget 50.0, cost so far 400.0
Day 10.0 of 10.0, new budget 50.0, cost so far 450.0
Day 11.0 of 10.0, new budget 0.0, cost so far 500.0

Cada día, la secuencia de comandos calcula un presupuesto nuevo para asegurarse de que la inversión del presupuesto se distribuya de manera uniforme. Cuando se alcanza el límite de presupuesto asignado, este se establece en cero, lo que detiene el gasto.

Puedes cambiar la estrategia de presupuesto usada si cambias qué función se usa o si modificas la función en sí. La secuencia de comandos incluye dos estrategias ya compiladas: calculateBudgetEvenly y calculateBudgetWeighted. Para establecer una estrategia de presupuesto de prueba ponderado, cambia testBudgetStrategy de la siguiente manera:

testBudgetStrategy(calculateBudgetWeighted, 10, 500);

Haz clic en Preview y verifica el resultado del registrador. Ten en cuenta que esta estrategia de presupuesto asigna menos presupuesto al principio del período y más durante los últimos días.

Puedes usar este método de prueba a fin de simular cambios en las funciones de cálculo de presupuesto y probar tu propio enfoque para distribuir un presupuesto.

Asignación de un presupuesto

La estrategia de presupuesto calculateBudgetWeighted se implementa mediante la siguiente función:

function calculateBudgetWeighted(costSoFar, totalBudget, daysSoFar, totalDays) {
  const daysRemaining = totalDays - daysSoFar;
  const budgetRemaining = totalBudget - costSoFar;
  if (daysRemaining <= 0) {
    return budgetRemaining;
  } else {
    return budgetRemaining / (2 * daysRemaining - 1) ;
  }
}

Esta función toma los siguientes argumentos:

costSoFar
Costo acumulado de la campaña desde el START_DATE hasta el día de hoy.
totalBudget
Se asignó la inversión de START_DATE a END_DATE.
daysSoFar
Días transcurridos desde START_DATE hasta hoy.
totalDays
Cantidad total de días entre el START_DATE y el END_DATE.

Puedes escribir tu propia función, siempre que tome estos argumentos. Con estos valores, puedes comparar cuánto dinero gastaste hasta el momento con cuánto gastar en total y determinar en qué momento te encuentras dentro del cronograma de todo el presupuesto.

En particular, esta estrategia de presupuesto determina cuánto presupuesto queda (totalBudget - costSoFar) y lo divide por el doble de la cantidad de días restantes. Esto pondera la distribución del presupuesto hacia el final de la campaña. Cuando se usa el costo desde START_DATE, también se tienen en cuenta los "días lentos" en los que el presupuesto establecido no se invierte por completo.

Elaboración de presupuestos reales

Una vez que estés conforme con tu estrategia de presupuesto, debes hacer algunos cambios antes de programar esta secuencia de comandos para que se ejecute a diario.

Primero, actualiza las constantes que se encuentran en la parte superior del archivo:

  • START_DATE: Establece esto al comienzo de tu estrategia de presupuesto. Debe ser la fecha actual o una anterior.
  • END_DATE: Establece esto para el último día en el que deseas publicar anuncios con este presupuesto.
  • TOTAL_BUDGET: Es el importe total que intentas invertir. Este valor se indica en la moneda de la cuenta y es posible que se supere según el momento para el que esté programada la ejecución de la secuencia de comandos.
  • CAMPAIGN_NAME: Es el nombre de la campaña a la que se aplicará la estrategia de presupuesto.

A continuación, inhabilita la prueba y habilita la lógica para cambiar el presupuesto:

function main() {
  // testBudgetStrategy(calculateBudgetEvenly, 10, 500);
  setNewBudget(calculateBudgetWeighted, CAMPAIGN_NAME, TOTAL_BUDGET, START_DATE, END_DATE);
}

Programación

Programa esta secuencia de comandos para que se ejecute diariamente, a la medianoche de la zona horaria local o poco después, de modo que ajuste, en la medida de lo posible, el presupuesto del día siguiente. Sin embargo, ten en cuenta que los datos de informes recuperados, como el costo, podrían retrasarse alrededor de 3 horas, por lo que el parámetro costSoFar podría hacer referencia al total del día anterior para una secuencia de comandos programada para ejecutarse después de la medianoche.

Configuración

  • Haz clic en el siguiente botón para crear la secuencia de comandos en tu cuenta de Google Ads.

    Instala la plantilla de secuencia de comandos

  • Guarda la secuencia de comandos y haz clic en el botón Vista previa. De forma predeterminada, esta secuencia de comandos simula una estrategia de presupuesto con USD 500 durante 10 días. El resultado del registrador refleja el día que se simula, el presupuesto asignado para ese día y el importe total invertido hasta la fecha.

Código fuente

// 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 Flexible Budgets
 *
 * @overview The Flexible budgets script dynamically adjusts campaign budget for
 *     an advertiser account with a custom budget distribution scheme on a daily
 *     basis. See
 *     https://developers.google.com/google-ads/scripts/docs/solutions/flexible-budgets
 *     for more details.
 *
 * @author Google Ads Scripts Team [adwords-scripts@googlegroups.com]
 *
 * @version 2.1
 *
 * @changelog
 * - version 2.1
 *   - Split into info, config, and code.
 * - version 2.0
 *   - Updated to use new Google Ads scripts features.
 * - version 1.0.3
 *   - Add support for video and shopping campaigns.
 * - version 1.0.2
 *   - Use setAmount on the budget instead of campaign.setBudget.
 * - version 1.0.1
 *   - Improvements to time zone handling.
 * - version 1.0
 *   - Released initial version.
 */

/**
 * Configuration to be used for the Flexible Budgets script.
 */

CONFIG = {
  'total_budget': 500,
  'campaign_name': 'Special Promotion',
  'start_date': 'November 1, 2021 0:00:00 -0500',
  'end_date': 'December 1, 2021 0:00:00 -0500'
};

const TOTAL_BUDGET = CONFIG.total_budget;
const CAMPAIGN_NAME = CONFIG.campaign_name;
const START_DATE = new Date(CONFIG.start_date);
const END_DATE = new Date(CONFIG.end_date);

function main() {
  testBudgetStrategy(calculateBudgetEvenly, 10, 500);
//  setNewBudget(calculateBudgetEvenly, CAMPAIGN_NAME, TOTAL_BUDGET,
//      START_DATE, END_DATE);
}

function setNewBudget(budgetFunction, campaignName, totalBudget, start, end) {
  const today = new Date();
  if (today < start) {
    console.log('Not ready to set budget yet');
    return;
  }
  const campaign = getCampaign(campaignName);
  const costSoFar = campaign.getStatsFor(
        getDateStringInTimeZone('yyyyMMdd', start),
        getDateStringInTimeZone('yyyyMMdd', end)).getCost();
  const daysSoFar = datediff(start, today);
  const totalDays = datediff(start, end);
  const newBudget = budgetFunction(costSoFar, totalBudget, daysSoFar,
                                   totalDays);
  campaign.getBudget().setAmount(newBudget);
}

function calculateBudgetEvenly(costSoFar, totalBudget, daysSoFar, totalDays) {
  const daysRemaining = totalDays - daysSoFar;
  const budgetRemaining = totalBudget - costSoFar;
  if (daysRemaining <= 0) {
    return budgetRemaining;
  } else {
    return budgetRemaining / daysRemaining;
  }
}

function calculateBudgetWeighted(costSoFar, totalBudget, daysSoFar,
    totalDays) {
  const daysRemaining = totalDays - daysSoFar;
  const budgetRemaining = totalBudget - costSoFar;
  if (daysRemaining <= 0) {
    return budgetRemaining;
  } else {
    return budgetRemaining / (2 * daysRemaining - 1);
  }
}

function testBudgetStrategy(budgetFunc, totalDays, totalBudget) {
  let daysSoFar = 0;
  let costSoFar = 0;
  while (daysSoFar <= totalDays + 2) {
    const newBudget = budgetFunc(costSoFar, totalBudget, daysSoFar, totalDays);
    console.log(`Day ${daysSoFar + 1} of ${totalDays}, new budget ` +
                `${newBudget}, cost so far ${costSoFar}`);
    costSoFar += newBudget;
    daysSoFar += 1;
  }
}

/**
 * Returns number of days between two dates, rounded up to nearest whole day.
 */
function datediff(from, to) {
  const millisPerDay = 1000 * 60 * 60 * 24;
  return Math.ceil((to - from) / millisPerDay);
}

function getDateStringInTimeZone(format, date, timeZone) {
  date = date || new Date();
  timeZone = timeZone || AdsApp.currentAccount().getTimeZone();
  return Utilities.formatDate(date, timeZone, format);
}

/**
 * Finds a campaign by name, whether it is a regular, video, or shopping
 * campaign, by trying all in sequence until it finds one.
 *
 * @param {string} campaignName The campaign name to find.
 * @return {Object} The campaign found, or null if none was found.
 */
function getCampaign(campaignName) {
  const selectors = [AdsApp.campaigns(), AdsApp.videoCampaigns(),
      AdsApp.shoppingCampaigns()];
  for (const selector of selectors) {
    const campaignIter = selector
        .withCondition(`CampaignName = "${campaignName}"`)
        .get();
    if (campaignIter.hasNext()) {
      return campaignIter.next();
    }
  }
  throw new Error(`Could not find specified campaign: ${campaignName}`);
}