honeymaker 0.8.0 → 0.9.2

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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +22 -10
  3. data/lib/honeymaker/clients/kraken.rb +18 -1
  4. data/lib/honeymaker/exchanges/binance.rb +2 -1
  5. data/lib/honeymaker/exchanges/bingx.rb +2 -1
  6. data/lib/honeymaker/exchanges/bitget.rb +2 -1
  7. data/lib/honeymaker/exchanges/bitmart.rb +2 -1
  8. data/lib/honeymaker/exchanges/bitrue.rb +2 -1
  9. data/lib/honeymaker/exchanges/bitvavo.rb +2 -1
  10. data/lib/honeymaker/exchanges/bybit.rb +2 -1
  11. data/lib/honeymaker/exchanges/coinbase.rb +11 -1
  12. data/lib/honeymaker/exchanges/gemini.rb +2 -1
  13. data/lib/honeymaker/exchanges/hyperliquid.rb +2 -1
  14. data/lib/honeymaker/exchanges/kraken.rb +2 -1
  15. data/lib/honeymaker/exchanges/kucoin.rb +2 -1
  16. data/lib/honeymaker/exchanges/mexc.rb +2 -1
  17. data/lib/honeymaker/version.rb +1 -1
  18. data/test/honeymaker/clients/kraken_client_test.rb +58 -0
  19. data/test/honeymaker/exchanges/binance_test.rb +13 -0
  20. data/test/honeymaker/exchanges/binance_us_test.rb +2 -0
  21. data/test/honeymaker/exchanges/bingx_test.rb +1 -0
  22. data/test/honeymaker/exchanges/bitget_test.rb +4 -2
  23. data/test/honeymaker/exchanges/bitmart_test.rb +4 -2
  24. data/test/honeymaker/exchanges/bitrue_test.rb +1 -0
  25. data/test/honeymaker/exchanges/bitvavo_test.rb +4 -2
  26. data/test/honeymaker/exchanges/bybit_test.rb +1 -0
  27. data/test/honeymaker/exchanges/coinbase_test.rb +23 -0
  28. data/test/honeymaker/exchanges/gemini_test.rb +1 -0
  29. data/test/honeymaker/exchanges/hyperliquid_test.rb +1 -0
  30. data/test/honeymaker/exchanges/kraken_test.rb +32 -0
  31. data/test/honeymaker/exchanges/kucoin_test.rb +1 -0
  32. data/test/honeymaker/exchanges/mexc_test.rb +4 -2
  33. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 329432e2569d62afa1bd99352d9f9075dbfb93004b27856f3ae535e03aba2a00
4
- data.tar.gz: fe3f83098b328ad88e41c385efd8fe855ba8386c838beae26caab2d02a479a45
3
+ metadata.gz: ac4aba6f18266cfffed7dfe3939a60198cb6bdb7361818db8f25f435e19d92f9
4
+ data.tar.gz: e0e398092c55d7483ac386a94846fd5eff4abf115feb9dffd59a85c59462da37
5
5
  SHA512:
6
- metadata.gz: 1f38749e06bf4b3fbf03da5830bcc68bfe581b8f901f566894ee51d81a0b6883cd59bd8646ed98ca2fa119db70beee055b10dce2068387b85377b1b1e6cef6bc
7
- data.tar.gz: b83aa96da78eab87f3004321175b470ade7caa34b7843f326c72a3b479d548cedf223328a70700afadc46e96bca17844002ab6467fc9cfd31313bd7ea5118825
6
+ metadata.gz: aabbbc8fdd2c884c85770fc21a5862fe05c014860775f44e362e59c7db7c841cf92e74494af5028abdf10f4af70d88dc5fe13cc4fdc1838e359dc44f6f5c6dd5
7
+ data.tar.gz: a6cb39b92b07b6a5d04bb9b5d3adc14f11f7ea045b628c3b7dc09dd7501ddc0b9268bd3b477d8f2aac5072cfd379afe527738899c706b3d60ace82edd91073ad
data/Rakefile CHANGED
@@ -29,26 +29,38 @@ def bump_version(segment)
29
29
  puts "Bumped version to #{new_version}"
