From ff294f9f7487376299ac19cd0e813eebea4301f7 Mon Sep 17 00:00:00 2001 From: Emil Koutanov Date: Tue, 23 Jan 2024 08:28:30 +1100 Subject: [PATCH] Revised initial estimates for power and odds-ratio --- Overround.Tests/OddsRatioTest.cs | 4 ++-- Overround.Tests/PowerTest.cs | 4 ++-- Overround/OddsRatio.cs | 13 +++++++++---- Overround/Power.cs | 10 +++++----- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Overround.Tests/OddsRatioTest.cs b/Overround.Tests/OddsRatioTest.cs index 0bf2674..2c8f98b 100644 --- a/Overround.Tests/OddsRatioTest.cs +++ b/Overround.Tests/OddsRatioTest.cs @@ -24,14 +24,14 @@ public void TestApplyWithFairBooksumOf1() double[] fairPrices = [1 / 0.1, 1 / 0.2, 1 / 0.3, 1 / 0.4]; double[] odds = method.Apply(fairPrices, idealOverround); Assert.AreEqual(idealOverround, Booksum.FromPrices(odds), Delta); - ArrayAssert.AreEqual([8.328244274809158, 4.256997455470738, 2.8999151823579306, 2.2213740458015265], odds, Delta); + ArrayAssert.AreEqual([8.328, 4.257, 2.9, 2.221], odds, Delta); } { double idealOverround = 1.15; double[] fairPrices = [1 / 0.01, 1 / 0.29, 1 / 0.3, 1 / 0.4]; double[] odds = method.Apply(fairPrices, idealOverround); Assert.AreEqual(idealOverround, Booksum.FromPrices(odds), Delta); - ArrayAssert.AreEqual([80.59798994974874, 2.968463004678565, 2.876046901172529, 2.2060301507537687], odds, Delta); + ArrayAssert.AreEqual([80.644, 2.97, 2.877, 2.206], odds, Delta); } } diff --git a/Overround.Tests/PowerTest.cs b/Overround.Tests/PowerTest.cs index 245c29d..b265648 100644 --- a/Overround.Tests/PowerTest.cs +++ b/Overround.Tests/PowerTest.cs @@ -24,14 +24,14 @@ public void TestApplyWithFairBooksumOf1() double[] fairPrices = [1 / 0.1, 1 / 0.2, 1 / 0.3, 1 / 0.4]; double[] odds = method.Apply(fairPrices, idealOverround); Assert.AreEqual(idealOverround, Booksum.FromPrices(odds), Delta); - ArrayAssert.AreEqual([7.792612295808612, 4.200100853723753, 2.9257830833421794, 2.2637912052854765], odds, Delta); + ArrayAssert.AreEqual([7.793, 4.2, 2.926, 2.264], odds, Delta); } { double idealOverround = 1.15; double[] fairPrices = [1 / 0.01, 1 / 0.29, 1 / 0.3, 1 / 0.4]; double[] odds = method.Apply(fairPrices, idealOverround); Assert.AreEqual(idealOverround, Booksum.FromPrices(odds), Delta); - ArrayAssert.AreEqual([56.99885594904725, 2.9646851350987014, 2.877746548950255, 2.235448624371958], odds, Delta); + ArrayAssert.AreEqual([56.999, 2.965, 2.878, 2.235], odds, Delta); } } diff --git a/Overround/OddsRatio.cs b/Overround/OddsRatio.cs index 3fcd0b6..b04288f 100644 --- a/Overround/OddsRatio.cs +++ b/Overround/OddsRatio.cs @@ -2,10 +2,15 @@ namespace Overround; public class OddsRatio : IOverroundMethod { - private const double InitStep = 0.1; + private const double InitStep = 0.01; private const double ErrorThreshold = 1e-6; private const int MaxIterations = 100; + private static double GetInitEstimate(double fairBooksum, double idealBooksum, int numOutcomes) + { + return (numOutcomes / fairBooksum - 1) / (numOutcomes / idealBooksum - 1); + } + private static double[] ComputeOdds(double[] fairPrices, double g) { double[] odds = new double[fairPrices.Length]; @@ -19,13 +24,13 @@ private static double[] ComputeOdds(double[] fairPrices, double g) public double[] Apply(double[] fairPrices, double idealOverround) { double fairBooksum = Booksum.FromPrices(fairPrices); - double targetBooksum = idealOverround * fairBooksum; - double initEstimate = idealOverround; + double idealBooksum = idealOverround * fairBooksum; + double initEstimate = GetInitEstimate(fairBooksum, idealBooksum, fairPrices.Length); Solution solution = Solver.Solve(initEstimate, InitStep, ErrorThreshold, MaxIterations, estimate => { double[] odds = ComputeOdds(fairPrices, estimate); double booksum = Booksum.FromPrices(odds); - return Math.Pow(booksum - targetBooksum, 2); + return Math.Pow(booksum - idealBooksum, 2); }); return ComputeOdds(fairPrices, solution.Value); } diff --git a/Overround/Power.cs b/Overround/Power.cs index 03b0b51..c177f81 100644 --- a/Overround/Power.cs +++ b/Overround/Power.cs @@ -6,9 +6,9 @@ public class Power : IOverroundMethod private const double ErrorThreshold = 1e-6; private const int MaxIterations = 100; - private static double GetInitEstimate(double overround, int numOutcomes) + private static double GetInitEstimate(double fairBooksum, double idealBooksum, int numOutcomes) { - return 1 + Math.Log(1 / overround) / Math.Log(numOutcomes); + return Math.Log(idealBooksum / numOutcomes) / Math.Log(fairBooksum / numOutcomes); } private static double[] ComputeOdds(double[] fairPrices, double k) @@ -24,13 +24,13 @@ private static double[] ComputeOdds(double[] fairPrices, double k) public double[] Apply(double[] fairPrices, double idealOverround) { double fairBooksum = Booksum.FromPrices(fairPrices); - double targetBooksum = idealOverround * fairBooksum; - double initEstimate = GetInitEstimate(idealOverround, fairPrices.Length); + double idealBooksum = idealOverround * fairBooksum; + double initEstimate = GetInitEstimate(fairBooksum, idealBooksum, fairPrices.Length); Solution solution = Solver.Solve(initEstimate, InitStep, ErrorThreshold, MaxIterations, estimate => { double[] odds = ComputeOdds(fairPrices, estimate); double booksum = Booksum.FromPrices(odds); - return Math.Pow(booksum - targetBooksum, 2); + return Math.Pow(booksum - idealBooksum, 2); }); return ComputeOdds(fairPrices, solution.Value); }