irix 2.4.2 → 2.4.5
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/.drone.yml +15 -0
- data/Gemfile.lock +9 -9
- data/lib/irix/bitfinex.rb +126 -2
- data/lib/irix/huobi.rb +96 -1
- data/lib/irix/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f657a9eb4e3dfc49657b176fafc409ef49511836fffe48cfaa13d80b0d39368c
|
4
|
+
data.tar.gz: 00baaa01a84aafd3ff46ec00752fbd99705edf206a5e2c76483926555b1065e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d506765d1553093958e4597267bc0c3588648af480de6fb56ca9767c023ef17583a75da2c6806344e0732dd72a15fcd5ab650e0bb5a6d0bf6e469d699ef2709c
|
7
|
+
data.tar.gz: aafdb928c1c213c7685600a45812d0d1d630694c731b173ffdf2fe62155b4cf9de1fce67d039f5239590f670e004d3f86415375fbe786e3b7bcf0d206f1e81fa
|
data/.drone.yml
CHANGED
@@ -9,6 +9,21 @@ steps:
|
|
9
9
|
- gem install bundler:2.0.2
|
10
10
|
- bundle install --jobs=$(nproc) --retry=3 --path vendor/bundle
|
11
11
|
- bundle exec rspec
|
12
|
+
|
13
|
+
- name: Release gem
|
14
|
+
image: ruby:2.6
|
15
|
+
environment:
|
16
|
+
GEM_CREDENTIALS:
|
17
|
+
from_secret: gem_credentials
|
18
|
+
commands:
|
19
|
+
- mkdir -p ~/.gem
|
20
|
+
- echo $GEM_CREDENTIALS | base64 -d > ~/.gem/credentials
|
21
|
+
- chmod 0600 ~/.gem/credentials
|
22
|
+
- gem build irix.gemspec
|
23
|
+
- gem push irix-*.gem
|
24
|
+
when:
|
25
|
+
branch:
|
26
|
+
- master
|
12
27
|
|
13
28
|
trigger:
|
14
29
|
event:
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
irix (2.4.
|
4
|
+
irix (2.4.5)
|
5
5
|
em-synchrony (~> 1.0)
|
6
6
|
em-websocket
|
7
7
|
eventmachine
|
@@ -22,13 +22,13 @@ GEM
|
|
22
22
|
zeitwerk (~> 2.1, >= 2.1.8)
|
23
23
|
addressable (2.7.0)
|
24
24
|
public_suffix (>= 2.0.2, < 5.0)
|
25
|
-
amq-protocol (2.3.
|
25
|
+
amq-protocol (2.3.1)
|
26
26
|
amqp (1.8.0)
|
27
27
|
amq-protocol (>= 2.2.0)
|
28
28
|
eventmachine
|
29
29
|
ast (2.4.0)
|
30
|
-
bunny (2.
|
31
|
-
amq-protocol (~> 2.3, >= 2.3.
|
30
|
+
bunny (2.15.0)
|
31
|
+
amq-protocol (~> 2.3, >= 2.3.1)
|
32
32
|
byebug (11.1.1)
|
33
33
|
clamp (1.3.1)
|
34
34
|
coderay (1.1.2)
|
@@ -60,7 +60,7 @@ GEM
|
|
60
60
|
multipart-post (>= 1.2, < 3)
|
61
61
|
faraday_middleware (0.13.1)
|
62
62
|
faraday (>= 0.7.4, < 1.0)
|
63
|
-
faye (1.2.
|
63
|
+
faye (1.2.5)
|
64
64
|
cookiejar (>= 0.3.0)
|
65
65
|
em-http-request (>= 0.3.0)
|
66
66
|
eventmachine (>= 0.12.0)
|
@@ -85,7 +85,7 @@ GEM
|
|
85
85
|
parallel (1.19.0)
|
86
86
|
parser (2.6.5.0)
|
87
87
|
ast (~> 2.4.0)
|
88
|
-
peatio (2.4.
|
88
|
+
peatio (2.4.4)
|
89
89
|
activemodel (> 5.2, <= 6.0.0)
|
90
90
|
amqp
|
91
91
|
bunny
|
@@ -106,7 +106,7 @@ GEM
|
|
106
106
|
pry-byebug (3.8.0)
|
107
107
|
byebug (~> 11.0)
|
108
108
|
pry (~> 0.10)
|
109
|
-
public_suffix (4.0.
|
109
|
+
public_suffix (4.0.5)
|
110
110
|
rack (2.2.2)
|
111
111
|
rainbow (3.0.0)
|
112
112
|
rake (13.0.1)
|
@@ -151,7 +151,7 @@ GEM
|
|
151
151
|
eventmachine (~> 1.0, >= 1.0.4)
|
152
152
|
rack (>= 1, < 3)
|
153
153
|
thread_safe (0.3.6)
|
154
|
-
tzinfo (1.2.
|
154
|
+
tzinfo (1.2.7)
|
155
155
|
thread_safe (~> 0.1)
|
156
156
|
unicode-display_width (1.6.0)
|
157
157
|
websocket (1.2.8)
|
@@ -177,4 +177,4 @@ DEPENDENCIES
|
|
177
177
|
simplecov-json
|
178
178
|
|
179
179
|
BUNDLED WITH
|
180
|
-
2.
|
180
|
+
2.1.4
|
data/lib/irix/bitfinex.rb
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
module Irix
|
4
4
|
class Bitfinex < Peatio::Upstream::Base
|
5
|
+
require 'time'
|
6
|
+
|
7
|
+
MIN_INCREMENT_COUNT_TO_SNAPSHOT = 100
|
8
|
+
MIN_PERIOD_TO_SNAPSHOT = 5
|
9
|
+
MAX_PERIOD_TO_SNAPSHOT = 60
|
10
|
+
|
11
|
+
attr_accessor :snap, :snapshot_time, :increment_count, :sequence_number,
|
12
|
+
:open_channels, :asks, :bids
|
13
|
+
|
5
14
|
def initialize(config)
|
6
15
|
super
|
7
16
|
@connection = Faraday.new(url: (config['rest']).to_s) do |builder|
|
@@ -12,15 +21,22 @@ module Irix
|
|
12
21
|
builder.ssl[:verify] = config['verify_ssl']
|
13
22
|
end
|
14
23
|
end
|
24
|
+
@open_channels = {}
|
15
25
|
@ping_set = false
|
16
26
|
@rest = (config['rest']).to_s
|
17
|
-
@ws_url =
|
27
|
+
@ws_url = (config['websocket']).to_s
|
18
28
|
end
|
19
29
|
|
20
30
|
def ws_connect
|
21
31
|
super
|
22
32
|
return if @ping_set
|
23
33
|
|
34
|
+
@ws.on(:open) do |_e|
|
35
|
+
subscribe_trades(@target, @ws)
|
36
|
+
subscribe_orderbook(@target, @ws)
|
37
|
+
logger.info { 'Websocket connected' }
|
38
|
+
end
|
39
|
+
|
24
40
|
Fiber.new do
|
25
41
|
EM::Synchrony.add_periodic_timer(80) do
|
26
42
|
@ws.send('{"event":"ping"}')
|
@@ -30,6 +46,8 @@ module Irix
|
|
30
46
|
end
|
31
47
|
|
32
48
|
def subscribe_trades(market, ws)
|
49
|
+
return unless @config['trade_proxy']
|
50
|
+
|
33
51
|
sub = {
|
34
52
|
event: 'subscribe',
|
35
53
|
channel: 'trades',
|
@@ -42,9 +60,40 @@ module Irix
|
|
42
60
|
end
|
43
61
|
end
|
44
62
|
|
63
|
+
def subscribe_orderbook(market, ws)
|
64
|
+
return unless @config['orderbook_proxy']
|
65
|
+
|
66
|
+
@sequence_number = 0
|
67
|
+
@increment_count = 0
|
68
|
+
@bids = []
|
69
|
+
@asks = []
|
70
|
+
@snap = { 'asks' => [], 'bids' => [] }
|
71
|
+
sub = {
|
72
|
+
event: 'subscribe',
|
73
|
+
channel: 'book',
|
74
|
+
symbol: market.upcase,
|
75
|
+
len: 25
|
76
|
+
}
|
77
|
+
Rails.logger.info 'Open event' + sub.to_s
|
78
|
+
EM.next_tick do
|
79
|
+
ws.send(JSON.generate(sub))
|
80
|
+
end
|
81
|
+
Fiber.new do
|
82
|
+
EM::Synchrony.add_periodic_timer(0.2) do
|
83
|
+
publish_increment
|
84
|
+
end
|
85
|
+
end.resume
|
86
|
+
end
|
87
|
+
|
45
88
|
def ws_read_public_message(msg)
|
46
89
|
if msg.is_a?(Array)
|
47
|
-
|
90
|
+
if msg[1] == 'hb'
|
91
|
+
@ws.send('{"event":"ping"}')
|
92
|
+
elsif @open_channels[msg[0]] == 'trades'
|
93
|
+
detect_trade(msg)
|
94
|
+
elsif @open_channels[msg[0]] == 'book'
|
95
|
+
detect_order(msg)
|
96
|
+
end
|
48
97
|
elsif msg.is_a?(Hash)
|
49
98
|
message_event(msg)
|
50
99
|
end
|
@@ -65,10 +114,85 @@ module Irix
|
|
65
114
|
end
|
66
115
|
end
|
67
116
|
|
117
|
+
# [
|
118
|
+
# CHANNEL_ID,
|
119
|
+
# [
|
120
|
+
# PRICE,
|
121
|
+
# COUNT,
|
122
|
+
# AMOUNT
|
123
|
+
# ]
|
124
|
+
# ]
|
125
|
+
def detect_order(msg)
|
126
|
+
if msg[1][0].is_a?(Array)
|
127
|
+
msg[1].each do |point|
|
128
|
+
if point[2] > 0
|
129
|
+
@snap['bids'] << [point[0].to_s, point[2].to_s]
|
130
|
+
else
|
131
|
+
@snap['asks'] << [point[0].to_s, point[2].abs.to_s]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
publish_snapshot
|
135
|
+
else
|
136
|
+
if @increment_count < MIN_INCREMENT_COUNT_TO_SNAPSHOT && @snapshot_time <= Time.now - MAX_PERIOD_TO_SNAPSHOT
|
137
|
+
publish_snapshot
|
138
|
+
@increment_count = 0
|
139
|
+
elsif @increment_count >= MIN_INCREMENT_COUNT_TO_SNAPSHOT && @snapshot_time < Time.now - MIN_PERIOD_TO_SNAPSHOT
|
140
|
+
publish_snapshot
|
141
|
+
@increment_count = 0
|
142
|
+
end
|
143
|
+
|
144
|
+
fill_increment(msg[1])
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def fill_increment(order)
|
149
|
+
side = order[2].positive? ? 'bid' : 'ask'
|
150
|
+
price = order[0].to_s
|
151
|
+
if order[1].zero?
|
152
|
+
amount = 0
|
153
|
+
@snap["#{side}s"].delete_if { |point| point[0] == price }
|
154
|
+
else
|
155
|
+
amount = order[2].abs.to_s
|
156
|
+
@snap["#{side}s"].delete_if { |point| point[0] == price }
|
157
|
+
@snap["#{side}s"] << [price.to_s, amount.to_s]
|
158
|
+
end
|
159
|
+
if side == 'bid'
|
160
|
+
@bids.delete_if { |point| point[0] == price }
|
161
|
+
@bids << [price.to_s, amount.to_s]
|
162
|
+
elsif side == 'ask'
|
163
|
+
@asks.delete_if { |point| point[0] == price }
|
164
|
+
@asks << [price.to_s, amount.to_s]
|
165
|
+
end
|
166
|
+
@increment_count += 1
|
167
|
+
end
|
168
|
+
|
169
|
+
def publish_increment
|
170
|
+
inc = {}
|
171
|
+
inc['bids'] = @bids.sort.reverse if @bids.present?
|
172
|
+
inc['asks'] = @asks.sort if @asks.present?
|
173
|
+
if inc.present?
|
174
|
+
@sequence_number += 1
|
175
|
+
@peatio_mq.enqueue_event('public', @market, 'ob-inc',
|
176
|
+
'bids' => inc['bids'], 'asks' => inc['asks'],
|
177
|
+
'sequence' => @sequence_number)
|
178
|
+
end
|
179
|
+
@bids = []
|
180
|
+
@asks = []
|
181
|
+
end
|
182
|
+
|
183
|
+
def publish_snapshot
|
184
|
+
@snapshot_time = Time.now
|
185
|
+
@peatio_mq.enqueue_event('public', @market, 'ob-snap',
|
186
|
+
'bids' => @snap['bids'].sort.reverse,
|
187
|
+
'asks' => @snap['asks'].sort,
|
188
|
+
'sequence' => @sequence_number)
|
189
|
+
end
|
190
|
+
|
68
191
|
def message_event(msg)
|
69
192
|
case msg['event']
|
70
193
|
when 'subscribed'
|
71
194
|
Rails.logger.info "Event: #{msg}"
|
195
|
+
@open_channels[msg['chanId']] = msg['channel']
|
72
196
|
when 'error'
|
73
197
|
Rails.logger.info "Event: #{msg} ignored"
|
74
198
|
end
|
data/lib/irix/huobi.rb
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
module Irix
|
4
4
|
class Huobi < Peatio::Upstream::Base
|
5
|
+
require 'time'
|
6
|
+
|
7
|
+
MIN_INCREMENT_COUNT_TO_SNAPSHOT = 100
|
8
|
+
MIN_PERIOD_TO_SNAPSHOT = 5
|
9
|
+
MAX_PERIOD_TO_SNAPSHOT = 60
|
10
|
+
|
11
|
+
attr_accessor :snap, :snapshot_time, :increment_count, :sequence_number,
|
12
|
+
:asks, :bids
|
5
13
|
# WS huobi global
|
6
14
|
# websocket: "wss://api.huobi.pro/ws/"
|
7
15
|
# WS for krw markets
|
@@ -37,11 +45,72 @@ module Irix
|
|
37
45
|
end
|
38
46
|
|
39
47
|
case msg['ch']
|
40
|
-
when /market\.
|
48
|
+
when /market\.#{@target}\.trade\.detail/
|
41
49
|
detect_trade(msg.dig('tick', 'data'))
|
50
|
+
when /market\.#{@target}\.mbp\.150/
|
51
|
+
detect_order(msg.dig('tick'))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def detect_order(msg)
|
56
|
+
if @increment_count < MIN_INCREMENT_COUNT_TO_SNAPSHOT && @snapshot_time <= Time.now - MAX_PERIOD_TO_SNAPSHOT
|
57
|
+
publish_snapshot
|
58
|
+
@increment_count = 0
|
59
|
+
elsif @increment_count >= MIN_INCREMENT_COUNT_TO_SNAPSHOT && @snapshot_time < Time.now - MIN_PERIOD_TO_SNAPSHOT
|
60
|
+
publish_snapshot
|
61
|
+
@increment_count = 0
|
62
|
+
end
|
63
|
+
fill_increment(msg)
|
64
|
+
end
|
65
|
+
|
66
|
+
def fill_increment(inc)
|
67
|
+
fill_side(inc, "bids")
|
68
|
+
fill_side(inc, "asks")
|
69
|
+
@increment_count += 1
|
70
|
+
end
|
71
|
+
|
72
|
+
def fill_side(inc, side)
|
73
|
+
inc[side].each do |price_point|
|
74
|
+
price = price_point[0]
|
75
|
+
amount = price_point[1]
|
76
|
+
if amount.zero?
|
77
|
+
@snap[side].delete_if { |point| point[0] == price.to_s }
|
78
|
+
else
|
79
|
+
@snap[side].delete_if { |point| point[0] == price.to_s }
|
80
|
+
@snap[side] << [price.to_s, amount.to_s]
|
81
|
+
end
|
82
|
+
if side == "bids"
|
83
|
+
@bids.delete_if { |point| point[0] == price }
|
84
|
+
@bids << [price.to_s, amount.to_s]
|
85
|
+
elsif side == "asks"
|
86
|
+
@asks.delete_if { |point| point[0] == price }
|
87
|
+
@asks << [price.to_s, amount.to_s]
|
88
|
+
end
|
42
89
|
end
|
43
90
|
end
|
44
91
|
|
92
|
+
def publish_increment
|
93
|
+
inc = {}
|
94
|
+
inc['bids'] = @bids.sort.reverse if @bids.present?
|
95
|
+
inc['asks'] = @asks.sort if @asks.present?
|
96
|
+
if inc.present?
|
97
|
+
@sequence_number += 1
|
98
|
+
@peatio_mq.enqueue_event('public', @market, 'ob-inc',
|
99
|
+
'bids' => inc['bids'], 'asks' => inc['asks'],
|
100
|
+
'sequence' => @sequence_number)
|
101
|
+
end
|
102
|
+
@bids = []
|
103
|
+
@asks = []
|
104
|
+
end
|
105
|
+
|
106
|
+
def publish_snapshot
|
107
|
+
@snapshot_time = Time.now
|
108
|
+
@peatio_mq.enqueue_event('public', @market, 'ob-snap',
|
109
|
+
'bids' => @snap['bids'].sort.reverse,
|
110
|
+
'asks' => @snap['asks'].sort,
|
111
|
+
'sequence' => @sequence_number)
|
112
|
+
end
|
113
|
+
|
45
114
|
def detect_trade(msg)
|
46
115
|
msg.map do |t|
|
47
116
|
trade =
|
@@ -69,6 +138,8 @@ module Irix
|
|
69
138
|
end
|
70
139
|
|
71
140
|
def subscribe_trades(market, ws)
|
141
|
+
return unless @config['trade_proxy']
|
142
|
+
|
72
143
|
sub = {
|
73
144
|
'sub' => "market.#{market}.trade.detail"
|
74
145
|
}
|
@@ -78,5 +149,29 @@ module Irix
|
|
78
149
|
ws.send(JSON.generate(sub))
|
79
150
|
end
|
80
151
|
end
|
152
|
+
|
153
|
+
def subscribe_orderbook(market, ws)
|
154
|
+
return unless @config['orderbook_proxy']
|
155
|
+
|
156
|
+
@sequence_number = 0
|
157
|
+
@increment_count = 0
|
158
|
+
@snapshot_time = Time.now
|
159
|
+
@bids = []
|
160
|
+
@asks = []
|
161
|
+
@snap = { 'asks' => [], 'bids' => [] }
|
162
|
+
sub = {
|
163
|
+
'sub' => "market.#{market}.mbp.150"
|
164
|
+
}
|
165
|
+
|
166
|
+
Rails.logger.info 'Open event' + sub.to_s
|
167
|
+
EM.next_tick do
|
168
|
+
ws.send(JSON.generate(sub))
|
169
|
+
end
|
170
|
+
Fiber.new do
|
171
|
+
EM::Synchrony.add_periodic_timer(0.2) do
|
172
|
+
publish_increment
|
173
|
+
end
|
174
|
+
end.resume
|
175
|
+
end
|
81
176
|
end
|
82
177
|
end
|
data/lib/irix/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: irix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Naichuk M.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: em-synchrony
|