在 python 中生成价格情景
generate price scenarios in python
我有一个变量列表 price
更改:
price = 1000
changes = [0, -0.5, +0.5, -1, 1]
# change means new_price = old_price * (1 + change)
我需要一个列表,显示 price
将如何因多次连续更改而发生变化;例如,这是 2 次连续更改的样子:
[1000, 1000, 1000]
[1000, 1000, 500]
[1000, 1000, 1500]
[1000, 1000, 0]
[1000, 1000, 2000]
[1000, 500, 500]
[1000, 500, 250]
[1000, 500, 750]
[1000, 500, 0]
[1000, 500, 1000]
[1000, 1500, 1500]
[1000, 1500, 750]
[1000, 1500, 2250]
[1000, 1500, 0]
[1000, 1500, 3000]
[1000, 0, 0]
[1000, 0, 0]
[1000, 0, 0]
[1000, 0, 0]
[1000, 0, 0]
[1000, 2000, 2000]
[1000, 2000, 1000]
[1000, 2000, 3000]
[1000, 2000, 0]
[1000, 2000, 4000]
允许使用numpy
库。
看起来很复杂,但矩阵很容易解决。为了解决问题,有几个关键要理解。
让我们采用以下矩阵:
[1000, 1000, 1000] <- list_of_changes
[1000, 1000, 500] <- list_of_changes
[1000, 1000, 1500] <- list_of_changes
[1000, 1000, 0] <- list_of_changes
[1000, 1000, 2000] <- list_of_changes
每个更改列表可以分为 3 个部分:index0
、index1
、rest_of_indexes
。
- 最终矩阵总是有 3 个轴
index0
永远等于 price
index1
将始终是 price
的变化 axis0
从 changes
的索引
rest_of_indexes
可以像下面的例子一样计算buy迭代过程
change_mat[0, :, 2] =
[1000] [0]
[1000] [-0.5]
[1000] * [+0.5]
[1000] [-1]
[1000] [1]
change_mat[1, :, 2] =
[500] [0]
[500] [-0.5]
[500] * [+0.5]
[500] [-1]
[500] [1]
这应该可以解决问题:
import numpy as np
price = 1000
changes = np.array([0, -0.5, 0.5, -1, 1])
combinations = 2
change_mat = np.zeros((len(changes), len(changes), combinations + 1))
change_mat[:, :, 0] = price
for axis0 in range(len(changes)):
change_mat[axis0, :, 1] = change_mat[axis0, :, 0] * (1 + changes[axis0])
for combination in range(combinations-1):
change_mat[:, :, combination+2] = change_mat[:, :, combination+1] * (1 + changes)
重复广播计算,然后互相广播结果,最后移动坐标轴:
>>> changes = np.array([0, -0.5, +0.5, -1, 1])
>>> price = np.array(1000)
>>> prices = [price]
>>> times = 2
>>> for _ in range(times):
... prices.append(prices[-1][..., None] * (changes + 1))
...
>>> shape = prices[-1].shape
>>> ar = np.array([np.broadcast_to(a[(...,) + (None,) * (times - i)], shape) for i, a in enumerate(prices)])
>>> np.moveaxis(ar, 0, -1)
array([[[1000., 1000., 1000.],
[1000., 1000., 500.],
[1000., 1000., 1500.],
[1000., 1000., 0.],
[1000., 1000., 2000.]],
[[1000., 500., 500.],
[1000., 500., 250.],
[1000., 500., 750.],
[1000., 500., 0.],
[1000., 500., 1000.]],
[[1000., 1500., 1500.],
[1000., 1500., 750.],
[1000., 1500., 2250.],
[1000., 1500., 0.],
[1000., 1500., 3000.]],
[[1000., 0., 0.],
[1000., 0., 0.],
[1000., 0., 0.],
[1000., 0., 0.],
[1000., 0., 0.]],
[[1000., 2000., 2000.],
[1000., 2000., 1000.],
[1000., 2000., 3000.],
[1000., 2000., 0.],
[1000., 2000., 4000.]]])
我有一个变量列表 price
更改:
price = 1000
changes = [0, -0.5, +0.5, -1, 1]
# change means new_price = old_price * (1 + change)
我需要一个列表,显示 price
将如何因多次连续更改而发生变化;例如,这是 2 次连续更改的样子:
[1000, 1000, 1000]
[1000, 1000, 500]
[1000, 1000, 1500]
[1000, 1000, 0]
[1000, 1000, 2000]
[1000, 500, 500]
[1000, 500, 250]
[1000, 500, 750]
[1000, 500, 0]
[1000, 500, 1000]
[1000, 1500, 1500]
[1000, 1500, 750]
[1000, 1500, 2250]
[1000, 1500, 0]
[1000, 1500, 3000]
[1000, 0, 0]
[1000, 0, 0]
[1000, 0, 0]
[1000, 0, 0]
[1000, 0, 0]
[1000, 2000, 2000]
[1000, 2000, 1000]
[1000, 2000, 3000]
[1000, 2000, 0]
[1000, 2000, 4000]
允许使用numpy
库。
看起来很复杂,但矩阵很容易解决。为了解决问题,有几个关键要理解。
让我们采用以下矩阵:
[1000, 1000, 1000] <- list_of_changes
[1000, 1000, 500] <- list_of_changes
[1000, 1000, 1500] <- list_of_changes
[1000, 1000, 0] <- list_of_changes
[1000, 1000, 2000] <- list_of_changes
每个更改列表可以分为 3 个部分:index0
、index1
、rest_of_indexes
。
- 最终矩阵总是有 3 个轴
index0
永远等于price
index1
将始终是price
的变化axis0
从changes
的索引
rest_of_indexes
可以像下面的例子一样计算buy迭代过程
change_mat[0, :, 2] =
[1000] [0]
[1000] [-0.5]
[1000] * [+0.5]
[1000] [-1]
[1000] [1]
change_mat[1, :, 2] =
[500] [0]
[500] [-0.5]
[500] * [+0.5]
[500] [-1]
[500] [1]
这应该可以解决问题:
import numpy as np
price = 1000
changes = np.array([0, -0.5, 0.5, -1, 1])
combinations = 2
change_mat = np.zeros((len(changes), len(changes), combinations + 1))
change_mat[:, :, 0] = price
for axis0 in range(len(changes)):
change_mat[axis0, :, 1] = change_mat[axis0, :, 0] * (1 + changes[axis0])
for combination in range(combinations-1):
change_mat[:, :, combination+2] = change_mat[:, :, combination+1] * (1 + changes)
重复广播计算,然后互相广播结果,最后移动坐标轴:
>>> changes = np.array([0, -0.5, +0.5, -1, 1])
>>> price = np.array(1000)
>>> prices = [price]
>>> times = 2
>>> for _ in range(times):
... prices.append(prices[-1][..., None] * (changes + 1))
...
>>> shape = prices[-1].shape
>>> ar = np.array([np.broadcast_to(a[(...,) + (None,) * (times - i)], shape) for i, a in enumerate(prices)])
>>> np.moveaxis(ar, 0, -1)
array([[[1000., 1000., 1000.],
[1000., 1000., 500.],
[1000., 1000., 1500.],
[1000., 1000., 0.],
[1000., 1000., 2000.]],
[[1000., 500., 500.],
[1000., 500., 250.],
[1000., 500., 750.],
[1000., 500., 0.],
[1000., 500., 1000.]],
[[1000., 1500., 1500.],
[1000., 1500., 750.],
[1000., 1500., 2250.],
[1000., 1500., 0.],
[1000., 1500., 3000.]],
[[1000., 0., 0.],
[1000., 0., 0.],
[1000., 0., 0.],
[1000., 0., 0.],
[1000., 0., 0.]],
[[1000., 2000., 2000.],
[1000., 2000., 1000.],
[1000., 2000., 3000.],
[1000., 2000., 0.],
[1000., 2000., 4000.]]])