A Fantasy Premier League Trading System

We will remember 2020. A year when we had to improvise. I want to highlight my achievements: many books, many tech learnings......and (almost) at 1st position in the Fantasy Premier League 😄 ⚽️. We've been playing with my friends since then and only good things have happened: tactical and bizarre discussions, funny stories, jokes and memes (of course). Being at home made me boost my critical thinking when using apps. I wondered: Why is this button here? Where can I provide feedback? Why this? Why that?, and the Fantasy was not the exception. It was even more savage and philosophical when I started to think why the game models a real football team but in an individualistic fashion. The football is a team sport. Of course there are players who shine and weight over the rest but at the end it's the group, the team who wins, loses or draws. This game is based on many rules but most of them are specific player rules. It makes sense for this game, but when you have a bad game week (GW), you realised that sometimes it's not fair enough (when you stand at first position everything shines and perfect). You have 11 players, if your striker scores 4 goals but his/her team was beaten by 10 goals, most likely your striker 🤷  will be rewarded with many points because for forward no matter the final result, every goal counts. Rules are the rules. I am fine with that and I really enjoy it even though sometimes the game it's so addictive and it makes you feel the worst human being in the world 😄, because you don't like player A, let's call it SN, but it turns out SN is a goals machine, so your team is made up of 80% (in a lucky day) trending and best ranked players, 19% cheapest players only to balance the budget and 1% it's your most loved player. Anyway, one day I started to think how to change the game but I can't of course, so I realised I wanted a new game with a better team balance scoring. If a player performs good it's probably because the team helps him/her so the team has influences on the individual score. So I came up with the idea of how the trading systems works and I started small: one player starts a game with X points and finishes it with: [X +/- ∑ actions], where ∑ actions is the sum of actions either good ➕ or bad ➖.A good action for me is a promising cross, to force a penalty or a save. A bad action is a yellow/red card, a foul or a wrong pass. So during a game (90') a player's score goes up and down, as a stock in Wall Street. Many team factors can affect this score. Also in a real stock trading system buyers and sellers move the numbers but here I am considering only performance index as main driver of points.

So I started a Proof of Concept, just for fun 🥳.

The Rules

The "market" opens when the referee starts the match. So a market is a match and we might have multiple matches per GW. Every player starts with a calculated score. For the first match of the season, this is calculated by some logic (TBD). The final scope for a given match will be the initial score for the next match.

So the idea is simple: during the match you can buy and sell players within a certain budget.

You can find the code here.

🙌 Hands-on


🛠  The stack: the project uses Grafana for visualisation and InfluxDB as time series database for recording events. For coding, since it's a PoC and I want agility and flexibility, Python will help for now.

Run the environment

  • make docker.run.dependencies: InfluxDB + Grafana

Events

If the system supports a minute to minute events, I need a source in order to collect information about every game and every player. Tough thing.
💡 The solution: Live commentaries. A description of an event that is broadcast in real-time on a website while the event is taking place. There are many websites, so I will use LiveScore for the sake of this experiment but any works if you set the proper collection and parsing rules.

The events in this site seem to follow always the same format. Some examples of the events that you can extract from this site:

53' - ⚽️ G O O O A A A L - Mohamed Salah reacts first on the loose ball and puts it away!
81' 🟨 After a tactical foul, Jordan Henderson sees no other way than stopping the counter and receives a yellow card.

In these examples it's clear that Salah's score would increase for the goal 📈 and Henderson's score would decrease 📉.

Sometimes the events might be like:

20' Shaqiri puts in a cross.

...and here the scoring should be different. Maybe the context of the previous seconds might give us insight to define.

Also we could have team events like this:

60' Ball possession: Arsenal: 44%, Liverpool: 56%.

...and the scoring should be distributed in 11 players.

So I have to handle different types of events, parse, extract the entities (player, team) and calculate a score which will increase or decrease the current one.

There are many algorithms, tools, frameworks which can help in this process. Maybe in real world a machine learning NLP model will work much more accurate of course but for the sake of the experiment and PoC I will use just static set of rules and the first naïve approach to extract entities will be extraction by position in the string.

Current Architecture

Future

Static Rules


As I mentioned before, I decided to start small with a static set of rules and a score for each rule which will increase or decrease the current score of the player and is decided by common sense.

There are team and player rules:

Team Rule:

  • X are clearly dominating possession => score 15

Player Rule:

  • X relieves the pressure with a clearance => score 10

... and so on.

Event Loader

The first thing is to load all raw events in our local storage. For that I need to know the start and end date and load the full fixture and then load every match/event.

./bin/loader run \
../stockball/output \
https://www.livescore.com/en/soccer/england/premier-league \ v1/api/react/stage/soccer/england/premier-league/1.00

The event loader takes 3 params:

  1. Output local destination
  2. URL from source
  3. Fixture Path

This process stores all matches for a given season:

The Fixture Path includes every matches in match-x folder. So now I have to read every file and extract the events.

Event Processor

Once we have ALL matches, this script will do the job and will send every normalised event to the DB.

The steps are:

  1. Read source (file).
  2. Normalize names (e.g. Mohamed Salah ==> mohamed_salah).
  3. Match rule pattern (team/player).
  4. Extract entities (team/player).
  5. Apply score.
  6. Store on DB.

Example of event for the DB:

{
    "measurement": "performance",
    "tags": {
        "player": "mohamed_salah",
        "team": "liverpool"
    },
    "time": "2020-11-01 14:03:00+00:00",
    "fields": {
        "value": 125
    }
}


Visualising

The data is already in DB, so now it's time to see how your team performed.
With the docker setup by default a pre-defined Dashboard is created when the service starts (see here).
You can use all features a graphs that Grafana provides.

Conclusion

There are many sports sites out there for playing and trading money for real. This was a very naïve and first solution to demonstrate how to build a homemade Football Trading System in a few hours using events in real-time and using public data. This is the Part I, and hopefully in Part II, I could share more and complete the idea. There are many other sources to get better quality of data.
On the contrary of this experiment, the text processing is not an easy task and it takes effort to get good results, here I started small just to see how the data looks like.

It's interesting the idea behind a trading system and how many factor might affect certain value in seconds. It seems like we can apply the same idea of any event streaming from different sources and model a set of rule to boost or penalise an entity's scoring: another sport, trending topics in social media, products in a e-commerce platform, cars models in the street.....what else?

Now it's time to iterate to the next stage. The main motivation and driver for this side project was the unbelievable year 2020 that we lived and the energy to learn something new.

In the current implementation there are LOTS of improvements: thousand of validations, code quality, testing, separate responsibilities, automation, new sources integration and so on.

This first approach was just for fun. 🎉

References

Fantasy Premier League, Official Fantasy Football Game of the Premier League
Official Fantasy Premier League 2020/21. Free to play fantasy football game, set up your fantasy football team at the Official Premier League site.
Premier League Live Scores, Results & Fixtures | LiveScore
Click here for the Fastest Premier League Live Score Updates. View previous results, upcoming fixtures & also a Real-Time view of the Premier League Table.