Skip to content

Instantly share code, notes, and snippets.

@StefanBelo
Created October 13, 2018 14:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save StefanBelo/0bab566dd8bbbd20922c51eb7ccdef26 to your computer and use it in GitHub Desktop.
Save StefanBelo/0bab566dd8bbbd20922c51eb7ccdef26 to your computer and use it in GitHub Desktop.
// Bfexplorer cannot be held responsible for any losses or damages incurred during the use of this betfair bot.
// It is up to you to determine the level of risk you wish to trade under.
// Do not gamble with money you cannot afford to lose.
module BfexplorerBot
#I @"C:\Program Files (x86)\BeloSoft\Bfexplorer\"
#r "BeloSoft.Data.dll"
#r "BeloSoft.Betfair.API.dll"
#r "BeloSoft.Bfexplorer.Domain.dll"
#r "BeloSoft.Bfexplorer.Trading.dll"
#r "BeloSoft.Bfexplorer.Service.Core.dll"
open System
open BeloSoft.Data
open BeloSoft.Bfexplorer.Domain
open BeloSoft.Bfexplorer.Trading
let getOddsDifference (selection1 : Selection, selection2 : Selection) =
selection1.OddsContext.GetOddsDifference(selection1.LastPriceTraded, selection2.LastPriceTraded)
let getBookValue (selections : Selection list) =
selections
|> List.map (fun mySelection -> toPriceProbability mySelection.LastPriceTraded)
|> List.sum
/// <summary>
/// TriggerStatus
/// </summary>
type TriggerStatus =
| Initialize
| WaitToPlaceBets
| WaitForBetsPlacing
| StartCloseBetPositionBot
| ReportError of string
/// <summary>
/// HorseRacingDutchTradingBotTrigger
/// </summary>
type HorseRacingDutchTradingBotTrigger(market : Market, _selection : Selection, _botName : string, botTriggerParameters : BotTriggerParameters, myBfexplorer : IMyBfexplorer) =
let mutable triggerStatus = TriggerStatus.Initialize
let mutable myFavourites = nil<Selection list>
let mutable initialBookValue = 0.0
let timeToPlaceBets = market.MarketInfo.StartTime.AddMinutes(-(defaultArg (botTriggerParameters.GetParameter<float>("TimeToPlaceBets")) 2.0))
let outputMessage message =
myBfexplorer.BfexplorerService.OutputMessage(message, market.Id)
let isHorseRacingMarket() =
market.MarketInfo.BetEventType.Id = 7 && market.MarketDescription.MarketType = "WIN"
let initialize() =
let minimumNumberOfRunners = defaultArg (botTriggerParameters.GetParameter<int>("MinimumNumberOfRunners")) 6
let selections =
market.Selections
|> Seq.filter isNotRemovedSelection
|> Seq.sortBy (fun mySelection -> mySelection.LastPriceTraded)
|> Seq.toList
let numberOfRunners = selections.Length
if numberOfRunners >= minimumNumberOfRunners
then
let minimumRank = defaultArg (botTriggerParameters.GetParameter<byte>("MinimumRank")) 50uy
let maximumRank = defaultArg (botTriggerParameters.GetParameter<byte>("MaximumRank")) 150uy
myFavourites <-
selections
|> List.take 3
|> List.choose (fun mySelection ->
maybe {
let! metaData = mySelection.MetaData
let horseRank = metaData.OfficialRating
if horseRank >= minimumRank && horseRank <= maximumRank
then
return mySelection
}
)
if myFavourites.Length = 3
then
let minimumOddsDifference = defaultArg (botTriggerParameters.GetParameter<int>("MinimumOddsDifference")) 2
let oddsDifference = getOddsDifference (myFavourites.[0], myFavourites.[1])
if oddsDifference >= minimumOddsDifference
then
initialBookValue <- getBookValue myFavourites
true
else
outputMessage (sprintf "Not allowed odds difference: %d!" oddsDifference)
false
else
outputMessage "Horse/s not in allowed rank!"
false
else
outputMessage (sprintf "Not allowed number of runners: %d!" numberOfRunners)
false
let isTimeToPlaceBets() =
DateTime.Now >= timeToPlaceBets
let canPlaceDutchBets() =
let minimumBookDifference = defaultArg (botTriggerParameters.GetParameter<float>("MinimumBookDifference")) 0.1
let bookValue = getBookValue myFavourites
let bookDifference = initialBookValue - bookValue
let status = bookDifference >= minimumBookDifference
if not status
then
outputMessage (sprintf "Book value: %.2f -> %.2f | %.2f" initialBookValue bookValue bookDifference)
status
let getBetsToDutch() =
let layPayout = defaultArg (botTriggerParameters.GetParameter<float>("LayPayout")) 5.0
let selectionBetPriceSizes =
myFavourites
|> Seq.map (fun mySelection -> SelectionBetPriceSize(mySelection, BetType.Lay))
|> Seq.toList
DutchingCalculations.CalculateForStakeToDutch(selectionBetPriceSizes, layPayout) |> ignore
selectionBetPriceSizes
|> List.map (fun selectionBetPriceSize -> selectionBetPriceSize.ToSelectionBetOrder())
let betPlacedHandler (status : bool) =
triggerStatus <-
if status
then
TriggerStatus.StartCloseBetPositionBot
else
TriggerStatus.ReportError "Failed to place dutch bets!"
let startClosePositionOnMarketBot() =
let botParameters = ClosePositionOnMarketBotParameters()
let profit = defaultArg (botTriggerParameters.GetParameter<float>("Profit")) 5.0
let loss = defaultArg (botTriggerParameters.GetParameter<float>("Loss")) 30.0
botParameters.Name <- "Close my market bet position"
botParameters.Profit <- profit
botParameters.Loss <- loss
botParameters.ProfitOrLossInPercentage <- true
botParameters.CheckingLastPriceTraded <- false
botParameters.BetMatchingTimeout <- Nullable(TimeSpan.FromSeconds 2.0)
market |> addBot (ClosePositionOnMarketBot(market, botParameters, myBfexplorer.BfexplorerService))
interface IBotTrigger with
/// <summary>
/// Execute
/// </summary>
member __.Execute() =
match triggerStatus with
| TriggerStatus.Initialize ->
if isHorseRacingMarket()
then
if initialize()
then
triggerStatus <- TriggerStatus.WaitToPlaceBets
TriggerResult.WaitingForOperation
else
TriggerResult.EndExecution
else
TriggerResult.EndExecutionWithMessage "You can execute this bot only on a horse racing market!"
| TriggerStatus.WaitToPlaceBets ->
if isTimeToPlaceBets()
then
if canPlaceDutchBets()
then
triggerStatus <- TriggerStatus.WaitForBetsPlacing
let betOrders = getBetsToDutch()
TriggerResult.PlaceBets (betOrders, PersistenceType.Persist, betPlacedHandler)
else
TriggerResult.EndExecutionWithMessage "Cannot place dutch bets!"
else
TriggerResult.WaitingForOperation
| TriggerStatus.WaitForBetsPlacing -> TriggerResult.WaitingForOperation
| TriggerStatus.StartCloseBetPositionBot ->
startClosePositionOnMarketBot()
TriggerResult.EndExecution
| TriggerStatus.ReportError errorMessage -> TriggerResult.EndExecutionWithMessage errorMessage
/// <summary>
/// EndExecution
/// </summary>
member __.EndExecution() =
()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment