Skip to content

Commit

Permalink
Upgrade Bid Adjustments (prebid#2678)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexBVolcy authored and prebid-bluesea committed Jun 2, 2023
1 parent 00b72f9 commit b143eea
Show file tree
Hide file tree
Showing 22 changed files with 2,181 additions and 51 deletions.
94 changes: 94 additions & 0 deletions bidadjustment/apply.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package bidadjustment

import (
"math"

"github.com/prebid/prebid-server/adapters"
"github.com/prebid/prebid-server/openrtb_ext"
)

const (
AdjustmentTypeCPM = "cpm"
AdjustmentTypeMultiplier = "multiplier"
AdjustmentTypeStatic = "static"
WildCard = "*"
Delimiter = "|"
)

const maxNumOfCombos = 8
const pricePrecision float64 = 10000 // Rounds to 4 Decimal Places
const minBid = 0.1

// Apply gets the highest priority adjustment slice given a map of rules, and applies those adjustments to a bid's price
func Apply(rules map[string][]openrtb_ext.Adjustment, bidInfo *adapters.TypedBid, bidderName openrtb_ext.BidderName, currency string, reqInfo *adapters.ExtraRequestInfo, bidType string) (float64, string) {
adjustments := []openrtb_ext.Adjustment{}
if len(rules) > 0 {
adjustments = get(rules, bidType, string(bidderName), bidInfo.Bid.DealID)
} else {
return bidInfo.Bid.Price, currency
}
adjustedPrice, adjustedCurrency := apply(adjustments, bidInfo.Bid.Price, currency, reqInfo)

if bidInfo.Bid.DealID != "" && adjustedPrice < 0 {
return 0, currency
}
if bidInfo.Bid.DealID == "" && adjustedPrice <= 0 {
return minBid, currency
}
return adjustedPrice, adjustedCurrency
}

func apply(adjustments []openrtb_ext.Adjustment, bidPrice float64, currency string, reqInfo *adapters.ExtraRequestInfo) (float64, string) {
if len(adjustments) == 0 {
return bidPrice, currency
}
originalBidPrice := bidPrice

for _, adjustment := range adjustments {
switch adjustment.Type {
case AdjustmentTypeMultiplier:
bidPrice = bidPrice * adjustment.Value
case AdjustmentTypeCPM:
convertedVal, err := reqInfo.ConvertCurrency(adjustment.Value, adjustment.Currency, currency)
if err != nil {
return originalBidPrice, currency
}
bidPrice = bidPrice - convertedVal
case AdjustmentTypeStatic:
bidPrice = adjustment.Value
currency = adjustment.Currency
}
}
roundedBidPrice := math.Round(bidPrice*pricePrecision) / pricePrecision

return roundedBidPrice, currency
}

// get() should return the highest priority slice of adjustments from the map that we can match with the given bid info
// given the bid info, we create the same format of combinations that's present in the key of the ruleToAdjustments map
// the slice is ordered by priority from highest to lowest, as soon as we find a match, we return that slice
func get(rules map[string][]openrtb_ext.Adjustment, bidType, bidderName, dealID string) []openrtb_ext.Adjustment {
priorityRules := [maxNumOfCombos]string{}
if dealID != "" {
priorityRules[0] = bidType + Delimiter + bidderName + Delimiter + dealID
priorityRules[1] = bidType + Delimiter + bidderName + Delimiter + WildCard
priorityRules[2] = bidType + Delimiter + WildCard + Delimiter + dealID
priorityRules[3] = WildCard + Delimiter + bidderName + Delimiter + dealID
priorityRules[4] = bidType + Delimiter + WildCard + Delimiter + WildCard
priorityRules[5] = WildCard + Delimiter + bidderName + Delimiter + WildCard
priorityRules[6] = WildCard + Delimiter + WildCard + Delimiter + dealID
priorityRules[7] = WildCard + Delimiter + WildCard + Delimiter + WildCard
} else {
priorityRules[0] = bidType + Delimiter + bidderName + Delimiter + WildCard
priorityRules[1] = bidType + Delimiter + WildCard + Delimiter + WildCard
priorityRules[2] = WildCard + Delimiter + bidderName + Delimiter + WildCard
priorityRules[3] = WildCard + Delimiter + WildCard + Delimiter + WildCard
}

for _, rule := range priorityRules {
if _, ok := rules[rule]; ok {
return rules[rule]
}
}
return nil
}
Loading

0 comments on commit b143eea

Please sign in to comment.