irix-jruby 2.6.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a8b16e3a189fc5135e79075f31de2bca30081c8bab5b0ddfa5896225c0edf854
4
+ data.tar.gz: 9300df9f50d1bf89d6250220dc5f103a46819de3cd4f57fa39b8ea866b88c666
5
+ SHA512:
6
+ metadata.gz: ee40b421fb1225bdf9150ac5e85d55ad447b55a8112fcdf008f41813ea8f5b5d35e30cd1750b8e78f4935eb1c44149a19b098b53b91bad8719cf1a047dcc1014
7
+ data.tar.gz: 1acb130fdcff98399a32716059b9d3069951b4972f2091f6e657351448d47dbdf8776889e5f651071283d013c16aa4bfeaedee48f3597aa9515f1b04a1136b2f
@@ -0,0 +1,30 @@
1
+ ---
2
+ kind: pipeline
3
+ name: default
4
+
5
+ steps:
6
+ - name: Run rspec
7
+ image: ruby:2.6
8
+ commands:
9
+ - gem install bundler:2.0.2
10
+ - bundle install --jobs=$(nproc) --retry=3 --path vendor/bundle
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
27
+
28
+ trigger:
29
+ event:
30
+ - push
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in irix.gemspec
4
+ gemspec
@@ -0,0 +1,188 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ irix (2.6.0)
5
+ em-synchrony (~> 1.0)
6
+ em-websocket
7
+ eventmachine
8
+ faraday_middleware (~> 0.13.1)
9
+ faye (~> 1.2)
10
+ peatio-jruby (>= 2.4.2)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ activemodel (6.0.0)
16
+ activesupport (= 6.0.0)
17
+ activerecord (6.0.0)
18
+ activemodel (= 6.0.0)
19
+ activesupport (= 6.0.0)
20
+ activerecord-jdbc-adapter (50.0)
21
+ activerecord (>= 2.2)
22
+ activerecord-jdbcmysql-adapter (50.0)
23
+ activerecord-jdbc-adapter (~> 50.0)
24
+ jdbc-mysql (~> 5.1.36)
25
+ activesupport (6.0.0)
26
+ concurrent-ruby (~> 1.0, >= 1.0.2)
27
+ i18n (>= 0.7, < 2)
28
+ minitest (~> 5.1)
29
+ tzinfo (~> 1.1)
30
+ zeitwerk (~> 2.1, >= 2.1.8)
31
+ addressable (2.7.0)
32
+ public_suffix (>= 2.0.2, < 5.0)
33
+ amq-protocol (2.3.2)
34
+ amqp (1.8.0)
35
+ amq-protocol (>= 2.2.0)
36
+ eventmachine
37
+ ast (2.4.0)
38
+ bunny (2.17.0)
39
+ amq-protocol (~> 2.3, >= 2.3.1)
40
+ clamp (1.3.2)
41
+ concurrent-ruby (1.1.8)
42
+ cookiejar (0.3.3)
43
+ diff-lcs (1.3)
44
+ docile (1.3.2)
45
+ em-http-request (1.1.6)
46
+ addressable (>= 2.3.4)
47
+ cookiejar (!= 0.3.1)
48
+ em-socksify (>= 0.3)
49
+ eventmachine (>= 1.0.3)
50
+ http_parser.rb (>= 0.6.0)
51
+ em-socksify (0.3.2)
52
+ eventmachine (>= 1.0.0.beta.4)
53
+ em-spec (0.2.7)
54
+ eventmachine
55
+ em-synchrony (1.0.6)
56
+ eventmachine (>= 1.0.0.beta.1)
57
+ em-websocket (0.5.1)
58
+ eventmachine (>= 0.12.9)
59
+ http_parser.rb (~> 0.6.0)
60
+ em-websocket-client (0.1.2)
61
+ eventmachine
62
+ websocket
63
+ eventmachine (1.2.7)
64
+ eventmachine (1.2.7-java)
65
+ faraday (0.17.3)
66
+ multipart-post (>= 1.2, < 3)
67
+ faraday_middleware (0.13.1)
68
+ faraday (>= 0.7.4, < 1.0)
69
+ faye (1.3.0)
70
+ cookiejar (>= 0.3.0)
71
+ em-http-request (>= 0.3.0)
72
+ eventmachine (>= 0.12.0)
73
+ faye-websocket (>= 0.9.1)
74
+ multi_json (>= 1.0.0)
75
+ rack (>= 1.0.0)
76
+ websocket-driver (>= 0.5.1)
77
+ faye-websocket (0.10.9)
78
+ eventmachine (>= 0.12.0)
79
+ websocket-driver (>= 0.5.1)
80
+ http_parser.rb (0.6.0)
81
+ http_parser.rb (0.6.0-java)
82
+ i18n (1.8.7)
83
+ concurrent-ruby (~> 1.0)
84
+ jaro_winkler (1.5.4)
85
+ jaro_winkler (1.5.4-java)
86
+ jdbc-mysql (5.1.47)
87
+ jruby-rack (1.1.21)
88
+ json (2.2.0)
89
+ json (2.2.0-java)
90
+ jwt (2.2.2)
91
+ minitest (5.14.3)
92
+ multi_json (1.14.1)
93
+ multipart-post (2.1.1)
94
+ parallel (1.19.0)
95
+ parser (2.6.5.0)
96
+ ast (~> 2.4.0)
97
+ peatio-jruby (2.6.2)
98
+ activemodel (> 5.2, <= 6.0.0)
99
+ activerecord-jdbc-adapter
100
+ activerecord-jdbcmysql-adapter
101
+ amqp
102
+ bunny
103
+ clamp
104
+ em-synchrony (~> 1.0)
105
+ em-websocket
106
+ eventmachine
107
+ faraday_middleware (~> 0.13.1)
108
+ faye (~> 1.2)
109
+ jdbc-mysql
110
+ jwt
111
+ prometheus-client
112
+ trinidad
113
+ prometheus-client (2.1.0)
114
+ public_suffix (4.0.5)
115
+ rack (2.2.2)
116
+ rainbow (3.0.0)
117
+ rake (13.0.1)
118
+ rspec (3.9.0)
119
+ rspec-core (~> 3.9.0)
120
+ rspec-expectations (~> 3.9.0)
121
+ rspec-mocks (~> 3.9.0)
122
+ rspec-core (3.9.1)
123
+ rspec-support (~> 3.9.1)
124
+ rspec-expectations (3.9.0)
125
+ diff-lcs (>= 1.2.0, < 2.0)
126
+ rspec-support (~> 3.9.0)
127
+ rspec-mocks (3.9.1)
128
+ diff-lcs (>= 1.2.0, < 2.0)
129
+ rspec-support (~> 3.9.0)
130
+ rspec-support (3.9.2)
131
+ rspec_junit_formatter (0.4.1)
132
+ rspec-core (>= 2, < 4, != 2.12.0)
133
+ rubocop (0.76.0)
134
+ jaro_winkler (~> 1.5.1)
135
+ parallel (~> 1.10)
136
+ parser (>= 2.6)
137
+ rainbow (>= 2.2.2, < 4.0)
138
+ ruby-progressbar (~> 1.7)
139
+ unicode-display_width (>= 1.4.0, < 1.7)
140
+ rubocop-github (0.13.0)
141
+ rubocop (~> 0.70)
142
+ rubocop-performance (~> 1.3.0)
143
+ rubocop-performance (1.3.0)
144
+ rubocop (>= 0.68.0)
145
+ ruby-progressbar (1.10.1)
146
+ simplecov (0.17.1)
147
+ docile (~> 1.1)
148
+ json (>= 1.8, < 3)
149
+ simplecov-html (~> 0.10.0)
150
+ simplecov-html (0.10.2)
151
+ simplecov-json (0.2)
152
+ json
153
+ simplecov
154
+ thread_safe (0.3.6)
155
+ thread_safe (0.3.6-java)
156
+ trinidad (1.4.6)
157
+ jruby-rack (~> 1.1.13)
158
+ trinidad_jars (>= 1.3.0, < 1.5.0)
159
+ trinidad_jars (1.4.2)
160
+ tzinfo (1.2.9)
161
+ thread_safe (~> 0.1)
162
+ unicode-display_width (1.6.0)
163
+ websocket (1.2.8)
164
+ websocket-driver (0.7.2)
165
+ websocket-extensions (>= 0.1.0)
166
+ websocket-driver (0.7.2-java)
167
+ websocket-extensions (>= 0.1.0)
168
+ websocket-extensions (0.1.5)
169
+ zeitwerk (2.4.2)
170
+
171
+ PLATFORMS
172
+ ruby
173
+ universal-java-1.8
174
+
175
+ DEPENDENCIES
176
+ bundler (~> 2.0)
177
+ em-spec
178
+ em-websocket-client
179
+ irix!
180
+ rake (~> 13.0)
181
+ rspec (~> 3.0)
182
+ rspec_junit_formatter
183
+ rubocop-github
184
+ simplecov
185
+ simplecov-json
186
+
187
+ BUNDLED WITH
188
+ 2.2.7
@@ -0,0 +1,35 @@
1
+ # Irix
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/irix`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'irix'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install irix
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/irix.
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "irix"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,41 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "irix/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "irix-jruby"
7
+ spec.version = Irix::VERSION
8
+ spec.authors = ["Naichuk M."]
9
+ spec.email = ["mnaichuk@heliostech.fr"]
10
+
11
+ spec.summary = %q{Irix is implementing several crypto-exchange for Arke and Peatio.}
12
+ spec.description = %q{Irix is implementing several crypto-exchange for Arke and Peatio.}
13
+ spec.homepage = "https://www.openware.com"
14
+
15
+ # Specify which files should be added to the gem when it is released.
16
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
17
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ end
20
+ spec.bindir = "bin"
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_dependency "em-synchrony", "~> 1.0"
25
+ spec.add_dependency "em-websocket"
26
+ spec.add_dependency "eventmachine"
27
+ spec.add_dependency "faraday_middleware", "~> 0.13.1"
28
+ spec.add_dependency "faye", "~> 1.2"
29
+ spec.add_dependency "peatio-jruby", ">= 2.4.2"
30
+
31
+ spec.add_development_dependency "bundler", "~> 2.0"
32
+ spec.add_development_dependency "em-spec"
33
+ spec.add_development_dependency "em-websocket-client"
34
+ # spec.add_development_dependency "pry-byebug"
35
+ spec.add_development_dependency "rake", "~> 13.0"
36
+ spec.add_development_dependency "rspec", "~> 3.0"
37
+ spec.add_development_dependency "rspec_junit_formatter"
38
+ spec.add_development_dependency "rubocop-github"
39
+ spec.add_development_dependency "simplecov"
40
+ spec.add_development_dependency "simplecov-json"
41
+ end
@@ -0,0 +1,14 @@
1
+ require "peatio"
2
+ require "faraday_middleware"
3
+ require "em-synchrony"
4
+ require "em-websocket"
5
+ require "eventmachine"
6
+ require "faraday_middleware"
7
+ require "faye"
8
+
9
+ module Irix
10
+ require "irix/bitfinex"
11
+ require "irix/huobi"
12
+ require "irix/hooks"
13
+ require "irix/version"
14
+ end
@@ -0,0 +1,205 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irix
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
+
14
+ def initialize(config)
15
+ super
16
+ @connection = Faraday.new(url: (config['rest']).to_s) do |builder|
17
+ builder.response :json
18
+ builder.response :logger if config['debug']
19
+ builder.adapter(@adapter)
20
+ unless config['verify_ssl'].nil?
21
+ builder.ssl[:verify] = config['verify_ssl']
22
+ end
23
+ end
24
+ @open_channels = {}
25
+ @ping_set = false
26
+ @rest = (config['rest']).to_s
27
+ @ws_url = (config['websocket']).to_s
28
+ end
29
+
30
+ def ws_connect
31
+ super
32
+ return if @ping_set
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
+
40
+ Fiber.new do
41
+ EM::Synchrony.add_periodic_timer(80) do
42
+ @ws.send('{"event":"ping"}')
43
+ end
44
+ end.resume
45
+ @ping_set = true
46
+ end
47
+
48
+ def subscribe_trades(market, ws)
49
+ return unless @config['trade_proxy']
50
+
51
+ sub = {
52
+ event: 'subscribe',
53
+ channel: 'trades',
54
+ symbol: market.upcase
55
+ }
56
+
57
+ Rails.logger.info 'Open event' + sub.to_s
58
+ EM.next_tick do
59
+ ws.send(JSON.generate(sub))
60
+ end
61
+ end
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
+
88
+ def ws_read_public_message(msg)
89
+ if msg.is_a?(Array)
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
97
+ elsif msg.is_a?(Hash)
98
+ message_event(msg)
99
+ end
100
+ end
101
+
102
+ def detect_trade(msg)
103
+ if msg[1] == 'tu'
104
+ data = msg[2]
105
+ trade =
106
+ {
107
+ 'tid' => data[0],
108
+ 'amount' => data[2].to_d.abs,
109
+ 'price' => data[3],
110
+ 'date' => data[1] / 1000,
111
+ 'taker_type' => data[2].to_d.positive? ? 'buy' : 'sell'
112
+ }
113
+ notify_public_trade(trade)
114
+ end
115
+ end
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
+
191
+ def message_event(msg)
192
+ case msg['event']
193
+ when 'subscribed'
194
+ Rails.logger.info "Event: #{msg}"
195
+ @open_channels[msg['chanId']] = msg['channel']
196
+ when 'error'
197
+ Rails.logger.info "Event: #{msg} ignored"
198
+ end
199
+ end
200
+
201
+ def info(msg)
202
+ Rails.logger.info "Bitfinex: #{msg}"
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irix
4
+ module Hooks
5
+ class << self
6
+ def register
7
+ Peatio::Upstream.registry[:bitfinex] = Irix::Bitfinex
8
+ Peatio::Upstream.registry[:huobi] = Irix::Huobi
9
+ end
10
+ end
11
+
12
+ if defined?(Rails::Railtie)
13
+ require 'irix/railtie'
14
+ else
15
+ register
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irix
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
13
+ # WS huobi global
14
+ # websocket: "wss://api.huobi.pro/ws/"
15
+ # WS for krw markets
16
+ # websocket: "wss://api-cloud.huobi.co.kr/ws/"
17
+
18
+ def initialize(config)
19
+ super
20
+ @connection = Faraday.new(url: (config['rest']).to_s) do |builder|
21
+ builder.response :json
22
+ builder.response :logger if config['debug']
23
+ builder.adapter(@adapter)
24
+ unless config['verify_ssl'].nil?
25
+ builder.ssl[:verify] = config['verify_ssl']
26
+ end
27
+ end
28
+ @ping_set = false
29
+ @rest = (config['rest']).to_s
30
+ @ws_url = (config['websocket']).to_s
31
+ end
32
+
33
+ def ws_read_message(msg)
34
+ data = Zlib::GzipReader.new(StringIO.new(msg.data.map(&:chr).join)).read
35
+ Rails.logger.debug { "received websocket message: #{data}" }
36
+
37
+ object = JSON.parse(data)
38
+ ws_read_public_message(object)
39
+ end
40
+
41
+ def ws_read_public_message(msg)
42
+ if msg['ping'].present?
43
+ @ws.send(JSON.dump('pong': msg['ping']))
44
+ return
45
+ end
46
+
47
+ case msg['ch']
48
+ when /market\.#{@target}\.trade\.detail/
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
89
+ end
90
+ end
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
+
114
+ def detect_trade(msg)
115
+ msg.map do |t|
116
+ trade =
117
+ {
118
+ 'tid' => t['tradeId'],
119
+ 'amount' => t['amount'].to_d,
120
+ 'price' => t['price'].to_d,
121
+ 'date' => t['ts'] / 1000,
122
+ 'taker_type' => t['direction']
123
+ }
124
+ notify_public_trade(trade)
125
+ end
126
+ end
127
+
128
+ def ws_connect
129
+ super
130
+ return if @ping_set
131
+
132
+ Fiber.new do
133
+ EM::Synchrony.add_periodic_timer(80) do
134
+ @ws.send(JSON.dump('ping' => Time.now.to_i))
135
+ end
136
+ end.resume
137
+ @ping_set = true
138
+ end
139
+
140
+ def subscribe_trades(market, ws)
141
+ return unless @config['trade_proxy']
142
+
143
+ sub = {
144
+ 'sub' => "market.#{market}.trade.detail"
145
+ }
146
+
147
+ Rails.logger.info 'Open event' + sub.to_s
148
+ EM.next_tick do
149
+ ws.send(JSON.generate(sub))
150
+ end
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
176
+ end
177
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Irix
4
+ class Railtie < Rails::Railtie
5
+ config.after_initialize do
6
+ Hooks.register
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Irix
2
+ VERSION = "2.6.0"
3
+ end
metadata ADDED
@@ -0,0 +1,270 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: irix-jruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.6.0
5
+ platform: ruby
6
+ authors:
7
+ - Naichuk M.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-01-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.0'
19
+ name: em-synchrony
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ name: em-websocket
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ name: eventmachine
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: 0.13.1
61
+ name: faraday_middleware
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.13.1
69
+ - !ruby/object:Gem::Dependency
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.2'
75
+ name: faye
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.2'
83
+ - !ruby/object:Gem::Dependency
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 2.4.2
89
+ name: peatio-jruby
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 2.4.2
97
+ - !ruby/object:Gem::Dependency
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.0'
103
+ name: bundler
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.0'
111
+ - !ruby/object:Gem::Dependency
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ name: em-spec
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ name: em-websocket-client
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '13.0'
145
+ name: rake
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '13.0'
153
+ - !ruby/object:Gem::Dependency
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '3.0'
159
+ name: rspec
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '3.0'
167
+ - !ruby/object:Gem::Dependency
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ name: rspec_junit_formatter
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ requirement: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ name: rubocop-github
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ requirement: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ name: simplecov
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ requirement: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ name: simplecov-json
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ description: Irix is implementing several crypto-exchange for Arke and Peatio.
224
+ email:
225
+ - mnaichuk@heliostech.fr
226
+ executables:
227
+ - console
228
+ - setup
229
+ extensions: []
230
+ extra_rdoc_files: []
231
+ files:
232
+ - ".drone.yml"
233
+ - ".gitignore"
234
+ - ".rspec"
235
+ - Gemfile
236
+ - Gemfile.lock
237
+ - README.md
238
+ - Rakefile
239
+ - bin/console
240
+ - bin/setup
241
+ - irix.gemspec
242
+ - lib/irix.rb
243
+ - lib/irix/bitfinex.rb
244
+ - lib/irix/hooks.rb
245
+ - lib/irix/huobi.rb
246
+ - lib/irix/railtie.rb
247
+ - lib/irix/version.rb
248
+ homepage: https://www.openware.com
249
+ licenses: []
250
+ metadata: {}
251
+ post_install_message:
252
+ rdoc_options: []
253
+ require_paths:
254
+ - lib
255
+ required_ruby_version: !ruby/object:Gem::Requirement
256
+ requirements:
257
+ - - ">="
258
+ - !ruby/object:Gem::Version
259
+ version: '0'
260
+ required_rubygems_version: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
265
+ requirements: []
266
+ rubygems_version: 3.0.6
267
+ signing_key:
268
+ specification_version: 4
269
+ summary: Irix is implementing several crypto-exchange for Arke and Peatio.
270
+ test_files: []