Uvod

Razjasnimo za početak sa kojim ciljem i na koji način pristupamo i analiziramo samo sportsko klađenje. Najpre, zapitajmo se na koji način funkcionišu sportske kladionice i kakvim mehanizmima se služe ne bi li profitirali. Obratimo najpre pažnju na najkonvencionalniji, sada već tradicionalni pristup klađenja: klađenje na konačan ishod sportskog dogadjala. Fokusiraćemo se na fudbalski meč. Mogući ishodi su: 1 - pobedio je domaćin; X - nema pobednika; 2 - pobedila je gostujuća ekipa. Teorijska verovatnoća svakog od tri pomenuta ishoda je 1/3. Na koji način bi se ove verovatnoće izrazile pomoću kvota? Kvote su ništa drugo nego recipročne vrednosti predviđenih verovatnoća ishoda. Dakle, u našem slučaju, kada posmatramo fudbalski meč, kvote na svaki od ishoda (1 X 2) bile bi 3.
U praksi, nije podjednako verovatno da će pobediti domaćin, pobediti gostujuća ekipa, ili da neće biti pobednika. Na svakom fudbalskom meču postoji ekipa koja je favorit. Veća je verovatnoća da će pobediti ekipa koja se smatra boljom u odnosu na reprezentativne parametre koji se posmatraju (npr. često se pretpostavlja da ekipa koja zauzima više mesto na tabeli fudbalskog prvenstva ima veće šanse za pobedom od ekipe koja zauzima niže mesto, u direktnom okršaju, jer je na osnovu pređašnjih rezultata pokazala da je bolja). Dakle, u praksi nikada neće kvote na svaki od krajnjih ishoda fudbalskog meča biti 3. Kako u praksi izgledaju kvote?

Realan primer kvota na krajnji ishod fudbalskog meča.
Kada prevedemo kvote u verovatnoće, možemo videti da prema ovoj kladionici, Man. City ima približno 71% šansi za pobedom, naspram svega 12% šansi Arsenala i 22% šansi za nerešenim ishodom. Zbir procenata je 105%. Nešto se ne uklapa? Trebalo bi da zbir verovatnoća bude 100%? Zaključujemo da opklada nije fer. Fer opklada bi bila u slučaju da je zbirni procenat verovatnoća za svaki od ishoda dogadjaja 100. U ovom slučaju, kladionica je u prednosti nad igračima za 5%. Postoje slučajevi kada je zbir verovatnoća svakog od ishoda manji od 100. Tada su igrači u prednosti nad kladionicom i takvim slučajevima ćemo se mi pozabaviti ovom prilikom.
Pre nego što se pozabavimo primenom programskog jezika R, napomenimo da postoje različiti zapisi kvota za različita tržišta. Malopređašnji zapis, decimalni, bi trebalo da je jasan. U SAD se primenjuje drugačiji sistem, koji je opet sveden na isto. Kvote koje mozete zateći u Američkim kladionicama su, na primer, +200 -150. Kvota +200 znači da na uloženih 100 dinara, u slučaju povoljnog ishoda, profitirate 200. U decimalnom zapisu, ovo bi bila kvota 3. -150 kvota znači da na uloženih 150 dinara, profitirate 100. U decimalnom zapisu, ovo bi bila kvota 1.67. Postoji još i zapis kvota u frakcijama, koji je zastupljen u Velikoj Britaniji. Kvote kakve možete zateći u VB su oblika 4/1, 23/2 itd. Njih čitamo po principu PROFIT/ULOG. 4/1 znači da na uložen 1 dinar, profitiramo 4.

# install.packages("devtools")
# devtools::install_github("a-i-sports/bettoR")

Instalirali smo najpre neophodan paket devtools koji nam omogućava instalaciju i primenu paketa sa Github-a. Potom smo instalirali prvi i osnovni paket koji ćemo obraditi bettoR. Ovaj paket sadrži neke od osnovnih funkcija koje nam pomažu da analiziramo i manipulišemo kvotama.

