With matched bets, how can I get the total stake and averaged odds for both back and lay?
With unmatched bets, how to get the betType, stakes and odds?
And lastly, how to cancel an unmatched bet?
Thanks
Comments ( 12 )
Betfair Bot
26.10.2019 14:17:38
You can access market’s bets or selection’s bets directly (line 76 and 31), and for matched bets you can access BetPosition property, the line 79 and 34.
BetPosition type/class allows you to calculate hedge stake and so on, have a look at on the type methods.
To cancel bets you can use TriggerResult.CancelBets, the line 150.
I already mentioned that the better way is to orchestrate existing bots to execute parts of your strategy, for instance you set trading bot and all bet placing/updating or cancelling your bets is then managed by this trading bot.
In my bot trigger I showed what you asked and created such simple bots’ orchestration:
Please watch my video. To show how to cancel bets, I set my action bot: “Back 1 tick better”, so bot offers 2 Euro back bet 1 tick over best offered price. When odds changes and are in allowed odds range Minimum/MaximumOdds, the bot updates its unmatched bet to always offer its back bet 1 tick over the best offered, set by the parameter: PriceImprovemnt.
Now, in my bot trigger I cancelled unmatched bet on my selection, the line 150. But what happened?
As the bet was placed by my action bot, and the bot is managing its bets itself, the bet was again placed.
What does it mean?
If you place your bets by action bots, you do not need to manage bets placed by the action bot, but of course if you do not want your unmatched bets be offered on the market anymore, you need to stop the action bot, and as the action bot managing its bets, the unmatched bets will cancel its bets when you end its execution, the line 160.
It is really better way to orchestrate action bots in your bot trigger than managing bet status in your bot trigger.
Well yes, if you want to place your bets directly then you can do so, you have got:
TriggerResult.PlaceBets
TriggerResult.CancelBets
Let’s say you have got strange trading strategy, where you setup the trading bot:
"Place Bet and Close Selection Bet Position"
To offer bet 3 ticks from best offered price, and close its bet position with profit of 3 ticks, or 5 ticks to lose.
You would setup two versions of this trading bot one offering back and the other one lay bet. In your bot trigger you would execute such pair of trading bots on 3 favourites when some conditions occurred.
Now imagine what you would have to program to manage such complex trading strategy in your bot trigger by directly placing your bets.
peteresgate@outlook.com
28.10.2019 3:03:32
Thanks for the info Stefan. I am trying to use the info for a selection like this:
let UnmatchedLayBets () =
if _selection.Bets |> Seq.exists (fun bet -> bet.OrderStatus <> BetOrderStatus.Matched && bet.BetType = BetType.Lay) then let price = _selection.GetPrice(BetType.Lay) let Stake = _selection.GetPriceSize(BetType.Lay)
But the error exists because the result is a float option. I have tried to find how to cast the float option to float so that I can use the result in calculations but have not found how to do it yet. How would I return the stake and price as a float so that I can use it? I'm sure this is an easy question for you but I have been pulling my hair out over this.
Betfair Bot
28.10.2019 10:12:58
Peter may I ask you to explain me by your own words, how do you understand this line of code?
let Stake = _selection.GetPriceSize(BetType.Lay)
As you may know, and now I speak not about programming languages, but about languages, my mother’s language is Slovak, and in many Slavic languages there is no such strict rule for word order like in English sentence.
That is the funny part in your question, because well my understanding of any language construct is a little bit different from the way only English people could read the code, the sentence.
Well, yes I understand what you want to try to do in your code, but the “words” you chose to do so are quite unclear for me.
peteresgate@outlook.com
28.10.2019 11:26:57
Maybe GetPriceSize is not the code I'm looking for? When a bet is matched or partially matched, it has the Stake that is matched and the odds it is matched at. So the code I am looking for that you have questioned is to find the stake amount that is matched. Thanks
Betfair Bot
28.10.2019 13:20:07
Any code, in any programming language is “sentence” expressed by programming language “words” and constructs you can make by programming, adds the language vocabulary.
So the vocabulary you can use to express your intentions in programming language is limited to couple words.
The above line of code:
let Stake = _selection.GetPriceSize(BetType.Lay)
In human sentence expresses:
Selection, get PriceSize object for Lay side to stake!
As English have strict words order in sentence, to be grammatically correct, we command so exclamation mark at the end of sentence.
So you command selection to get PriceSize, and in this context it is Lay PriceSize offered. It is not bet, it is offer on this selection other bettors placed.
You can command bet object to get price or size to you, so odds or stake you placed a bet with.
So you must ask/command _selection.Bets to get all unmatched bets to you (to value), and then ask a bet to get you price, size and so on, like I did in my bot trigger code:
Read further only when you want to learn some advance features of F# programming language.
***
I do not know in what context you use _selection, but please keep in mind that in F# underscore _ is used as intention to declare not used value, because in F# you must declare exact intention, so like in mathematics it does not make sense to express something what is not used.
Yes, in other programming languages, programmers used to declare object variables with _, but in F# it has different meaning, for instance here:
On the line 52, where I declared construct for BetStatusBetCancellingBotOrchestrationBotTrigger type, I used _ for not used values, because in F# any input value/s in constructor are declared as well as object values you can access not only in constructor but in entire type.
On the line 106, you can see __ (two underscores), so in type member you must type __ to declare not used self-identifier of object. I use this as self-identifier, but you can use whatever word/character.
Ok, this underscore issue is for advance developers, you code will work whatever you will use.
***
Option value
***
For the option types/values it is similar like in C# for Nullable. So you can use anOptionValue.IsSome and if is some you can get value by: anOptionValue.Value, but better way is to use match expression or functions from Option module, like Option.iter.
In my code you can find maybe, computation expression I created, so for options you can type simplified expressions, for instance here:
Lines from 39 to 43, and then on line 40, let! ... actually evaluates if mySelection.MetaData.IsSome and continues only when it is assigning to metaData the value, otherwise returning None.
Such expression allows me to write less code. Programming is not about writing a lot of code, actually less code is always better approach.
Programming is about understanding of context in which you write the code, and so it is about interpreting of “words”.
peteresgate@outlook.com
28.10.2019 14:57:26
So do you mean something like this?:
let betSize(bet : Bet) = bet.Size
let getBetSize() =
if selection.Bets |> Seq.exists (fun bet -> bet.OrderStatus <> BetOrderStatus.Matched && bet.BetType = BetType.Lay) then let price = selection.Bets |> Seq.map betSize |> Seq.head
This is the correct way? Is there not a way to do something like selection.Bets.Size or selection.Bets.Price or selection.Bets.BetType etc?
Betfair Bot
28.10.2019 16:01:12
Yes, exactly. You simply must use correct wording. “Bets” is plural, right? So it is collection, not one bet. On the object property that is bet, you could do so: bet.Price and so on.
I do not know what exactly you want to achieve as it is clear that you could have more unmatched bets on selection, so make reusable functions you could use/reuse in your bot triggers.
I wanted to explain in my sample bot trigger code, how you can work on bfexplorer domain objects, so I used direct code, but if you try to write: unmatched .. Visual Studio will offer you all available functions/types and so available for you after you
open BeloSoft.Bfexplorer.Domain
so surprising it is offered for you:
isUnmatchedBet, unmatchedBetsExists, getBets, getUnmatchedBets, getUnmatchedBetsByBetType and so on and on.
So code I already had wrote and is reusable.
Then you could write:
let layUnmtached = market.Bets |> getUnmatchedBetsByBetType BetType.Lay
if not layUnmtached.IsEmpty
then
let firstUnmatched = layUnmtached.Head
firstUnmatched.Price
...
peteresgate@outlook.com
30.10.2019 2:34:41
The unmatched data works great thanks Stefan. I really appreciate the code thanks.
But I still have a problem getting the matched data. When the orders are matched, I am trying to get the combined Odds (as float) and combined Stake (as float) for Matched Lays, and Matched Backs as shown in the Market Bets window (it combines all the Matched Lays and all the Matched Backs). All I get with the code I posted recently is the head which is the first item shown in ther market bets window, but I can't sort the map to get the requested matched/unmatched to the head. Could you please post the code snippet for this?
selection.BetPosition object offers your bet position, so please browse data, put their break point when dubbing your bot trigger code.
peteresgate@outlook.com
30.10.2019 12:05:50
Yes but this prints all the bets, with no way to get just the matched lay or matched back bets. To get the unmatched with your code is good, but the matched doesn't work this way. Could you please show a code sample?
Hello. Since yesterday I have a delayed API on my BF Explorer trading software. I had no bots running when this happened and now I am also unable to trade as all stakes in the markets keep flashing all over the ladders on random odds, being absolutely impossible to figure out what was the last price ...
I tried BFexplorer, having used 3-4 different software applications beforehand.
The 2 days utilising the software, I managed to get a feel for the product and like the modern display on the black background.
Bets placed were very responsive with no lagging experienced from other products.
A few ...
Version 3.23.1126
Cumulative updates to the Bfexplorer Preview version (.net 9.0)
Version 3.22.0821
Cumulative updates to the Bfexplorer Preview version
Version 3.10.0721
Cumulative updates to the Bfexplorer Preview version (.net 8.0)
Version 3.9.0425
Cumulative ...
In the new year I will release the new version of bfexplorer. If you want to test the preview version, please download it from my dropbox:
https://www.dropbox.com/s/ewmbdcgqf75ak3t/Bfexplorer.msi?dl=0
.net 9 SDK
Download .NET 9.0 SDK (v9.0.100) - Windows x64 Installer
The app requires WebView2 ...
Version 3.23.1126
Cumulative updates to the Bfexplorer Preview version (.net 9.0)
Version 3.22.0821
Cumulative updates to the Bfexplorer Preview version
Version 3.10.0721
Cumulative updates to the Bfexplorer Preview version (.net 8.0)
Version 3.9.0425
Cumulative ...
Overfitting: The art of avoiding overfitting and the importance of comparing training and test results to detect it.
ROI Calculation: Different methods of calculating ROI, including the impact of flat stakes versus stakes based on odds.
Feature Selection: Emphasize the importance of ...
Comments ( 12 )
Betfair Bot
You can access market’s bets or selection’s bets directly (line 76 and 31), and for matched bets you can access BetPosition property, the line 79 and 34.
BetPosition type/class allows you to calculate hedge stake and so on, have a look at on the type methods.
To cancel bets you can use TriggerResult.CancelBets, the line 150.
I already mentioned that the better way is to orchestrate existing bots to execute parts of your strategy, for instance you set trading bot and all bet placing/updating or cancelling your bets is then managed by this trading bot.
In my bot trigger I showed what you asked and created such simple bots’ orchestration:
BetStatusBetCancellingBotOrchestrationBotTrigger.fsx
Please watch my video. To show how to cancel bets, I set my action bot: “Back 1 tick better”, so bot offers 2 Euro back bet 1 tick over best offered price. When odds changes and are in allowed odds range Minimum/MaximumOdds, the bot updates its unmatched bet to always offer its back bet 1 tick over the best offered, set by the parameter: PriceImprovemnt.
Now, in my bot trigger I cancelled unmatched bet on my selection, the line 150. But what happened?
As the bet was placed by my action bot, and the bot is managing its bets itself, the bet was again placed.
What does it mean?
If you place your bets by action bots, you do not need to manage bets placed by the action bot, but of course if you do not want your unmatched bets be offered on the market anymore, you need to stop the action bot, and as the action bot managing its bets, the unmatched bets will cancel its bets when you end its execution, the line 160.
It is really better way to orchestrate action bots in your bot trigger than managing bet status in your bot trigger.
Well yes, if you want to place your bets directly then you can do so, you have got:
TriggerResult.PlaceBets
TriggerResult.CancelBets
Let’s say you have got strange trading strategy, where you setup the trading bot:
"Place Bet and Close Selection Bet Position"
To offer bet 3 ticks from best offered price, and close its bet position with profit of 3 ticks, or 5 ticks to lose.
You would setup two versions of this trading bot one offering back and the other one lay bet. In your bot trigger you would execute such pair of trading bots on 3 favourites when some conditions occurred.
Now imagine what you would have to program to manage such complex trading strategy in your bot trigger by directly placing your bets.
peteresgate@outlook.com
Thanks for the info Stefan. I am trying to use the info for a selection like this:
let UnmatchedLayBets () =
if _selection.Bets |> Seq.exists (fun bet -> bet.OrderStatus <> BetOrderStatus.Matched && bet.BetType = BetType.Lay)
then
let price = _selection.GetPrice(BetType.Lay)
let Stake = _selection.GetPriceSize(BetType.Lay)
if price > 10.0
then
outputMessage (sprintf "Unmatched Price > 10: %.2f " price )
But the error exists because the result is a float option. I have tried to find how to cast the float option to float so that I can use the result in calculations but have not found how to do it yet. How would I return the stake and price as a float so that I can use it? I'm sure this is an easy question for you but I have been pulling my hair out over this.
Betfair Bot
Peter may I ask you to explain me by your own words, how do you understand this line of code?
let Stake = _selection.GetPriceSize(BetType.Lay)
As you may know, and now I speak not about programming languages, but about languages, my mother’s language is Slovak, and in many Slavic languages there is no such strict rule for word order like in English sentence.
That is the funny part in your question, because well my understanding of any language construct is a little bit different from the way only English people could read the code, the sentence.
Well, yes I understand what you want to try to do in your code, but the “words” you chose to do so are quite unclear for me.
peteresgate@outlook.com
Maybe GetPriceSize is not the code I'm looking for? When a bet is matched or partially matched, it has the Stake that is matched and the odds it is matched at. So the code I am looking for that you have questioned is to find the stake amount that is matched. Thanks
Betfair Bot
Any code, in any programming language is “sentence” expressed by programming language “words” and constructs you can make by programming, adds the language vocabulary.
So the vocabulary you can use to express your intentions in programming language is limited to couple words.
The above line of code:
let Stake = _selection.GetPriceSize(BetType.Lay)
In human sentence expresses:
Selection, get PriceSize object for Lay side to stake!
As English have strict words order in sentence, to be grammatically correct, we command so exclamation mark at the end of sentence.
So you command selection to get PriceSize, and in this context it is Lay PriceSize offered. It is not bet, it is offer on this selection other bettors placed.
You can command bet object to get price or size to you, so odds or stake you placed a bet with.
So you must ask/command _selection.Bets to get all unmatched bets to you (to value), and then ask a bet to get you price, size and so on, like I did in my bot trigger code:
BetStatusBetCancellingBotOrchestrationBotTrigger.fsx
on the line 31.
***
Read further only when you want to learn some advance features of F# programming language.
***
I do not know in what context you use _selection, but please keep in mind that in F# underscore _ is used as intention to declare not used value, because in F# you must declare exact intention, so like in mathematics it does not make sense to express something what is not used.
Yes, in other programming languages, programmers used to declare object variables with _, but in F# it has different meaning, for instance here:
ShowPriceTradedVolume.fsx
On the line 52, where I declared construct for BetStatusBetCancellingBotOrchestrationBotTrigger type, I used _ for not used values, because in F# any input value/s in constructor are declared as well as object values you can access not only in constructor but in entire type.
On the line 106, you can see __ (two underscores), so in type member you must type __ to declare not used self-identifier of object. I use this as self-identifier, but you can use whatever word/character.
Ok, this underscore issue is for advance developers, you code will work whatever you will use.
***
Option value
***
For the option types/values it is similar like in C# for Nullable. So you can use anOptionValue.IsSome and if is some you can get value by: anOptionValue.Value, but better way is to use match expression or functions from Option module, like Option.iter.
In my code you can find maybe, computation expression I created, so for options you can type simplified expressions, for instance here:
ShowHorseData.fsx
Lines from 39 to 43, and then on line 40, let! ... actually evaluates if mySelection.MetaData.IsSome and continues only when it is assigning to metaData the value, otherwise returning None.
Such expression allows me to write less code. Programming is not about writing a lot of code, actually less code is always better approach.
Programming is about understanding of context in which you write the code, and so it is about interpreting of “words”.
peteresgate@outlook.com
So do you mean something like this?:
let betSize(bet : Bet) =
bet.Size
let getBetSize() =
if selection.Bets |> Seq.exists (fun bet -> bet.OrderStatus <> BetOrderStatus.Matched && bet.BetType = BetType.Lay)
then
let price = selection.Bets |> Seq.map betSize |> Seq.head
This is the correct way? Is there not a way to do something like selection.Bets.Size or selection.Bets.Price or selection.Bets.BetType etc?
Betfair Bot
Yes, exactly. You simply must use correct wording. “Bets” is plural, right? So it is collection, not one bet. On the object property that is bet, you could do so: bet.Price and so on.
I do not know what exactly you want to achieve as it is clear that you could have more unmatched bets on selection, so make reusable functions you could use/reuse in your bot triggers.
I wanted to explain in my sample bot trigger code, how you can work on bfexplorer domain objects, so I used direct code, but if you try to write: unmatched .. Visual Studio will offer you all available functions/types and so available for you after you
open BeloSoft.Bfexplorer.Domain
so surprising it is offered for you:
isUnmatchedBet, unmatchedBetsExists, getBets, getUnmatchedBets, getUnmatchedBetsByBetType and so on and on.
So code I already had wrote and is reusable.
Then you could write:
peteresgate@outlook.com
The unmatched data works great thanks Stefan. I really appreciate the code thanks.
But I still have a problem getting the matched data. When the orders are matched, I am trying to get the combined Odds (as float) and combined Stake (as float) for Matched Lays, and Matched Backs as shown in the Market Bets window (it combines all the Matched Lays and all the Matched Backs). All I get with the code I posted recently is the head which is the first item shown in ther market bets window, but I can't sort the map to get the requested matched/unmatched to the head. Could you please post the code snippet for this?
Betfair Bot
Have a look at the line 34:
sprintf "%s: %A" selection.Name selection.BetPosition
selection.BetPosition object offers your bet position, so please browse data, put their break point when dubbing your bot trigger code.
peteresgate@outlook.com
Yes but this prints all the bets, with no way to get just the matched lay or matched back bets. To get the unmatched with your code is good, but the matched doesn't work this way. Could you please show a code sample?