Suppose you want to predict which of three basketball teams will win a tournament. In a prediction market, you get a bunch of experts and let them buy and sell shares of each team. The price of a team will go up as more shares of the team are bought, and vice versa.

The number of outstanding shares can be mapped to the probabilities that each team will win, giving you your prediction. If x, y, and z are the number of outstanding shares of each team, then the probability that team X wins is:

And similarly for teams Y and Z. In the equation, b is a constant called the liquidity factor. The liquidity is also used in a different equation that determines the cost off a share of a team.

In many situations you can initialize the shares of each team to 0. This yields equal prices per share of $0.33 and equal initial probabilities of winning of 0.3333.

But in some situations you want to initialize the market to certain probabilities. So, the problem becomes, given a set of probabilities, what are the shares (x, y, z) that generate the probabilities?

The problem is a bit subtle and the solution is best explained with a concrete example. Suppose the desired initial probabilities are (0.3, 0.2, 0.5). It turns out that one solution for the (x, y, z) is approximately (141, 100, 192).

The first step is to find the smallest probability and then divide each probability by the smallest. Then you take the ln() of each and add 1. Then you multiply each by b and round off:

P p/min ln(_)+1 _ * b 0.3 1.5 1.4055 141 0.2 1.0 1.0000 100 0.5 2.5 1.9163 192

The idea is to use the lowest probability as a baseline that corresponds to 1 outstanding share, then determine the other values. Multiplying by b scales the number of shares up so that when rounded (because shares have to be integer values) there’s enough difference between values to keep the resulting probabilities close to the desired probabilities.

Here’s some demo code in C#:

using System; namespace MarketInit { class Program { static void Main(string[] args) { Console.WriteLine("\nBegin demo\n"); double[] p = new double[] { 0.3, 0.2, 0.5 }; double b = 100.0; Console.Write("probs = "); for (int i = 0; i < 3; ++i) Console.Write(p[i].ToString("F1") + " "); Console.WriteLine("\nb = " + b.ToString("F1")); Console.WriteLine("\nComputing initial shares"); int[] shares = InitialShares(p, b); Console.Write("\nInitial shares are: "); for (int i = 0; i < 3; ++i) Console.Write(shares[i] + " "); Console.WriteLine("\n\nEnd demo\n"); Console.ReadLine(); } // Main static int[] InitialShares(double[] p, double b) { int n = p.Length; double min = p[0]; // find min for (int i = 1; i < n; ++i) if (p[i] < min) min = p[i]; double[] f = new double[n]; // p / min for (int i = 0; i < n; ++i) f[i] = p[i] / min; double[] lg = new double[n]; for (int i = 0; i < n; ++i) lg[i] = Math.Log(f[i]) + 1; int[] result = new int[n]; for (int i = 0; i < n; ++i) result[i] = (int)Math.Round((lg[i] * b), 0); return result; } } // Program } // ns

I’ve left out a ton of details but this post has the essence of the key ideas.