Created
February 9, 2022 13:18
-
-
Save StefanBelo/c4dd35758c5bbdb01e879dc105782d0f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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