m <- -235;
n <- 152;
bettoR::convert_odds(m, input = "us", output = "dec")
## [1] 1.425532
bettoR::convert_odds(n, input = "us", output = "dec")
## [1] 2.52

Funckija convert_odds prebacuje kvote kroz različite zapise. Vrednost “us” predstavlja američki zapis, vrednost “dec” decimalni, a “frac” britanski. Izračunajmo ručno vrednost kvote -235 i +152 u decimalnom zapisu.

1 - 100/m
## [1] 1.425532
1 + n/100
## [1] 2.52

Ukoliko kao argument za output stavimo “all”, funkcija će nam izlistati vrednosti zatražene kvote u svim zapisima.

bettoR::convert_odds(m, input = "us", output = "all")
##   Decimal American Fraction Implied_Probability
## 1  1.4255     -235    20/47           0.7014925
bettoR::convert_odds(n, input = "us", output = "all")
##   Decimal American Fraction Implied_Probability
## 1    2.52      152    38/25           0.3968254


Funkcija bet_calc računa nam povratnu sumu novca (ulog + potencijalni profit) u slučaju povoljnog ishoda opklade. Povratnu sumu novca u slučaju povoljnog ishoda opklade, ili žargonski u slučaju da nam “prođe tiket” računamo tako što ulog pomnožimo sa kvotom.

bettoR::bet_calc(risk = 30, odds = 1.85, type = "dec")
## [1] 55.5

Ovo bi bio povrat u slučaju da smo se opkladili samo na jednom događaju. Moguće je uvezati više događaja na jednoj opkladi. Tada se verovatnoća povoljnog ishoda celokupne opklade smanjuje, ali se kvota umnožava. Kvota u slučaju uvezane opklade računa se tako što se pomnože kvote sa svakog pojedinačnog uvezanog događaja. Funkcija parlay_calc računa profit u slučaju uvezane opklade.

bettoR::parlay_calc(risk = 100, odds = c(1.2, 2, 3.2), type = "dec")
## [1] 668

Ovo smo mogli i pomoću funkcije bet_calc da izračunamo.

kvote <- c(1.2, 2, 3.2);
ulog <- 100;
bettoR::bet_calc(risk = ulog, odds = prod(kvote), type = "dec") - ulog
## [1] 668


Osvrnimo se za trenutak ka košarci. Česte su opklade na ukupan broj poena na samoj utakmici, kao i na koš razliku kojom će se utakmica završiti. Kladionica zadaje granicu ukupnog broja poena, a mi imamo mogućnost da se opkladimo da li će biti više ili manje poena od zadate granice. Hendikep klađenje funkcioniše na sledeći način. Procena kladionice je da je ekipa koja je favorit na utakmici bolja za 20 razlike. Osim konvencionalnih opklada, kladionica nam nudi da se po jednakim kvotama opkladimo da će favorit pobediti u slučaju da mu se na kraju utakmice oduzme 20 poena od skora, kao i da će podređena ekipa pobediti u slučaju da joj se na kraju utakmice doda 20 poena. Tako se verovatnoće oba ishoda događaja iz opklade, po proceni kladionice, svode na 50%. Funkcija expected_scores nam na osnovu zadate granice ukupnog broja poena, kao i granice hendikepa vraća predviđen rezultat utakmice.

bettoR::expected_scores(home_line = -20, total = 200)
##   home_line total home_score away_score
## 1       -20   200        110         90
bettoR::expected_scores(home_line = 16, total = 200)
##   home_line total home_score away_score
## 1        16   200         92        108


Funkcija implied_prob računa nam verovatnoću povoljnog ishoda opklade u zavisnosti od kvote na koju smo se opkladili.

bettoR::implied_prob(odds = 2, type = "dec")
## [1] 0.5

Inverzna funkcija koja računa kvotu u zavisnosti od zadate verovatnoće povoljnog ishoda opklade je implied_odds.

bettoR::implied_odds(prob = 0.5, type = "dec")
## [1] 2

