从循环python创建蒙特卡罗模拟

时间:2018-01-12 06:12:09

标签: python loops montecarlo

我试图计算for循环的可能性,使用monte-carlo模拟返回低于初始值输入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)

这会产生“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)

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

1 个答案:

答案 0 :(得分:0)

发布答案,因为我没有评论要点。有关您的代码的一些问题 - 通过这些查询可能会帮助您找到答案:

  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到几天),以确保它能按照您的想法进行操作?从您的问题中不清楚您是否已经验证它曾经正在做正确的事情,任何输入和您的评论&#34; {{1 }}&#34;听起来不太自信。

  4. 剧透警报 - 它几乎肯定没有。在函数...(possibly?)中,您的return语句在 stock_value循环中。它会在for时第一次被执行,并且循环将永远不会比这更进一步。这将是函数为循环提供不同结果的主要原因。

  5. 此外,如果您说&#34;返回低于...&#34;的10%的值,我认为您的意思是&#34;返回的值比...低至少10%。 。&#34;,因为那是i = 0计算的概率。

  6. 我希望这会有所帮助。您可能希望在首选IDE(stock < stock_initial * .9idlethonny中使用调试器逐步执行代码,无论它是什么),以查看代码实际执行的操作。