Track Topic
: rss

Topic: Exposure calculation

posts 1–12 of 12
Page 1
?
16 posts

Anyone out there got a nice routine to calculate exposures (given a list of bets e.g. MUBets)? I've just tried writing one and make a pig's ear of it - can't see the wood for the trees at the moment. There has to a more elegant way!

I trying to create the same calc that the GetAccountFunds API call uses...

?
47 posts

My only advice would be to play around on a spreadsheet first. That way the logic can be understood first, then the coding second.

Hope this helps,
Brendan

?
62 posts

I don't have a code snippet I'm afraid, but I guess the logic (for fixed odds bets rather than Asians) must be as follows:

 - Step 1 - For each market and selection, calculate the amount you'd lose if the selection won (i.e. sum over lay bets of stake*(odds-1) - sum over back bets of stake*(odds-1) and the amount you'd lose if the selection lost (i.e. sum of back bet stakes - sum of lay bet stakes).  (I'm assuming we'll treat losses as positive and so come up with a positive exposure value, but you can flip all the signs and treat exposures as negative if that's more convenient).

- Step 2 - Look at each market as a whole.  Find the largest of all the individual loss values calculated for that market in step 1, and that's your exposure to the market as a whole i.e. the worst-case scenario.  (This is capped at zero i.e. the exposure for an all-green book is zero.)

- Step 3 - Add the exposures for all the individual markets to get a total exposure.

?
62 posts

Thinking aloud a bit more, I've never actually tested how they treat unmatched bets in this calculation, but presumably (as they want to capture the worst case scenario) they would include losing unmatched bets in the calculation, but not winning unmatched bets.

I've not thought about this before - there's more to it than meets the eye isn't there?

?
31 posts

For single selections I use this:

for (index = ladder.LowestInterestingPriceIndex; index <= ladder.HighestInterestingPriceIndex; index++)
{
	layMatchedStake += ladder.Prices[index].MatchedLays;
	layMatchedProfit += ladder.Prices[index].MatchedLays * (ladder.Prices[index].Odds - 1);
	layExposure -= ladder.Prices[index].UnmatchedLays * (ladder.Prices[index].Odds - 1);

	backMatchedStake += ladder.Prices[index].MatchedBacks;
	backMatchedProfit += ladder.Prices[index].MatchedBacks * (ladder.Prices[index].Odds - 1);
	backExposure -= ladder.Prices[index].UnmatchedBacks;
}

netStakes = layMatchedStake - backMatchedStake;
netProfit = Math.Round(backMatchedProfit - layMatchedProfit, 2);

bestCase = Math.Max(netStakes, netProfit);
worstCase = Math.Min(netStakes, netProfit);

I'm looping across my ladder where I have cuimulative bet records, but the logic should be the same if you are doing a list of MUBets.

Should be relatively easy to extend for multiple selections.

?
31 posts

Ooops see I missed a bit

layExposureNet = netProfit + layExposure;
backExposureNet = netStakes + backExposure;
exposure = Math.Min(layExposureNet, backExposureNet);
?
16 posts

Thanks guys, an excellent example of why I love this forum!

BTW PeteB, I understand your code but I haven't come across the idea of a "price ladder" before. What's the idea behind it? I keep track of bets using a List<MUBet>, does using a ladder make anything easier? Is there some golden botting nugget of goodness about to be revealed?!

?
31 posts

It's just another way of viewing the market - several of the big tools support it - have a look at the videos on http://www.racingtraders.com/ for an example. A vertical column of prices from 1.01 to 1000, and the market lays on the left and backs on the right. And then your lays appear in another column on the left, and your backs on the right.

I find this the most intuitive interface to trade on manually (I use the Gruss one) - and so I based my code the same way - just makes it easier for me to understand as I write it. Not sure it gives any programming advantage - for example if I get a price improvement I have to then split the matched bet across prices when I update my cumulative records on the ladder - I'm starting to think this is a pain. With lots of bets, then there might be less processing of the cumulative records than processing the raw list of bets - but I think I would have to re-process the raw list of bets after a reduction factor anyway - so maybe I will scrap this and just store a list of MUBets!

?
128 posts
Things like this is why i scrape the website rather than use the API. For instance, a call to https://uk.site.sports.betfair.com/wallet/LocalAccountSummaryWalletView.do returns the same info as a call to GetAccountFunds. One is restricted to 1 call per minute, the other is only governed by the data useage rules of 20x per sec...
Wink
?
16 posts

Yeah, I guess I could scrape it, but I was really after the exposure for just the market I'm currently 'looking' at. I assume the scrape call will return the exposure for all markets that I have bets on ie. for markets that haven't settled, yet even though I'm looking at the next race...if that makes sense?!

?
128 posts
Yeah, that would give you your total exposure. For current matket exposure (i.e. the market you're refreshing), the market data includes the P&L on each runner so it's simply a case of finding the worst outcome. Of course, i'm very biased towards scraping because i think it is better than the paid for API due to having more info such as form figures, weights, jockeys, etc, etc. And of course it's free. I've written 3 free API bots and ended up going back to scraping every time.
Undecided
?
47 posts
I use a python class (as per attached) and feed one instance matched bets and another instance unmatched bets and matched.

This does not cover the worst-case of some of the unmatched bet being matched and some not, but if I really wanted this I could feed a sub-set of bets to the class.

Hope this helps,
Brendan

class liableClass:
    def __init__(self):
        self.runnerNames = []
        self.totalLaid = []
        self.winPayOut = []
        self.totalBet  = []
    def newRunner(self, runnerName):
        self.runnerNames.append(runnerName)
        self.totalLaid.append(0)
        self.winPayOut.append(0)
        self.totalBet.append(0)
    def addBet(self, runnerName, odds, stake, betOrLay='L'):
        if runnerName not in self.runnerNames:
            self.newRunner(runnerName)
        i = self.runnerNames.index(runnerName)
        if betOrLay == 'L':
            self.totalLaid[i] = self.totalLaid[i] + stake
            self.winPayOut[i] = self.winPayOut[i] + round(((odds -1) * stake),2)
        else:
            self.totalBet[i] = self.totalBet[i] + stake
            self.winPayOut[i] = self.winPayOut[i] - round(((odds -1) * stake),2)
    def profitIfWinner(self, winnerRunnerName):
        profit = 0
        for runnerName in self.runnerNames:
            i = self.runnerNames.index(runnerName)
            if runnerName == winnerRunnerName:
                profit = profit - self.winPayOut[i]
            else:
                profit = profit + self.totalLaid[i] - self.totalBet[i]
        return profit
    def minProfit(self):
        allProfits = []
        for runnerName in self.runnerNames:
            p = self.profitIfWinner(runnerName)
            allProfits.append(p)
        if allProfits:
            return min(allProfits)
        else:
            return 0
    def maxProfit(self):
        allProfits = []
        for runnerName in self.runnerNames:
            p = self.profitIfWinner(runnerName)
            allProfits.append(p)
        if allProfits:
            return max(allProfits)
        else:
            return 0
    def spreadProfit(self):
        return self.maxProfit() - self.minProfit()


posts 1–12 of 12
Page 1

This Topic Is Locked To Guest Posts

It's been a while since this topic was active, if you'd like to get it going again, please post as a registered member

join now