Недавно вышедшая бета-версия jquants-api позволяет получать массивы суточных финансовых данных от более чем четырёх тысяч компаний, представленных на Токийской фондовой бирже.
На данный момент через API доступны следующие массивы данных:
- Информация о котирующихся эмиссиях
- Информация о курсе акций
- Информация о трейдинге
В будущем добавятся новые массивы данных.
Хотя текущие исторические данные доступны только начиная с 2017 года, поощряется отправка пользователями отзывов об API через обычные каналы github (и т. п.), чтобы разработчики могли подробнее понять особенности его использования.
В настоящий момент API бесплатен для личного пользования, для доступа к нему достаточно потратить несколько секунд на регистрацию и создание аккаунта на официальном веб-сайте с указанием адреса электронной почты, пароля и основных сведений.
Участники сообщества уже предложили создать обёртки вокруг http-вызовов для упрощения анализа данных.
Часть этих обёрток доступна в github JQuants, в основном дата-саентисты использовали языки наподобие R и Python.
В этой статье мы расскажем о доступе к JQuants API при помощи языка JavaVM, в частности, Java и Clojure, посредством проекта jquant-api-jvm.
▍ Доступ к JQuants API при помощи Java
После настройки пароля имени пользователя в онлайн-форме нужно выполнить одно из следующих действий:
- Создать файл в $HOME/.config/jquants/login.edn со следующим содержимым:
{:mailaddress "john@doe.com", :password "johndoe"}
Или
- Вызвать функцию
login
объектаjquantsapi
.
jquantsapi api = new jquantsapi();
api.login("john@doe.com", "johndoe");
Стоит заметить, что второй способ, по сути, выполнит то же самое, что и ручной процесс выше, и создаст файл login.edn с вашими учётными данными.
▍ Простой вызов API для получения суточных данных
Map<?,?> result = api.daily(code, "20220301");
System.out.println(result);
Полученный от API результат в виде map, состоящей из нескольких map — это отдельная суточная запись, соответствующая спецификациям JQuants API.
{
"daily_quotes": [
{
"Code": "86970",
"Close": 2178.0,
"Date": "20220301",
"AdjustmentHigh": 2204.5,
"Volume": 1180200.0,
"TurnoverValue": 2575637550.0,
"AdjustmentClose": 2178.0,
"AdjustmentLow": 2172.5,
"Low": 2172.5,
"High": 2204.5,
"Open": 2183.5,
"AdjustmentOpen": 2183.5,
"AdjustmentFactor": 1.0,
"AdjustmentVolume": 1180200.0
}
]
}
Также можно удобно запрашивать этот объект при помощи jxpath.
JXPathContext context = JXPathContext.newContext(result);
Double open = (Double) context.getValue("/daily_quotes[1]/Open");
System.out.printf("Quote for %s on day %s is %f\n", code, date, open);
// OUTPUT
// Quote for 24130 on day 20220301 is 4315.000000
При вызове calling jquants можно также указать диапазон дат получаемых котировок:
Map<?,?> result = api.daily(code, from, to);
JXPathContext context = JXPathContext.newContext(result);
System.out.println(context.selectNodes("//Open"));
// OUTPUT
// [4315.0, 4455.0, 4595.0, 4479.0]
Получение информации о котировках или финансовой отчётности можно также выполнить как показано в примере ниже:
Map<?,?> listedInfo = api.listedInfo(code);
JXPathContext context = JXPathContext.newContext(listedInfo);
System.out.printf("Code %s is for companyName %s\n", code, context.getValue("//CompanyNameFull"));
// OUTPUT
// Code 24130 is for companyName エムスリー
Map<?,?> statements = api.statements(code, "20220727");
JXPathContext context2 = JXPathContext.newContext(statements);
System.out.printf("Profit: %s for Code %s\n", context2.getValue("//Profit"), code);
// OUTPUT
// Profit: 12127000000 for Code 24130
Вместо того, чтобы использовать код для доступа к суточным данным, Java-обёртка также позволяет использовать метод dailyFuzzy, при помощи которого можно напрямую использовать EnglishName компании вместо её кода.
Для этого она создаёт локальный кэш, поэтому первый вызов будет немного медленным, однако потом вы сможете, например, выполнять запросы котировок по названию компании:
Map m = Map.of("CompanyNameEnglish","Japan Exchange","from", "20220301","to", "20220401");
Map result = api.dailyFuzzy(m);
System.out.println(result);
Этот фрагмент кода возвращает такой же тип результатов, что и стандартная функция суточных результатов.
{
"daily_quotes"[
{
"Volume"1180200.0,
"AdjustmentOpen"2183.5,
"Open"2183.5,
"Close"2178.0,
"AdjustmentClose"2178.0,
"Date""20220301",
"AdjustmentVolume"1180200.0,
"High"2204.5,
"AdjustmentHigh"2204.5,
"Low"2172.5,
"Code""86970",
"AdjustmentFactor"1.0,
"TurnoverValue"2.57563755E9,
"AdjustmentLow"2172.5
}
...
{
"Volume"1150000.0,
"AdjustmentOpen"2273.5,
"Open"2273.5,
"Close"2323.5,
"AdjustmentClose"2323.5,
"Date""20220401",
"AdjustmentVolume"1150000.0,
"High"2330.5,
"AdjustmentHigh"2330.5,
"Low"2253.5,
"Code""86970",
"AdjustmentFactor"1.0,
"TurnoverValue"2.659037E9,
"AdjustmentLow"2253.5
}
]
}
В подпроекте JavaSample на github можно также найти краткий пример того, как создавать график возвращаемых котировок при помощи quickchart.io.
```java
Map<?,?> result = api.daily(code, "20220301", "20220505");
JXPathContext context = JXPathContext.newContext(result);
QuickChart chart = new QuickChart();
chart.setWidth(500);
chart.setHeight(300);
String config =
format("{type: 'line',data: {labels: %s , datasets: [{label: 'Open', data:%s ,fill: false}, {label: 'Close', data:%s ,fill: false}]}}",
context.selectNodes("//Date"),
context.selectNodes("//Open"),
context.selectNodes("//Close"));
chart.setConfig(config);
System.out.println(chart.getUrl());
API quickchart.io с базовой функциональностью бесплатен и довольно удобен для демонстрации сгенерированного графика. Конфигурация самого графика является стандартной конфигурацией JSON.
При выполнении приведённого выше кода будет получен URL графика, который можно использовать для многократного доступа к сгенерированному графику.
Другие примеры кода можно найти в коде; например, там есть пример генерации графика скользящего среднего за три дня суточных котировок на момент открытия…
Полный код на Java для этого есть на github.
▍ Доступ к JQuants API при помощи Clojure
Код самой оболочки внутри написан на Clojure, поэтому доступ к JQuants API при помощи Clojure удобен в том смысле, что вы можете получать map, заполненные обычными ключевыми словами формата edn вместо строк.
Функции обёртки соответствуют функциям на Java. Для получения суточных котировок нужно выполнить следующее:
(require '[hellonico.jquants-api :as api])
(def raw (api/daily {:code 2413 :from 20220301 :to 20220328}))
(def data (raw :daily_quotes))
Дополнительное преимущество использования Clojure в JVM заключается в том, что для запросов данных требуется внешняя библиотека.
(-> data first :Open)
; 4315.0
Здесь для обёртки снова есть понятный пример того, как создавать график скользящего среднего суточных котировок при помощи обёртки JQuants и библиотеки для построения графиков oz.
Из суточных котировок, полученных от JQuants API, сначала вычисляется пятидневное скользящее среднее:
(defn average [coll]
(/ (reduce + coll)
(count coll)))
(defn ma [period coll]
(lazy-cat (repeat (dec period) nil)
(map average (partition period 1 coll))))
(def ma-5 (partial ma 5))
(def _data
(map #(assoc %1 :ma %2) data (ma-5 (map :High data))))
Таким образом, данные дополняются записью :ma для каждой котировки, и используются в конфигурации графика:
(def data-plot
{:data {:values _data}
:encoding {:x {:field "Date" :type "ordinal"}
:y {:field "ma" :type "quantitative"}
:color {:field "Code" :type "nominal"}}
:mark "line"})
Всё это можно отобразить на графике при помощи синтаксиса в стиле hiccup.
(def viz
[:div
[:h1 "5 days Moving average"]
[:p "Entity code 24130"]
[:p "from 20220301 to 20220328"]
[:vega-lite data-plot]
;[:h2 "If ever, oh ever a viz there was, the vizard of oz is one because, because, because..."]
[:p (str (java.util.Date.))]
])
Что приводит к созданию следующего графика:
Чтобы всё это было ещё полезнее и интереснее, можно воспользоваться сторонними проектами, например, готовым примером Jupyter Notebook из IJava.
jquants-api-jvm доступен по дружественной к опенсорсу лицензии Eclipse. Разработчики приглашают обсуждать новые массивы данных для jquants API и делиться ими с сообществом.
Telegram-канал с полезностями и уютный чат