Существуют ли известные методы для создания реалистичных фальшивых биржевых данных? - PullRequest
16 голосов
/ 22 декабря 2011

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

Ответы [ 11 ]

48 голосов
/ 22 декабря 2011

Простой алгоритм заключается в использовании простого числа волатильности, которое ограничивает, насколько акции могут измениться в течение определенного периода (скажем, одного дня).Чем выше число, тем более изменчиво.Таким образом, каждый день вы можете вычислить новую цену следующим образом:

rnd = Random_Float(); // generate number, 0 <= x < 1.0
change_percent = 2 * volatility * rnd;
if (change_percent > volatility)
    change_percent -= (2 * volatility);
change_amount = old_price * change_percent;
new_price = old_price + change_amount;

Стабильная акция будет иметь волатильность, равную, возможно, 2%.Волатильность в 10% показала бы довольно большие колебания.

Не идеально, но это может выглядеть довольно реалистично.

Образцы

enter image description here

6 голосов
/ 25 ноября 2013

Есть несколько ответов, которые дают достаточно учебный ответ: используйте геометрическое броуновское движение для моделирования цен на акции. Но есть одна главная причина считать это неправильным. Реальные цены на акции не ведут себя как геометрическое броуновское движение (GBM). Я объясню это немного.

Причина, по которой GBM используется в учебниках для моделирования процесса определения цены акций, заключается в простоте. Это поможет вам развить теорию и получить некоторые базовые результаты, которые кажутся «по существу» правильными. Это не значит, что вы должны думать, что именно так «выглядят» цены на акции. Это все равно что вывести уравнение движения без учета трения (что теоретически очень полезно), а затем подумать, что именно так выглядит движение в реальной жизни, например, каждый катается на своих ботинках, как коньки.

Одним из теоретически наиболее полезных свойств GBM является то, что будущие изменения не зависят от прошлых изменений. Это правда о ценах на акции? Нету. Не за что. Последовательная корреляция встречается повсеместно. Мало того, что за большим падением обычно следует увеличение волатильности, а за большим увеличением обычно следует снижение волатильности.

Полагаю, меня могут обвинить в придирках, но эти стилизованные факты обычно известны инвесторам и экономистам, поэтому я думаю, что будет справедливо сказать, что GBM не выглядит реалистичным для тех, кто знаком с поведением фондового рынка.