Međutim, setimo se da kladionica retko postavlja fer opklade. Realna verovatnoća povoljnog ishoda opklade često je manja u odnosu na verovatnoću prema zadatoj kvoti. U slučaju da klađenja na ukupan broj poena na košarkaškoj utakmici, kvote na koje možemo naići su uglavnom 1.85. Funkcija hold_calc računa procenat interesa koji kladionica naplaćuje kroz kvote.

kvota <- bettoR::convert_odds(1.85, "dec", "us");
bettoR::hold_calc(kvota, kvota)
## [1] 0.07627119

Naravno, dešava se i da kvote budu posložene tako da u prednosti ne budu kladionice, već igrači. Malo je verovatno da se takve kvote nađu objedinjene u istoj kladionici, ali sasvim je realno pronaći u tri različite kladionice tri kvote koje zajedno grupisane daju igračima prednost. No, time ćemo se detaljnije pozabaviti u posebnom delu.
Funkcija fair_odds vraća nam fer kvotu korigovanjem one koju je kladionica postavila.

bettoR::fair_odds(line = 1.85, odds = c(1.85, 1.85), type = "dec")
## [1] 2

U slučaju fudbalske utakmice između Mančester Sitija i Arsenala, fer kvote bile bi:

bettoR::fair_odds(1.4, c(1.4, 4.5, 8.5), type = "dec")
## [1] 1.475797
bettoR::fair_odds(4.5, c(1.4, 4.5, 8.5), type = "dec")
## [1] 4.743833
bettoR::fair_odds(8.5, c(1.4, 4.5, 8.5), type = "dec")
## [1] 8.960573

Funkcija true_implied_prob vraća nam svarne verovatnoće povoljnih ishoda opkada prema postavljenim kvotama, naspram verovatnoća koje je kladionica nametnula (direktne recipročne vrednosti kvota).

bettoR::true_implied_prob(odds = c(1.4, 4.5, 8.5), type = "dec")
##   true_prob imp_prob
## 1    0.6776   0.7143
## 2    0.2108   0.2222
## 3    0.1116   0.1176

Funkcija true_probability radi istu stvar, ali samo za onu kvotu koju mi unesemo kao argument.

bettoR::true_probability(line = 1.4, odds = c(1.4, 4.5, 8.5), type = "dec")
## [1] 0.6776


Sada kada u osnovi znamo kako možemo analizirati kvote i manipulisati njima, možemo postaviti strategiju kako da steknemo prednost u odnosu na kladionicu i profitiramo. Dva osnovna pristupa strateškom klađenju su Value betting i Sure betting.

Value betting

Koncept Value betting strategije zasniva se na prepoznavanju vrednosti određene kvote i ulaganju u istu. Vrednost kvote se može posmatrati kao “greška” koju kladionica svesno ili nesvesno pravi u kreiranju kvota. Posmatrajmo na primer kvotu 1.45.

(verovatnoca <- round(bettoR::convert_odds(1.45, input = "dec", output = "prob"), digits = 2))
## [1] 0.69

Mi kao igrači upoznati smo sa događajem na koji želimo da se opkladimo, informisani smo o mogućim ishodima i zaključujemo da je realna verovatnoća pozitivnog ishoda opklade 75%. Dakle, po našoj proceni, realna kvota na događaj na koji želimo da se opkladimo je:

(kvota <- bettoR::implied_odds(prob = 0.75, type = "dec"))
## [1] 1.333333

Predviđamo da je u pitanju greška kladionice - postavili su veću kvotu od realne. Iskoristimo to. Ukoliko procenjujemo da je realna verovatnoća pozitivnog ishoda opklade 75%, očekujemo da ako kontinuirano kladimo na pozitivan ishod ovog događaja, po ovoj kvoti, u 3 od 4 puta osvojimo opkladu. U tom slučaju, profit u slučaju pozitivnog ishoda biće:

ulog <- 100;
profit <- bettoR::bet_calc(risk = ulog, odds = 1.45, type = "dec") - 100 #dinara

