Как сделать простой процесс моделирования цены акций более эффективным в Python? - PullRequest
1 голос
/ 10 июля 2019

У меня есть очень простой код, написанный для имитации цены акций, предполагающей случайное движение от -2% до + 2% в день (это слишком упрощенно, но для демонстрации я решил, что это проще, чем использовать формулу GMB).

У меня проблема в том, что это очень медленно, я понимаю, что это потому, что я использую двойные циклы. Из того, что я понимаю, я мог бы использовать векторизацию, но я не могу понять, как.

По сути, я создал 100 симуляций, предполагая 256 торговых дней в году, каждый день предыдущая цена акций умножалась на случайное число от 0,98 до 1,02.

В настоящее время я делаю это, используя вложенный цикл for. Как я понимаю, это нехорошо, но, как новичок, мне трудно векторизоваться. Я читал об этом в Интернете, и из того, что я понимаю, в основном, вместо того, чтобы использовать циклы, вы пытались бы преобразовать их в матрицы и использовать умножение матриц, но я не уверен, как применить это здесь. Может кто-то указать мне верное направление?

from numpy import exp, sqrt, log, linspace
from random import gauss
from random import uniform
import pandas as pd


nsims = 100
stpx = 100
days = 256
mainframe = pd.DataFrame(0, index = list(range(1,days)), columns = list(range(1,nsims)))
mainframe.iloc[0] = stpx
for i in range(0, nsims-1):
    for x in range(1, days-1):
        mainframe.iloc[x, i] = mainframe.iloc[x-1, i]* uniform(.98, 1.02)

1 Ответ

0 голосов
/ 10 июля 2019

Векторизация может быть сложной, если один расчет основан на результате предыдущего расчета, как в этом случае, когда день x должен знать результаты дня x-1. Я не скажу, что это невозможно сделать, поскольку вполне возможно, что кто-то найдет способ, но вот мое решение, которое, по крайней мере, избавляет от одного из циклов. Мы по-прежнему перебираем дни, но мы делаем все 100 симуляций одновременно, генерируя массив случайных чисел и используя поэлементное умножение numpy (что намного быстрее, чем использование цикла):

Вам нужно будет добавить следующий импорт:

import numpy as np

А затем замените ваш вложенный цикл следующим циклом:

for x in range(1, days-1):
    mainframe.iloc[x] = mainframe.iloc[x-1] * np.random.uniform(0.98, 1.02, nsims-1)

Изменить, чтобы добавить: поскольку вы используете очень простую формулу, которая включает в себя только базовое умножение, вы фактически можете избавиться от обоих циклов, генерируя случайную матрицу чисел, используя кумулятивную функцию произведения numpy по столбцам и умножая ее на DataFrame, где каждое значение начинается с 100. Я не уверен, что такой подход был бы жизнеспособным, если бы вы начали использовать более сложную формулу. Вот это все равно:

import pandas as pd
import numpy as np

nsims = 100
stpx = 100
days = 256

mainframe = pd.DataFrame(stpx, index=list(range(1, days)), columns=list(range(1, nsims)))
rand_matrix = np.random.uniform(0.98, 1.02, (days-2, nsims-1)).cumprod(axis=0)
mainframe.iloc[1:] *= rand_matrix
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...