Created
June 16, 2018 18:48
-
-
Save StefanBelo/de7168b7cf860ba2e4622c03203a9f28 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
// 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 FootballOverUnderStrategyBotTrigger | |
//#I @"D:\Projects\Bfexplorer\Development\Applications\BeloSoft.Bfexplorer.App\bin\Debug\" | |
#I @"C:\Program Files (x86)\BeloSoft\Bfexplorer\" | |
#r "BeloSoft.Data.dll" | |
#r "BeloSoft.Betfair.API.dll" | |
#r "BeloSoft.Bfexplorer.Domain.dll" | |
#r "BeloSoft.Bfexplorer.FootballScoreProvider.dll" | |
#r "BeloSoft.Bfexplorer.Trading.dll" | |
#r "BeloSoft.Bfexplorer.Service.Core.dll" | |
open System | |
open System.Text | |
open BeloSoft.Data | |
open BeloSoft.Bfexplorer.Domain | |
open BeloSoft.Bfexplorer.Trading | |
open BeloSoft.Bfexplorer.FootballScoreProvider | |
open BeloSoft.Bfexplorer.FootballScoreProvider.API.Models | |
open BeloSoft.Bfexplorer.FootballScoreProvider.Models | |
/// <summary> | |
/// TriggerStatus | |
/// </summary> | |
type TriggerStatus = | |
| Initialize | |
| UpdateMatchScore | |
| WaitNoOperation | |
| OpenOverUnderMarket | |
| ExecuteMyStrategy | |
| ReportError of string | |
| NoTrades | |
/// <summary> | |
/// FootballOverUnderStrategyBotTrigger | |
/// </summary> | |
type FootballOverUnderStrategyBotTrigger(market : Market, _selection : Selection, _botName : string, botTriggerParameters : BotTriggerParameters, myBfexplorer : IMyBfexplorer) = | |
let executeAtMatchTime = defaultArg (botTriggerParameters.GetParameter<int>("ExecuteAtMatchTime")) 88 | |
let lastGoalTimeAllowed = defaultArg (botTriggerParameters.GetParameter<int>("LastGoalTimeAllowed")) 80 | |
let mutable status = TriggerStatus.Initialize | |
let mutable footballMatch = nil<FootballMatch> | |
let mutable updateTime = DateTime.MinValue | |
let mutable matchDetailData = nil<MatchDetailData> | |
let mutable executeOnMarket = nil<Market> | |
let isTimeToCheckMatchDetails() = | |
footballMatch.MatchTime >= executeAtMatchTime | |
let canExecuteMyStrategy() = | |
let goals = | |
matchDetailData.UpdateDetails | |
|> Array.filter (fun updateDetail -> updateDetail.UpdateType = "Goal") | |
if goals.Length > 0 | |
then | |
(goals |> Array.last).MatchTime <= lastGoalTimeAllowed | |
else | |
true | |
let footballMatchScoreUpdated(result : bool) = | |
updateTime <- DateTime.Now.AddSeconds(15.0) | |
status <- | |
if result | |
then | |
if isTimeToCheckMatchDetails() | |
then | |
Async.StartWithContinuations( | |
computation = FootballScoreProvider.GetMatchDetails(footballMatch), | |
continuation = (fun result -> | |
status <- | |
if result.IsSuccessResult | |
then | |
matchDetailData <- result.SuccessResult | |
if canExecuteMyStrategy() | |
then | |
TriggerStatus.OpenOverUnderMarket | |
else | |
TriggerStatus.NoTrades | |
else | |
TriggerStatus.ReportError result.FailureMessage | |
), | |
exceptionContinuation = (fun ex -> status <- TriggerStatus.ReportError ex.Message), | |
cancellationContinuation = (fun ex -> status <- TriggerStatus.ReportError ex.Message) | |
) | |
TriggerStatus.WaitNoOperation | |
else | |
TriggerStatus.UpdateMatchScore | |
else | |
TriggerStatus.ReportError "Failed to update the match score." | |
let initialize() = | |
if market.MarketInfo.BetEventType.Id = 1 && market.MarketDescription.MarketType = "MATCH_ODDS" | |
then | |
footballMatch <- CreateFootballMatch market | |
TriggerResult.UpdateFootballMatchScore (footballMatch, footballMatchScoreUpdated) | |
else | |
TriggerResult.EndExecutionWithMessage "You can execute this bot only on a football market." | |
let openOverUnderMarket() = | |
let marketName = sprintf "OVER_UNDER_%d5" (footballMatch.HomeScore + footballMatch.AwayScore) | |
OpenAssociatedMarkets ([| marketName |], fun result -> | |
status <- | |
if result.IsSuccessResult | |
then | |
executeOnMarket <- result.SuccessResult.[0] | |
TriggerStatus.ExecuteMyStrategy | |
else | |
TriggerStatus.ReportError (sprintf "Failed to open the market: %s" marketName) | |
) | |
let getGoals(updateDetails : UpdateDetailData[]) = | |
if updateDetails.Length > 0 | |
then | |
updateDetails |> Array.map (fun updateDetail -> sprintf "%d' %s" updateDetail.MatchTime updateDetail.Team) |> String.concat ", " | |
else | |
"no goals scored" | |
let reportGoalScored() = | |
let sb = StringBuilder() | |
sb.AppendLine(footballMatch.ToString()) |> ignore | |
let goals = matchDetailData.UpdateDetails |> Array.filter (fun updateDetail -> updateDetail.UpdateType = "Goal") | |
let message = | |
if goals.Length > 0 | |
then | |
let firstHalfGoals, secondHalfGoals = goals |> Array.partition (fun updateDetail -> updateDetail.MatchTime <= 45) | |
sb | |
.AppendLine(sprintf "The first half goals: %s" (getGoals(firstHalfGoals))) | |
.AppendLine(sprintf "The second half goals: %s" (getGoals(secondHalfGoals))) | |
.ToString() | |
else | |
sb | |
.AppendLine("No goals scored.") | |
.ToString() | |
myBfexplorer.BfexplorerService.OutputMessage(message) | |
interface IBotTrigger with | |
/// <summary> | |
/// Execute | |
/// </summary> | |
member this.Execute() = | |
match status with | |
| TriggerStatus.Initialize -> initialize() | |
| TriggerStatus.UpdateMatchScore -> | |
if DateTime.Now >= updateTime | |
then | |
TriggerResult.UpdateFootballMatchScore (footballMatch, footballMatchScoreUpdated) | |
else | |
TriggerResult.WaitingForOperation | |
| TriggerStatus.WaitNoOperation -> TriggerResult.WaitingForOperation | |
| TriggerStatus.OpenOverUnderMarket -> openOverUnderMarket() | |
| TriggerStatus.ExecuteMyStrategy -> | |
reportGoalScored() | |
TriggerResult.ExecuteActionBotOnMarketSelectionAndContinueToExecute (executeOnMarket, executeOnMarket.Selections.[0], false) | |
| TriggerStatus.ReportError errorMessage -> TriggerResult.EndExecutionWithMessage errorMessage | |
| TriggerStatus.NoTrades -> TriggerResult.EndExecution | |
/// <summary> | |
/// EndExecution | |
/// </summary> | |
member this.EndExecution() = | |
() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment