irix-jruby 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []