In order to set up a custom bidding algorithm in the DSP, it must be written in the form of a decision tree using the Sequoia language. Sequoia is a high-level, domain specific language that can be used to write custom predictive bidding models for optimizing bidding based on multiple targeting attributes.
Limitations
Use only allowed keywords, operators and statements. Otherwise, the rules file will not be processed.
Terms
Before writing the algorithm in Sequoia, there are a few key terms to be aware of.
Rule - A rule is a combination of conditions involving targeting attributes (features) that are evaluated against a bid opportunity and if satisfied, corresponding bid_price/bid_multiplier is used in the final bid price calculation.
Feature - A feature is a set of attributes like (domain, viewability etc ) that are supported.
Node - A node defines the point in the decision tree where a rule is evaluated and a bid price or bid multiplier is assigned. A node consists of a rule_name(which uniquely identifies the rule & bid_price/bid_multipler) and specifies a bid_price or bid_multiplier value. Specifying the rule name might help to easily identify which rule got applied during serving time. Like any other language, Sequoia has syntax and comes with supported constructs including: expressions, operators (both relational & logical), and constraints.
Expressions - Sequoia supports if/else and switch expressions.
Operator - Sequoia supports relational, logical, and In operators.
Rules
Rule: <Set of Conditions separated by logical operators>
<Assignment Statements>
Conditions: Feature keywords, operators (logical and relational)
Assignment Statements: set ``bid_price``/``bid_multiplier``, rule_nameMultiple rules can be combined for optimization by combining conditions that are evaluated repeatedly into a single condition by using if or if /else or switch expression statements. This makes reading the decision tree with multiple rules easy for humans as well as machines.
Features
Every decision tree is composed of algorithms for evaluating sets of conditions called features and assigning values based on those evaluations.
A feature consists of three elements: a keyword, a logical operator, and a value that is evaluated.
The keyword identifies a targetable attribute. The following keywords are listed in the Supported Features table.
The relational operator specifies how the platform should evaluate the feature. Sequoia supports the following logical operators: ==, IN, !, >, >=, <, and <=.
The value specifies the value of the targetable attribute.
In the following example, the feature is composed of the user_day keyword, the equals (==) operator, and a value of 28.
if(user_day == 28) {
rule_name = “X1234”;
bid_price = 0.21;
}Supported Features
DSP Field | Keyword | Supported Relational Operators | Valid Values |
|---|---|---|---|
Day of the Week | user_day |
| An integer value between 0 to 6 that represents the day of the week. 0 is Sunday and 6 is Saturday. |
Time of day | user_hour |
| An integer between 0 to 23 that represents the hour of the day. |
Country | pulse_country_id |
| The id is an integer value that is returned in the code field in the DSP API that identifies a country. |
State | pulse_region_id |
| The id is an integer value that is returned in the code field in the DSP API that identifies a state. |
Region | pulse_locality_woeid |
| The id is an integer value that is returned in the woeid field in the DSP API that identifies a region. |
Sub Region | pulse_sub_locality_woeid |
| The id is an integer value that is returned in the woeid field in the DSP API that identifies a sub region. |
Metro Area | pulse_major_metro_area_woeid |
| The id is an integer value that is returned in the woeid field in the DSP API that identifies a metro area. |
DMA | pulse_metro_id |
| The id is an integer value that is returned in the code field in the DSP API that identifies a DMA. |
City | pulse_city_id |
| The id is an integer value that is returned in the code field in the DSP API that identifies a city. |
Zip | postal_code |
| The id is an integer value that is returned in the woeid field in the DSP API that identifies a postal code. |
Domain / App | domain/appname |
| A string that represents the address of the publisher site. For example, sports.yahoo.com. A comma separated list of addresses when used with IN clause like domain IN “address1,address2,address3” |
Ad size | layout |
| An integer that represents the layout |
Ad Position | ad_position |
| An Integer representing the position of the ad. |
Device Type | device_type |
| An integer representing the device type |
Predicted Viewability | viewability |
| A Double value representing the viewability percentage |
Audience | Segment |
| A comma separated list of segment ids enclosed in double quotes Ex: “1234,89653,76542” |
User Day
The user_day feature enables you to evaluate ad placement opportunities based on the day of the week.
The day of the week is specified as an integer value between 0 to 6.
0 - Sunday
1 - Monday
2 - Tuesday
3 - Wednesday
4 - Thursday
5 - Friday
6 - Saturday
The user_day feature accepts five operators.
==
>
>=
<
<=
Using the == operator, you can target consumers on a specific day of the week. For example, if you want to specify a bid price for ads served on Saturday, you could write the following set of rules.
if(user_day == 6) {
rule_name = “A123”;
bid_price = 1.2;
} else {
rule_name = “A124”;
bid_price = 1.1;
}User Hour
The user_hour feature enables you to target ad placement opportunities based on the hour of the day that the ad is served to the consumer.
A user_hour value is an integer between 0 to 23 that represents the hour of the day. The hour specified is always local to the time of the day of the consumer.
The user_hour feature accepts two operators.
==
>
>=
<
<=
Geo Related Features
Use the Geography Targeting Trafficking API endpoint to obtain the correct ID (code or woeid field integer value) in order to target specific geographical locations with BYOA.
Supported Features
Level Field from Geography Targeting API | BYOA Rule Parameter | Field to use from Geography Targeting API |
|---|---|---|
Zip | postal_code | woeid |
Country | pulse_country_id | code |
State | pulse_region_id | code |
Region | pulse_locality_woeid | woeid |
Sub Region | pulse_sub_locality_woeid | woeid |
Metro Area | pulse_major_metro_area_woeid | woeid |
DMA | pulse_metro_id | code |
City | pulse_city_id | code |
For example, New York can refer to a city or a state, each having its own ID.
if(postal_code == 12784282) {
rule_name = “A123”;
bid_price = 1.4;
}
else if(pulse_metro_id == 501) {
rule_name = "M60629";
bid_multiplier = 1.05;
}
else if(pulse_city_id == 57) {
rule_name = "M60630";
bid_multiplier = 1.05;
}
else if(pulse_country_id == 840) {
rule_name = "M60629";
bid_multiplier = 1.05;
}Domain/Appname
The domain feature enables you to target ad placement opportunities based on the web page address serving the ad.
A domain value is a string that represents the address of the publisher site. For example, sports.yahoo.com.
The domain feature accepts two operators.
==
IN (to support single or multiple domain values)
Using the == operator, you can set bid prices for ads served to consumers in a specific domain. For example, if you want to specify a bid price for ads served to a domain, you could write the following set of rules.
if(domain ==“sports.yahoo.com”) {
rule_name = “A123”;
bid_price = 1.4;
} else {
rule_name = “A124”;
bid_price = 1.2;
}It’s important to have an exact match of the domain or subdomain that the rule is targeting. For example, if a rule is set up for “yahoo.com”, impressions coming from “sports.yahoo.com” will not match it. Instead, a second rule for “sports.yahoo.com” should be set up.
Layout
The layout/ad_size feature enables you to target ad placement opportunities based on the size of the ad.
An layout/ad_size value is an integer that specifies the size of the ad.
The layout/ad_size feature accepts two operators.
==
>
>=
<
<=
You can set bid prices for ads served to consumers based on the size of the ad. For example, if you are willing to bid more to deliver large ads, you could write the following set of rules.
if(layout >=4 and layout <=6) {
rule_name = “A123”;
bid_price = 1.4;
} else {
rule_name = “A124”;
bid_price = 1.2;
}Ad Position
The ad_position feature enables you to target ad placement opportunities based on the position of the ad on the web page.
The ad_position value is defined as an integer that identifies the ad position.
0-Unknown
1- Above the fold
2- Partial view
3- Below fold
4- Header
5-Footer
The ad_position feature accepts a single operator.
==
>
>=
<
<=
Using the == operator, you can set bid prices based on the position of the ad on the page. For example, if you are willing to pay more for ads that are above the fold, you could write the following set of rules.
if(ad_position == 1000) { // like Above the fold
rule_name = “A123”;
bid_price = 1.4;
} else {
rule_name = “A124”;
bid_price = 1.2;
}Device Type
The device_type feature enables you to target ad placement opportunities based on the types of physical devices serving the impression.
The device_type value is defined as an integer that represents the device type.
1 - Desktop
2 - Laptop
3 - Phone/Mobile
4 - Tablet
5- Connected TV
The device_type feature accepts a single operator.
==
>
>=
<
<=
Using the == operator, you can set bid prices for ads served to consumers using specific types of devices. For example, if you are willing to pay more for ads served to consumers using a mobile phone, you could write the following set of rules.
if(device_type == 3) {
rule_name = “A123”;
bid_price = 1.4;
} else {
rule_name = “A124”;
bid_price = 1.2;
}Viewability
The viewability feature enables you to target ad placement opportunities based on the viewability rate of the impressions as measured by Moat.
The viewability value is specified as a number between 0 and 1 that represents a viewability rate percentage. For example, 0.65 means 65%.
The viewability feature accepts five operators.
==
>
>=
<
<=
Using the > operator, you can set bid prices for ads with a viewability rate that is greater than the value specified. For example, if you are willing to bid more for ads that are more than 54% visible, you could write the following set of rules.
if(viewability_rate > 0.54) {
rule_name = “A123”;
bid_price = 1.4;
} else {
rule_name = “A124”;
bid_price = 1.2;
}Segment
The segment feature enables you to target ad placement opportunities based on the audience. Audience groups are identified as segments of users and advertisers can target various segments of people.
The segment feature accepts only one operator.
IN
Using the IN operator, you can specify a list of segment ids to target multiple groups of audiences. For example, if you are willing to bid more for ads that are for segment Ids 2345 or 7895 or 3459.
if(segment IN “2345,7895,3459”) {
rule_name = “A999”;
bid_price = 1.23;
} else {
rule_name = “A1000”;
bid_price = 1.145;
}Expressions
In Sequoia, decision trees can be written using following expressions.
if/else
switch
If Else Statement
As with any modern language, Sequoia supports if and else to enable users to write conditions that execute a set of statements when evaluated as true and optionally execute a different set of statements if evaluated as false.
if (pulse_country_id == 1001) {
bid_price = 0.5;
rule_name = “A1234”;
} else {
bid_price = 0.4;
rule_name = “A1235”;
}Is the user from pulse_country_id 1001
If yes then set the bid price as 0.5
else set the bid price as 0.4
Nested if or if/else statements are also allowed and any combination of them.
Note
To evaluate a condition using an if statement, we use the == operator, while for assigning a value we use =.
Switch Statement
The switch statement is an alternative to writing multiple nested if /else statements. It will be handy to test against a lot of values for a single feature and have different bid prices.
switch(expression) {
case 1: {
statement1;
Break;
}
case 2: {
statement2;
Break;
}
case 3: {
statement3;
Break;
}
Default: {
statement;
Break;
}
}The switch statement will have an expression that will be evaluated, and based on the value of the expression, the statements of case that match with the expression value get executed. If no cases match then statements in the default section will get executed.
Each case block should end with a break statement, and every switch must have a default clause.
Example
if(domain == “sports.yahoo.com”) {
switch(pulse_country_id) {
case 3261: {
rule_name = “S1111”;
bid_multiplier = 2.5;
break;
}
case 4425: {
if(user_hour == 5 && segment IN “2222,3333,4444”) {
rule_name = “S1114”;
Bid_price = 3.5;
}
break;
}
case 4578:
rule_name = “S1118”;
bid_multiplier = 2.38;
break;
default : {
rule_name = “S1120”;
bid_price = 1.42;
break;
}
}
}
}The example uses the following logic.
Is the domain user visited “sports.yahoo.com”
If yes go to step 2
If no, then NO bid
Is the user pulse_country_id 3261
If yes use bid 0.34
If no go to step 3
Is the user pulse_country_id 4425
If yes use go to step 4
If no go to step 5
Is the user came at 5th hour and user belongs to any segment 2222,3333,4444
If yes use bid 0.36
If no, NO bid
Is the user pulse_country_id 4578
If yes, bid 0.38
If no, NO bid
If user doesn’t belong to any of the pulse_country_id 3261, 4425, 4578
Bid 0.42
Operators
Relational Operators
Sequoia supports six relational operators. Use these operators to make comparisons against primitive data types like integer, long, and float.
Operator | Meaning |
|---|---|
== | Equal to used for comparison |
< | Less than |
<= | Less than or equal to |
> | Greater than |
>= | Greater than or equal to |
In the example, a user_day feature is evaluated using the >=, <=, and == operators.
if(user_day >= 5 && user_day <= 8 && (user_hour == 9 || user_hour == 22)) {
rule_name = “C1111”;
bid_multiplier = 1.54;
}Logical Operators
Sequoia supports three logical operators.
Operator | Meaning |
|---|---|
&& | AND |
|| | OR |
! | NOT |
Example
if(!(domain == “finance.yahoo.com”) && user_hour <= 15 && (user_day == 2 || user_day == 06)) {
rule_name = “L1111”;
bid_multiplier = 1.71;
}IN Operator (for ‘segment’ and ‘domain’/’appname’ features)
The IN operator can be used to test whether the value of the feature is among a list of the values. The list of values must be enclosed using double quotes (“ ‘).
if(segment in “23456,4789654,67544332”) {
rule_name = “X1234”;
bid_multiplier = 1.33;
}
if(domain in “finance.yahoo.com,cnn.com,abcnews.com”) {
rule_name = “X333”;
bid_price = 0.85;
}Special Flags
When writing your algorithm, you can use some special flags that will overwrite some functions of the bidder.
Default Bid
default_bid_flag = 0;
In a situation that doesn’t match a rule defined in the custom algorithm, the DSP will not bid.
default_bid_flag = 1;
In a situation that doesn’t match a rule defined in the custom algorithm, the DSP will bid as per the optimisation.