【问题标题】:Creating a monte carlo simulation from a loop python从循环python创建蒙特卡罗模拟
【发布时间】:2018-06-21 13:53:07
【问题描述】:

我正在尝试使用蒙特卡罗模拟计算 for 循环返回低于初始值输入 10% 的值的概率。

for i in range(0, period):
    if i < 1:
        r=(rtn_daily[i]+sig_daily[i]*D[i])
        stock = stock_initial * (1+r)
    elif i >=1:
        r=(rtn_daily[i]+sig_daily[i]*D[i])
        stock = stock * (1+r)
print(stock)

这是我希望多次运行的 for 循环(粗略数字为 200000)并计算以下概率:

stock < stock_initial * .9

我找到了将初始循环定义为函数然后将在循环中使用该函数的示例,因此我尝试从我的循环中定义一个函数:

def stock_value(period):
    for i in range(0, period):
        if i < 1:
            r=(rtn_daily[i]+sig_daily[i]*D[i])
            stock = stock_initial * (1+r)
        elif i >=1:
            r=(rtn_daily[i]+sig_daily[i]*D[i])
            stock = stock * (1+r)
    return(stock)

这会产生“股票”的值,这些值似乎与定义为函数之前的范围不同。

我尝试使用此代码运行蒙特卡罗模拟:

# code to implement monte-carlo simulation
number_of_loops = 200 # lower number to run quicker 

for stock_calc in range(1,period+1):
    moneyneeded = 0
    for i in range(number_of_loops):
        stock=stock_value(stock_calc)
        if stock < stock_initial * 0.90:
            moneyneeded += 1
    #print(stock) this is to check the value of stock being produced.
stock_percentage = float(moneyneeded) / number_of_loops
print(stock_percentage)

但是即使循环 200000 次,这也不会返回 10% 范围之外的结果,似乎结果的范围/分布在我定义的函数中以某种方式大大减少了。

任何人都可以在我定义的函数“stock_value”中看到问题,或者可以看到以我没有遇到过的方式实现蒙特卡罗模拟的方法吗?

我的完整代码供参考:

#import all modules required
import numpy as np # using different notation for easier writting
import scipy as sp 
import matplotlib.pyplot as plt

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#collect variables provided by the user
stock_initial = float(12000) # can be input for variable price of stock initially.
period = int(63) # can be edited to an input() command for variable periods.
mrgn_dec = .10 # decimal value of 10%, can be manipulated to produce a 10% increase/decrease
addmoremoney = stock_initial*(1-mrgn_dec)

rtn_annual = np.repeat(np.arange(0.00,0.15,0.05), 31) 
sig_annual = np.repeat(np.arange(0.01,0.31,0.01), 3) #use .31 as python doesn't include the upper range value.

#functions for variables of daily return and risk.
rtn_daily = float((1/252))*rtn_annual
sig_daily = float((1/(np.sqrt(252))))*sig_annual
D=np.random.normal(size=period) # unsure of range to use for standard distribution


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# returns the final value of stock after 63rd day(possibly?)
def stock_value(period):
    for i in range(0, period):
        if i < 1:
            r=(rtn_daily[i]+sig_daily[i]*D[i])
            stock = stock_initial * (1+r)
        elif i >=1:
            r=(rtn_daily[i]+sig_daily[i]*D[i])
            stock = stock * (1+r)
        return(stock)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# code to implement monte-carlo simulation
number_of_loops = 20000

for stock_calc in range(1,period+1):
    moneyneeded = 0
    for i in range(number_of_loops):
        stock=stock_value(stock_calc)
        if stock < stock_initial * 0.90:
            moneyneeded += 1
    print(stock)
stock_percentage = float(moneyneeded) / number_of_loops
print(stock_percentage)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

【问题讨论】:

  • 好的。在这种情况下,您需要明确描述与您想要的代码不同的代码。说“它失败了”几乎什么也没告诉我们。您可能希望 stock_value 函数将 return stock 用于调用代码,以便可以将其与 stock_initial 进行比较。
  • @PM2Ring 编辑了我的帖子。在定义 stock_value 的过程中,它似乎产生了比应有的更窄的价差。这与代码不属于函数时的样子不同,并且这些值是通过手动重复运行代码来生成的。

标签: python loops montecarlo


【解决方案1】:

发布答案,因为我没有评论的要点。关于您的代码的一些问题 - 仔细阅读这些问题可能会帮助您找到答案:

  1. 为什么将rtn_annual 定义为数组np.repeat(np.arange(0.00,0.15,0.05), 31)?既然只是重复了[0.0, 0.05, 0.1]的值,为什么不把它定义为一个函数呢?:

    def rtn_annual(i):
      vals = [0.0,  0.05,  0.1]
      return vals[i % 3]
    

    sig_annualrtn_dailysig_daily 也是如此——它们的内容都是索引的直接函数,所以我不确定将它们设为数组有什么好处。

  2. D 实际上代表什么?正如您所定义的,它是一个随机变量,平均值为0.0,标准差为1.0。所以D 中大约 95% 的值将在 (-2.0, +2.0) 范围内 - 这是您所期望的吗?

  3. 您是否测试过您的 stock_value() 函数,即使是在很短的时间段内(例如从 0 到几天),以确保它按照您认为的方式运行?从您的问题中不清楚您是否已验证它曾经针对任何输入做正确的事情,并且您的评论“...(possibly?)”听起来不太自信。

  4. 剧透警告 - 几乎可以肯定不会。在函数stock_value 中,您的返回语句for 循环中。它将在第一次执行,当i = 0 时,循环将永远不会比这更进一步。这将是函数为循环提供不同结果的主要原因。

  5. 另外,如果您说“返回的值低于...的 10%”,我假设您的意思是“返回的值至少低于...的 10%”,因为这就是您的概率 @ 987654337@正在计算中。

我希望这会有所帮助。您可能希望使用首选 IDE(idlethonnyeclipse,无论它可能是什么)中的调试器单步调试您的代码,以查看您的代码实际在做什么。

【讨论】:

    猜你喜欢
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多