Skip to content

Instantly share code, notes, and snippets.

@StefanBelo
Created February 9, 2022 13:18
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/c4dd35758c5bbdb01e879dc105782d0f to your computer and use it in GitHub Desktop.
Save StefanBelo/c4dd35758c5bbdb01e879dc105782d0f to your computer and use it in GitHub Desktop.
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.Betfair
open BeloSoft.Bfexplorer.Domain
open BeloSoft.Bfexplorer.Trading
/// <summary>
/// SelectionData
/// </summary>
type SelectionData(selection : Selection) =
member _this.Selection
with get() = selection
member _this.LastPriceTraded
with get() = selection.LastPriceTraded
member val NearPrice : float = 0.0 with get, set
member val FarPrice : float = 0.0 with get, set
member val ActualSP : float = 0.0 with get, set
override this.ToString() =
sprintf "%s: %.2f | %.3f ~ %.3f" selection.Name this.LastPriceTraded this.NearPrice this.ActualSP
static member DataKey = "SelectionData"
static member Set (selection : Selection) =
selection.SetData(SelectionData.DataKey, SelectionData(selection))
static member Get (selection : Selection) =
selection.GetData<SelectionData>(SelectionData.DataKey)
[<AutoOpen>]
module ApiHelpers =
let updateSelectionSpPrice (selection : Selection, runner : API.Models.Runner) =
SelectionData.Get selection
|> Option.iter (fun selectionData ->
let spPrices = runner.sp
let spPrice = spPrices.actualSP
if spPrice = 0.0
then
selectionData.NearPrice <- spPrices.nearPrice
selectionData.FarPrice <- spPrices.farPrice
else
selectionData.ActualSP <- spPrice
)
/// <summary>
/// TriggerStatus
/// </summary>
type TriggerStatus =
| Initialize
| WaitForUpdateSpPrices
| WaitForRaceStart
| WaitToTriggerMyActionBot
| TriggerMyActionBot
| ReportError of string
/// <summary>
/// HorseRacingProjectedBspBotTrigger
/// </summary>
type HorseRacingProjectedBspBotTrigger(market : Market, _selection : Selection, _botName : string, botTriggerParameters : BotTriggerParameters, myBfexplorer : IMyBfexplorer) =
let useBspPrice = defaultArg (botTriggerParameters.GetParameter<bool>("UseBspPrice")) true
let doWaitForRaceStart = defaultArg (botTriggerParameters.GetParameter<bool>("WaitForRaceStart")) true
let mutable status = TriggerStatus.Initialize
let mutable myActionBotStartTime = DateTime.MinValue
let isHorseRacingMarket() =
market.MarketInfo.BetEventType.Id = 7 && market.MarketDescription.MarketType = "WIN"
let setMySelectionsData() =
market.Selections
|> Seq.filter isActiveSelection
|> Seq.iter SelectionData.Set
let updateBetfairSpPrices() =
async {
let! result = myBfexplorer.BfexplorerService.UpdateMarketData(market, API.Models.PriceProjection.DefaultBetfairSpPrice(), updateSelectionSpPrice)
status <-
if result.IsSuccessResult
then
myActionBotStartTime <- DateTime.Now.AddSeconds(defaultArg (botTriggerParameters.GetParameter<float>("ActionBotStartTime")) 0.0)
if doWaitForRaceStart && not useBspPrice
then
TriggerStatus.WaitForRaceStart
else
TriggerStatus.WaitToTriggerMyActionBot
else
TriggerStatus.ReportError result.FailureMessage
}
|> Async.Start
let outputMessage message =
myBfexplorer.BfexplorerService.OutputMessage(message, market.Id)
let reportData (selectionDatas : SelectionData list) =
selectionDatas
|> List.map (fun selectionData -> selectionData.ToString())
|> String.concat "\n"
|> outputMessage
let isMySelectionData (selectionData : SelectionData) =
if useBspPrice
then
selectionData.ActualSP > selectionData.LastPriceTraded
else
selectionData.FarPrice > selectionData.LastPriceTraded
let getMySelection() = maybe {
let selectionDatas =
market.Selections
|> Seq.sortBy (fun selection -> selection.LastPriceTraded)
|> Seq.choose SelectionData.Get
|> Seq.toList
reportData selectionDatas
let! selectionData = selectionDatas |> List.tryFind isMySelectionData
return selectionData.Selection
}
interface IBotTrigger with
/// <summary>
/// Execute
/// </summary>
member _this.Execute() =
match status with
| TriggerStatus.Initialize ->
if isHorseRacingMarket()
then
setMySelectionsData()
status <-
if useBspPrice
then
TriggerStatus.WaitForRaceStart
else
updateBetfairSpPrices()
TriggerStatus.WaitForUpdateSpPrices
TriggerResult.WaitingForOperation
else
TriggerResult.EndExecutionWithMessage "You can run this bot on a horse racing market only!"
| TriggerStatus.WaitForUpdateSpPrices -> TriggerResult.WaitingForOperation
| TriggerStatus.WaitForRaceStart ->
if market.IsInPlay
then
status <-
if useBspPrice
then
updateBetfairSpPrices()
TriggerStatus.WaitForUpdateSpPrices
else
TriggerStatus.WaitToTriggerMyActionBot
TriggerResult.WaitingForOperation
| TriggerStatus.WaitToTriggerMyActionBot ->
if DateTime.Now >= myActionBotStartTime
then
status <- TriggerStatus.TriggerMyActionBot
TriggerResult.WaitingForOperation
| TriggerStatus.TriggerMyActionBot ->
match getMySelection() with
| Some mySelection -> TriggerResult.ExecuteActionBotOnSelection mySelection
| None -> TriggerResult.EndExecution
| TriggerStatus.ReportError errorMessage -> TriggerResult.EndExecutionWithMessage errorMessage
/// <summary>
/// EndExecution
/// </summary>
member _this.EndExecution() =
()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment