honeymaker 0.6.0 → 0.7.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/honeymaker/exchange.rb +43 -0
  3. data/lib/honeymaker/exchanges/binance.rb +13 -0
  4. data/lib/honeymaker/exchanges/bingx.rb +14 -0
  5. data/lib/honeymaker/exchanges/bitget.rb +14 -0
  6. data/lib/honeymaker/exchanges/bitmart.rb +14 -0
  7. data/lib/honeymaker/exchanges/bitrue.rb +13 -0
  8. data/lib/honeymaker/exchanges/bitvavo.rb +13 -0
  9. data/lib/honeymaker/exchanges/bybit.rb +14 -0
  10. data/lib/honeymaker/exchanges/coinbase.rb +11 -0
  11. data/lib/honeymaker/exchanges/gemini.rb +11 -0
  12. data/lib/honeymaker/exchanges/hyperliquid.rb +14 -0
  13. data/lib/honeymaker/exchanges/kraken.rb +17 -0
  14. data/lib/honeymaker/exchanges/kucoin.rb +14 -0
  15. data/lib/honeymaker/exchanges/mexc.rb +13 -0
  16. data/lib/honeymaker/version.rb +1 -1
  17. data/test/fixtures/binance_book_ticker.json +7 -0
  18. data/test/fixtures/bingx_ticker.json +12 -0
  19. data/test/fixtures/bitget_tickers.json +14 -0
  20. data/test/fixtures/bitmart_ticker.json +12 -0
  21. data/test/fixtures/bitrue_book_ticker.json +7 -0
  22. data/test/fixtures/bitvavo_book_ticker.json +7 -0
  23. data/test/fixtures/bybit_tickers.json +19 -0
  24. data/test/fixtures/coinbase_product.json +7 -0
  25. data/test/fixtures/gemini_pubticker.json +10 -0
  26. data/test/fixtures/hyperliquid_all_mids.json +5 -0
  27. data/test/fixtures/kraken_ticker.json +16 -0
  28. data/test/fixtures/kucoin_orderbook_level1.json +10 -0
  29. data/test/fixtures/mexc_book_ticker.json +7 -0
  30. data/test/honeymaker/exchange_test.rb +97 -0
  31. data/test/honeymaker/exchanges/binance_test.rb +21 -0
  32. data/test/honeymaker/exchanges/binance_us_test.rb +11 -0
  33. data/test/honeymaker/exchanges/bingx_test.rb +11 -0
  34. data/test/honeymaker/exchanges/bitget_test.rb +11 -0
  35. data/test/honeymaker/exchanges/bitmart_test.rb +11 -0
  36. data/test/honeymaker/exchanges/bitrue_test.rb +11 -0
  37. data/test/honeymaker/exchanges/bitvavo_test.rb +11 -0
  38. data/test/honeymaker/exchanges/bybit_test.rb +11 -0
  39. data/test/honeymaker/exchanges/coinbase_test.rb +11 -0
  40. data/test/honeymaker/exchanges/gemini_test.rb +11 -0
  41. data/test/honeymaker/exchanges/hyperliquid_test.rb +11 -0
  42. data/test/honeymaker/exchanges/kraken_test.rb +20 -0
  43. data/test/honeymaker/exchanges/kucoin_test.rb +11 -0
  44. data/test/honeymaker/exchanges/mexc_test.rb +11 -0
  45. metadata +14 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4a5dc67259d8ff33eba5584ed8fe9cc59e0f7d62c2d6bf6f794fbe24430bf93
4
- data.tar.gz: 2115566b5168a2b5588e71292292a010a9f3d88673d127a75a2e71427876994b
3
+ metadata.gz: b5111180bb98ceb8eae9aad595851e28a45a10d908f780f2e69325df702b29aa
4
+ data.tar.gz: e1aea0e0de8989a11f19a7a3fb5cab7d64a9b4944efb86bac69d7ecafb0e6096
5
5
  SHA512:
6
- metadata.gz: 2cd7119999981ce3e901dbeb2b172f037c0a077d5ee13f902f7fabdf320a336461e35c395eb7bbce07f6e2cc3fc3a35f1c06c691013a3904a8c73df40ce2ff38
7
- data.tar.gz: c0ebe66c0a2ada2c2fe7cb255df67d2d07f22c17e39e54dd50f5a10185bcc67b5bd5c80a4e1d56bc351942473678399dd924a808aa16809acc47809b82c8d667
6
+ metadata.gz: c0df0bf1c364389aac57e683a6ff74aa1b5282c9ad95b63379901d291d0a5c5f22e11878a87c9f231047d858062fce1038326be2c5c4472296f146fef111122f
7
+ data.tar.gz: d7f22d0e9f0d7af33eaa0d5e82633b6a01caf01d83246558af40befa365df99d59db9d33fd9cd4c8ddccc56ba70b6ec54a1188507bd6c75171873b726c464ac3
@@ -14,6 +14,49 @@ module Honeymaker
14
14
  raise NotImplementedError, "#{self.class} must implement #get_tickers_info"
15
15
  end
16
16
 
17
+ def get_bid_ask(symbol)
18
+ raise NotImplementedError, "#{self.class} must implement #get_bid_ask"
19
+ end
20
+
21
+ def get_price(symbol)
22
+ result = get_bid_ask(symbol)
23
+ return result if result.failure?
24
+
25
+ Result::Success.new((result.data[:bid] + result.data[:ask]) / 2)
26
+ end
27
+
28
+ def tickers_info
29
+ if @tickers_info_cache && @tickers_info_expires_at && @tickers_info_expires_at > Time.now
30
+ return Result::Success.new(@tickers_info_cache)
31
+ end
32
+
33
+ result = get_tickers_info
34
+ if result.success?
35
+ @tickers_info_cache = result.data
36
+ @tickers_info_expires_at = Time.now + cache_ttl
37
+ end
38
+ result
39
+ end
40
+
41
+ def find_ticker(symbol)
42
+ result = tickers_info
43
+ return result if result.failure?
44
+
45
+ ticker = result.data.find { |t| t[:ticker] == symbol }
46
+ ticker ? Result::Success.new(ticker) : Result::Failure.new("Unknown symbol: #{symbol}")
47
+ end
48
+
49
+ def symbols
50
+ result = tickers_info
51
+ return result if result.failure?
52
+
53
+ Result::Success.new(result.data.map { |t| { base: t[:base], quote: t[:quote] } })
54
+ end
55
+
56
+ def cache_ttl
57
+ 3600
58
+ end
59
+
17
60
  private
18
61
 
19
62
  def with_rescue
@@ -31,6 +31,19 @@ module Honeymaker
31
31
  end
32
32
  end
33
33
 
34
+ def get_bid_ask(symbol)
35
+ with_rescue do
36
+ response = connection.get("/api/v3/ticker/bookTicker") do |req|
37
+ req.params = { symbol: symbol }
38
+ end
39
+
40
+ {
41
+ bid: BigDecimal(response.body["bidPrice"]),
42
+ ask: BigDecimal(response.body["askPrice"])
43
+ }
44
+ end
45
+ end
46
+
34
47
  private
35
48
 
36
49
  def connection
@@ -31,6 +31,20 @@ module Honeymaker
31
31
  end
32
32
  end
33
33
 
34
+ def get_bid_ask(symbol)
35
+ with_rescue do
36
+ response = connection.get("/openApi/spot/v2/market/ticker") do |req|
37
+ req.params = { symbol: symbol }
38
+ end
39
+
40
+ data = response.body["data"].first
41
+ {
42
+ bid: BigDecimal(data["bestBidPrice"]),
43
+ ask: BigDecimal(data["bestAskPrice"])
44
+ }
45
+ end
46
+ end
47
+
34
48
  private
35
49
 
36
50
  def connection
@@ -27,6 +27,20 @@ module Honeymaker
27
27
  end
28
28
  end
29
29
 
30
+ def get_bid_ask(symbol)
31
+ with_rescue do
32
+ response = connection.get("/api/v2/spot/market/tickers") do |req|
33
+ req.params = { symbol: symbol }
34
+ end
35
+
36
+ ticker = response.body["data"].first
37
+ {
38
+ bid: BigDecimal(ticker["bestBid"]),
39
+ ask: BigDecimal(ticker["bestAsk"])
40
+ }
41
+ end
42
+ end
43
+
30
44
  private
31
45
 
32
46
  def connection
@@ -27,6 +27,20 @@ module Honeymaker
27
27
  end
28
28
  end
29
29
 
30
+ def get_bid_ask(symbol)
31
+ with_rescue do
32
+ response = connection.get("/spot/quotation/v3/ticker") do |req|
33
+ req.params = { symbol: symbol }
34
+ end
35
+
36
+ data = response.body["data"]
37
+ {
38
+ bid: BigDecimal(data["best_bid"]),
39
+ ask: BigDecimal(data["best_ask"])
40
+ }
41
+ end
42
+ end
43
+
30
44
  private
31
45
 
32
46
  def connection
@@ -29,6 +29,19 @@ module Honeymaker
29
29
  end
30
30
  end
31
31
 
32
+ def get_bid_ask(symbol)
33
+ with_rescue do
34
+ response = connection.get("/api/v1/ticker/bookTicker") do |req|
35
+ req.params = { symbol: symbol }
36
+ end
37
+
38
+ {
39
+ bid: BigDecimal(response.body["bidPrice"]),
40
+ ask: BigDecimal(response.body["askPrice"])
41
+ }
42
+ end
43
+ end
44
+
32
45
  private
33
46
 
34
47
  def connection
@@ -30,6 +30,19 @@ module Honeymaker
30
30
  end
31
31
  end
32
32
 
33
+ def get_bid_ask(symbol)
34
+ with_rescue do
35
+ response = connection.get("/v2/ticker/book") do |req|
36
+ req.params = { market: symbol }
37
+ end
38
+
39
+ {
40
+ bid: BigDecimal(response.body["bid"]),
41
+ ask: BigDecimal(response.body["ask"])
42
+ }
43
+ end
44
+ end
45
+
33
46
  private
34
47
 
35
48
  def connection
@@ -32,6 +32,20 @@ module Honeymaker
32
32
  end
33
33
  end
34
34
 
35
+ def get_bid_ask(symbol)
36
+ with_rescue do
37
+ response = connection.get("/v5/market/tickers") do |req|
38
+ req.params = { category: "spot", symbol: symbol }
39
+ end
40
+
41
+ ticker = response.body["result"]["list"].first
42
+ {
43
+ bid: BigDecimal(ticker["bid1Price"]),
44
+ ask: BigDecimal(ticker["ask1Price"])
45
+ }
46
+ end
47
+ end
48
+
35
49
  private
36
50
 
37
51
  def connection
@@ -37,6 +37,17 @@ module Honeymaker
37
37
  end
38
38
  end
39
39
 
40
+ def get_bid_ask(symbol)
41
+ with_rescue do
42
+ response = connection.get("/api/v3/brokerage/market/products/#{symbol}")
43
+
44
+ {
45
+ bid: BigDecimal(response.body["bid"]),
46
+ ask: BigDecimal(response.body["ask"])
47
+ }
48
+ end
49
+ end
50
+
40
51
  private
41
52
 
42
53
  def connection
@@ -33,6 +33,17 @@ module Honeymaker
33
33
  end
34
34
  end
35
35
 
36
+ def get_bid_ask(symbol)
37
+ with_rescue do
38
+ response = connection.get("/v1/pubticker/#{symbol.downcase}")
39
+
40
+ {
41
+ bid: BigDecimal(response.body["bid"]),
42
+ ask: BigDecimal(response.body["ask"])
43
+ }
44
+ end
45
+ end
46
+
36
47
  private
37
48
 
38
49
  def connection
@@ -37,6 +37,20 @@ module Honeymaker
37
37
  end
38
38
  end
39
39
 
40
+ def get_bid_ask(symbol)
41
+ with_rescue do
42
+ response = connection.post("/info") do |req|
43
+ req.body = { type: "allMids" }.to_json
44
+ end
45
+
46
+ price = BigDecimal(response.body[symbol])
47
+ {
48
+ bid: price,
49
+ ask: price
50
+ }
51
+ end
52
+ end
53
+
40
54
  private
41
55
 
42
56
  def connection
@@ -58,6 +58,23 @@ module Honeymaker
58
58
  end
59
59
  end
60
60
 