Dok će u slučaju negativnog ishoda, profit biti -100 dinara. Dakle, očekujemo da (teorijski) posle četiri opklade, na stanju imamo:

3 * profit - 1 * ulog
## [1] 35

Dakle, očekuje nas profit u iznosu od 35 dinara. Nije loše, za početak. Neophodno je strpljenje, jer može desiti da od prvih 20 opklada, izgubimo 10 i u tom trenutku na stanju imamo manje novca nego na početku, ali ukoliko smo sigurni da je verovatnoća pozitivnog ishoda svake pojedinačne opklade 75%, to znači da u narednih 40 opklada očekujemo da ćemo osvojiti 35 i onda budemo u plusu. Primer koji navodimo je prilično veštački i retke su situacije kada ćemo uspevati da “ulovimo” tako veliku razliku između realne kvote i kvote koju je postavila kladionica. Međutim, trebalo bi da je princip Value betting strategije sada jasan.
Funkcija clv_calc (closing line value) računa nam vrednost (value) kvote na kojoj smo se opkladili, u poređenju sa kvotom koja je aktuelna pred sam početak događaja na koji se kladimo. Smatra se da je najtačnija ona kvota koju kladionica postavi pred sam početak događaja.

bettoR::clv_calc(bet_odds = 1.45, closing_odds = kvota, type = "dec")
## [1] 0.0875

Pozitivna povratna vrednost funkcije ukazuje na to da je naša procena bila ispravna. U slučaju da smo pogrešili i vrednost kvote pred sam početak događaja bude veća od one na kojoj smo se opkladili, povratna vrednost biće negativna.

bettoR::clv_calc(bet_odds = 1.45, closing_odds = 1.6, type = "dec")
## [1] -0.09375

Funkcija expected_value računa nam očekivani profit na osnovu uloga, potencijalnog profita u slučaju povoljnog ishoda opklade i realne verovatnoće tog ishoda.

bettoR::expected_value(payout = profit, risk = ulog, win_prob = verovatnoca)
## [1] 0.05

Ovo možemo izračunati i pešaka:

profit * verovatnoca - ulog * (1 - verovatnoca)
## [1] 0.05

Funkcija expected_roi računa procentualni očekivani profit u odnosu na uplatu.

bettoR::expected_roi(payout = profit, risk = ulog, win_prob = verovatnoca)
## [1] 5e-04

Što je ekvivalentno računici:

bettoR::expected_value(payout = profit, risk = ulog, win_prob = verovatnoca) / ulog
## [1] 5e-04

Možemo se ponovo za trenutak fokusirati na košarkašku utakmicu i opklade na ukupan broj poena i hendikep. Često možemo kod različitih kladionica pronaći različite predikcije, odnosno zadate granice na ukupan broj poena i hendikep. Uz kraće istraživanje, lako se može zaključiti koja kladionica ima najtačnije i najrelevantnije granice. Uporedimo predviđene granice hendikepa u naredne dve kladionice.
Realan primer kvota na krajnji ishod fudbalskog meča.

Realan primer kvota na krajnji ishod fudbalskog meča.

Funkcija bet_prob računa verovatnoću povoljnog i nepovoljnog ishoda opklade na zadatu granicu hendikepa, uporedivši je sa realnom granicom. Kao realnu granicu računaćemo granicu sa prve slike. Želimo da se opkladimo po granici sa druge slike.

bettoR::bet_prob(pred_spread = -7.5, spread = -5.5, sport = "NBA")
##   Win.Probability Lose.Probability Push.Probability
## 1       0.5661838        0.4338162                0

Verovatnoća povoljnog ishoda je dakle približno 57%. Kvota po kojoj možemo da se opkladimo je 1.85. Dakle, na uloženih 100 dinara, u slučaju povoljnog ishoda, profit nam je 85. Proverimo da li kvota 1.85 na granici hendikepa -5.5 ima vrednost.

bettoR::expected_value(payout = 85, risk = 100, win_prob = 0.57)
## [1] 5.45

