c# - 随机双数的多次迭代往往会变小

标签 c# .net random double

我正在创建一个股票交易模拟器,其中将最后几天的交易价格作为开盘价并在当天进行模拟。

为此,我生成的随机双数可能是 lastTradePrice 的 -5% 和 lastTradePrice 之上的 5%。然而,在大约 240 次迭代之后,我看到生成的双数如何变得越来越小并接近于零。

Random rand = new Random();
Thread.Sleep(rand.Next(0,10));
Random random = new Random();
double lastTradeMinus5p = model.LastTradePrice - model.LastTradePrice * 0.05;
double lastTradePlus5p = model.LastTradePrice + model.LastTradePrice * 0.05;
model.LastTradePrice = random.NextDouble() * (lastTradePlus5p - lastTradeMinus5p) + lastTradeMinus5p;

如您所见,我正在尝试使用 Thread.sleep() 获取随机种子。然而它并不是真正随机化的。为什么总是会产生较小的数字?

enter image description here

更新:

数学本身实际上很好,尽管 Jon 已经证明了下降趋势。 还解释了获取范围之间的随机双数 here .

真正的问题是 Random 的种子。我听从了 Jon 的建议,为所有三种价格在线程中保持相同的 Random 实例。这已经产生了更好的结果;价格实际上正在反弹。我仍在调查并愿意接受如何改进这一点的建议。 Jon 提供的链接提供了一篇关于如何为每个线程生成随机实例的优秀文章。

顺便说一下整个project如果您有兴趣,它是开源的。 (在浏览器中使用 WCF、WPF、PRISM 4.2、.NET 4.5 堆栈)

TransformPrices 调用正在进行 here在一个单独的线程上。

如果我保留相同的随机实例,会发生这种情况: enter image description here

这是通过 RandomProvider.GetThreadRandom(); 生成的,正如文章中指出的那样: enter image description here

最佳答案

首先,像这样调用 Thread.Sleep 不是获得不同种子的好方法。每个线程使用一个 Random 实例会更好。看我的article on randomness对于一些建议的方法。

但是,您的代码本身也存在向下偏差。假设我们从随机数生成器“随机”得到 0.0 和 1.0,起始价格为 100 美元。这将给出:

  • 第 0 天:100 美元
  • 第 1 天:95 美元(-5% = 5 美元)
  • 第 2 天:99.75 美元(+5% = 4.75 美元)

现在我们同样可以随机得到 1.0 和 0.0:

  • 第 0 天:100 美元
  • 第 1 天:105 美元(+5% = 5 美元)
  • 第 2 天:99.75 美元(-5% = 5.25 美元)

请注意我们在这两种情况下的表现如何,尽管这是“公平的”。如果该值增加,这意味着它可以在下一次掷骰子时进一步下降,可以这么说……但如果该值下降,它就不能反弹那么远。

编辑:为了了解“合理公平”的随机数生成器如何仍然可能降低值(value),这里有一个小控制台应用程序:

using System;

class Test
{
    static void Main()
    {
        Random random = new Random();
        int under100 = 0;
        for (int i = 0; i < 100; i++)
        {
            double price = 100;
            double sum = 0;

            for (int j = 0; j < 1000; j++)
            {
                double lowerBound = price * 0.95;
                double upperBound = price * 1.05;
                double sample = random.NextDouble();
                sum += sample;
                price = sample * (upperBound - lowerBound) + lowerBound;                
            }
            Console.WriteLine("Average: {0:f2} Price: {1:f2}", sum / 1000, price);
            if (price < 100)
            {
                under100++;
            }
        }
        Console.WriteLine("Samples with a final price < 100: {0}", under100);
    }
}

在我的机器上,“平均”值总是非常接近 0.5(很少低于 0.48 或高于 0.52),但大多数“最终价格”总是低于 100 - 大约占其中的 65-70%。

关于c# - 随机双数的多次迭代往往会变小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22011270/

相关文章:

python - 在 Python 中以随机大小的部分拆分数字

c# - ASP.NET Core Web API + 对预检请求的 Angular 响应未通过访问控制检查 : Redirect is not allowed for a preflight request

c# - 绑定(bind)到 Monotouch 中的第 3 方库 - 映射 uint8_t * 和 uint8_t **

c# - V5R4 上 iSeries 的 .NET 数据提供程序

c# - 在哪里放置单元测试项目

c++ - 函数模板未正确生成随机数

r - 在向量中生成随机长度的 NA 随机序列

c# - 使用固定大小的缓冲区将结构数组从 C# 编码到 C++

c# - 简单注入(inject)器:跨相同图的服务注入(inject)相同的UnitOfWork实例

c# - 如何使用Task Parallel Library(TPL)实现重试逻辑