Last active
October 26, 2018 11:32
-
-
Save VitUrzh/464be31c5f823440dbbbbc276a91be6d to your computer and use it in GitHub Desktop.
Удержание позиции. Обновление. Быстрее вверх, медленней вниз
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //Чтобы скрипт знал с какими компаниями работать, для них нужно добавить ярлык с именем 'SC' - script control | |
| //Ярлык с именем "maxCPC15" укажет максимальное значение ставки. В данном случае ставка равна 15 | |
| //ярлык targetPosition2.4 указывает, что надо удерживать среднюю позиция 2.4 | |
| // Допустимое отклонение для средней позиции. Т.е. если допустимое отклонение = 0.1 а целевая позиция = 2, то скрипт не затронет ключи с позицией 1.9 и 2.1. | |
| var TOLERANCE = 0.2; | |
| // Множитель для изменения ставок. Т.е. если он равно 1.05 то ставки опустятся или поднимутся на 5%. | |
| // На повышение обычно множитель больше, так как важнее быть выше, чем ниже | |
| var BID_ADJUSTMENT_COEFFICIENT_up = 1.035; | |
| var BID_ADJUSTMENT_COEFFICIENT_down = 1.025; | |
| //не изменять ставку, если за выбранный период времени не было более IMPRESSIONS показов | |
| var IMPRESSIONS = 2; | |
| //Откуда брать максимальную цену | |
| //1 - цена по умолчанию, задается ниже | |
| //2 - цена из ярлыка | |
| //3 - цена из группы | |
| var cpcPlace = 2; | |
| //максимально возможная ставка по умолчанию в валюте аккаунта | |
| var maxCPC = 15.00; | |
| // Повышающий коэффициент. Т.е. если он равен 1.05 то изменение составит 5%. | |
| // задается на случай сильной волатильности стоимости клика | |
| var COEFFICIENT = 1.15; | |
| // Период, за который считаем статистику | |
| // Если установить маленький промежуток времени, то у фраз с малым количеством показов будут возникать проблемы, когда одну неделю есть показы а другую нет | |
| // TODAY, YESTERDAY, LAST_7_DAYS, THIS_WEEK_SUN_TODAY, LAST_WEEK, LAST_14_DAYS, LAST_30_DAYS, LAST_BUSINESS_WEEK, LAST_WEEK_SUN_SAT, THIS_MONTH, LAST_MONTH, ALL_TIME | |
| var PERIOD = "LAST_7_DAYS"; | |
| function main() { | |
| var campaignsWithPosition = AdWordsApp.campaigns().withCondition("LabelNames CONTAINS_ANY ['SC']").get(); | |
| while (campaignsWithPosition.hasNext()) { | |
| var campaign = campaignsWithPosition.next(); | |
| if(campaign.isEnabled()){ | |
| var targetPositionLabel = campaign.labels().withCondition("LabelName STARTS_WITH_IGNORE_CASE 'targetPosition'").get().next().getName(); | |
| var targetPosition = parseFloat(targetPositionLabel.replace(/[^\d.-]/g, '')); | |
| if(cpcPlace == 2){ | |
| var maxCpcLabel = campaign.labels().withCondition("LabelName STARTS_WITH_IGNORE_CASE 'maxCPC'").get().next().getName(); | |
| var maxCPC = parseFloat(maxCpcLabel.replace(/[^\d.-]/g, '')); | |
| } | |
| Logger.log(campaign.getName() + ' - target posinion: ' + targetPosition); | |
| raiseKeywordBids(campaign, targetPosition, maxCPC); | |
| lowerKeywordBids(campaign, targetPosition, maxCPC); | |
| TopOfPageKeywordBids(campaign, maxCPC); | |
| } | |
| } | |
| } | |
| function raiseKeywordBids(campaign, targetPosition, maxCPC) { | |
| var keywordsToRaise = campaign.keywords() | |
| .withCondition("Status = ENABLED") | |
| .withCondition("AdGroupStatus = ENABLED") | |
| .withCondition("AveragePosition > " + (targetPosition + TOLERANCE)) | |
| //.withCondition("Impressions > " + IMPRESSIONS) | |
| //.withCondition("Ctr > 0.01") //Note that Ctr is returned in 0..1 range, so 5% Ctr is represented as 0.05. | |
| .orderBy("AveragePosition ASC") | |
| .forDateRange(PERIOD) | |
| .get(); | |
| while (keywordsToRaise.hasNext()) { | |
| var keyword = keywordsToRaise.next(); | |
| if(cpcPlace == 3){ | |
| maxCPC = parseFloat(keyword.getAdGroup().bidding().getCpc()); | |
| } | |
| var NewCost = keyword.getMaxCpc() * BID_ADJUSTMENT_COEFFICIENT_up; | |
| //узнаем минимальную стоимость, чтобы показываться над результатами поиска | |
| var TopOfPageCpc = keyword.getTopOfPageCpc(); | |
| //добавляем коэффециент | |
| TopOfPageCpc = (TopOfPageCpc * COEFFICIENT); | |
| //если расчетная ставка оказалась ниже необходимой для показа над поиском, | |
| //то берем ставку необходимую для показа над поиском | |
| if (NewCost < TopOfPageCpc){ | |
| NewCost = TopOfPageCpc; | |
| } | |
| //если конечная цена получается намного меньше максимальной цены, то повышаем цену. | |
| //Например максимальная цена 80р, фактическая получается 2р, повышаем ее до 20, чтобы запас был. | |
| //чтобы не мелочиться | |
| if((maxCPC / NewCost) > 4){ | |
| NewCost = maxCPC / 4; | |
| } | |
| //ставка не должна быть больше заявленной нами | |
| if (NewCost > maxCPC){ | |
| NewCost = maxCPC; | |
| } | |
| keyword.setMaxCpc(NewCost); | |
| } | |
| } | |
| function lowerKeywordBids(campaign, targetPosition, maxCPC) { | |
| var keywordsToLower = campaign.keywords() | |
| //.withCondition("Ctr > 0.01") | |
| .withCondition("AveragePosition < " + (targetPosition - TOLERANCE)) | |
| .withCondition("Status = ENABLED") | |
| .withCondition("AdGroupStatus = ENABLED") | |
| //.withCondition("Impressions > " + IMPRESSIONS) | |
| .orderBy("AveragePosition DESC") | |
| .forDateRange(PERIOD) | |
| .get(); | |
| while (keywordsToLower.hasNext()) { | |
| var keyword = keywordsToLower.next(); | |
| if(cpcPlace == 3){ | |
| maxCPC = parseFloat(keyword.getAdGroup().bidding().getCpc()); | |
| } | |
| NewCost = (keyword.getMaxCpc() / BID_ADJUSTMENT_COEFFICIENT_down); | |
| //узнаем минимальную стоимость, чтобы показываться над результатами поиска | |
| var TopOfPageCpc = keyword.getTopOfPageCpc(); | |
| //добавляем защитный от скачков цены коэффециент | |
| TopOfPageCpc = (TopOfPageCpc * COEFFICIENT); | |
| //если расчетная ставка оказалась ниже необходимой для показа над поиском, | |
| //то берем ставку необходимую для показа над поиском | |
| if (NewCost < TopOfPageCpc){ | |
| NewCost = TopOfPageCpc; | |
| } | |
| //если конечная цена получается намного меньше максимальной цены, то повышаем цену. | |
| //Например максимальная цена 80р, фактическая получается 2р, повышаем ее до 20, чтобы запас был. | |
| if((maxCPC / NewCost) > 4){ | |
| NewCost = maxCPC / 4; | |
| } | |
| //ставка не должна быть больше заявленной нами | |
| if (NewCost > maxCPC){ | |
| NewCost = maxCPC; | |
| } | |
| keyword.setMaxCpc(NewCost); | |
| } | |
| } | |
| function TopOfPageKeywordBids(campaign, maxCPC) { | |
| var keywordsToLower = campaign.keywords() | |
| .withCondition("Impressions < 1") | |
| .withCondition("Status = ENABLED") | |
| .withCondition("AdGroupStatus = ENABLED") | |
| .forDateRange(PERIOD) | |
| .get(); | |
| while (keywordsToLower.hasNext()) { | |
| var keyword = keywordsToLower.next(); | |
| if(cpcPlace == 3){ | |
| maxCPC = parseFloat(keyword.getAdGroup().bidding().getCpc()); | |
| } | |
| //узнаем минимальную стоимость, чтобы показываться над результатами поиска | |
| var TopOfPageCpc = keyword.getTopOfPageCpc(); | |
| //добавляем защитный от скачков цены коэффециент | |
| TopOfPageCpc = (TopOfPageCpc * COEFFICIENT); | |
| NewCost = TopOfPageCpc; | |
| //если конечная цена получается намного меньше максимальной цены, то повышаем цену. | |
| //Например максимальная цена 80р, фактическая получается 2р, повышаем ее до 20, чтобы запас был. | |
| if((maxCPC / NewCost) > 4){ | |
| NewCost = maxCPC / 4; | |
| } | |
| //ставка не должна быть больше заявленной нами | |
| if (NewCost > maxCPC){ | |
| NewCost = maxCPC; | |
| } | |
| keyword.setMaxCpc(NewCost); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment