MyNixOS website logo
Description

Interact with Moscow Exchange Informational and Statistical Server ('ISS').

This is a thin wrapper around the 'MOEX' 'ISS' REST interface, see <https://iss.moex.com>. It allows to quickly fetch price candles for a particular security, obtain its profile information and so on.

moexer

Moscow Exchange (MOEX) provides a REST interface to its Informational and Statistical Server (ISS), see https://fs.moex.com/files/8888.

moexer is a thin wrapper around the REST interface. It allows to quickly fetch e.g. price candles for a particular security, obtain its profile information and so on. The data is returned as tibbles, making it easy to subsequently process and analyse it.

Installation

You can install the released version of moexer from CRAN with:

install.packages("moexer")

or the latest version from github:

devtools::install_github("x1o/moexer")

High-Level Interface to ISS

Suppose you want to download monthly candles from Jan 1, 2020 until the present day for the Sberbank common shares.

library(moexer)
library(dplyr)
library(purrr)

Each security on MOEX has an ID, e.g. a 4-letter ticker symbol for a share (“LKOH”) or an ISIN for a bond (“RU000A0JXPU3”).

Find the corresponding security ID:

search_security(query = 'Sberbank') |> 
    slice_head(n = 10) |> 
    select(secid, name, is_traded, type, primary_boardid)
secidnameis_tradedtypeprimary_boardid
SBERСбербанк России ПАО ао1common_shareTQBR
SBERPСбербанк России ПАО ап1preferred_shareTQBR
RU000A103WV8Сбербанк ПАО 001Р-SBER331exchange_bondTQCB
RU000A105SD9Сбербанк ПАО 001Р-SBER421exchange_bondTQCB
RU000A101QW2Сбербанк ПАО 001Р-SBER161exchange_bondTQCB
RU000A1069P3Сбербанк ПАО 002Р-SBER441exchange_bondTQCB
RU000A103661Сбербанк ПАО 001Р-SBER271exchange_bondTQCB
RU000A103KG4Сбербанк ПАО 001Р-SBERD11exchange_bondTQCB
RU000A103G42Сбербанк ПАО 001Р-SBER291exchange_bondTQCB
RU000A102YG7Сбербанк ПАО 001Р-SBER251exchange_bondTQCB

We can verify that SBER is indeed the symbol we were looking for and check the profile information:

sber_info <- get_security_info(secid = 'SBER')
sber_info$description |> 
    select(name, title, value)
nametitlevalue
SECIDКод ценной бумагиSBER
NAMEПолное наименованиеСбербанк России ПАО ао
SHORTNAMEКраткое наименованиеСбербанк
ISINISIN кодRU0009029540
REGNUMBERНомер государственной регистрации10301481B
ISSUESIZEОбъем выпуска21586948000
FACEVALUEНоминальная стоимость3
FACEUNITВалюта номиналаSUR
ISSUEDATEДата начала торгов2007-07-20
LATNAMEАнглийское наименованиеSberbank
LISTLEVELУровень листинга1
ISQUALIFIEDINVESTORSБумаги для квалифицированных инвесторов0
MORNINGSESSIONДопуск к утренней дополнительной торговой сессии1
EVENINGSESSIONДопуск к вечерней дополнительной торговой сессии1
TYPENAMEВид/категория ценной бумагиАкция обыкновенная
GROUPКод типа инструментаstock_shares
TYPEТип бумагиcommon_share
GROUPNAMEТипа инструментаАкции
EMITTER_IDКод эмитента1199
sber_info$boards |> 
    slice_head(n = 10) |> 
    select(secid, boardid, title, is_traded, history_from, history_till, currencyid)
secidboardidtitleis_tradedhistory_fromhistory_tillcurrencyid
SBERTQBRТ+: Акции и ДР - безадрес.12013-03-252024-03-11RUB
SBEREQBRОсновной режим: А1-Акции и паи - безадрес.02011-11-212013-08-30RUB
SBERSPEQПоставка по СК (акции)12018-06-292023-12-22RUB
SBERSMALТ+: Неполные лоты (акции) - безадрес.12011-11-212024-03-11RUB
SBERTQDPКрупные пакеты - Акции - безадрес.0NANARUB
SBEREQDPКрупные пакеты - Акции - безадрес.02011-12-122019-03-01RUB
SBERRPMOРЕПО-М - адрес.12019-04-222024-03-11RUB
SBERPTEQРПС с ЦК: Акции и ДР - адрес.12013-03-262024-03-11RUB
SBERMXBDMOEX Board02015-08-032024-03-11NA
SBERCLMRClassica - безадрес.02012-02-132015-07-31RUB

