Last active
December 21, 2018 13:14
-
-
Save StefanBelo/3baa73a8a33adb5147fecd4d75bf22ed 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 BeloSoft.Data | |
open BeloSoft.Betfair | |
open BeloSoft.Bfexplorer.Domain | |
open BeloSoft.Bfexplorer.Trading | |
/// <summary> | |
/// BetfairSpPrice | |
/// </summary> | |
type BetfairSpPrice() = | |
member val ActualSP : float = 0.0 with get, set | |
static member DataKey = "bsp" | |
static member Set (selection : Selection) = | |
selection.SetData(BetfairSpPrice.DataKey, BetfairSpPrice()) | |
static member Get (selection : Selection) = | |
selection.GetData<BetfairSpPrice>(BetfairSpPrice.DataKey) | |
/// <summary> | |
/// MySelectionData | |
/// </summary> | |
type MySelectionData(selection : Selection, spPrice : float) = | |
let mutable triggerPriceValue : float option = None | |
let mutable triggerOddsDifferenceCrossed = false | |
member _this.Selection | |
with get() = selection | |
member _this.SpPrice | |
with get() = spPrice | |
member _this.CanExecute | |
with get() = triggerOddsDifferenceCrossed | |
member _this.Update(triggerPrice : float, triggerOddsDifference : int) = | |
let price = selection.LastPriceTraded | |
match triggerPriceValue with | |
| Some myTriggerPrice -> | |
let oddsDifference = selection.OddsContext.GetOddsDifference(myTriggerPrice, price) | |
triggerOddsDifferenceCrossed <- oddsDifference >= triggerOddsDifference | |
| None -> | |
if price <= triggerPrice | |
then | |
triggerPriceValue <- Some price | |
/// <summary> | |
/// updateSelectionSpPrice | |
/// </summary> | |
/// <param name="selection"></param> | |
/// <param name="runner"></param> | |
let updateSelectionSpPrice (selection : Selection, runner : API.Models.Runner) = | |
BetfairSpPrice.Get selection | |
|> Option.iter (fun betfairSpPrices -> | |
let spPrices = runner.sp | |
betfairSpPrices.ActualSP <- spPrices.actualSP | |
) | |
/// <summary> | |
/// TriggerStatus | |
/// </summary> | |
type TriggerStatus = | |
| Initialize | |
| WaitForInPlay | |
| WaitForUpdateSpPrices | |
| ReportSpPrices | |
| WaitToTriggerActionBot | |
| ReportError of string | |
/// <summary> | |
/// HorseRacingSpFavouriteBotTrigger | |
/// </summary> | |
type HorseRacingSpFavouriteBotTrigger(market : Market, _selection : Selection, _botName : string, botTriggerParameters : BotTriggerParameters, myBfexplorer : IMyBfexplorer) = | |
let favouriteSpPrice = defaultArg (botTriggerParameters.GetParameter<float>("FavouriteSpPrice")) 2.0 | |
let myHorsesSpPrice = defaultArg (botTriggerParameters.GetParameter<float>("MyHorsesSpPrice")) 7.0 | |
let triggerPrice = defaultArg (botTriggerParameters.GetParameter<float>("TriggerPrice")) 3.0 | |
let triggerOddsDifference = defaultArg (botTriggerParameters.GetParameter<int>("TriggerOddsDifference")) 5 | |
let mutable status = TriggerStatus.Initialize | |
let mutable mySelectionsDatas = nil<MySelectionData list> | |
let outputMessage message = | |
myBfexplorer.BfexplorerService.OutputMessage(message, market.Id) | |
let getMySelectionsDatas() = | |
market.Selections | |
|> Seq.choose (fun selection -> | |
match BetfairSpPrice.Get selection with | |
| Some betfairSpPrice -> | |
let spPrice = betfairSpPrice.ActualSP | |
if spPrice = 0.0 | |
then | |
None | |
else | |
Some (MySelectionData(selection, spPrice)) | |
| None -> None | |
) | |
|> Seq.sortBy (fun mySelectionData -> mySelectionData.SpPrice) | |
|> Seq.toList | |
let showHorsesData (selectionsDatas : MySelectionData list) = | |
selectionsDatas | |
|> List.map (fun selectionData -> sprintf "%s: %.2f" selectionData.Selection.Name selectionData.SpPrice) | |
|> String.concat "\n" | |
|> outputMessage | |
let canExecuteMyStrategy (selectionsDatas : MySelectionData list) = | |
let favourite = selectionsDatas.Head | |
favourite.SpPrice <= favouriteSpPrice | |
let getMySelectionsDatasToWatch (selectionsDatas : MySelectionData list) = | |
selectionsDatas |> List.filter (fun selectionData -> selectionData.SpPrice >= myHorsesSpPrice) | |
let getMySelection() = | |
mySelectionsDatas |> List.iter (fun mySelectionsData -> mySelectionsData.Update(triggerPrice, triggerOddsDifference)) | |
mySelectionsDatas |> List.tryFind (fun mySelectionsData -> mySelectionsData.CanExecute) | |
interface IBotTrigger with | |
member __.Execute() = | |
match status with | |
| TriggerStatus.Initialize -> | |
if market.MarketInfo.BetEventType.Id = 7 | |
then | |
status <- TriggerStatus.WaitForInPlay | |
market.Selections | |
|> Seq.filter isActiveSelection | |
|> Seq.iter BetfairSpPrice.Set | |
TriggerResult.WaitingForOperation | |
else | |
TriggerResult.EndExecutionWithMessage "You can run this bot on a horse racing market only!" | |
| TriggerStatus.WaitForInPlay -> | |
if market.IsInPlay | |
then | |
status <- TriggerStatus.WaitForUpdateSpPrices | |
async { | |
let! result = myBfexplorer.BfexplorerService.UpdateMarketData(market, API.Models.PriceProjection.DefaultBetfairSpPrice(), updateSelectionSpPrice) | |
status <- | |
if result.IsSuccessResult | |
then | |
TriggerStatus.ReportSpPrices | |
else | |
TriggerStatus.ReportError result.FailureMessage | |
} | |
|> Async.Start | |
TriggerResult.WaitingForOperation | |
| TriggerStatus.WaitForUpdateSpPrices -> TriggerResult.WaitingForOperation | |
| TriggerStatus.ReportSpPrices -> | |
let selectionsDatas = getMySelectionsDatas() | |
showHorsesData selectionsDatas | |
if canExecuteMyStrategy selectionsDatas | |
then | |
mySelectionsDatas <- getMySelectionsDatasToWatch selectionsDatas | |
if mySelectionsDatas.Length > 0 | |
then | |
status <- TriggerStatus.WaitToTriggerActionBot | |
TriggerResult.WaitingForOperation | |
else | |
TriggerResult.EndExecution | |
else | |
TriggerResult.EndExecution | |
| TriggerStatus.WaitToTriggerActionBot -> | |
match getMySelection() with | |
| Some mySelectionData -> TriggerResult.ExecuteActionBotOnSelection mySelectionData.Selection | |
| None -> TriggerResult.WaitingForOperation | |
| TriggerStatus.ReportError errorMessage -> TriggerResult.EndExecutionWithMessage errorMessage | |
member __.EndExecution() = | |
() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment