У меня есть данные 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?
Первая попытка ответа удалена как неправильная
Исправленный ответ
Поскольку вы осуществляете предварительную обработку данных, давайте выберем удобный формат ввода для 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
, если она вас слишком раздражает.
Боюсь, график Ренко — это не то же самое, что график обычных свечей. Данная свеча представляет движение цены за фиксированный промежуток времени, тогда как кирпичик ренко представляет собой фиксированный интервал ценового движения, независимо от того, сколько времени оно занимает. Формирование одного кирпича может занять всего несколько секунд, а формирование следующего подряд кирпича может занять дни или недели.
Приношу извинения за то, что не смог перейти по предоставленной вами ссылке, чтобы найти полное определение сюжета Ренко. Я исходил из графика, который вы предоставили. Я попробую еще раз, если вы объясните, как ваши преобразованные данные фиксируют направление изменений и как вы прикрепляете к ним временную метку.
Итак, преобразованные данные — это просто верхний и нижний уровни цен каждого кирпича, а направление определяется этими уровнями относительно уровней предыдущего кирпича. Вот еще одна статья, которая может помочь: investopedia.com/terms/r/rенкоchart.asp Что касается отметки времени, я могу прикрепить ее любым способом, который подойдет для gnuplot, так как я получаю данные из API и жевать его локально. Часто можно увидеть, например. пунктирные вертикальные линии, обозначающие недели, дни, месяцы и т. д.
Вот еще одно предложение. На самом деле вы начинаете с каких-то данных 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()
(отметьте 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, пожалуйста! Собственно, когда я еще раз посмотрел скрипт, то обнаружил, что его можно упростить за счет уменьшения xtics. Проверьте help every
.
@nathanvy, извини, я еще раз просмотрел сценарий и думаю, что была ошибка в смещении кирпичей. Итак, я попытался это исправить. Как следствие, возникла проблема/вопрос по поводу окраски кирпичей. Если текущий кирпичик ниже/выше предыдущего, кирпичик окрашивается в красный/зеленый цвет соответственно. Поскольку у первого кирпича нет предыдущего, он всегда определяется как зеленый.
Не могли бы вы предоставить больший объем данных, включая дату, например. нравятся данные для графика Википедии для тестирования? Итак, нам не придется создавать/придумывать это самим. Я думаю, что более серьезной проблемой, чем раскраска коробки, является неправильная дата/время.