Fetch the SBER candles:

get_candles(secid = 'SBER', from = '2020-01-01', till = '2022-01-01', interval = 'monthly') |> 
    head()
secidopenclosehighlowvaluevolumebeginend
SBER255.99252.20270.80251.401940323919707471375202020-01-012020-01-31
SBER251.80233.36259.77231.002295156869759198227902020-02-012020-02-28
SBER238.93187.21241.00172.1558517868668130017366602020-03-012020-03-31
SBER183.20197.25205.44182.0033962647220817682227002020-04-012020-04-30
SBER195.68200.50205.00183.3326282747169813590452302020-05-012020-05-29
SBER203.10203.22223.15200.7532042416157615222683702020-06-012020-06-30

get_candles() also supports specifying date-times for the from, till arguments, e.g. '2020-01-01 09:00:00'. This is most useful for obtaining intraday candles, e.g with interval = 'hourly' — see options('moexer.candle.intervals').

If till = NULL, all candles up to today are fetched.

get_candles() is vectorised over secid, so it is possible to, say, fetch candles for both the common and the preferred shares. The returned object has class MoexCandles for which there’s an appropriate plot() method:

get_candles(
    secid = c('SBER', 'SBERP'), 
    from = '2020-01-01', 
    till = '2022-01-01', 
    interval = 'monthly'
) |> 
    plot()

Low-level Interface to ISS

Request

ISS is accessed via HTTP and/or HTTPS.

The interface is “RESTful”, meaning the endpoint parameters can be passed as a query string, but they form the path of the URL. For instance, to receive SBER candles, one would need to form a URL as below:

<base_url>/securities/SBER/candles?from=2020-01-10&till=2020-01-17

For a list of all public endpoints, see http://iss.moex.com/iss/reference/.

Response

ISS is capable of return data in several formats; the present package uses JSON internally.

Every response consists of named sections (“blocks”).

Every block contains the following sub-sections:

  • metadata with types
  • column with column names
  • data with the actual payload

All response blocks are parsed as tibbles using the information above.

Query String Parameters

The parameters can be applied to some sections (1), all section (2) or modify “system” ISS parameters (3).

  1. <block>.<parameter>=<value> (applicable for block <block>)
    • <block>.columns=<id_1>,<id_2>,...: only select these column in the block <block>
  2. <parameter>=<value> (all response blocks)
  3. iss.<parameter>=<value> (system parameter)
    • iss.only=<block_1>,<block_2>,...: only return these blocks

Examples

The main function for working with low-level requests is query_iss().

Simple Queries

Fetch possible values for certain market objects. This returns a list of sections such as engines, markets, etc, each being a dataframe.

iss_index <- query_iss('index')
names(iss_index)
#>  [1] "engines"             "markets"             "boards"             
#>  [4] "boardgroups"         "durations"           "securitytypes"      
#>  [7] "securitygroups"      "securitycollections"
iss_index$engines
idnametitle
1stockФондовый рынок и рынок депозитов
2stateРынок ГЦБ (размещение)
3currencyВалютный рынок
4futuresСрочный рынок
5commodityТоварный рынок
6interventionsТоварные интервенции
7offboardОТС-система
9agroАгро
1012otcОТС с ЦК
1282quotesКвоты

Query string parameters are specified as params argument; debug_output = TRUE results in the request URL being printed:

df <- query_iss(
    'index',
    params = list(
        iss.only = 'engines,markets', 
        markets.columns = 'id,market_name,market_title'
    ),
    debug_output = TRUE
)
#>  http://iss.moex.com/iss/index.json?iss.only=engines,markets&markets.columns=id,market_name,market_title
df$engines |> head()
idnametitle
1stockФондовый рынок и рынок депозитов
2stateРынок ГЦБ (размещение)
3currencyВалютный рынок
4futuresСрочный рынок
5commodityТоварный рынок
6interventionsТоварные интервенции
df$markets |> head()
idmarket_namemarket_title
5indexИндексы фондового рынка
1sharesРынок акций
2bondsРынок облигаций
4ndmРежим переговорных сделок
29otcОТС
27ccpРЕПО с ЦК
show_df <- function(df) {
    print(nrow(df))
    bind_rows(head(df), tail(df))
}

