The script below will help you do just that. I am assuming that many of your optimizations are based on cost per conversion as well as the current position on the page. Now we can start to put together a generic script for these optimizations.
The script starts with a CAMP_LIST variable that holds all the campaign names and their rules. You can add as many campaigns and rules per client as you like.
Take a look and let me know if you have any questions.
Thanks,
Russ
//-----------------------------------
// Unique Bid Updates By Campaign
// Created By: Russ Savage
// FreeAdWordsScripts.com
//-----------------------------------
function main() {
// this is the structure that holds all the bid information about your accounts.
var CAMP_LIST = [
{
'camp_name' : 'camp name 1',
'rules' : [
{
'cpv_min' : 0, 'cpv_max' : 10,
'avg_pos_min' : 2, 'avg_pos_max' : 6,
'bid_change_amt' : 1.1, 'bid_limit' : 10
},
{
'cpv_min' : 10, 'cpv_max' : 20,
'avg_pos_min' : 6, 'avg_pos_max' : 10,
'bid_change_amt' : 1.2, 'bid_limit' : 10
}
]
},
{
'camp_name' : 'camp name 2',
'rules' : [
{
'cpv_min' : 0, 'cpv_max' : 5,
'avg_pos_min' : 3, 'avg_pos_max' : 5,
'bid_change_amt' : .9, 'bid_limit' : .01
},
{
'cpv_min' : 5, 'cpv_max' : 20,
'avg_pos_min' : 5, 'avg_pos_max' : 8,
'bid_change_amt' : 1.2, 'bid_limit' : 10
}
]
}
];
var date_range = 'LAST_7_DAYS';
for (index in CAMP_LIST) {
var camp = CAMP_LIST[index];
var camp_name = camp.camp_name;
var rules = camp.rules;
var kw_iter = AdWordsApp.keywords()
.withCondition("CampaignName CONTAINS_IGNORE_CASE '" + camp_name + "'")
.get();
while(kw_iter.hasNext()) {
var kw = kw_iter.next();
var kw_stats = kw.getStatsFor(date_range);
var conv = kw_stats.getConversions();
if (conv == 0) { continue; } //skip anything with no conversions
var cost = kw_stats.getCost();
var cpv = cost/conv;
var avg_pos = kw_stats.getAveragePosition();
var max_cpc = kw.getMaxCpc();
for(i in rules) {
var r = rules[i];
if(cpv >= r.cpv_min &&
cpv < r.cpv_max &&
avg_pos >= r.avg_pos_min &&
avg_pos < r.avg_pos_max)
{
kw.setMaxCpc(calculate_bid(max_cpc,r.bid_change_amt,r.bid_limit));
break;
}
}
}
}
function calculate_bid(current_bid,perc_to_change,max_min_amt) {
if(perc_to_change >= 1) {
return (current_bid * perc_to_change > max_min_amt) ? max_min_amt : (current_bid * perc_to_change);
} else {
return (current_bid * perc_to_change < max_min_amt) ? max_min_amt : (current_bid * perc_to_change);
}
}
}