moex_iss 1.0.1 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/README.md +38 -9
- data/lib/moex_iss/client.rb +36 -2
- data/lib/moex_iss/connection.rb +0 -6
- data/lib/moex_iss/error.rb +1 -0
- data/lib/moex_iss/hendler.rb +10 -0
- data/lib/moex_iss/market/collection.rb +43 -0
- data/lib/moex_iss/market/currencies.rb +29 -0
- data/lib/moex_iss/market/currency.rb +34 -0
- data/lib/moex_iss/market/history/stock.rb +35 -0
- data/lib/moex_iss/market/history/stocks.rb +23 -0
- data/lib/moex_iss/market/stock.rb +13 -3
- data/lib/moex_iss/market/stocks.rb +10 -17
- data/lib/moex_iss/request.rb +2 -2
- data/lib/moex_iss/version.rb +1 -1
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71d87cc339f313c78295e2d5d3569aade22989f93ecef8cf27fcfde8cb151562
|
4
|
+
data.tar.gz: '0181b5dc0b1e9e01b93a685ce68bee1a84767c354b35ac27d3b50f48eeff2b5c'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5fc0c6b4c6884de71e79c727bb0c5a9923038783736a10f2d0806eef5c765f5cd50dd9f45ce7670cf08dda27279118dee7766d0baca73e1ac1428dcbb9f8165
|
7
|
+
data.tar.gz: f6281f2e0f278f577bacdbd179ed3bb7ddd7db31a5ebefc89453de63c5f49235a1658a6e2440cd2cbb387cc3621781d0fdd14866fe7eed2c625d7b98cc8a0568
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
1
|
# Change log
|
2
|
+
Все важные изменения в этом проекте будут задокументированы в этом файле.
|
2
3
|
|
3
|
-
|
4
|
+
Формат основан на ведении журнала изменений, и этот проект придерживается семантического управления версиями.
|
5
|
+
## [1.1.0] - 2023-12-30
|
6
|
+
### Добавлено
|
7
|
+
- Возможность работы с историческими данными акции
|
8
|
+
## [1.11.0] - 2024-01-03
|
9
|
+
### Добавлено
|
10
|
+
- Возможность получать данные об актуальных курсах валют ЦБ РФ
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[](https://
|
1
|
+
[](https://badge.fury.io/rb/moex_iss)
|
2
2
|
[](https://github.com/palkan/moex_iss/actions)
|
3
3
|
[](https://github.com/K0Hb/moex_iss/actions)
|
4
4
|
|
@@ -37,25 +37,54 @@ gem "moex_iss"
|
|
37
37
|
client = MoexIss.client
|
38
38
|
```
|
39
39
|
|
40
|
+
### Валюты
|
41
|
+
Для получения последних актульных данных о курсах валют:
|
42
|
+
```ruby
|
43
|
+
currencies = client.currencies # => MoexIss::Market::Currencies
|
44
|
+
|
45
|
+
cny_rub = currencues.cny_rub # => MoexIss::Market::Currency
|
46
|
+
cny_urb.price = 12.5762
|
47
|
+
...
|
48
|
+
```
|
49
|
+
|
40
50
|
### Акции
|
41
51
|
|
42
|
-
Для получения
|
52
|
+
Для получения последних актульных данных:
|
53
|
+
- Все акции
|
54
|
+
```ruby
|
55
|
+
client.stocks # => MoexIss::Market::Stocks
|
56
|
+
```
|
57
|
+
Получаем класс, по которому можно итерироваться а так же вызывать искомую ценную бумагу по ее `isin`
|
58
|
+
```ruby
|
59
|
+
stocks.sber # => MoexIss::Market::Stock
|
60
|
+
```
|
61
|
+
- Одна Акция
|
43
62
|
```ruby
|
44
63
|
client.stock(:sber) # => MoexIss::Market::Stock
|
45
64
|
```
|
46
|
-
Для получения
|
65
|
+
+ Для получения данные об исторических данных:
|
47
66
|
```ruby
|
48
|
-
client.
|
67
|
+
client.stock(:sber, from: '2023-12-01', till: '2023-12-05') # => MoexIss::Market::History::Stocks
|
49
68
|
```
|
50
|
-
|
69
|
+
Есть возможность работы с коллекцией через дату:
|
51
70
|
```ruby
|
52
|
-
stocks.sber
|
71
|
+
stocks = client.stock(:sber, from: '2023-12-01', till: '2023-12-05') # => MoexIss::Market::History::Stocks
|
72
|
+
stocks['2023-12-03'] # => MoexIss::Market::History::Stock
|
53
73
|
```
|
54
|
-
|
74
|
+
Максимальное количесво дней: _100_
|
75
|
+
|
76
|
+
Аргументы `from` и `till` можно использовать по одиночке
|
77
|
+
|
78
|
+
### Обратите внимание
|
79
|
+
|
80
|
+
Все экземпляры классов отвечает на метод `response`, который содержит полный ответ от MOEX ISS, из которого можно получать доп.параметры,
|
81
|
+
так же у каждого класса свой набор специфических методов для удобства работы с данными.
|
55
82
|
```ruby
|
56
|
-
|
83
|
+
# Пример
|
84
|
+
client.stock(:sber).market_price # => 271.37
|
85
|
+
client.stock(:sber).prev_date # => 2023-12-2
|
86
|
+
...
|
57
87
|
```
|
58
|
-
где `response` содержит полный ответ от MOEX ISS, из которого можно получать доп.параметры
|
59
88
|
|
60
89
|
|
61
90
|
## Лицензия
|
data/lib/moex_iss/client.rb
CHANGED
@@ -6,28 +6,62 @@ module MoexIss
|
|
6
6
|
include MoexIss::Hendler
|
7
7
|
|
8
8
|
STOCKS_ENDPOINT = "engines/stock/markets/shares/boards/tqbr/securities"
|
9
|
+
CURRENCIES_ENDPOINT = "statistics/engines/currency/markets/selt/rates"
|
9
10
|
STANDARD_PARAMS = {
|
10
11
|
"iss.json" => "extended",
|
11
|
-
"iss.only" => "securities,marketdata",
|
12
12
|
"iss.meta" => "off"
|
13
13
|
}
|
14
14
|
|
15
15
|
def stocks
|
16
16
|
endpoint = "#{STOCKS_ENDPOINT}.json"
|
17
17
|
params = STANDARD_PARAMS
|
18
|
+
params["iss.only"] = "securities,marketdata"
|
18
19
|
|
19
20
|
raw_response = get(endpoint, params)
|
20
21
|
|
21
22
|
MoexIss::Market::Stocks.new(handle_response(raw_response))
|
22
23
|
end
|
23
24
|
|
24
|
-
def stock(isin)
|
25
|
+
def stock(isin, from: nil, till: nil)
|
26
|
+
return historical_data_of_the_stock(isin, from, till) if from || till
|
27
|
+
|
25
28
|
endpoint = "#{STOCKS_ENDPOINT}/#{isin}.json"
|
26
29
|
params = STANDARD_PARAMS
|
30
|
+
params["iss.only"] = "securities,marketdata"
|
27
31
|
|
28
32
|
raw_response = get(endpoint, params)
|
29
33
|
|
30
34
|
MoexIss::Market::Stock.new(handle_response(raw_response))
|
31
35
|
end
|
36
|
+
|
37
|
+
def currencies
|
38
|
+
endpoint = "#{CURRENCIES_ENDPOINT}.json"
|
39
|
+
params = STANDARD_PARAMS
|
40
|
+
params["iss.only"] = "wap_rates"
|
41
|
+
|
42
|
+
raw_response = get(endpoint, params)
|
43
|
+
|
44
|
+
MoexIss::Market::Currencies.new(handle_response(raw_response))
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def historical_data_of_the_stock(isin, from, till)
|
50
|
+
validate_date(from, till) if from || till
|
51
|
+
|
52
|
+
endpoint = "history/#{STOCKS_ENDPOINT}/#{isin}.json"
|
53
|
+
params = STANDARD_PARAMS.merge({from: from, till: till})
|
54
|
+
|
55
|
+
raw_response = get(endpoint, params)
|
56
|
+
|
57
|
+
MoexIss::Market::History::Stocks.new(handle_response(raw_response))
|
58
|
+
end
|
59
|
+
|
60
|
+
def validate_date(*dates)
|
61
|
+
error = Error::InvalidDateError
|
62
|
+
message = "Невалидная дата"
|
63
|
+
|
64
|
+
dates.compact.each { |date| date.match?(/^\d{4}-\d{2}-\d{2}$/) ? nil : fail(error, message) }
|
65
|
+
end
|
32
66
|
end
|
33
67
|
end
|
data/lib/moex_iss/connection.rb
CHANGED
@@ -34,9 +34,3 @@ module MoexIss
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
38
|
-
# CURENCY https://iss.moex.com/iss/statistics/engines/currency/markets/selt/rates.json?iss.meta=off&iss.json=extended&iss.only=wap_rates
|
39
|
-
|
40
|
-
# STOCKS ALL https://iss.moex.com/iss/engines/stock/markets/shares/boards/tqbr/securities.json?iss.meta=off&iss.json=extended&iss.only=securities,marketdata&marketdata.columns=BID,OPEN,CLOSEPRICE,LOW,HIGH,LAST,VALUE,MARKETPRICETODAY,MARKETPRICE,TIME&securities.columns=SECID,SHORTNAME,LATNAME,BOARDID,BOARDNAME,ISIN,PREVPRICE
|
41
|
-
|
42
|
-
# STOCK ONE https://iss.moex.com/iss/engines/stock/markets/shares/boards/tqbr/securities/sber.json?iss.meta=off&iss.json=extended&iss.only=securities,marketdata&marketdata.columns=BID,OPEN,CLOSEPRICE,LOW,HIGH,LAST,VALUE,MARKETPRICETODAY,MARKETPRICE,TIME&securities.columns=SECID,SHORTNAME,LATNAME,BOARDID,BOARDNAME,ISIN,PREVPRICE
|
data/lib/moex_iss/error.rb
CHANGED
data/lib/moex_iss/hendler.rb
CHANGED
@@ -4,6 +4,8 @@ module MoexIss
|
|
4
4
|
module Hendler
|
5
5
|
def handle_response(response)
|
6
6
|
return standard_hendler(response) if standard_schema?(response)
|
7
|
+
return response[1] if history_schema?(response)
|
8
|
+
return response[1] if currencies_schema?(response)
|
7
9
|
|
8
10
|
fail MoexIss::Error::ResponseSchemaError, "Неизвестная схема ответа"
|
9
11
|
end
|
@@ -17,6 +19,14 @@ module MoexIss
|
|
17
19
|
response[1]["marketdata"].is_a?(Array)
|
18
20
|
end
|
19
21
|
|
22
|
+
def history_schema?(response)
|
23
|
+
response.is_a?(Array) && response[1]&.has_key?("history")
|
24
|
+
end
|
25
|
+
|
26
|
+
def currencies_schema?(response)
|
27
|
+
response.is_a?(Array) && response[1]&.has_key?("wap_rates")
|
28
|
+
end
|
29
|
+
|
20
30
|
def standard_hendler(response)
|
21
31
|
response[1]["securities"].map.with_index do |x, i|
|
22
32
|
{"securities" => x, "marketdata" => response[1]["marketdata"][i]}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MoexIss
|
4
|
+
module Market
|
5
|
+
class Collection
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
attr_reader :response
|
9
|
+
|
10
|
+
def initialize(response, instance_class: Security)
|
11
|
+
@response = response
|
12
|
+
@instance_class = instance_class
|
13
|
+
@stocks_map = {}
|
14
|
+
|
15
|
+
create_instances
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_instances
|
19
|
+
@response.each do |data|
|
20
|
+
method = method_name(data)
|
21
|
+
|
22
|
+
setup_method(method, data)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def each
|
27
|
+
@stocks_map.values.each { |stock| yield stock }
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def method_name(data)
|
33
|
+
:some_name
|
34
|
+
end
|
35
|
+
|
36
|
+
def setup_method(method, data)
|
37
|
+
@stocks_map[method] = @instance_class.new(data)
|
38
|
+
|
39
|
+
self.class.send(:define_method, method) { @stocks_map[method] }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MoexIss
|
4
|
+
module Market
|
5
|
+
class Currencies < Collection
|
6
|
+
def initialize(response, instance_class: MoexIss::Market::Currency)
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_instances
|
11
|
+
@response["wap_rates"].each do |data|
|
12
|
+
method = method_name(data)
|
13
|
+
|
14
|
+
setup_method(method, data)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def method_name(data)
|
21
|
+
data["shortname"]
|
22
|
+
.split("_")
|
23
|
+
.first.downcase
|
24
|
+
.insert(3, "_")
|
25
|
+
.to_sym
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MoexIss
|
4
|
+
module Market
|
5
|
+
class Currency
|
6
|
+
METHODS = {
|
7
|
+
"tradedate" => :trade_date, "tradetime" => :trade_time,
|
8
|
+
"secid" => :secid, "shortname" => :short_name,
|
9
|
+
"price" => :price, "lasttoprevprice" => :last_top_rev_price,
|
10
|
+
"nominal" => :nominal, "decimals" => :decimals
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
attr_reader(:response, *METHODS.values)
|
14
|
+
|
15
|
+
def initialize(response)
|
16
|
+
@response = response
|
17
|
+
|
18
|
+
setup_instance_varibales(@response)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def setup_instance_varibales(data)
|
24
|
+
return if data.nil?
|
25
|
+
|
26
|
+
data.each do |key, value|
|
27
|
+
next unless METHODS.has_key?(key)
|
28
|
+
|
29
|
+
instance_variable_set("@#{METHODS[key]}", value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MoexIss
|
4
|
+
module Market
|
5
|
+
module History
|
6
|
+
class Stock
|
7
|
+
METHODS = {
|
8
|
+
"TRADEDATE" => :trade_date, "SHORTNAME" => :short_name, "SECID" => :secid, "VALUE" => :value,
|
9
|
+
"OPEN" => :open, "LOW" => :low, "HIGH" => :high, "LEGALCLOSEPRICE" => :legal_close_price,
|
10
|
+
"VOLUME" => :volume
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
attr_reader(:response, *METHODS.values)
|
14
|
+
|
15
|
+
def initialize(response)
|
16
|
+
@response = response
|
17
|
+
|
18
|
+
setup_instance_varibales(@response["history"])
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def setup_instance_varibales(data)
|
24
|
+
return if data.nil?
|
25
|
+
|
26
|
+
data.each do |key, value|
|
27
|
+
next unless METHODS.has_key?(key)
|
28
|
+
|
29
|
+
instance_variable_set("@#{METHODS[key]}", value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MoexIss
|
4
|
+
module Market
|
5
|
+
module History
|
6
|
+
class Stocks < MoexIss::Market::Collection
|
7
|
+
def initialize(response, instance_class: MoexIss::Market::History::Stock)
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_instances
|
12
|
+
@response["history"].each do |data|
|
13
|
+
@stocks_map[data["TRADEDATE"]] = History::Stock.new({"history" => data})
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def [](key)
|
18
|
+
@stocks_map[key]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -19,13 +19,23 @@ module MoexIss
|
|
19
19
|
def initialize(response)
|
20
20
|
@response = response.is_a?(Array) ? response.first : response
|
21
21
|
|
22
|
-
@response["securities"]
|
22
|
+
setup_instance_varibales(@response["securities"])
|
23
|
+
setup_instance_varibales(@response["marketdata"])
|
24
|
+
setup_instance_varibales(@response["history"])
|
25
|
+
|
26
|
+
@market_data = @response["marketdata"]&.slice(*MARKET_DATA)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def setup_instance_varibales(data)
|
32
|
+
return if data.nil?
|
33
|
+
|
34
|
+
data.each do |key, value|
|
23
35
|
next unless METHODS.has_key?(key)
|
24
36
|
|
25
37
|
instance_variable_set("@#{METHODS[key]}", value)
|
26
38
|
end
|
27
|
-
|
28
|
-
@market_data = @response["marketdata"].slice(*MARKET_DATA)
|
29
39
|
end
|
30
40
|
end
|
31
41
|
end
|
@@ -2,30 +2,23 @@
|
|
2
2
|
|
3
3
|
module MoexIss
|
4
4
|
module Market
|
5
|
-
class Stocks
|
6
|
-
|
7
|
-
|
8
|
-
attr_reader :stocks_response
|
9
|
-
|
10
|
-
def initialize(stocks_response)
|
11
|
-
@stocks_response = stocks_response
|
12
|
-
@stocks_map = {}
|
13
|
-
|
14
|
-
create_instances_stock
|
5
|
+
class Stocks < Collection
|
6
|
+
def initialize(response, instance_class: MoexIss::Market::Stock)
|
7
|
+
super
|
15
8
|
end
|
16
9
|
|
17
10
|
def create_instances_stock
|
18
|
-
@
|
19
|
-
|
11
|
+
@response.each do |data|
|
12
|
+
method = method_name(data)
|
20
13
|
|
21
|
-
|
22
|
-
|
23
|
-
self.class.send(:define_method, sicid) { @stocks_map[sicid] }
|
14
|
+
setup_method(method, data)
|
24
15
|
end
|
25
16
|
end
|
26
17
|
|
27
|
-
|
28
|
-
|
18
|
+
private
|
19
|
+
|
20
|
+
def method_name(data)
|
21
|
+
data["securities"]["SECID"].downcase.to_sym
|
29
22
|
end
|
30
23
|
end
|
31
24
|
end
|
data/lib/moex_iss/request.rb
CHANGED
@@ -21,9 +21,9 @@ module MoexIss
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def respond_with_error(code, body)
|
24
|
-
|
24
|
+
fail(MoexIss::Error, body) unless MoexIss::Error::ERRORS.key?(code)
|
25
25
|
|
26
|
-
|
26
|
+
fail MoexIss::Error::ERRORS[code], body
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
data/lib/moex_iss/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moex_iss
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vyacheslav Konovalov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -96,6 +96,11 @@ files:
|
|
96
96
|
- lib/moex_iss/connection.rb
|
97
97
|
- lib/moex_iss/error.rb
|
98
98
|
- lib/moex_iss/hendler.rb
|
99
|
+
- lib/moex_iss/market/collection.rb
|
100
|
+
- lib/moex_iss/market/currencies.rb
|
101
|
+
- lib/moex_iss/market/currency.rb
|
102
|
+
- lib/moex_iss/market/history/stock.rb
|
103
|
+
- lib/moex_iss/market/history/stocks.rb
|
99
104
|
- lib/moex_iss/market/stock.rb
|
100
105
|
- lib/moex_iss/market/stocks.rb
|
101
106
|
- lib/moex_iss/request.rb
|
@@ -124,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
129
|
- !ruby/object:Gem::Version
|
125
130
|
version: '0'
|
126
131
|
requirements: []
|
127
|
-
rubygems_version: 3.
|
132
|
+
rubygems_version: 3.1.6
|
128
133
|
signing_key:
|
129
134
|
specification_version: 4
|
130
135
|
summary: Client for MOEX ISS API
|