Эконометристы придумали множество моделей по ценам на акции. Тот, который, кажется, работает во многих ситуациях, является авторегрессионной моделью для условного среднего в сочетании с моделью типа (G) Arch для волатильности. Для модели волатильности, асимметричный GARCH с распределением с толстым хвостом (как у Student's), кажется, работает лучше всего для множества финансовых рынков.

6 голосов
/ 23 декабря 2011
# The following is an adaptation from a program shown at page 140 in
# "Stochastic Simulations and Applications in Finance",
# a book written by Huynh, Lai and Soumaré.
# That program was written in MatLab and this one was written in R by me.
# That program produced many price paths and this one produces one.
# The latter is also somewhat simpler and faster.

# Y is the time period in years, for instance 1 (year)
# NbSteps is the number of steps in the simulation,
# for instance 250 (trading days in a year).
# DeltaY is the resulting time step.

# The computations shown implement the exact solution
# to the stochastic differential equation for
# the geometric Brownian motion modelling stock prices,
# with mean mu and volatility sigma, thus generating a stochastic price path
# such as that exhibited by stock prices when price jumps are rare.

PricePath <- function(Y,NbSteps,mu,sigma,InitPrice) {
    DeltaY <- Y/NbSteps; SqrtDeltaY <- sqrt(DeltaY)
    DeltaW <- SqrtDeltaY * rnorm(NbSteps)
    Increments <- (mu-sigma*sigma/2)*DeltaY + sigma*DeltaW
    ExpIncr <- exp(Increments)
    PricePath <- cumprod(c(InitPrice,ExpIncr))
    return(PricePath)
}

The plot of the output from this program looks very much like a stock price path:

5 голосов
/ 07 января 2014

Я написал короткую грязную версию JavaScript, вдохновленную ответом Питера П. здесь.Мне нужно было создавать еженедельные, годовые и общие тренды, чтобы они принимали массив параметров и накладывали их, чтобы получить более сложный (поддельный) тренд.

  function getRandomData(numPoints, center, min, max, cycles)
{
    var result = [];
    var phase = Math.random() * Math.PI;
    var y = center;

    function randomPlusMinus() { return (Math.random() * 2) - 1; }

    $.each(cycles, function(i,thisCycle) {
        thisCycle.phase = Math.random() * Math.PI;
        thisCycle.increment = Math.PI / thisCycle.length;
    });

    for (var i = 0; i < numPoints; i++)
    {
        $.each(cycles, function(i,thisCycle) {
            thisCycle.phase += thisCycle.increment * randomPlusMinus();
            y += (Math.sin(thisCycle.phase) * (thisCycle.variance / thisCycle.length) * (randomPlusMinus() * thisCycle.noise)) + (thisCycle.trend / thisCycle.length);

        });
        if (min) y = Math.max(y,min);
        if (max) y = Math.min(y,max);
        result.push(y);
    }

    return result;
}

var data = getRandomData(365,80,20,100,
                      [{ length: 7, variance: 50, noise: 1, trend: 0},
                       { length: 365, variance: 30, noise: 1, trend: 0},
                       { length: 700, variance: 2, noise: 0, trend: 100}]);

Я положил туда диаграмму, чтобы показать результат: http://jsfiddle.net/z64Jr/3/

5 голосов
/ 22 декабря 2011

У меня была книга Анализ рынка фракталов (недавно от нее только что избавились), в которой говорилось о статистических свойствах цен на акции.Не очень полезно для инвестирования, но оно могло бы помочь вам.

Вам понадобится что-то, что моделирует случайный процесс с желаемыми статистическими свойствами.Двумя примерами случайных процессов являются гауссовский белый шум и винеровский процесс (последний моделирует броуновское движение, а также является пределом случайного блуждания с небольшими шагами).

Если я правильно помню из книги «Анализ рынка фракталов», было утверждение, что логарифм цен на акции имел характеристики, аналогичные так называемому «шуму 1 / f» или «розовому шуму» , так что вы можете попробовать поискать статьи о генерации розового шума в программном обеспечении.(а затем возьмите результаты и вставьте их в e ^ x) (правка: упс, я ошибочно вспомнил. Похоже, это больше похоже на дробное броуновское движение )

(Вот хорошее читабельное эссе , в котором рассказывается об истории изучения фрактальных случайных процессов - и о том, как наводнение Нила связано с фондовым рынком - к сожалению, оно не попадает в технические данные, но, возможно, естьусловия поиска, такие как показатель Херста , которые могут помочь вам начать.)

Проблема становится более сложной, если вам требуется несколько серий данных о запасах.(в этом случае существует некоторая корреляция между акциями, которая зависит от различных общих факторов, например национальной экономики, типа промышленности и т. д.) Я не уверен, как вы могли бы это сделать, но сначала начните с одного случайного процесса.

2 голосов
/ 12 марта 2014

Я хотел ответить на пост Джима Мишеля выше (https://stackoverflow.com/a/8597889/1360592), но так как я хотел включить код, я вынужден разместить свой ответ здесь.

Основываясь на алгоритме Джима Мишеля, я сделалследующая реализация Java, и она хорошо работала для моих нужд, генерируя числа, которые в графическом виде приводили к визуально привлекательным, реалистичным ценам биржевого тикера.

Java:

private float getNextPrice(float oldPrice)
{
    // Instead of a fixed volatility, pick a random volatility
    // each time, between 2 and 10.
    float volatility = _random.nextFloat() * 10 + 2;

    float rnd = _random.nextFloat();

    float changePercent = 2 * volatility * rnd;

    if (changePercent > volatility) {
        changePercent -= (2 * volatility);
    }
    float changeAmount = oldPrice * changePercent/100;
    float newPrice = oldPrice + changeAmount;

    // Add a ceiling and floor.
    if (newPrice < MIN_PRICE) {
        newPrice += Math.abs(changeAmount) * 2;
    } else if (newPrice > MAX_PRICE) {
        newPrice -= Math.abs(changeAmount) * 2;
    }

    return newPrice;

}

Обратите внимание, что, как указал вихри в своем комментарии, мне нужно было поделить процент на 100 при объявлении переменной changeAmount.

1 голос
/ 21 мая 2017

Мне нужно было создать фиктивные рыночные данные для сим-игры, над которой я работал.Мне нужно было, чтобы данные выглядели как рыночные данные, но оставались в определенных диапазонах, поэтому они были предсказуемы с точки зрения начальной цены, максимума / минимума за день.

В итоге я объединил синусоидальные волны различной частоты, а затемдобавили некоторую случайность, и результаты не просто выглядят хорошо, но согласованно (вы не получите ничего, что выглядит странно).Даже там, где можно увидеть синусоидальный паттерн, он все равно выглядит хорошо.

Произвольно сгенерированные рыночные данные

Код написан на базовом языке сценариев, но он должен быть очень простым для понимания и преобразования на любой язык, который вы хотите.Получив массив нормализованных данных, умножьте значения на любое максимальное значение, которое вы хотите получить ограниченный набор данных.

dim values[] as float
dim offsets[] as integer
dim frequencies[] as float

function GetPoint(x#, f#, a#, o#)

    f# = 360.0 / f#

    x# = FMod(x# + o#, f#)
    angle# = (x# / f#) * 360.0

    r# = Sin(angle#) * a#

endfunction r#

function Generate()

    // Empty arrays
    offsets.Length = -1
    frequencies.Length = -1
    values.Length = -1

    offsets.Insert(Random(0, 359))
    offsets.Insert(Random(0, 359))
    offsets.Insert(Random(0, 359))

    f# = Random(100, 300)
    f# = f# / 1000.0
    frequencies.Insert(f#)
    f# = Random(500, 1000)
    f# = f# / 1000.0
    frequencies.Insert(f#)
    f# = Random(2000, 4000)
    f# = f# / 1000.0
    frequencies.Insert(f#)

    c# = 0
    for i = 0 to 1919
        v# = 0
        v# = v# + GetPoint(i, frequencies[0], 190, offsets[0])
        v# = v# + GetPoint(i, frequencies[1], 85, offsets[1])
        v# = v# + GetPoint(i, frequencies[2], 40, offsets[2])

        r# = Random(0, 40)
        r# = r# - 20.0

        c# = Clamp(c# + r#, c# - 40, c# + 40)
        v# = v# + c#

        values.Insert(v#)
    next i

    start# = values[0]
    max# = 0.0
    for i = 0 to values.Length
        values[i] = values[i] - start#
        if Abs(values[i]) > max#
            max# = Abs(values[i])
        endif
    next i

    // Normalize
    for i = 0 to values.Length
        values[i] = (values[i] / max#)
    next i

endfunction

function Clamp(v#, min#, max#)

    if v# < min#
        exitfunction min#
    elseif v# > max#
        exitfunction max#
    endif

endfunction v#
1 голос
/ 22 декабря 2011

Взгляните на финансы Yahoo, они предлагают бесплатные данные с биржи и графики с задержкой.

Вот статья об использовании канала: http://www.codeproject.com/KB/aspnet/StockQuote.aspx

Вам понадобится JQueryили вы можете просто использовать XMLHttpRequest, чтобы использовать сервис.К вашему сведению, есть плагин для JQuery для обработки CSV: http://code.google.com/p/js-tables/

0 голосов
/ 11 января 2017
double price=2000;
    while (true) {
        double min =  (price*-.02);
        double max =  (price*.02);
        double randomNum = ThreadLocalRandom.current().nextDouble(min, max+1);
        price=price+randomNum;
        System.out.println(price);
    }

Это в Яве. Просто отобразите результат в столбце Excel, чтобы увидеть график. Используйте большой набор значений для построения графика в Excel. Интересно видеть, насколько похожи эти данные на реальные акции.

0 голосов
/ 05 августа 2014

Вот код, который я создал для моего использования. Цены созданы для новой свечи, которая включает в себя Open, High, Low, Close и Volume. Новые цены генерируются на основе% волатильности. Я использовал всего 5% для цен.

Код основан на C #.

public class PriceBar
{
    public DateTime Date { get; set; }
    public double Open { get; set; }
    public double High { get; set; }
    public double Low { get; set; }
    public double Close { get; set; }
    public long Volume { get; set; }
}

public static double GetRandomNumber(double minimum, double maximum)
{
    Random random = new Random();
    return random.NextDouble() * (maximum - minimum) + minimum;
}

public static void GenerateRandomBar(PriceBar newBar)
{
    double fluct = 0.025;
    double volFluct = 0.40;

    //Open is equal to the previous close
    newBar.Open = newBar.Close;
    newBar.Close = GetRandomNumber(newBar.Close - newBar.Close * fluct, newBar.Close + newBar.Close * fluct);
    newBar.High = GetRandomNumber(Math.Max(newBar.Close, newBar.Open), Math.Max(newBar.Close, newBar.Open) + Math.Abs(newBar.Close - newBar.Open) * fluct);
    newBar.Low = GetRandomNumber(Math.Min(newBar.Close, newBar.Open), Math.Min(newBar.Close, newBar.Open) - Math.Abs(newBar.Close - newBar.Open) * fluct);
    newBar.Volume = (long)GetRandomNumber(newBar.Volume * volFluct, newBar.Volume);
}

Использование:

Создать экземпляр PriceBar, заполнить цены предыдущего бара. Передайте экземпляр PriceBar в функцию GenerateRandomBar () . Он вернет PriceBar с новыми значениями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...