30
30
  end
31
31
 
32
- task :bump_version do
33
- bump_version(@bump_segment || :patch)
34
- end
32
+ # Bundler's `release` task is defined when this Rakefile loads — it captures
33
+ # the gemspec version at that moment in `Bundler::GemHelper`. If we bump the
34
+ # version mid-run (as a build prerequisite), the gem is published correctly
35
+ # but the final "Pushed <gem> <ver>" log line still prints the old cached
36
+ # version. Fix: bump first, then invoke bundler's release in a subprocess so
37
+ # it re-reads the gemspec fresh.
38
+
39
+ Rake::Task[:release].clear
35
40
 
36
- task release_preflight: :bump_version do
41
+ def do_release(segment)
42
+ bump_version(segment)
37
43
  sh "bundle install"
38
44
  Rake::Task[:test].invoke
39
- sh 'git add -A && git diff --cached --quiet || git commit -m "$(ruby -e "require_relative \'lib/honeymaker/version\'; puts Honeymaker::VERSION")"'
45
+ sh %(git add -A && git diff --cached --quiet || git commit -m "v#{current_version}")
46
+ sh "bundle exec rake _bundler_release"
40
47
  end
41
48
 
42
- Rake::Task[:build].enhance([:release_preflight])
49
+ task _bundler_release: %w[build release:guard_clean release:source_control_push release:rubygem_push]
50
+
51
+ desc "Bump patch, run tests, push to rubygems"
52
+ task :release do
53
+ do_release(:patch)
54
+ end
43
55
 
44
56
  namespace :release do
57
+ desc "Bump minor, run tests, push to rubygems"
45
58
  task :minor do
46
- @bump_segment = :minor
47
- Rake::Task[:release].invoke
59
+ do_release(:minor)
48
60
  end
49
61
 
62
+ desc "Bump major, run tests, push to rubygems"
50
63
  task :major do
51
- @bump_segment = :major
52
- Rake::Task[:release].invoke
64
+ do_release(:major)
53
65
  end
54
66
  end
@@ -237,8 +237,25 @@ module Honeymaker
237
237
  end
238
238
  end
239
239
 
240
+ # Kraken rejects any request whose nonce is <= the last nonce it saw for the
241
+ # same API key. We protect against in-process collisions (microsecond bursts,
242
+ # backward clock corrections) by tracking the last issued nonce per API key
243
+ # under a mutex. Cross-process reuse of the same API key (other workers,
244
+ # other containers, other tools) is not protected here — affected users
245
+ # should increase the Nonce Window on their Kraken API key.
246
+ @@nonce_mutex = Mutex.new
247
+ @@last_nonces = {}
248
+
249
+ def self.reset_nonce_state!
250
+ @@nonce_mutex.synchronize { @@last_nonces.clear }
251
+ end
252
+
240
253
  def nonce
241
- (Time.now.utc.to_f * 1_000_000).to_i
254
+ key = @api_key ? Digest::SHA256.hexdigest(@api_key) : :__no_api_key__
255
+ @@nonce_mutex.synchronize do
256
+ candidate = (Time.now.utc.to_f * 1_000_000).to_i
257
+ @@last_nonces[key] = [candidate, (@@last_nonces[key] || 0) + 1].max
258
+ end
242
259
  end
243
260
 
244
261
  def private_headers(path, body)
@@ -25,7 +25,8 @@ module Honeymaker
25
25
  base_decimals: Utils.decimals(f[:lot_size]["stepSize"]),
26
26
  quote_decimals: product["quoteAssetPrecision"],
27
27
  price_decimals: Utils.decimals(f[:price]["tickSize"]),
28
- available: product["status"] == "TRADING"
28
+ available: true,
29
+ trading_enabled: product["status"] == "TRADING"
29
30
  }
30
31
  end
31
32
  end
@@ -25,7 +25,8 @@ module Honeymaker
25
25
  base_decimals: Utils.decimals(product["stepSize"]),
26
26
  quote_decimals: Utils.decimals(product["tickSize"]),
27
27
  price_decimals: Utils.decimals(product["tickSize"]),
28
- available: product["status"].to_i == 1
28
+ available: true,
29
+ trading_enabled: product["status"].to_i == 1
29
30
  }
30
31
  end
31
32
  end
@@ -21,7 +21,8 @@ module Honeymaker
21
21
  base_decimals: product["quantityPrecision"].to_i,
22
22
  quote_decimals: product["quotePrecision"].to_i,
23
23
  price_decimals: product["pricePrecision"].to_i,
24
- available: product["status"] == "online"
24
+ available: true,
25
+ trading_enabled: product["status"] == "online"
25
26
  }
26
27
  end
27
28
  end
@@ -21,7 +21,8 @@ module Honeymaker
21
21
  base_decimals: Utils.decimals(product["base_min_size"]),
22
22
  quote_decimals: Utils.decimals(product["quote_increment"]),
23
23
  price_decimals: product["price_max_precision"].to_i,
24
- available: product["trade_status"] == "trading"
24
+ available: true,
25
+ trading_enabled: product["trade_status"] == "trading"
25
26
  }
26
27
  end
27
28
  end
@@ -23,7 +23,8 @@ module Honeymaker
23
23
  base_decimals: f[:lot_size] ? Utils.decimals(f[:lot_size]["stepSize"]) : product["baseAssetPrecision"],
24
24
  quote_decimals: product["quotePrecision"],
25
25
  price_decimals: f[:price] ? Utils.decimals(f[:price]["tickSize"]) : product["quotePrecision"],
26
- available: product["status"] == "TRADING"
26
+ available: true,
27
+ trading_enabled: product["status"] == "TRADING"
27
28
  }
28
29
  end
29
30
  end
@@ -24,7 +24,8 @@ module Honeymaker
24
24
  base_decimals: product["pricePrecision"] || 8,
25
25
  quote_decimals: product["pricePrecision"] || 8,
26
26
  price_decimals: product["pricePrecision"] || 8,
27
- available: product["status"] == "trading"
27
+ available: true,
28
+ trading_enabled: product["status"] == "trading"
28
29
  }
29
30
  end
30
31
  end
@@ -26,7 +26,8 @@ module Honeymaker
26
26
  base_decimals: Utils.decimals(lot_size_filter["basePrecision"]),
27
27
  quote_decimals: Utils.decimals(lot_size_filter["quotePrecision"]),
28
28
  price_decimals: Utils.decimals(price_filter["tickSize"]),
29
- available: product["status"] == "Trading"
29
+ available: true,
30
+ trading_enabled: product["status"] == "Trading"
30
31
  }
31
32
  end
32
33
  end
@@ -31,7 +31,8 @@ module Honeymaker
31
31
  base_decimals: Utils.decimals(product["base_increment"]),
32
32
  quote_decimals: Utils.decimals(product["quote_increment"]),
33
33
  price_decimals: Utils.decimals(product["price_increment"]),
34
- available: true
34
+ available: true,
35
+ trading_enabled: trading_enabled?(product)
35
36
  }
36
37
  end
37
38
  end
@@ -50,6 +51,15 @@ module Honeymaker
50
51
 
51
52
  private
52
53
 
54
+ # Coinbase only signals problems explicitly: a `trading_disabled` flag or a non-"online"
55
+ # `status`. Absent either signal, treat the pair as enabled.
56
+ def trading_enabled?(product)
57
+ return false if product["trading_disabled"] == true
58
+ return false if product.key?("status") && product["status"] != "online"
59
+
60
+ true
61
+ end
62
+
53
63
  def connection
54
64
  @connection ||= build_connection(BASE_URL)
55
65
  end
@@ -27,7 +27,8 @@ module Honeymaker
27
27
  base_decimals: Utils.decimals(tick_size),
28
28
  quote_decimals: Utils.decimals(quote_increment),
29
29
  price_decimals: Utils.decimals(quote_increment),
