我试图计算一个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)这是我希望运行大量次数(200000作为粗略数字)并计算以下概率的for-循环:
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)但这不会返回10%范围以外的结果,即使循环200000次,结果的范围/扩展似乎在我定义的函数中得到了极大的减少。
有人能在我定义的函数'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)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~发布于 2018-01-14 07:52:58
贴出一个答案,因为我没有问题要评论。一些关于您的代码的查询--浏览这些代码--可能会帮助您找到一个答案:
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返回valsi %3
同样,对于sig_annual、rtn_daily和sig_daily,它们的内容都是索引的直接函数,所以我不知道使它们成为数组有什么好处。D实际上代表什么?正如您所定义的,它是一个具有0.0均值和标准差1.0的随机变量。因此,D中大约95%的值将在(-2.0,+2.0)范围内--这就是您所期望的吗?stock_value()函数,即使在很小的时间内(例如,从0到几天),以确保它正在做您认为应该做的事情?从你的问题中还不清楚你是否已经证实它是否做过正确的事情,对于任何输入来说,而且你的评论"...(possibly?)“听起来不太自信。stock_value中,返回语句在for循环中。它将在第一次循环(即i = 0时)被执行,而循环将永远不会得到更多的结果。这将是函数给循环提供不同结果的主要原因。stock < stock_initial * .9计算的。我希望这能帮到你。您可能希望使用首选IDE中的调试器(idle、thonny或eclipse,不管它是什么)逐步遍历您的代码,以查看您的代码实际上在做什么。
https://stackoverflow.com/questions/48220545
复制相似问题