61
+ def get_bid_ask(symbol)
62
+ with_rescue do
63
+ response = connection.get("/0/public/Ticker") do |req|
64
+ req.params = { pair: symbol }
65
+ end
66
+
67
+ error = response.body["error"]
68
+ raise StandardError, error.first if error.is_a?(Array) && error.any?
69
+
70
+ _key, data = response.body["result"].first
71
+ {
72
+ bid: BigDecimal(data["b"][0]),
73
+ ask: BigDecimal(data["a"][0])
74
+ }
75
+ end
76
+ end
77
+
61
78
  private
62
79
 
63
80
  def connection
@@ -27,6 +27,20 @@ module Honeymaker
27
27
  end
28
28
  end
29
29
 
30
+ def get_bid_ask(symbol)
31
+ with_rescue do
32
+ response = connection.get("/api/v1/market/orderbook/level1") do |req|
33
+ req.params = { symbol: symbol }
34
+ end
35
+
36
+ data = response.body["data"]
37
+ {
38
+ bid: BigDecimal(data["bestBid"]),
39
+ ask: BigDecimal(data["bestAsk"])
40
+ }
41
+ end
42
+ end
43
+
30
44
  private
31
45
 
32
46
  def connection
@@ -29,6 +29,19 @@ module Honeymaker
29
29
  end
30
30
  end
31
31
 
32
+ def get_bid_ask(symbol)
33
+ with_rescue do
34
+ response = connection.get("/api/v3/ticker/bookTicker") do |req|
35
+ req.params = { symbol: symbol }
36
+ end
37
+
38
+ {
39
+ bid: BigDecimal(response.body["bidPrice"]),
40
+ ask: BigDecimal(response.body["askPrice"])
41
+ }
42
+ end
43
+ end
44
+
32
45
  private
33
46
 
34
47
  def connection
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Honeymaker
4
- VERSION = "0.6.0"
4
+ VERSION = "0.7.0"
5
5
  end