Eto nama prilike za zaradom! Zaključujemo da kvota ima vrednost. Prethodnom metodom možemo stalno pronalaziti ovakve kvote i eksploatišemo ih u skladu sa mogućnostima. Tu prednost možemo vizuelizovati pomoću funkcije bet_prob_plot.

bettoR::bet_prob_plot(pred_spread = -7.5, spread = -5.5, sport = "NBA")


Možemo na kraju simulirati strategiju Value bettinga kroz klađenje na hendikepe košarkaških utakmica. Kvotu i verovatnoću iz prethodnog primera ćemo posmatrati kao prosečne vrednosti u simulaciji. Kladićemo se svakoga dana na po jednu utakmicu tokom cele godine i konstantno ćemo ulagati po 100 dinara/dolara na svaku opkladu. Simulaciju sprovodimo pomoću funkcije bankroll_plot. Radi preglednosti trajektorija profita kroz opklade, najpre ćemo sprovesti mali broj simulacija.

bettoR::bankroll_plot(bets = 365, 
              win_rate = 0.57,
              bet_size = 100,
              sim_length = 10,
              avg_odds = 1.85,
              odds_type = "dec",
              current_bet = NULL,
              current_win = NULL)
## 
## Positive Negative 
##      0.9      0.1 
## 
##  Median Profit/Loss = $1,838
## Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
## use `guide = "none"` instead.


Zelene trajektorije predstavljaju slučajeve u kojima smo nakon godinu dana klađenja u suficitu, a crvene trajektorije slučajeve kada završavamo u deficitu. I na malom uzorku zaključujemo da je veća šansa za dugoročnom zaradom nego za gubitkom. U svrhu potvrde isplativosti ove strategije, sprovešćemo još jednu simulaciju, samo ovoga puta sa večim brojem ponavljana. Sami prosudite da li je strategija isplativa i u kojoj meri.

bettoR::bankroll_plot(bets = 365, 
              win_rate = 0.57,
              bet_size = 100,
              sim_length = 500,
              avg_odds = 1.85,
              odds_type = "dec",
              current_bet = NULL,
              current_win = NULL)
## 
## Positive Negative 
##    0.868    0.132 
## 
##  Median Profit/Loss = $2,274
## Warning: It is deprecated to specify `guide = FALSE` to remove a guide. Please
## use `guide = "none"` instead.

Sure betting

Sure betting pristup strateškom klađenju ima za cilj da nezavisno od ishoda događaja donese profit. Setimo se priče sa početka - postoje slučajevi kada su kvote postavljene tako da igrači budu u prednosti u odnosu na kladionice. Uzmimo primer slučajno izabrane utakmice i uporedimo kvote na svaki od ishoda (1 X 2).
Realan primer kvota na krajnji ishod fudbalskog meča.
Različite kladionice daju različite kvote za opkladu na isti događaj. Nama kao igračima, najprimamljivije su najviše kvote. Izabraćemo zato najvišu kvotu za svaki od ishoda događaja.

k1 <- 3.22;
american_k1 <- bettoR::convert_odds(k1, "dec", "us");
kX <- 3.55;
american_kX <- bettoR::convert_odds(kX, "dec", "us");
k2 <- 3;
american_k2 <- bettoR::convert_odds(k2, "dec", "us");
(prednost <- bettoR::hold_calc(american_k1, american_kX, american_k2))
## [1] -0.08040074

Eto nama još jedne prilike za zaradom - imamo 8.04% prednosti nad kladionicom! Sada je još samo potrebno da izračunamo kako da rasporedimo novackoji imamo na svaku od kvota, tako da profit bude približno isti, nezavisno od samog ishoda događaja. Pretpostavimo da imamo 100 dinara.

ulog <- 100;
profit <- abs(prednost) * 100;
(ulog1 <- (ulog + profit) / k1)
## [1] 33.55282
(ulogX <- (ulog + profit) / kX)
## [1] 30.43382
(ulog2 <- (ulog + profit) / k2)
## [1] 36.01336

