我试图计算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)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
答案 0 :(得分:0)
发布答案,因为我没有评论要点。有关您的代码的一些问题 - 通过这些查询可能会帮助您找到答案:
为什么要将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_annual
,rtn_daily
和sig_daily
- 这些内容都是索引的直接功能,所以我不确定它的优势是什么制作阵列。
D
实际代表什么?正如您所定义的那样,它是一个随机变量,平均值为0.0
,标准差为1.0
。因此D
中大约95%的值都在(-2.0,+ 2.0)范围内 - 是您所期望的吗?
您是否测试了stock_value()
功能,即使是在很短的时间内(例如从0到几天),以确保它能按照您的想法进行操作?从您的问题中不清楚您是否已经验证它曾经正在做正确的事情,任何输入和您的评论&#34; {{1 }}&#34;听起来不太自信。
剧透警报 - 它几乎肯定没有。在函数...(possibly?)
中,您的return语句在 stock_value
循环中。它会在for
时第一次被执行,并且循环将永远不会比这更进一步。这将是函数为循环提供不同结果的主要原因。
此外,如果您说&#34;返回低于...&#34;的10%的值,我认为您的意思是&#34;返回的值比...低至少10%。 。&#34;,因为那是i = 0
计算的概率。
我希望这会有所帮助。您可能希望在首选IDE(stock < stock_initial * .9
,idle
或thonny
中使用调试器逐步执行代码,无论它是什么),以查看代码实际执行的操作。