Отображение финансовых данных в стиле Ренко в gnuplot

У меня есть данные OHLC для S&P 500, которые я хотел бы построить в виде так называемого графика Ренко (https://en.wikipedia.org/wiki/Renko_chart) в gnuplot. Я преобразовал данные OHLC в блоки фиксированного размера, представленные на data.dat в виде верхних и нижних диагональных углов прямоугольников. Вот условный пример:

# x1, y1, x2, y2
0 6 1 4
1 8 2 6
2 10 3 8
3 12 4 10
4 14 5 12
5 12 6 10

И пока что я могу включить их в сюжет, используя следующий скрипт:

set terminal pngcairo size 800,600
set output 'renko_chart.png'
set grid

set style fill solid
plot 'data.dat' using 1:2:1:3:2:4 with boxxy

Что производит следующее:

Я хотел бы покрасить «кирпичи вверх» зеленым цветом, а кирпичи «вниз» — красным. Кроме того, я хотел бы включить дату по оси X, не затрагивая горизонтальный масштаб кирпичей. Чтобы получить более четкое представление о том, что я имею в виду, вот изображение из статьи в Википедии:

Обратите внимание на дату внизу и на то, как масштаб оси меняется по ширине изображения. Слева мы видим, что период около 6 дней занимает на графике столько же места, сколько период всего в несколько часов справа. Идея состоит в том, что ценовое действие отделено от временного интервала, и это ось, которая масштабируется в зависимости от данных.

Возможно ли это в gnuplot?

Не могли бы вы предоставить больший объем данных, включая дату, например. нравятся данные для графика Википедии для тестирования? Итак, нам не придется создавать/придумывать это самим. Я думаю, что более серьезной проблемой, чем раскраска коробки, является неправильная дата/время.

theozh 25.06.2024 07:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
89
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Первая попытка ответа удалена как неправильная

Исправленный ответ

Поскольку вы осуществляете предварительную обработку данных, давайте выберем удобный формат ввода для gnuplot. Как я теперь понял, прочитав описание графиков Ренко в Википедии, нет необходимости сохранять левую и правую координаты каждого ящика. Все коробки одинаковой ширины. Поэтому я думаю, что в идеале самым простым форматом для чтения gnuplot будет: high low timestamp при падении цены и low high timestamp при росте цены. Таким образом, вся необходимая информация для каждого ящика кодируется в одной строке. В целях быстрого примера я помечаю каждое поле меткой времени, указанной в файле, но вам может понадобиться более сложная функция фильтра, которая, например, создает метку только в том случае, если день изменился или в начале недели. или в другом формате времени, чем входной.

$DATA << EOD
115.5 105.5 "06-21-2024 11:00"
105.5  95.5 "06-21-2024 16:00"
105.5 115.5 "06-23-2024 12:00"
105.5  95.5 "06-24-2024 10:10"
105.5 115.5 "06-25-2024 13:30"
115.5 125.5 "07-01-2024 10:00"
125.5 135.5 "07-03-2024 16:00"
135.5 145.5 "07-05-2024 16:00"
145.5 155.5 "07-05-2024 16:00"
EOD

set linetype 101 lc "dark-red"
set linetype 102 lc "forest-green"
unset key
set style fill solid
set boxwidth 1.0
format(col) = strcol(col)       # could be a more complicated filter
                                # and reformat time representation
set xtics rotate by -90.
set xrange [-1:25]

plot $DATA using 0:1:1:2:2:($1>$2 ? 101 : 102):xtic(format(3)) with candlestick lc variable

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

set link x2
set x2tics
set grid x2
set grid linewidth 1 linecolor "black" dashtype "."
set tics nomirror

# This function returns 1 if the month has changed since the last call,
# 0 if it has not changed.  Date format is assumed to be "MM-DD-YYYY".
last_month = -1
function $newmonth(date) << EOF
    this_month = int(date[1:2])
    if (this_month == last_month) {
        return 0
    } else {
        last_month = this_month
        return 1
    }
EOF

plot $DATA using 0:1:1:2:2:($1>$2 ? 101 : 102):xtic(format(3)) with candlestick lc variable, \
     $DATA using ( $newmonth(strcol(3)) ? column(0) : NaN ):(0):x2ticlabel("") axes x2y1 with dots 

Примечание. При запуске этот сценарий выдает предупреждающие сообщения «add_tic_user: ошибка сортировки списка». Кажется, это ничему не вредит, но на данный момент я не могу объяснить, что их вызывает и как этого избежать. Вы можете добавить команду unset warnings, если она вас слишком раздражает.

Боюсь, график Ренко — это не то же самое, что график обычных свечей. Данная свеча представляет движение цены за фиксированный промежуток времени, тогда как кирпичик ренко представляет собой фиксированный интервал ценового движения, независимо от того, сколько времени оно занимает. Формирование одного кирпича может занять всего несколько секунд, а формирование следующего подряд кирпича может занять дни или недели.

nathanvy 25.06.2024 04:29

Приношу извинения за то, что не смог перейти по предоставленной вами ссылке, чтобы найти полное определение сюжета Ренко. Я исходил из графика, который вы предоставили. Я попробую еще раз, если вы объясните, как ваши преобразованные данные фиксируют направление изменений и как вы прикрепляете к ним временную метку.

Ethan 25.06.2024 05:04

Итак, преобразованные данные — это просто верхний и нижний уровни цен каждого кирпича, а направление определяется этими уровнями относительно уровней предыдущего кирпича. Вот еще одна статья, которая может помочь: investopedia.com/terms/r/rенкоchart.asp Что касается отметки времени, я могу прикрепить ее любым способом, который подойдет для gnuplot, так как я получаю данные из API и жевать его локально. Часто можно увидеть, например. пунктирные вертикальные линии, обозначающие недели, дни, месяцы и т. д.

nathanvy 25.06.2024 05:48
Ответ принят как подходящий

Вот еще одно предложение. На самом деле вы начинаете с каких-то данных OHLC. Здесь, в целях иллюстрации, в сценарии генерируются некоторые случайные входные данные для тестирования (всего с одним значением y) и выглядят следующим образом:

2024-05-23 19:17:19      93.1655
2024-05-23 20:17:19      94.1
2024-05-23 21:17:19      94.008
2024-05-23 22:17:19      94.5589
2024-05-23 23:17:19      94.1284
2024-05-24 00:17:19      93.9924
2024-05-24 01:17:19      93.8272
2024-05-24 02:17:19      94.3609

Данные в $Renko выглядят, например, так: столбцы 1 и 2 содержат дату начала создания кирпича, столбец 3 содержит значение y, а столбец 4 содержит -1 и +1 в зависимости от того, уменьшались или увеличивались данные в этом кирпиче соответственно. .

2024-05-18 12:17:19      96.9638        1
2024-05-20 00:17:19      99.4638        1
2024-05-20 07:17:19      96.9638       -1
2024-05-21 18:17:19      94.4638       -1
2024-05-22 11:17:19      91.9638       -1
2024-05-23 02:17:19      94.4638        1

Некоторые комментарии:

  • Я очень надеюсь, что я правильно реализовал принцип Ренко (пожалуйста, проверьте еще раз)
  • высота кирпича Ренко определяется h, здесь h = 2.5.
  • Чтобы уменьшить количество отображаемых xtics, вы используете вторую «фиктивную» команду построения графика, используя xtics() (отметьте help xticlabels) и every (отметьте help every). Не уверен, что это легко понять. Если вам нужны дополнительные объяснения, дайте мне знать.

Скрипт:

### Renko style plot
reset session

myFmt = "%Y-%m-%d %H:%M:%S"

# create some random test data
set table $Data
    set samples 2000
    t0 = time(0)-1e7
    y0 = 100
    plot '+' u (strftime(myFmt,t0+$0*3600)):(y0=y0+rand(0)*2-1) w table
unset table

colX = 1
colY = 3
h    = 2.5   # Renko brick height

set table $Renko
    plot $Data u (strftime(myFmt,timecolumn(colX,myFmt))): \
         (y=column(colY), $0==0 ? (s0=s1=1, y0=y) : 0, dy=y-y0, y0): \
         ((newBrick=abs(dy)>h) ? (y0=y0+sgn(dy)*h, s0=s1, s1=sgn(dy)) : 0, s0) \
          with table if newBrick
unset table

N           = |$Renko|       # number of Renko bricks
Tx          = 7              # number of approx. xtics
M           = int(N/(Tx-1))  # show only every M-th xtic
myXtic(col) = strftime("%Y\n%m-%d",strptime(myFmt,strcol(col)))   # xtic format

set key noautotitle
set style fill solid 0.3
set xrange[:] noextend
set offsets graph 0.02, graph 0.02, 0, 0
set grid x,y

set multiplot layout 2,1

    set format x "%Y\n%m-%d" timedate
    plot $Data u (timecolumn(1,myFmt)):3 w l lc "blue"

    set format x "\n" numeric
    plot $Renko u 0:3:(0.5):(h/2.): \
         ($4>0 ? 0x00cc00 : 0xff0000) w boxxy lc rgb var, \
         '' every M u ($0*M):3:xtic(myXtic(1)) w p ps 0
unset multiplot
### end of script

Результат:

Верхний график: входные данные.
Нижний график: кирпичи Ренко (обратите внимание на неравномерную шкалу времени по оси X).

Это отлично, спасибо! Мне придется потратить некоторое время, чтобы полностью понять эту сюжетную команду.

nathanvy 27.06.2024 00:25

@nathanvy, пожалуйста! Собственно, когда я еще раз посмотрел скрипт, то обнаружил, что его можно упростить за счет уменьшения xtics. Проверьте help every.

theozh 27.06.2024 05:58

@nathanvy, извини, я еще раз просмотрел сценарий и думаю, что была ошибка в смещении кирпичей. Итак, я попытался это исправить. Как следствие, возникла проблема/вопрос по поводу окраски кирпичей. Если текущий кирпичик ниже/выше предыдущего, кирпичик окрашивается в красный/зеленый цвет соответственно. Поскольку у первого кирпича нет предыдущего, он всегда определяется как зеленый.

theozh 27.06.2024 11:10

Другие вопросы по теме