Formirali smo sigurnu opkladu. Ostaje nam samo da sačekamo krajnji ishod događaja i naplatimo dobitak. Da bi strategija dostigla svoj pun potencijal, trebalo bi da težimo ka tome da na svakom događaju (fudbalskoj utakmici) pronađemo najbolju kvotu za svaki od mogućih ishoda (1 X 2) i u slučaju da možemo, formiramo sigurnu opkladu.
Instalirajmo i učitajmo paket tidyverse, koji sadrži objedinjene pakete za obradu i vizuelizaciju podataka koje ćemo koristiti.

rm(list = ls())
#install.packages("tidyverse")
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.5     ✓ purrr   0.3.4
## ✓ tibble  3.1.6     ✓ dplyr   1.0.7
## ✓ tidyr   1.1.4     ✓ stringr 1.4.0
## ✓ readr   2.0.1     ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

Poslužićemo se bazom podataka koja između ostalog sadrži arhive kvota različitih kladionica, za sve fudbalske mečeve odigrane u glavnim evropskim fudbalskim ligama. Slične baze podataka mogu se pronaći na sledećem linku. Iz baze uzimamo one kolone koje su nam potrebne kako bismo formirali sigurne opklade. Ograničavamo se na tradicionalan vid klađenja - klađenje na konačan ishod fudbalske utakmice (1 X 2).

library(readr)
baza <- read.csv("E0.csv")
baza <- baza %>% select(Date, HomeTeam, AwayTeam, FTR, MaxH, MaxD, MaxA)
head(baza)
##         Date       HomeTeam    AwayTeam FTR MaxH MaxD  MaxA
## 1 12/09/2020         Fulham     Arsenal   A 6.55 4.55  1.60
## 2 12/09/2020 Crystal Palace Southampton   H 3.36 3.36  2.50
## 3 12/09/2020      Liverpool       Leeds   H 1.35 6.50 10.75
## 4 12/09/2020       West Ham   Newcastle   A 2.24 3.70  3.60
## 5 13/09/2020      West Brom   Leicester   A 4.00 3.82  2.04
## 6 13/09/2020      Tottenham     Everton   A 1.98 3.68  4.50


Promenljiva FTR odnosi se na konačan ishod utakmice Posmatramo bazu koja sadrži arhivirane utakmice - znamo konačne ishode svih utakmica jer se u ovom slučaju bavimo isključivo analizom i upoznavanjem sa strateškim klađenjem. Svakako, sve dalje navedeno moglo bi se primeniti i u slučaju da baza podataka zapravo sadrži utakmice na čije ishode možemo još uvek da se opkladimo. MaxH referiše na maksimalnu ponuđenu kvotu na pobedu domaće ekipe (HomeTeam) koju izvojene kladionice nude. Analogno važi za MaxD (nerešen ishod) i MaxA (pobeda gostujuće ekipe - AwayTeam).
Dodajemo u bazu kolone koje primenjenu verovatnoću opklade na svaki od događaja, procentualnu prednost koju ostvarujemo nad kladionicom (ili kladionica nad nama) i indikator da li možemo formirati sigurnu opkladu.

baza$impliedProb <- 1/baza$MaxH + 1/baza$MaxD + 1/baza$MaxA
baza$advantage <- 1 - baza$impliedProb
baza$surebet <- ifelse(baza$advantage > 0, 1, 0)
head(baza %>% select(-MaxH, -MaxD, -MaxA))
##         Date       HomeTeam    AwayTeam FTR impliedProb     advantage surebet
## 1 12/09/2020         Fulham     Arsenal   A   0.9974520  0.0025480245       1
## 2 12/09/2020 Crystal Palace Southampton   H   0.9952381  0.0047619048       1
## 3 12/09/2020      Liverpool       Leeds   H   0.9876102  0.0123898496       1
## 4 12/09/2020       West Ham   Newcastle   A   0.9944766  0.0055233805       1
## 5 13/09/2020      West Brom   Leicester   A   1.0019762 -0.0019761831       0
## 6 13/09/2020      Tottenham     Everton   A   0.9990119  0.0009881423       1


