Skip to content

Instantly share code, notes, and snippets.

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/de7168b7cf860ba2e4622c03203a9f28 to your computer and use it in GitHub Desktop.
Save StefanBelo/de7168b7cf860ba2e4622c03203a9f28 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 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