Suppose you want to predict which of three candidates will win a political election. One approach is to get a group of experts and allow them to buy and sell shares of each candidate, in a way similar to how the stock market works. As shares in a candidate are bought, the price of the candidate increases. As shares are sold, the price decreases. The number of shares held by the experts on a candidate can be mapped to his probability of winning.

This scheme is called a prediction market. Prediction markets are often extremely accurate, in part because the experts have a monetary incentive to give a truthful, thoughtful opinion.

Determining the cost of a share of an option is somewhat deep mathematically, but not too difficult to implement. There are two cost equations. The first is a theoretical Cost that depends on the current number of outstanding shares for each option. A liquidity constant b, typically with value 100.0, controls how much the cost of a transaction changes after shares are bought or sold.

The second Cost function is the actual cost of buying n shares of an option i. This function calls the theoretical Cost function. One important detail is that when computing the theoretical cost, if you aren’t careful, it can blow up for even moderately large input values. A solution is to use a math trick that I call a softsum calculation (described in an earlier post).

Suppose that for three candidates, the current numbers of outstanding shares are (10, 30, 20). The cost before (using a simplified non-safe calculation approach) is:

C = 100.0 * ln(e^10/100 + e^30/100 + e^20/100) = 100.0 * ln(3.6764) = 100.0 * 1.3019 = 130.19

If 5 shares of the first candidate were purchased, the new number of outstanding shares would be (15, 30, 20) and so the cost after is:

C = 100.0 * ln(e^15/100 + e^30/100 + e^20/100) = 100.0 * ln(3.7331) = 100.0 * 1.3172 = 131.72

Therefore, the cost of the transaction to the expert would be $131.72 – $130.19 = $1.53.

Here’s a demo program:

using System; namespace MarketCost { class Program { static void Main(string[] args) { int[] shares = new int[] { 0, 0, 0 }; double b = 100.0; double c = Cost(shares, b, 3, 2); Console.Write("\nCost to buy 3 shares of option [2] = "); Console.WriteLine("$" + c.ToString("F4")); Console.WriteLine("NO purchase made"); c = Cost(shares, b, 1, 2); Console.Write("\nCost to buy 1 shares of option [2] = "); Console.WriteLine("$" + c.ToString("F4")); ++shares[2]; Console.WriteLine("Purchase made"); c = Cost(shares, b, 1, 2); Console.Write("\nCost to buy 1 shares of option [2] = "); Console.WriteLine("$" + c.ToString("F4")); ++shares[2]; Console.WriteLine("Purchase made"); c = Cost(shares, b, 1, 2); Console.Write("\nCost to buy 1 shares of option [2] = "); Console.WriteLine("$" + c.ToString("F4")); ++shares[2]; Console.WriteLine("Purchase made"); Console.WriteLine("\nEnd demo \n"); Console.ReadLine(); } // Main static double Cost(int[] shares, double b) { // underlying Cost function. safe version. int n = shares.Length; double[] vals = new double[n]; for (int i = 0; i < n; ++i) vals[i] = shares[i] / b; return b * Softsum(vals); } static double Softsum(double[] vals) { // safe calculation of ln(sum(exp(xi)) double max = vals[0]; for (int i = 1; i < vals.Length; ++i) if (vals[i] > max) max = vals[i]; double sum = 0.0; for (int i = 0; i < vals.Length; ++i) sum += Math.Exp(vals[i] - max); return Math.Log(sum) + max; } static double Cost(int[] shares, double b, int n, int i) { // cost to buy n shares of option i double cBefore = Cost(shares, b); int[] newShares = new int[shares.Length]; Array.Copy(shares, newShares, shares.Length); newShares[i] += n; double cAfter = Cost(newShares, b); return cAfter - cBefore; } } // Program } // ns