Queries Involving Cursor

Some queries return large responses, which are split into pages that must accessed using start query string parameter as indicated in the auxiliary section history.cursor, also returned by ISS:

df <- query_iss(
    'history/engines/stock/markets/shares/securities/MOEX',
    params = list(
        from = '2021-09-01',
        till = '2021-12-31',
        start = 10
    )
)
show_df(df$history[,1:10])
#>  [1] 100
BOARDIDTRADEDATESHORTNAMESECIDNUMTRADESVALUEOPENLOWHIGHLEGALCLOSEPRICE
SMAL2021-09-08МосБиржаMOEX163.869140e+03184.91183.00186.00NA
TQBR2021-09-08МосБиржаMOEX200401.331147e+09187.00181.30187.83182.88
SMAL2021-09-09МосБиржаMOEX225.684990e+03182.50182.00184.49NA
TQBR2021-09-09МосБиржаMOEX212681.162550e+09182.95181.02184.88183.18
SMAL2021-09-10МосБиржаMOEX224.622800e+03182.35182.35187.40NA
TQBR2021-09-10МосБиржаMOEX176261.390805e+09182.84182.58187.78184.90
TQBR2021-11-12МосБиржаMOEX221041.369847e+09171.49168.01171.66169.73
SMAL2021-11-15МосБиржаMOEX113.743810e+03158.08158.08172.70NA
TQBR2021-11-15МосБиржаMOEX208601.276717e+09169.27168.82173.70171.69
SMAL2021-11-16МосБиржаMOEX103.443480e+03172.90168.80173.97NA
TQBR2021-11-16МосБиржаMOEX235851.410013e+09172.18168.22173.09168.58
SMAL2021-11-17МосБиржаMOEX92.547600e+03168.51168.49172.39NA
df$history.cursor
INDEXTOTALPAGESIZE
10174100

An adverb following_cursor() decorates query_iss() to follow the cursor until the requested information is received completely. The .cursor dataframe is dropped.

following_cursor(query_iss)(
    'history/engines/stock/markets/shares/securities/MOEX',
    params = list(
        from = '2021-09-01',
        till = '2021-12-31',
        start = 10
    )
) |> 
    pluck('history') |> 
    select(1:10) |> 
    show_df()
#>  [1] 164
BOARDIDTRADEDATESHORTNAMESECIDNUMTRADESVALUEOPENLOWHIGHLEGALCLOSEPRICE
SMAL2021-09-08МосБиржаMOEX163.869140e+03184.91183.00186.00NA
TQBR2021-09-08МосБиржаMOEX200401.331147e+09187.00181.30187.83182.88
SMAL2021-09-09МосБиржаMOEX225.684990e+03182.50182.00184.49NA
TQBR2021-09-09МосБиржаMOEX212681.162550e+09182.95181.02184.88183.18
SMAL2021-09-10МосБиржаMOEX224.622800e+03182.35182.35187.40NA
TQBR2021-09-10МосБиржаMOEX176261.390805e+09182.84182.58187.78184.90
SMAL2021-12-28МосБиржаMOEX39.473100e+02159.90150.13159.90NA
TQBR2021-12-28МосБиржаMOEX190401.097535e+09152.15151.27153.34152.38
SMAL2021-12-29МосБиржаMOEX143.190540e+03154.86143.02156.98NA
TQBR2021-12-29МосБиржаMOEX155188.011846e+08151.84150.80152.59152.10
SMAL2021-12-30МосБиржаMOEX112.600790e+03153.01145.79165.34NA
TQBR2021-12-30МосБиржаMOEX174258.129008e+08152.57152.10153.67153.18

Queries With Automatical start Increment

Some responses are large yet are not accompanied by a .cursor block.

query_iss(
    'engines/stock/markets/shares/boards/TQBR/securities/SBER/candles',
    params = list(
        from = URLencode('2020-01-10 10:00:00'),
        till = URLencode('2020-01-10 23:59:59'),
        interval = 1,
        start = 10
    ),
    debug_output = TRUE
) |> 
    pluck('candles') |> 
    show_df()