30
- available: detail["status"] == "open"
30
+ available: true,
31
+ trading_enabled: detail["status"] == "open"
31
32
  }
32
33
  end
33
34
  end
@@ -31,7 +31,8 @@ module Honeymaker
31
31
  base_decimals: base_token["szDecimals"] || 0,
32
32
  quote_decimals: 2,
33
33
  price_decimals: 5,
34
- available: true
34
+ available: true,
35
+ trading_enabled: true
35
36
  }
36
37
  end
37
38
  end
@@ -59,7 +59,8 @@ module Honeymaker
59
59
  base_decimals: info["lot_decimals"],
60
60
  quote_decimals: info["cost_decimals"],
61
61
  price_decimals: info["pair_decimals"],
62
- available: true
62
+ available: true,
63
+ trading_enabled: info.key?("status") ? info["status"] == "online" : true
63
64
  }
64
65
  end
65
66
  end
@@ -21,7 +21,8 @@ module Honeymaker
21
21
  base_decimals: Utils.decimals(product["baseIncrement"]),
22
22
  quote_decimals: Utils.decimals(product["quoteIncrement"]),
23
23
  price_decimals: Utils.decimals(product["priceIncrement"]),
24
- available: product["enableTrading"]
24
+ available: true,
25
+ trading_enabled: product["enableTrading"]
25
26
  }
26
27
  end
27
28
  end
@@ -23,7 +23,8 @@ module Honeymaker
23
23
  base_decimals: f[:lot_size] ? Utils.decimals(f[:lot_size]["stepSize"]) : product["baseAssetPrecision"],
24
24
  quote_decimals: product["quoteAssetPrecision"],
25
25
  price_decimals: f[:price] ? Utils.decimals(f[:price]["tickSize"]) : product["quotePrecision"],
26
- available: product["status"] == "TRADING"
26
+ available: true,
27
+ trading_enabled: product["status"] == "TRADING"
27
28
  }
28
29
  end
29
30
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Honeymaker
4
- VERSION = "0.8.0"
4
+ VERSION = "0.9.2"
5
5
  end
@@ -4,6 +4,7 @@ require "test_helper"
4
4
 
5
5
  class Honeymaker::Clients::KrakenTest < Minitest::Test
6
6
  def setup