Možemo predstaviti verovatnoće svih opklada preko grafika i razdvojiti sigurne opklade od onih koje je trebalo preskočiti.

(plot1 <- ggplot(baza, aes(x = c(1:nrow(baza)), y = impliedProb)) +
  geom_point(aes(col = surebet)) +
  coord_cartesian(ylim=c(0.95, 1.05)) +
  ggtitle("Verovatnoće opkladana konačan ishod utakmica Premier lige", subtitle = "za sezonu 2020/2021") +
  xlab("Utakmice") + ylab("Verovatnoće"))


Ukupan broj utakmica na kojima smo mogli zaraditi primenom Sure betting strategije je:

sum(baza$surebet)
## [1] 162

Izračunajmo sada kolika bi nam zarada bila u slučaju da smo se na svakoj od poželjnih utakmica opkladili sa po 100 dinara. Dodajemo bazi kolone u kojima ćemo zabeležiti uloge koje je trebalo uplatiti na svaki od ishoda događaja (1 X 2).

ulog <- 100;
baza$ulogH <- round(ifelse(baza$surebet == 1, ulog * 1/baza$MaxH * (1+baza$advantage), 0), 2)
baza$ulogD <- round(ifelse(baza$surebet == 1, ulog * 1/baza$MaxD * (1+baza$advantage), 0), 2)
baza$ulogA <- round(ifelse(baza$surebet == 1, ulog * 1/baza$MaxA * (1+baza$advantage), 0), 2)
head(baza %>% select(HomeTeam, AwayTeam, FTR, impliedProb, ulogH, ulogD, ulogA))
##         HomeTeam    AwayTeam FTR impliedProb ulogH ulogD ulogA
## 1         Fulham     Arsenal   A   0.9974520 15.31 22.03 62.66
## 2 Crystal Palace Southampton   H   0.9952381 29.90 29.90 40.19
## 3      Liverpool       Leeds   H   0.9876102 74.99 15.58  9.42
## 4       West Ham   Newcastle   A   0.9944766 44.89 27.18 27.93
## 5      West Brom   Leicester   A   1.0019762  0.00  0.00  0.00
## 6      Tottenham     Everton   A   0.9990119 50.55 27.20 22.24

Dodajemo bazi kolone u kojima u kojima ćemo zabeležiti potencijalne dobitke u svakom od tri povoljna ishoda, kao i kolonu u kojoj beležimo profit koji smo mogli ostvariti na svakoj utakmici.

baza$dobitakH <- round(ifelse(baza$FTR == "H",1,0) * baza$ulogH * baza$MaxH,2)
baza$dobitakD <- round(ifelse(baza$FTR == "D",1,0) * baza$ulogD * baza$MaxD,2) 
baza$dobitakA <- round(ifelse(baza$FTR == "A",1,0) * baza$ulogA * baza$MaxA,2)
baza$profit <- baza$dobitakH + baza$dobitakD + baza$dobitakA - baza$ulogH - baza$ulogD - baza$ulogA

Ukupan profit koji bismo ostvarili da smo se opkladili sa po 100 dinara na svakoj poželjnoj fudbalskoj utakmici Premier lige u sezoni 2020/2021 bio bi:

sum(baza$profit)
## [1] 82.14

Moglo je to i bolje. U prethodnom slučaju, kladili smo se sa po 100 dinara na svakoj utakmici. Šta bi bilo da smo na svakoj ulagali i ostvaren profit do tog trenutka? U tom slučaju zaradili bismo mnogo više novca, a na koji način, obrazložili smo u narednom delu. Svakoga dana, odabrali bismo najprofitabilniju utakmicu, odnosno utakmicu sa najvišim % prednosti koji bismo ostvarili u odnosu na kladionicu (ukoliko takva uopšte postoji) i sav novac koji trenutno imamo na raspolaganju uložili bismo na tu utakmicu. Postavimo početni ulog ponovo na 100 dinara i formirajmo niz u kojima ćemo beležiti stanja novca koja bismo posle svake utakmice.

rm(list = ls())
baza <- read.csv("E0.csv")
baza <- baza %>% select(Date, HomeTeam, AwayTeam, FTR, MaxH, MaxD, MaxA)
baza$Date <- as.Date(as.character(baza$Date),"%d/%m/%Y")
baza$impliedProb <- 1/baza$MaxH + 1/baza$MaxD + 1/baza$MaxA
baza$advantage <- 1 - baza$impliedProb
baza$surebet <- ifelse(baza$advantage > 0, 1, 0)
baza <- baza %>% filter(surebet == 1)

pocetni_ulog <- 100
raspoloziva_stanja <- c(pocetni_ulog)

Iteriramo kroz bazu po danima, selektujemo svakoga dana najprofitabilniju utakmicu, zatim trenutno raspoloživo stanje uložimo na tu utakmicu i izračunamo dobitak koji ostvarujemo. Na kraju svake iteracije, ažuriramo sanje novca. Iz baze uklanjamo utakmice na kojima nemamo mogućnosti da postavimo sigurnu opkladu.

datumi <- unique(baza$Date)
for(dan in datumi) {
  ulog <- raspoloziva_stanja[length(raspoloziva_stanja)]
  najbolja_utakmica <- baza %>% filter(Date == dan) %>% filter(impliedProb == min(impliedProb))
  
  najbolja_utakmica$ulogH <- round(ulog * (1/najbolja_utakmica$MaxH) * (1 + najbolja_utakmica$advantage), 2)
  najbolja_utakmica$ulogD <- round(ulog * (1/najbolja_utakmica$MaxD) * (1 + najbolja_utakmica$advantage), 2)
  najbolja_utakmica$ulogA <- round(ulog * (1/najbolja_utakmica$MaxA) * (1 + najbolja_utakmica$advantage), 2)
  
  najbolja_utakmica$dobitakH <- round(ifelse(najbolja_utakmica$FTR == "H", 1, 0) * najbolja_utakmica$ulogH * najbolja_utakmica$MaxH, 2)
  najbolja_utakmica$dobitakD <- round(ifelse(najbolja_utakmica$FTR == "D", 1, 0) * najbolja_utakmica$ulogD * najbolja_utakmica$MaxD, 2)
  najbolja_utakmica$dobitakA <- round(ifelse(najbolja_utakmica$FTR == "A", 1, 0) * najbolja_utakmica$ulogA * najbolja_utakmica$MaxA, 2)
  
  raspoloziva_stanja <- c(raspoloziva_stanja, 
                          (najbolja_utakmica$dobitakH + najbolja_utakmica$dobitakD + najbolja_utakmica$dobitakA))
}

Prikažimo grafički količinu novca koji bismo imali na raspolaganju vremenom.

raspoloziva_stanja <- raspoloziva_stanja[-1]
set <- cbind(datumi, raspoloziva_stanja)
(plot2 <- ggplot(as.data.frame(set), aes(x = datumi, y = raspoloziva_stanja)) +
  geom_line(color = "darkgreen") +
  labs(x = "Vreme", y = "Količina raspoloživog novca")) +
  scale_x_continuous(breaks = seq(0, length(datumi), by = length(datumi)))


Kada se podvuče crta, profitirali bismo:

raspoloziva_stanja[length(raspoloziva_stanja)] - pocetni_ulog
## [1] 91.37

Kada uzmemo u obzir činjenicu da smo strategiju postavili isključivo prema utakmicama engleske Premier lige, zaključujemo da ovo nije ni približna vrednost maksimalnom profitu koji bismo ostvarili da smo u bazu uključili i utakmice drugih evropskih liga.

Zaključak

Potrudili smo se da rad prilagodimo tako da i potpuni laik koji nikada nije ni pomislio da uđe u kladionicu, a kamoli da se i opkladi može da razume o čemu smo pisali. Sve gore napisano ima za cilj da čitaocima približi koncept strateškog klađenja i ujedno im ponudi alat pomoću kog strategiju mogu sprovesti u delo.

Hvala na pažnji i srećno!