@@ -0,0 +1,7 @@
1
+ {
2
+ "symbol": "BTCUSDT",
3
+ "bidPrice": "67123.45000000",
4
+ "bidQty": "1.23456700",
5
+ "askPrice": "67125.67000000",
6
+ "askQty": "0.98765400"
7
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "code": 0,
3
+ "data": [
4
+ {
5
+ "symbol": "BTC-USDT",
6
+ "bestBidPrice": "67123.45",
7
+ "bestBidQty": "1.234567",
8
+ "bestAskPrice": "67125.67",
9
+ "bestAskQty": "0.987654"
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "code": "00000",
3
+ "msg": "success",
4
+ "data": [
5
+ {
6
+ "symbol": "BTCUSDT",
7
+ "bestBid": "67123.45",
8
+ "bestAsk": "67125.67",
9
+ "lastPr": "67124.56",
10
+ "high24h": "67500.00",
11
+ "low24h": "66800.00"
12
+ }
13
+ ]
14
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "code": 1000,
3
+ "message": "OK",
4
+ "data": {
5
+ "symbol": "BTC_USDT",
6
+ "last": "67124.56",
7
+ "best_bid": "67123.45",
8
+ "best_ask": "67125.67",
9
+ "high_24h": "67500.00",
10
+ "low_24h": "66800.00"
11
+ }
12
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "symbol": "BTCUSDT",
3
+ "bidPrice": "67123.45",
4
+ "bidQty": "1.234567",
5
+ "askPrice": "67125.67",
6
+ "askQty": "0.987654"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "market": "BTC-EUR",
3
+ "bid": "67123.45",
4
+ "bidSize": "1.234567",
5
+ "ask": "67125.67",
6
+ "askSize": "0.987654"
7
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "retCode": 0,
3
+ "retMsg": "OK",
4
+ "result": {
5
+ "category": "spot",
6
+ "list": [
7
+ {
8
+ "symbol": "BTCUSDT",
9
+ "bid1Price": "67123.45",
10
+ "bid1Size": "1.234567",
11
+ "ask1Price": "67125.67",
12
+ "ask1Size": "0.987654",
13
+ "lastPrice": "67124.56",
14
+ "highPrice24h": "67500.00",
15
+ "lowPrice24h": "66800.00"
16
+ }
17
+ ]
18
+ }
19
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "product_id": "BTC-USD",
3
+ "price": "67124.56",
4
+ "bid": "67123.45",
5
+ "ask": "67125.67",
6
+ "volume_24h": "12345.678"
7
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "bid": "67123.45",
3
+ "ask": "67125.67",
4
+ "last": "67124.56",
5
+ "volume": {
6
+ "BTC": "1234.5678",
7
+ "USD": "82888888.88",
8
+ "timestamp": 1700000000000
9
+ }
10
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "PURR/USDC": "0.001234",
3
+ "BTC/USDC": "67124.56",
4
+ "ETH/USDC": "3456.78"
5
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "error": [],
3
+ "result": {
4
+ "XBTUSDT": {
5
+ "a": ["67125.67000", "1", "1.000"],
6
+ "b": ["67123.45000", "2", "2.000"],
7
+ "c": ["67124.50000", "0.00100000"],
8
+ "v": ["1234.56789012", "5678.90123456"],
9
+ "p": ["67100.00000", "67050.00000"],
10
+ "t": [12345, 67890],
11
+ "l": ["66800.00000", "66500.00000"],
12
+ "h": ["67500.00000", "67800.00000"],
13
+ "o": "67000.00000"
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "code": "200000",
3
+ "data": {
4
+ "bestBid": "67123.45",
5
+ "bestBidSize": "1.234567",
6
+ "bestAsk": "67125.67",
7
+ "bestAskSize": "0.987654",
8
+ "time": 1700000000000
9
+ }
10
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "symbol": "BTCUSDT",
3
+ "bidPrice": "67123.45",
4
+ "bidQty": "1.234567",
5
+ "askPrice": "67125.67",
6
+ "askQty": "0.987654"
7
+ }
@@ -28,4 +28,101 @@ class Honeymaker::ExchangeTest < Minitest::Test
28
28
  assert result.success?
29
29
  assert_equal [1, 2, 3], result.data
30
30
  end
31
+
32
+ def test_get_bid_ask_raises_not_implemented
33
+ exchange = Honeymaker::Exchange.new
34
+ assert_raises(NotImplementedError) { exchange.get_bid_ask("BTCUSDT") }
35
+ end
36
+
37
+ def test_get_price_returns_midpoint
38
+ exchange = Honeymaker::Exchange.new
39
+ bid_ask = { bid: BigDecimal("100"), ask: BigDecimal("102") }
40
+ exchange.define_singleton_method(:get_bid_ask) { |_| Honeymaker::Result::Success.new(bid_ask) }
41
+
42
+ result = exchange.get_price("BTCUSDT")
43
+ assert result.success?
44
+ assert_equal BigDecimal("101"), result.data
45
+ end
46
+
47
+ def test_get_price_propagates_failure
48
+ exchange = Honeymaker::Exchange.new
49
+ exchange.define_singleton_method(:get_bid_ask) { |_| Honeymaker::Result::Failure.new("error") }
50
+
51
+ result = exchange.get_price("BTCUSDT")
52
+ assert result.failure?
53
+ end
54
+
55
+ def test_tickers_info_caches_result
56
+ exchange = Honeymaker::Exchange.new
57
+ tickers = [{ ticker: "BTCUSDT", base: "BTC", quote: "USDT" }]
58
+ call_count = 0
59
+ exchange.define_singleton_method(:get_tickers_info) do
60
+ call_count += 1
61
+ Honeymaker::Result::Success.new(tickers)
62
+ end
63
+
64
+ result1 = exchange.tickers_info
65
+ result2 = exchange.tickers_info
66
+ assert result1.success?
67
+ assert result2.success?
68
+ assert_equal 1, call_count
69
+ end
70
+
71
+ def test_tickers_info_does_not_cache_failure
72
+ exchange = Honeymaker::Exchange.new
73
+ call_count = 0
74
+ exchange.define_singleton_method(:get_tickers_info) do
75
+ call_count += 1
76
+ Honeymaker::Result::Failure.new("error")
77
+ end
78
+
79
+ exchange.tickers_info
80
+ exchange.tickers_info
81
+ assert_equal 2, call_count
82
+ end
83
+
84
+ def test_find_ticker_returns_matching_ticker
85
+ exchange = Honeymaker::Exchange.new
86
+ tickers = [
87
+ { ticker: "BTCUSDT", base: "BTC", quote: "USDT" },
88
+ { ticker: "ETHUSDT", base: "ETH", quote: "USDT" }
89
+ ]
90
+ exchange.define_singleton_method(:get_tickers_info) do
91
+ Honeymaker::Result::Success.new(tickers)
92
+ end
93
+
94
+ result = exchange.find_ticker("ETHUSDT")
95
+ assert result.success?
96
+ assert_equal "ETH", result.data[:base]
97
+ end
98
+
99
+ def test_find_ticker_returns_failure_for_unknown_symbol
100
+ exchange = Honeymaker::Exchange.new
101
+ exchange.define_singleton_method(:get_tickers_info) do
102
+ Honeymaker::Result::Success.new([{ ticker: "BTCUSDT" }])
103
+ end
104
+
105
+ result = exchange.find_ticker("NOPE")
106
+ assert result.failure?
107
+ end
108
+
109
+ def test_symbols_returns_base_quote_pairs
110
+ exchange = Honeymaker::Exchange.new
111
+ tickers = [
112
+ { ticker: "BTCUSDT", base: "BTC", quote: "USDT" },
113
+ { ticker: "ETHUSDT", base: "ETH", quote: "USDT" }
114
+ ]
115
+ exchange.define_singleton_method(:get_tickers_info) do
116
+ Honeymaker::Result::Success.new(tickers)
117
+ end
118
+
119
+ result = exchange.symbols
120
+ assert result.success?
121
+ assert_equal [{ base: "BTC", quote: "USDT" }, { base: "ETH", quote: "USDT" }], result.data
122
+ end
123
+
124
+ def test_cache_ttl_defaults_to_3600
125
+ exchange = Honeymaker::Exchange.new
126
+ assert_equal 3600, exchange.cache_ttl
127
+ end
31
128
  end
@@ -38,6 +38,27 @@ class Honeymaker::Exchanges::BinanceTest < Minitest::Test
38
38
  assert result.failure?
39
39
  end
40
40
 
41
+ def test_get_bid_ask_parses_response
42
+ body = load_fixture("binance_book_ticker.json")
43
+ stub_connection(body)
44
+
45
+ result = @exchange.get_bid_ask("BTCUSDT")
46
+
47
+ assert result.success?
48
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
49
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
50
+ end
51
+
52
+ def test_get_bid_ask_handles_api_error
53
+ connection = stub
54
+ connection.stubs(:get).raises(Faraday::ServerError.new("500", { status: 500, body: "Internal Server Error" }))
55
+ @exchange.instance_variable_set(:@connection, connection)
56
+
57
+ result = @exchange.get_bid_ask("BTCUSDT")
58
+
59
+ assert result.failure?
60
+ end
61
+
41
62
  private
42
63
 
43
64
  def stub_connection(body)
@@ -29,6 +29,17 @@ class Honeymaker::Exchanges::BinanceUsTest < Minitest::Test
29
29
  assert_equal "BTC", ticker[:base]
30
30
  end
31
31
 
32
+ def test_get_bid_ask_parses_response
33
+ body = load_fixture("binance_book_ticker.json")
34
+ stub_connection(body)
35
+
36
+ result = @exchange.get_bid_ask("BTCUSDT")
37
+
38
+ assert result.success?
39
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
40
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
41
+ end
42
+
32
43
  private
33
44
 
34
45
  def stub_connection(body)
@@ -42,6 +42,17 @@ class Honeymaker::Exchanges::BingXTest < Minitest::Test
42
42
  refute_includes tickers, "INVALID"
43
43
  end
44
44
 
45
+ def test_get_bid_ask_parses_response
46
+ body = load_fixture("bingx_ticker.json")
47
+ stub_connection(body)
48
+
49
+ result = @exchange.get_bid_ask("BTC-USDT")
50
+
51
+ assert result.success?
52
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
53
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
54
+ end
55
+
45
56
  private
46
57
 
47
58
  def stub_connection(body)
@@ -41,6 +41,17 @@ class Honeymaker::Exchanges::BitgetTest < Minitest::Test
41
41
  refute eth[:available]
42
42
  end
43
43
 
44
+ def test_get_bid_ask_parses_response
45
+ body = load_fixture("bitget_tickers.json")
46
+ stub_connection(body)
47
+
48
+ result = @exchange.get_bid_ask("BTCUSDT")
49
+
50
+ assert result.success?
51
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
52
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
53
+ end
54
+
44
55
  private
45
56
 
46
57
  def stub_connection(body)
@@ -41,6 +41,17 @@ class Honeymaker::Exchanges::BitMartTest < Minitest::Test
41
41
  refute eth[:available]
42
42
  end
43
43
 
44
+ def test_get_bid_ask_parses_response
45
+ body = load_fixture("bitmart_ticker.json")
46
+ stub_connection(body)
47
+
48
+ result = @exchange.get_bid_ask("BTC_USDT")
49
+
50
+ assert result.success?
51
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
52
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
53
+ end
54
+
44
55
  private
45
56
 
46
57
  def stub_connection(body)
@@ -42,6 +42,17 @@ class Honeymaker::Exchanges::BitrueTest < Minitest::Test
42
42
  assert_equal 2, eth[:price_decimals]
43
43
  end
44
44
 
45
+ def test_get_bid_ask_parses_response
46
+ body = load_fixture("bitrue_book_ticker.json")
47
+ stub_connection(body)
48
+
49
+ result = @exchange.get_bid_ask("BTCUSDT")
50
+
51
+ assert result.success?
52
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
53
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
54
+ end
55
+
45
56
  private
46
57
 
47
58
  def stub_connection(body)
@@ -41,6 +41,17 @@ class Honeymaker::Exchanges::BitvavoTest < Minitest::Test
41
41
  refute eth[:available]
42
42
  end
43
43
 
44
+ def test_get_bid_ask_parses_response
45
+ body = load_fixture("bitvavo_book_ticker.json")
46
+ stub_connection(body)
47
+
48
+ result = @exchange.get_bid_ask("BTC-EUR")
49
+
50
+ assert result.success?
51
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
52
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
53
+ end
54
+
44
55
  private
45
56
 
46
57
  def stub_connection(body)
@@ -32,6 +32,17 @@ class Honeymaker::Exchanges::BybitTest < Minitest::Test
32
32
  assert ticker[:available]
33
33
  end
34
34
 
35
+ def test_get_bid_ask_parses_response
36
+ body = load_fixture("bybit_tickers.json")
37
+ stub_connection(body)
38
+
39
+ result = @exchange.get_bid_ask("BTCUSDT")
40
+
41
+ assert result.success?
42
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
43
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
44
+ end
45
+
35
46
  private
36
47
 
37
48
  def stub_connection(body)
@@ -41,6 +41,17 @@ class Honeymaker::Exchanges::CoinbaseTest < Minitest::Test
41
41
  refute_includes bases, "RENDER"
42
42
  end
43
43
 
44
+ def test_get_bid_ask_parses_response
45
+ body = load_fixture("coinbase_product.json")
46
+ stub_connection(body)
47
+
48
+ result = @exchange.get_bid_ask("BTC-USD")
49
+
50
+ assert result.success?
51
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
52
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
53
+ end
54
+
44
55
  private
45
56
 
46
57
  def stub_connection(body)
@@ -37,6 +37,17 @@ class Honeymaker::Exchanges::GeminiTest < Minitest::Test
37
37
  assert ticker[:available]
38
38
  end
39
39
 
40
+ def test_get_bid_ask_parses_response
41
+ body = load_fixture("gemini_pubticker.json")
42
+ stub_connection(body)
43
+
44
+ result = @exchange.get_bid_ask("BTCUSD")
45
+
46
+ assert result.success?
47
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
48
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
49
+ end
50
+
40
51
  private
41
52
 
42
53
  def stub_connection(body)
@@ -41,6 +41,17 @@ class Honeymaker::Exchanges::HyperliquidTest < Minitest::Test
41
41
  assert_equal 1, result.data.size
42
42
  end
43
43
 
44
+ def test_get_bid_ask_parses_response
45
+ body = load_fixture("hyperliquid_all_mids.json")
46
+ stub_connection(body)
47
+
48
+ result = @exchange.get_bid_ask("BTC/USDC")
49
+
50
+ assert result.success?
51
+ assert_equal BigDecimal("67124.56"), result.data[:bid]
52
+ assert_equal BigDecimal("67124.56"), result.data[:ask]
53
+ end
54
+
44
55
  private
45
56
 
46
57
  def stub_connection(body)
@@ -60,6 +60,26 @@ class Honeymaker::Exchanges::KrakenTest < Minitest::Test
60
60
  assert_includes result.errors, "EGeneral:Internal error"
61
61
  end
62
62
 
63
+ def test_get_bid_ask_parses_response
64
+ body = load_fixture("kraken_ticker.json")
65
+ stub_request(body)
66
+
67
+ result = @exchange.get_bid_ask("XBTUSDT")
68
+
69
+ assert result.success?
70
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
71
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
72
+ end
73
+
74
+ def test_get_bid_ask_handles_api_error
75
+ body = { "error" => ["EGeneral:Internal error"], "result" => {} }
76
+ stub_request(body)
77
+
78
+ result = @exchange.get_bid_ask("XBTUSDT")
79
+
80
+ assert result.failure?
81
+ end
82
+
63
83
  private
64
84
 
65
85
  def stub_request(body)
@@ -32,6 +32,17 @@ class Honeymaker::Exchanges::KucoinTest < Minitest::Test
32
32
  assert ticker[:available]
33
33
  end
34
34
 
35
+ def test_get_bid_ask_parses_response
36
+ body = load_fixture("kucoin_orderbook_level1.json")
37
+ stub_connection(body)
38
+
39
+ result = @exchange.get_bid_ask("BTC-USDT")
40
+
41
+ assert result.success?
42
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
43
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
44
+ end
45
+
35
46
  private
36
47
 
37
48
  def stub_connection(body)
@@ -53,6 +53,17 @@ class Honeymaker::Exchanges::MexcTest < Minitest::Test
53
53
  assert_equal 2, eth[:price_decimals]
54
54
  end
55
55
 
56
+ def test_get_bid_ask_parses_response
57
+ body = load_fixture("mexc_book_ticker.json")
58
+ stub_connection(body)
59
+
60
+ result = @exchange.get_bid_ask("BTCUSDT")
61
+
62
+ assert result.success?
63
+ assert_equal BigDecimal("67123.45"), result.data[:bid]
64
+ assert_equal BigDecimal("67125.67"), result.data[:ask]
65
+ end
66
+
56
67
  private
57
68
 
58
69
  def stub_connection(body)
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.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Deltabadger
@@ -128,19 +128,32 @@ files:
128
128
  - lib/honeymaker/utils.rb
129
129
  - lib/honeymaker/version.rb
130
130
  - sig/honeymaker.rbs
131
+ - test/fixtures/binance_book_ticker.json
131
132
  - test/fixtures/binance_exchange_info.json
132
133
  - test/fixtures/bingx_symbols.json
134
+ - test/fixtures/bingx_ticker.json
133
135
  - test/fixtures/bitget_symbols.json
136
+ - test/fixtures/bitget_tickers.json
134
137
  - test/fixtures/bitmart_symbols.json
138
+ - test/fixtures/bitmart_ticker.json
139
+ - test/fixtures/bitrue_book_ticker.json
135
140
  - test/fixtures/bitrue_exchange_info.json
141
+ - test/fixtures/bitvavo_book_ticker.json
136
142
  - test/fixtures/bitvavo_markets.json
137
143
  - test/fixtures/bybit_instruments.json
144
+ - test/fixtures/bybit_tickers.json
145
+ - test/fixtures/coinbase_product.json
138
146
  - test/fixtures/coinbase_products.json
147
+ - test/fixtures/gemini_pubticker.json
139
148
  - test/fixtures/gemini_symbol_detail.json
140
149
  - test/fixtures/gemini_symbols.json
150
+ - test/fixtures/hyperliquid_all_mids.json
141
151
  - test/fixtures/hyperliquid_spot_meta.json
142
152
  - test/fixtures/kraken_asset_pairs.json
153
+ - test/fixtures/kraken_ticker.json
154
+ - test/fixtures/kucoin_orderbook_level1.json
143
155
  - test/fixtures/kucoin_symbols.json
156
+ - test/fixtures/mexc_book_ticker.json
144
157
  - test/fixtures/mexc_exchange_info.json
145
158
  - test/honeymaker/client_test.rb
146
159
  - test/honeymaker/clients/binance_client_test.rb