7
+ Honeymaker::Clients::Kraken.reset_nonce_state! if Honeymaker::Clients::Kraken.respond_to?(:reset_nonce_state!)
7
8
  @client = Honeymaker::Clients::Kraken.new(
8
9
  api_key: "test_key",
9
10
  api_secret: Base64.strict_encode64("test_secret_key_1234567890123456")
@@ -74,8 +75,65 @@ class Honeymaker::Clients::KrakenTest < Minitest::Test
74
75
  refute headers.key?(:"API-Key")
75
76
  end
76
77
 
78
+ def test_reset_nonce_state_is_available_for_test_isolation
79
+ assert_respond_to Honeymaker::Clients::Kraken, :reset_nonce_state!
80
+ end
81
+
82
+ def test_nonce_is_strictly_increasing_in_a_tight_loop
83
+ nonces = Array.new(10_000) { @client.send(:nonce) }
84
+
85
+ assert_strictly_increasing nonces
86
+ end
87
+
88
+ def test_nonce_is_strictly_increasing_when_clock_is_frozen
89
+ frozen_time = Time.utc(2026, 1, 1, 12, 0, 0)
90
+ Time.stubs(:now).returns(frozen_time)
91
+
92
+ nonces = Array.new(3) { @client.send(:nonce) }
93
+
94
+ assert_strictly_increasing nonces
95
+ end
96
+
97
+ def test_nonce_is_strictly_increasing_across_clients_with_the_same_api_key
98
+ frozen_time = Time.utc(2026, 1, 1, 12, 0, 0)
99
+ Time.stubs(:now).returns(frozen_time)
100
+ other_client = Honeymaker::Clients::Kraken.new(
101
+ api_key: "test_key",
102
+ api_secret: Base64.strict_encode64("test_secret_key_1234567890123456")
103
+ )
104
+
105
+ nonces = [
106
+ @client.send(:nonce),
107
+ other_client.send(:nonce),
108
+ @client.send(:nonce),
109
+ other_client.send(:nonce)
110
+ ]
111
+
112
+ assert_strictly_increasing nonces
113
+ end
114
+
115
+ def test_nonce_sequences_are_independent_for_different_api_keys
116
+ frozen_time = Time.utc(2026, 1, 1, 12, 0, 0)
117
+ Time.stubs(:now).returns(frozen_time)
118
+ first_key_client = Honeymaker::Clients::Kraken.new(api_key: "first_key", api_secret: @client.api_secret)
119
+ second_key_client = Honeymaker::Clients::Kraken.new(api_key: "second_key", api_secret: @client.api_secret)
120
+
121
+ first_key_first_nonce = first_key_client.send(:nonce)
122
+ first_key_second_nonce = first_key_client.send(:nonce)
123
+ second_key_first_nonce = second_key_client.send(:nonce)
124
+
125
+ assert_operator first_key_second_nonce, :>, first_key_first_nonce
126
+ assert_equal first_key_first_nonce, second_key_first_nonce
127
+ end
128
+
77
129
  private
78
130
 
131
+ def assert_strictly_increasing(values)
132
+ values.each_cons(2) do |previous, current|
133
+ assert_operator current, :>, previous
134
+ end
135
+ end
136
+
79
137
  def stub_connection(method, body)
80
138
  response = stub(body: body)
81
139
  connection = stub
@@ -26,6 +26,19 @@ class Honeymaker::Exchanges::BinanceTest < Minitest::Test
26
26
  assert_equal 8, ticker[:quote_decimals]
27
27
  assert_equal 2, ticker[:price_decimals]
28
28
  assert ticker[:available]
29
+ assert ticker[:trading_enabled]
30
+ end
31
+
32
+ def test_get_tickers_info_marks_non_trading_pairs_disabled
33
+ body = load_fixture("binance_exchange_info.json")
34
+ body["symbols"].first["status"] = "BREAK"
35
+ stub_connection(body)
36
+
37
+ result = @exchange.get_tickers_info
38
+
39
+ ticker = result.data.first
40
+ assert ticker[:available] # still listed
41
+ refute ticker[:trading_enabled] # but not trading
29
42
  end
30
43
 
31
44
  def test_get_tickers_info_handles_api_error
@@ -27,6 +27,8 @@ class Honeymaker::Exchanges::BinanceUsTest < Minitest::Test
27
27
  ticker = result.data.first
28
28
  assert_equal "BTCUSDT", ticker[:ticker]
29
29
  assert_equal "BTC", ticker[:base]
30
+ assert ticker[:available]
31
+ assert ticker[:trading_enabled]
30
32
  end
31
33
 
32
34
  def test_get_bid_ask_parses_response
@@ -30,6 +30,7 @@ class Honeymaker::Exchanges::BingXTest < Minitest::Test
30
30
  assert_equal 2, ticker[:quote_decimals]
31
31
  assert_equal 2, ticker[:price_decimals]
32
32
  assert ticker[:available]
33
+ assert ticker[:trading_enabled]
33
34
  end
34
35
 
35
36
  def test_skips_symbols_without_dash
@@ -29,16 +29,18 @@ class Honeymaker::Exchanges::BitgetTest < Minitest::Test
29
29
  assert_equal 8, ticker[:quote_decimals]
30
30
  assert_equal 2, ticker[:price_decimals]
31
31
  assert ticker[:available]
32
+ assert ticker[:trading_enabled]
32
33
  end
33
34
 
34
- def test_offline_symbol_not_available
35
+ def test_offline_symbol_listed_but_not_trading_enabled
35
36
  body = load_fixture("bitget_symbols.json")
36
37
  stub_connection(body)
37
38
 
38
39
  result = @exchange.get_tickers_info
39
40
 
40
41
  eth = result.data.find { |t| t[:ticker] == "ETHUSDT" }
41
- refute eth[:available]
42
+ assert eth[:available] # still listed
43
+ refute eth[:trading_enabled] # but not trading
42
44
  end
43
45
 
44
46
  def test_get_bid_ask_parses_response
@@ -29,16 +29,18 @@ class Honeymaker::Exchanges::BitMartTest < Minitest::Test
29
29
  assert_equal 2, ticker[:quote_decimals]
30
30
  assert_equal 2, ticker[:price_decimals]
31
31
  assert ticker[:available]
32
+ assert ticker[:trading_enabled]
32
33
  end
33
34
 
34
- def test_pre_trade_not_available
35
+ def test_pre_trade_listed_but_not_trading_enabled
35
36
  body = load_fixture("bitmart_symbols.json")
36
37
  stub_connection(body)
37
38
 
38
39
  result = @exchange.get_tickers_info
39
40
 
40
41
  eth = result.data.find { |t| t[:ticker] == "ETH_USDT" }
41
- refute eth[:available]
42
+ assert eth[:available] # still listed
43
+ refute eth[:trading_enabled] # but not trading
42
44
  end
43
45
 
44
46
  def test_get_bid_ask_parses_response
@@ -29,6 +29,7 @@ class Honeymaker::Exchanges::BitrueTest < Minitest::Test
29
29
  assert_equal 2, ticker[:quote_decimals]
30
30
  assert_equal 2, ticker[:price_decimals]
31
31
  assert ticker[:available]
32
+ assert ticker[:trading_enabled]
32
33
  end
33
34
 
34
35
  def test_falls_back_to_precision_fields_when_no_filters
@@ -29,16 +29,18 @@ class Honeymaker::Exchanges::BitvavoTest < Minitest::Test
29
29
  assert_equal 5, ticker[:quote_decimals]
30
30
  assert_equal 5, ticker[:price_decimals]
31
31
  assert ticker[:available]
32
+ assert ticker[:trading_enabled]
32
33
  end
33
34
 
34
- def test_halted_market_not_available
35
+ def test_halted_market_listed_but_not_trading_enabled
35
36
  body = load_fixture("bitvavo_markets.json")
36
37
  stub_connection(body)
37
38
 
38
39
  result = @exchange.get_tickers_info
39
40
 
40
41
  eth = result.data.find { |t| t[:ticker] == "ETH-EUR" }
41
- refute eth[:available]
42
+ assert eth[:available] # still listed
43
+ refute eth[:trading_enabled] # but not trading
42
44
  end
43
45
 
44
46
  def test_get_bid_ask_parses_response
@@ -30,6 +30,7 @@ class Honeymaker::Exchanges::BybitTest < Minitest::Test
30
30
  assert_equal 8, ticker[:quote_decimals]
31
31
  assert_equal 2, ticker[:price_decimals]
32
32
  assert ticker[:available]
33
+ assert ticker[:trading_enabled]
33
34
  end
34
35
 
35
36
  def test_get_bid_ask_parses_response
@@ -29,6 +29,29 @@ class Honeymaker::Exchanges::CoinbaseTest < Minitest::Test
29
29
  assert_equal 2, ticker[:quote_decimals]
30
30
  assert_equal 2, ticker[:price_decimals]
31
31
  assert ticker[:available]
32
+ assert ticker[:trading_enabled] # no disabled signal -> defaults to true
33
+ end
34
+
35
+ def test_get_tickers_info_disables_when_trading_disabled
36
+ body = load_fixture("coinbase_products.json")
37
+ body["products"].first["trading_disabled"] = true
38
+ stub_connection(body)
39
+
40
+ result = @exchange.get_tickers_info
41
+
42
+ ticker = result.data.first
43
+ assert ticker[:available] # still listed
44
+ refute ticker[:trading_enabled] # but not trading
45
+ end
46
+
47
+ def test_get_tickers_info_disables_when_status_not_online
48
+ body = load_fixture("coinbase_products.json")
49
+ body["products"].first["status"] = "delisted"
50
+ stub_connection(body)
51
+
52
+ result = @exchange.get_tickers_info
53
+
54
+ refute result.data.first[:trading_enabled]
32
55
  end
33
56
 
34
57
  def test_filters_blacklisted_assets
@@ -35,6 +35,7 @@ class Honeymaker::Exchanges::GeminiTest < Minitest::Test
35
35
  assert_equal 2, ticker[:quote_decimals]
36
36
  assert_equal 2, ticker[:price_decimals]
37
37
  assert ticker[:available]
38
+ assert ticker[:trading_enabled]
38
39
  end
39
40
 
40
41
  def test_get_bid_ask_parses_response
@@ -28,6 +28,7 @@ class Honeymaker::Exchanges::HyperliquidTest < Minitest::Test
28
28
  assert_equal 2, ticker[:quote_decimals]
29
29
  assert_equal 5, ticker[:price_decimals]
30
30
  assert ticker[:available]
31
+ assert ticker[:trading_enabled] # no native status -> always true
31
32
  end
32
33
 
33
34
  def test_skips_pairs_with_missing_tokens
@@ -26,6 +26,38 @@ class Honeymaker::Exchanges::KrakenTest < Minitest::Test
26
26
  assert_equal 5, ticker[:quote_decimals]
27
27
  assert_equal 1, ticker[:price_decimals]
28
28
  assert ticker[:available]
29
+ assert ticker[:trading_enabled] # fixture has no status -> defaults to true
30
+ end
31
+
32
+ def test_get_tickers_info_disables_non_online_status
33
+ body = load_fixture("kraken_asset_pairs.json")
34
+ body["result"]["XBTUSDT"]["status"] = "cancel_only"
35
+ stub_request(body)
36
+
37
+ result = @exchange.get_tickers_info
38
+
39
+ ticker = result.data.first
40
+ assert ticker[:available] # still listed
41
+ refute ticker[:trading_enabled] # but not trading
42
+ end
43
+
44
+ def test_get_tickers_info_enables_online_status
45
+ body = load_fixture("kraken_asset_pairs.json")
46
+ body["result"]["XBTUSDT"]["status"] = "online"
47
+ stub_request(body)
48
+
49
+ result = @exchange.get_tickers_info
50
+
51
+ assert result.data.first[:trading_enabled]
52
+ end
53
+
54
+ def test_get_tickers_info_defaults_trading_enabled_when_status_absent
55
+ body = load_fixture("kraken_asset_pairs.json") # no status key
56
+ stub_request(body)
57
+
58
+ result = @exchange.get_tickers_info
59
+
60
+ assert result.data.first[:trading_enabled]
29
61
  end
30
62
 
31
63
  def test_get_tickers_info_skips_pairs_without_wsname
@@ -30,6 +30,7 @@ class Honeymaker::Exchanges::KucoinTest < Minitest::Test
30
30
  assert_equal 6, ticker[:quote_decimals]
31
31
  assert_equal 1, ticker[:price_decimals]
32
32
  assert ticker[:available]
33
+ assert ticker[:trading_enabled]
33
34
  end
34
35
 
35
36
  def test_get_bid_ask_parses_response
@@ -29,16 +29,18 @@ class Honeymaker::Exchanges::MexcTest < Minitest::Test
29
29
  assert_equal 8, ticker[:quote_decimals]
30
30
  assert_equal 2, ticker[:price_decimals]
31
31
  assert ticker[:available]
32
+ assert ticker[:trading_enabled]
32
33
  end
33
34
 
34
- def test_halted_symbol_not_available
35
+ def test_halted_symbol_listed_but_not_trading_enabled
35
36
  body = load_fixture("mexc_exchange_info.json")
36
37
  stub_connection(body)
37
38
 
38
39
  result = @exchange.get_tickers_info
39
40
 
40
41
  halted = result.data.find { |t| t[:ticker] == "ETHUSDT" }
41
- refute halted[:available]
42
+ assert halted[:available] # still listed
43
+ refute halted[:trading_enabled] # but not trading
42
44
  end
43
45
 
44
46
  def test_falls_back_to_precision_fields_when_no_filters
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeymaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Deltabadger