#>  http://iss.moex.com/iss/engines/stock/markets/shares/boards/TQBR/securities/SBER/candles.json?from=2020-01-10%2010:00:00&till=2020-01-10%2023:59:59&interval=1&start=10
#>  [1] 500
openclosehighlowvaluevolumebeginend
257.00257.30257.39256.90305155481186602020-01-10 10:10:002020-01-10 10:10:59
257.24257.32257.38257.2014548053565502020-01-10 10:11:002020-01-10 10:11:59
257.30257.37257.38257.165638369219202020-01-10 10:12:002020-01-10 10:12:59
257.28257.30257.47257.234317722167802020-01-10 10:13:002020-01-10 10:13:59
257.30257.44257.44257.308505667330502020-01-10 10:14:002020-01-10 10:14:59
257.43257.32257.43257.2012989804504902020-01-10 10:15:002020-01-10 10:15:59
257.86257.85257.87257.803640487141202020-01-10 18:24:002020-01-10 18:24:59
257.84257.85257.97257.8019307540748602020-01-10 18:25:002020-01-10 18:25:59
257.84257.70257.84257.705734978222502020-01-10 18:26:002020-01-10 18:26:59
257.71257.71257.82257.708255241320302020-01-10 18:27:002020-01-10 18:27:59
257.77257.82257.83257.719292759360502020-01-10 18:28:002020-01-10 18:28:59
257.80257.90257.97257.7521327564827302020-01-10 18:29:002020-01-10 18:29:59

These queries may accessed by query_iss() wrapped into fetching_fully decorator, which automatically increases the value of start parameter until no more data is received:

fetching_fully(query_iss)(
    'engines/stock/markets/shares/boards/TQBR/securities/SBER/candles',
    params = list(
       from = URLencode('2020-01-10 10:00:00'),
       till = URLencode('2020-01-10 23:59:59'),
       interval = 1,
       start = 10
    )
) |> 
    pluck('candles') |> 
    show_df()
#>  [1] 515
openclosehighlowvaluevolumebeginend
257.00257.30257.39256.90305155481186602020-01-10 10:10:002020-01-10 10:10:59
257.24257.32257.38257.2014548053565502020-01-10 10:11:002020-01-10 10:11:59
257.30257.37257.38257.165638369219202020-01-10 10:12:002020-01-10 10:12:59
257.28257.30257.47257.234317722167802020-01-10 10:13:002020-01-10 10:13:59
257.30257.44257.44257.308505667330502020-01-10 10:14:002020-01-10 10:14:59
257.43257.32257.43257.2012989804504902020-01-10 10:15:002020-01-10 10:15:59
257.81257.81257.85257.8017768959689202020-01-10 18:39:002020-01-10 18:39:59
258.19258.19258.19258.1932881271112735302020-01-10 18:45:002020-01-10 18:45:59
258.19258.19258.19258.193268685126602020-01-10 18:46:002020-01-10 18:46:59
258.19258.19258.19258.192065528002020-01-10 18:47:002020-01-10 18:47:59
258.19258.19258.19258.1925819010002020-01-10 18:48:002020-01-10 18:48:59
258.19258.19258.19258.19258990391003102020-01-10 18:49:002020-01-10 18:49:59

Some endpoints do not support start parameter – fetching_fully() knows how to handle that:

fetching_fully(query_iss)('turnovers', params = list(iss.only = 'turnovers'))$turnovers
#>  ! Received identical sections: the endpoint probably does not support `start` parameter
NAMEIDVALTODAYVALTODAY_USDNUMTRADESUPDATETIMETITLE
stock12702212.550329817.45199218984552024-03-12 13:15:41Фондовый рынок и рынок депозитов
currency3961403.122210608.562764917632024-03-12 13:15:41Валютный рынок
futures4166537.28001837.6486904893712024-03-12 13:15:42Срочный рынок
commodity5NANANA2024-03-12 07:00:00Товарный рынок
agro9278.08313.068497472024-03-12 13:10:00Агро
otc1012831.20279.17187213242024-03-12 13:15:37ОТС с ЦК
quotes1282NANANA2024-03-12 09:30:01Квоты
TOTALSNA3831262.238442275.90381524809602024-03-12 13:15:42Всего по Московской Бирже.
Metadata

Version

0.3.0

License

Unknown

Platforms (75)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows