bitcoin-api 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +2 -2
- data/README.md +31 -8
- data/bin/bitcoin +1 -1
- data/lib/bitcoin.rb +13 -37
- data/lib/bitcoin/analyzer.rb +110 -17
- data/lib/bitcoin/candle.rb +23 -15
- data/lib/bitcoin/cli.rb +29 -4
- data/lib/bitcoin/client/account.rb +40 -0
- data/lib/bitcoin/display.rb +2 -1
- data/lib/bitcoin/order_book.rb +10 -8
- data/lib/bitcoin/ssymbol.rb +17 -19
- data/lib/bitcoin/ticker.rb +17 -16
- data/lib/bitcoin/trade.rb +2 -1
- data/lib/bitcoin/version.rb +1 -1
- data/lib/exchanges/coin_market_cap.rb +12 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 737260dd6e60fc31d810b99815023506f794d7c35e17b72edb1a4a9dd56d6970
|
4
|
+
data.tar.gz: 64f44b4660e3ceeb07766cf2924df52c7e800b9b3b53e2a048db29e04cf8c4d2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cd7c2b461651f2bd228285937b838a5d534fbe53507661ca268e787216744bad76325da395da2a352c94d342ab6e859c3d26549e148bc12a963c44dcd3aad37
|
7
|
+
data.tar.gz: 10b17f043ec07b9139e43a5d461a732f8cef55d7dd0b3d4e06cafe5cc337e63081024915f76b92ab8c9f05ebd623ecbbb66863d153f8ef53ccd3c64b82acf39d
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -12,11 +12,11 @@ GEM
|
|
12
12
|
diff-lcs (1.3)
|
13
13
|
domain_name (0.5.20190701)
|
14
14
|
unf (>= 0.0.5, < 1.0.0)
|
15
|
+
dotenv (2.7.5)
|
15
16
|
ffi (1.11.3)
|
16
17
|
ffi-compiler (1.0.1)
|
17
18
|
ffi (>= 1.0.0)
|
18
19
|
rake
|
19
|
-
gchart (1.0.0)
|
20
20
|
http (4.3.0)
|
21
21
|
addressable (~> 2.3)
|
22
22
|
http-cookie (~> 1.0)
|
@@ -66,7 +66,7 @@ PLATFORMS
|
|
66
66
|
|
67
67
|
DEPENDENCIES
|
68
68
|
bitcoin-api!
|
69
|
-
|
69
|
+
dotenv
|
70
70
|
http
|
71
71
|
json
|
72
72
|
pry
|
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[](https://badge.fury.io/rb/bitcoin-api)
|
2
|
+
|
1
3
|
# Bitcoin
|
2
4
|
|
3
5
|
This is a CLI using the bitcoin.com exchange API to view market data and provide limited analysis.
|
@@ -11,27 +13,48 @@ Planned features:
|
|
11
13
|
- Algotrading, arbitrage
|
12
14
|
- UI
|
13
15
|
|
14
|
-
|
16
|
+
Walkthrough of source code: https://youtu.be/TuTf84mZAEY
|
15
17
|
|
16
|
-
|
18
|
+
Blog Post: https://briannicholls.home.blog/2020/01/18/cli-project-bitcoin-com-crypto-api/
|
17
19
|
|
18
|
-
|
19
|
-
gem 'bitcoin'
|
20
|
-
```
|
20
|
+
## Installation
|
21
21
|
|
22
|
+
Add this line to your application's Gemfile:
|
23
|
+
```ruby
|
24
|
+
gem 'bitcoin-api'
|
25
|
+
```
|
22
26
|
And then execute:
|
23
|
-
|
27
|
+
```
|
24
28
|
$ bundle install
|
29
|
+
```
|
25
30
|
|
26
31
|
Or install it yourself as:
|
27
32
|
|
28
|
-
$ gem
|
33
|
+
$ gem install bitcoin-api
|
34
|
+
|
29
35
|
|
30
36
|
## Usage
|
31
37
|
|
32
|
-
|
38
|
+
In your code use:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
require 'bitcoin'
|
42
|
+
|
43
|
+
Bitcoin::CLI.new # to start the CLI
|
44
|
+
```
|
45
|
+
|
46
|
+
If you've cloned the repo, run `bin/console` to play around, or `bin/bitcoin` to start the CLI.
|
33
47
|
|
48
|
+
## Add API Key / Secret
|
34
49
|
|
50
|
+
Get your API Key and secret from your account settings at https://exchange.bitcoin.com/settings/api-keys.
|
51
|
+
|
52
|
+
Create a file named `.env` in root directory. The contents should look like this:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
API_KEY={your API key (no quotes or brackets)}
|
56
|
+
SECRET={your Secret key (no quotes or brackets)}
|
57
|
+
```
|
35
58
|
|
36
59
|
## Development
|
37
60
|
|
data/bin/bitcoin
CHANGED
data/lib/bitcoin.rb
CHANGED
@@ -5,45 +5,21 @@ require 'net/http'
|
|
5
5
|
require 'uri'
|
6
6
|
require 'time'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
require_relative
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
require_relative
|
14
|
-
require_relative
|
15
|
-
require_relative
|
16
|
-
require_relative
|
17
|
-
require_relative
|
18
|
-
require_relative
|
19
|
-
require_relative
|
20
|
-
|
8
|
+
# require_relative "./bitcoin/version"
|
9
|
+
require_relative './bitcoin/version.rb'
|
10
|
+
require_relative './bitcoin/display.rb'
|
11
|
+
require_relative './bitcoin/cli.rb'
|
12
|
+
require_relative './bitcoin/currency.rb'
|
13
|
+
require_relative './bitcoin/order_book.rb'
|
14
|
+
require_relative './bitcoin/trade.rb'
|
15
|
+
require_relative './bitcoin/ssymbol.rb'
|
16
|
+
require_relative './bitcoin/candle.rb'
|
17
|
+
require_relative './bitcoin/ticker.rb'
|
18
|
+
require_relative './bitcoin/analyzer.rb'
|
19
|
+
require_relative './bitcoin/client/account.rb'
|
21
20
|
|
22
21
|
module Bitcoin
|
23
|
-
|
24
22
|
class Error < StandardError; end
|
25
23
|
# Your code goes here...
|
26
|
-
BASE =
|
27
|
-
def self.get_datetime
|
28
|
-
puts "Enter Date (YYYY MM DD)"
|
29
|
-
d = gets.strip
|
30
|
-
puts "Enter Time (24-hour format) (hh mm ss)"
|
31
|
-
t = gets.strip
|
32
|
-
d = d.split(" ")
|
33
|
-
t = t.split(" ")
|
34
|
-
r = "#{d[0]}-#{d[1]}-#{d[2]}T#{t[0]}:#{t[1]}:#{t[2]}Z"
|
35
|
-
puts "Is this correct? #{d[0]}/#{d[1]}/#{d[2]}"
|
36
|
-
puts "Y / N"
|
37
|
-
gets.strip.upcase == 'Y' ? r : self.get_datetime
|
38
|
-
end
|
39
|
-
|
40
|
-
# returns 2-element array with datetimes in ISO format
|
41
|
-
def self.get_datetimes_from_user
|
42
|
-
puts "*** Enter Start Time *** (2014 or later)"
|
43
|
-
from = Bitcoin.get_datetime
|
44
|
-
puts "*** Enter End Time *** (2014 or later)"
|
45
|
-
to = Bitcoin.get_datetime
|
46
|
-
return [from, to]
|
47
|
-
end
|
48
|
-
|
24
|
+
BASE = 'https://api.exchange.bitcoin.com/api/2'
|
49
25
|
end
|
data/lib/bitcoin/analyzer.rb
CHANGED
@@ -1,28 +1,121 @@
|
|
1
1
|
class Bitcoin::Analyzer
|
2
2
|
|
3
|
+
# input Symbol object, prints results
|
4
|
+
def self.analyze_trades(symbol)
|
5
|
+
trades = Bitcoin::Trade.get_trades_in_range(symbol.id,
|
6
|
+
get_datetimes_from_user)
|
7
|
+
puts ''
|
8
|
+
puts '///// [Analysis Results] /////'
|
9
|
+
puts '|'
|
10
|
+
puts '| Trade with highest price:'
|
11
|
+
puts "| #{get_max(trades).display_details}"
|
12
|
+
puts '| Trade with lowest price:'
|
13
|
+
puts "| #{get_min(trades).display_details}"
|
14
|
+
puts '| Largest trade:'
|
15
|
+
puts "| #{get_max(trades, :quantity).display_details}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.analyze_candles(symbol)
|
19
|
+
candles = Bitcoin::Candle.new_from_range(symbol.id, get_datetimes_from_user,
|
20
|
+
interval_from_user)
|
21
|
+
return "No candles found! :(" if !candles
|
22
|
+
puts ''
|
23
|
+
puts '///// [Analysis Results] /////'
|
24
|
+
puts ''
|
25
|
+
puts "Got #{candles.length} candles from #{candles.last.timestamp} - #{candles.first.timestamp}"
|
26
|
+
puts '|'
|
27
|
+
puts '| Period with highest price:'
|
28
|
+
puts "| #{get_max(candles, :max).display_details}"
|
29
|
+
puts '| Period with lowest open:'
|
30
|
+
puts "| #{get_min(candles, :open).display_details}"
|
31
|
+
puts '| Period with lowest volume:'
|
32
|
+
puts "| #{get_min(candles, :volume).display_details}"
|
33
|
+
puts "| Average Volume: #{avg(candles, 'volume')}"
|
34
|
+
puts '| Avg Open, Close, Min and Max:'
|
35
|
+
puts "| #{candle_averages(candles)}"
|
36
|
+
end
|
37
|
+
|
38
|
+
# returns ISO formatted datetime string from user
|
39
|
+
def self.get_datetime
|
40
|
+
d = date_from_user
|
41
|
+
t = time_from_user
|
42
|
+
r = "#{d[0]}-#{d[1]}-#{d[2]}T#{t[0]}:#{t[1]}:#{t[2]}Z"
|
43
|
+
puts "Is this correct? #{d[0]}/#{d[1]}/#{d[2]}, #{t[0]}:#{t[1]}:#{t[2]}"
|
44
|
+
puts 'Y / N'
|
45
|
+
gets.strip.upcase == 'Y' ? r : get_datetime
|
46
|
+
end
|
47
|
+
|
48
|
+
# returns 2-element array with formatted datetimes
|
49
|
+
def self.get_datetimes_from_user
|
50
|
+
puts '*** Enter Start Time *** (2014 or later)'
|
51
|
+
from = get_datetime
|
52
|
+
puts '*** Enter End Time *** (2014 or later)'
|
53
|
+
to = get_datetime
|
54
|
+
[from, to]
|
55
|
+
end
|
56
|
+
|
57
|
+
# calculate moving averages of candles array
|
58
|
+
# return: [ open, close, min, max]
|
59
|
+
def self.candle_averages(candles)
|
60
|
+
result = [0, 0, 0, 0]
|
61
|
+
candles.each do |candle|
|
62
|
+
result[0] += candle.open.to_f
|
63
|
+
result[1] += candle.close.to_f
|
64
|
+
result[2] += candle.min.to_f
|
65
|
+
result[3] += candle.max.to_f
|
66
|
+
end
|
67
|
+
result.map { |e| e / candles.length }
|
68
|
+
end
|
69
|
+
|
70
|
+
# calculate avg of attribute
|
71
|
+
def self.avg(object_array, attribute)
|
72
|
+
num = object_array.length
|
73
|
+
sum = object_array.inject(0) { |memo, e| memo + e.send("#{attribute}").to_i}
|
74
|
+
sum.to_f / num.to_f
|
75
|
+
end
|
76
|
+
|
77
|
+
# returns object with largest attribute
|
3
78
|
def self.get_max(object_array, attribute = :price)
|
4
|
-
object_array.max_by{ |e|
|
5
|
-
e.send("#{attribute}")
|
6
|
-
}
|
79
|
+
object_array.max_by{ |e| e.send("#{attribute}") }
|
7
80
|
end
|
8
81
|
|
82
|
+
# returns object with smallest attribute
|
9
83
|
def self.get_min(object_array, attribute = :price)
|
10
|
-
object_array.min_by{ |e|
|
11
|
-
e.send("#{attribute}")
|
12
|
-
}
|
84
|
+
object_array.min_by{ |e| e.send("#{attribute}") }
|
13
85
|
end
|
14
86
|
|
15
|
-
|
16
|
-
|
17
|
-
puts
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
87
|
+
# returns time in array format ['HH', 'MM', 'SS']
|
88
|
+
def self.time_from_user
|
89
|
+
puts 'Enter Time (24-hour format) (hh mm ss)'
|
90
|
+
t = gets.strip.split(' ')
|
91
|
+
if !t[0].to_i.between?(0, 23) || !t[1].to_i.between?(0, 59) || !t[2].to_i.between?(0, 59) || t[0].length != 2 || t[1].length != 2 || t[2].length != 2
|
92
|
+
puts 'Invalid time.'
|
93
|
+
time_from_user
|
94
|
+
end
|
95
|
+
t
|
96
|
+
end
|
97
|
+
|
98
|
+
# returns date in array format ['YYYY', 'MM', 'DD']
|
99
|
+
def self.date_from_user
|
100
|
+
puts 'Enter Year (YYYY MM DD)'
|
101
|
+
d = gets.strip.split(' ')
|
102
|
+
if d[0].to_i < 2014 || !d[1].to_i.between?(1, 12) || !d[2].to_i.between?(1, 31) || d[0].length != 4 || d[1].length != 2 || d[2].length != 2
|
103
|
+
puts 'Invalid Date. Try Again'
|
104
|
+
date_from_user
|
105
|
+
end
|
106
|
+
d
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.interval_from_user
|
110
|
+
puts 'Enter time interval. Accepted values:'
|
111
|
+
puts ' M1 (one minute), M3, M5, M15, M30, '
|
112
|
+
puts ' H1 (one hour), H4, '
|
113
|
+
puts ' D1 (one day), D7, '
|
114
|
+
puts ' 1M (one month)'
|
115
|
+
valid = ['M1', 'M3', 'M5', 'M15', 'M30', 'H1', 'H4', 'D1', 'D7', '1M']
|
116
|
+
input = gets.strip
|
117
|
+
interval_from_user if !valid.any?(input)
|
118
|
+
input
|
26
119
|
end
|
27
120
|
|
28
121
|
end
|
data/lib/bitcoin/candle.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
class Bitcoin::Candle
|
2
2
|
|
3
|
-
attr_accessor :timestamp, :open, :close, :min, :max, :volume, :volumeQuote
|
3
|
+
attr_accessor :timestamp, :open, :close, :min, :max, :volume, :volumeQuote, :interval
|
4
4
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
}
|
5
|
+
def display_details
|
6
|
+
puts <<-DOC
|
7
|
+
#{@timestamp}
|
8
|
+
Open: #{@open} || Close: #{@close}
|
9
|
+
Min: #{@min} || Max: #{@max}
|
10
|
+
Volume: #{@volume} || Volume Quote: #{@volumeQuote}
|
11
|
+
|
12
|
+
DOC
|
10
13
|
end
|
11
14
|
|
12
15
|
def self.new_from_object(object)
|
@@ -18,18 +21,23 @@ class Bitcoin::Candle
|
|
18
21
|
c.max = object['max']
|
19
22
|
c.volume = object['volume']
|
20
23
|
c.volumeQuote = object['volumeQuote']
|
24
|
+
#puts "candle retreived ()"
|
21
25
|
c
|
22
26
|
end
|
23
27
|
|
24
|
-
def
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
Volume: #{@volume} || Volume Quote: #{@volumeQuote}
|
30
|
-
|
31
|
-
DOC
|
28
|
+
def self.all(symbol)
|
29
|
+
data = JSON.parse(RestClient.get("#{Bitcoin::BASE}/public/candles/#{symbol}?limit=1000"))
|
30
|
+
data.map{ |candle|
|
31
|
+
Bitcoin::Candle.new_from_object(candle)
|
32
|
+
}
|
32
33
|
end
|
33
34
|
|
34
|
-
|
35
|
+
# returns array of candles between two datetimes
|
36
|
+
def self.new_from_range(symbol_name, timestamps, interval = '30M')
|
37
|
+
url = "#{Bitcoin::BASE}/public/candles/#{symbol_name}?limit=1000&sort=DESC"
|
38
|
+
params = "&from=#{timestamps[0]}&till=#{timestamps[1]}&period=#{interval}"
|
39
|
+
params = params.gsub(':', '%3A')
|
40
|
+
data = JSON.parse RestClient.get("#{url}#{params}")
|
41
|
+
data.map { |e| Bitcoin::Candle.new_from_object(e) }
|
42
|
+
end
|
35
43
|
end
|
data/lib/bitcoin/cli.rb
CHANGED
@@ -14,7 +14,7 @@ class Bitcoin::CLI
|
|
14
14
|
puts "* [1] Select Symbol"
|
15
15
|
puts "* [2] View Currency Information"
|
16
16
|
puts "* [3] View Tickers"
|
17
|
-
|
17
|
+
puts "* [4] User Dashboard"
|
18
18
|
puts " "
|
19
19
|
end
|
20
20
|
|
@@ -59,7 +59,28 @@ class Bitcoin::CLI
|
|
59
59
|
|
60
60
|
### TODO: USER SUBMENU ###
|
61
61
|
def user_menu
|
62
|
-
|
62
|
+
user_menu_display
|
63
|
+
|
64
|
+
input = gets.strip
|
65
|
+
menu if input == '0'
|
66
|
+
Bitcoin::Account.show_balances if input == '1'
|
67
|
+
Bitcoin::Account.show_deposit_address if input == '2'
|
68
|
+
exit if input == 'exit'
|
69
|
+
user_menu
|
70
|
+
end
|
71
|
+
|
72
|
+
def user_menu_display
|
73
|
+
puts ''
|
74
|
+
puts 'Type "exit" to quit'
|
75
|
+
puts ''
|
76
|
+
puts '====== [User Menu] ======'
|
77
|
+
puts '| [0] Main Menu'
|
78
|
+
puts '| [1] View Account Balances'
|
79
|
+
puts '| [2] View Deposit Address...'
|
80
|
+
# puts "* [3] Order Menu" # Create New, Cancel, Get by ID, Get History
|
81
|
+
# puts "* [4] Trade Menu"
|
82
|
+
# puts "* [5] Transfer To / From Bank Account"
|
83
|
+
# puts '* [5] Transfer To / From Bank Account'
|
63
84
|
end
|
64
85
|
|
65
86
|
### SYMBOL SUBMENUS ###
|
@@ -248,7 +269,9 @@ class Bitcoin::CLI
|
|
248
269
|
|
249
270
|
input = gets.strip
|
250
271
|
menu if input == '0'
|
272
|
+
symbol_menu(symbol) if input == '00'
|
251
273
|
Bitcoin::Analyzer.analyze_trades symbol if input == '1'
|
274
|
+
Bitcoin::Analyzer.analyze_candles symbol if input == '2'
|
252
275
|
analysis_menu(symbol)
|
253
276
|
end
|
254
277
|
|
@@ -257,8 +280,10 @@ class Bitcoin::CLI
|
|
257
280
|
puts " Type 'exit' to quit"
|
258
281
|
puts ""
|
259
282
|
puts "///// [Analysis Mode - #{symbol.id}] /////"
|
260
|
-
puts "/
|
261
|
-
puts "/ [
|
283
|
+
puts "/ [0] Main Menu"
|
284
|
+
puts "/ [00] Symbol Menu"
|
285
|
+
puts "/ [1] Analyze Trades Within Range..."
|
286
|
+
puts "/ [2] Analyze Candles Within Range..."
|
262
287
|
puts ""
|
263
288
|
end
|
264
289
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Bitcoin::Account
|
2
|
+
|
3
|
+
def self.show_balances
|
4
|
+
request = JSON.parse RestClient::Request.new(
|
5
|
+
:method => :get,
|
6
|
+
:url => "#{Bitcoin::BASE}/account/balance",
|
7
|
+
:user => ENV['API_KEY'],
|
8
|
+
:password => ENV['SECRET'],
|
9
|
+
:verify_ssl => false
|
10
|
+
).execute
|
11
|
+
|
12
|
+
puts "Currency | Available:"
|
13
|
+
puts "---------|-----------"
|
14
|
+
request.each{ |e|
|
15
|
+
puts "#{e['currency'].rjust(8)} | #{e['available']}"
|
16
|
+
#puts "Reserved: #{e['reserved']}"
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.show_deposit_address(currency_symbol = nil)
|
21
|
+
puts "Enter currency symbol:" if !currency_symbol
|
22
|
+
currency_symbol = gets.strip if !currency_symbol
|
23
|
+
|
24
|
+
request = JSON.parse RestClient::Request.new(
|
25
|
+
:method => :get,
|
26
|
+
:url => "#{Bitcoin::BASE}/account/crypto/address/#{currency_symbol}",
|
27
|
+
:user => ENV['API_KEY'],
|
28
|
+
:password => ENV['SECRET'],
|
29
|
+
:verify_ssl => false
|
30
|
+
).execute
|
31
|
+
puts ''
|
32
|
+
puts '************************************************'
|
33
|
+
puts "* Address: #{request['address']}"
|
34
|
+
puts "* Payment ID: #{request['paymentId']}"
|
35
|
+
puts '************************************************'
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
end
|
data/lib/bitcoin/display.rb
CHANGED
@@ -28,6 +28,7 @@ class Bitcoin::Display
|
|
28
28
|
candles.each_with_index{ |candle, i|
|
29
29
|
puts "#{(i+1).to_s.rjust(4)}. #{candle.timestamp} [#{candle.open.rjust(11)} -> #{candle.close.rjust(11)}] [#{candle.min.rjust(11)} - #{candle.max.rjust(11)}] vol: #{candle.volume.rjust(11)}"
|
30
30
|
}
|
31
|
+
# insert key at top and bottom of list
|
31
32
|
end
|
32
33
|
|
33
34
|
def self.list_tickers(tickers)
|
@@ -37,7 +38,7 @@ class Bitcoin::Display
|
|
37
38
|
end
|
38
39
|
|
39
40
|
private
|
40
|
-
# input array of hashes, and
|
41
|
+
# input array of hashes, and attribute to be displayed
|
41
42
|
def self.numerize(array, attribute = nil)
|
42
43
|
if attribute
|
43
44
|
array.each_with_index{ |e, i| puts "#{i+1}. #{e.send("#{attribute}")}"}
|
data/lib/bitcoin/order_book.rb
CHANGED
@@ -2,6 +2,16 @@ class Bitcoin::OrderBook
|
|
2
2
|
|
3
3
|
attr_accessor :side, :price, :size, :timestamp, :limit, :symbol
|
4
4
|
|
5
|
+
def display_details
|
6
|
+
puts <<-DOC
|
7
|
+
#{@symbol} #{@side.upcase} Order:
|
8
|
+
#{@price}
|
9
|
+
Quantity: #{@size}
|
10
|
+
#{@timestamp}
|
11
|
+
|
12
|
+
DOC
|
13
|
+
end
|
14
|
+
|
5
15
|
def self.new_from_object(object)
|
6
16
|
o = Bitcoin::OrderBook.new
|
7
17
|
o.size = object['size'].to_f
|
@@ -34,13 +44,5 @@ class Bitcoin::OrderBook
|
|
34
44
|
}
|
35
45
|
end
|
36
46
|
|
37
|
-
def display_details
|
38
|
-
puts <<-DOC
|
39
|
-
#{@symbol} #{@side.upcase} Order:
|
40
|
-
#{@price}
|
41
|
-
Quantity: #{@size}
|
42
|
-
#{@timestamp}
|
43
47
|
|
44
|
-
DOC
|
45
|
-
end
|
46
48
|
end
|
data/lib/bitcoin/ssymbol.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
class Bitcoin::Ssymbol
|
2
2
|
|
3
|
-
attr_accessor :id, :baseCurrency, :quoteCurrency, :quantityIncrement, :tickSize,
|
4
|
-
:takeLiquidityRate, :provideLiquidityRate, :feeCurrency
|
3
|
+
attr_accessor :id, :baseCurrency, :quoteCurrency, :quantityIncrement, :tickSize, :takeLiquidityRate, :provideLiquidityRate, :feeCurrency
|
5
4
|
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
}
|
5
|
+
def display_details
|
6
|
+
puts <<-DOC
|
7
|
+
ID: #{@id}
|
8
|
+
Base Currency: #{@baseCurrency} || Quote Currency: #{@quoteCurrency}
|
9
|
+
Quantity Increment: #{@quantityIncrement} || Tick Size: #{@tickSize}
|
10
|
+
Take Liquidity Rate: #{@takeLiquidityRate} || Provide Liquidity Rate: #{@provideLiquidityRate}
|
11
|
+
Fee Currency: #{@feeCurrency}
|
12
|
+
|
13
|
+
DOC
|
11
14
|
end
|
12
15
|
|
13
16
|
def self.new_from_object(data)
|
@@ -23,21 +26,16 @@ class Bitcoin::Ssymbol
|
|
23
26
|
s
|
24
27
|
end
|
25
28
|
|
29
|
+
def self.all
|
30
|
+
data = JSON.parse(RestClient.get("#{Bitcoin::BASE}/public/symbol"))
|
31
|
+
data.map{ |ssymbol|
|
32
|
+
Bitcoin::Ssymbol.new_from_object(ssymbol)
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
26
36
|
def self.new_from_symbol_name(symbol_name)
|
27
37
|
data = JSON.parse(RestClient.get("#{Bitcoin::BASE}/public/symbol/#{symbol_name}"))
|
28
38
|
Bitcoin::Ssymbol.new_from_object(data)
|
29
39
|
end
|
30
40
|
|
31
|
-
def display_details
|
32
|
-
puts <<-DOC
|
33
|
-
ID: #{@id}
|
34
|
-
Base Currency: #{@baseCurrency} || Quote Currency: #{@quoteCurrency}
|
35
|
-
Quantity Increment: #{@quantityIncrement} || Tick Size: #{@tickSize}
|
36
|
-
Take Liquidity Rate: #{@takeLiquidityRate} || Provide Liquidity Rate: #{@provideLiquidityRate}
|
37
|
-
Fee Currency: #{@feeCurrency}
|
38
|
-
|
39
|
-
DOC
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
41
|
end
|
data/lib/bitcoin/ticker.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
class Bitcoin::Ticker
|
2
2
|
|
3
|
-
attr_accessor :ask, :bid, :last, :open, :low, :high, :volume, :volumeQuote,
|
4
|
-
:timestamp, :symbol
|
3
|
+
attr_accessor :ask, :bid, :last, :open, :low, :high, :volume, :volumeQuote, :timestamp, :symbol
|
5
4
|
|
6
|
-
def
|
7
|
-
|
8
|
-
|
5
|
+
def display_details
|
6
|
+
puts <<-DOC
|
7
|
+
#{@symbol}
|
8
|
+
Best Ask : #{@ask.to_s.rjust(9)} || Best Bid: #{@bid}
|
9
|
+
Last Trade Price: #{@last}
|
10
|
+
Open: #{@open}
|
11
|
+
24-Hour Low: #{@low.to_s.rjust(9)} || 24-Hour High: #{@high}
|
12
|
+
Total 24-Hour Volume (Base): #{@volume} (Quote): #{@volumeQuote}
|
13
|
+
#{@timestamp}
|
14
|
+
|
15
|
+
DOC
|
9
16
|
end
|
10
17
|
|
11
18
|
def self.new_from_object(data)
|
@@ -23,6 +30,11 @@ class Bitcoin::Ticker
|
|
23
30
|
t
|
24
31
|
end
|
25
32
|
|
33
|
+
def self.new_from_symbol_name(symbol_name)
|
34
|
+
data = JSON.parse(RestClient.get("#{Bitcoin::BASE}/public/ticker/#{symbol_name}"))
|
35
|
+
Bitcoin::Ticker.new_from_object(data)
|
36
|
+
end
|
37
|
+
|
26
38
|
def self.all
|
27
39
|
data = JSON.parse(RestClient.get("#{Bitcoin::BASE}/public/ticker"))
|
28
40
|
data.map{ |ticker|
|
@@ -30,16 +42,5 @@ class Bitcoin::Ticker
|
|
30
42
|
}
|
31
43
|
end
|
32
44
|
|
33
|
-
def display_details
|
34
|
-
puts <<-DOC
|
35
|
-
#{@symbol}
|
36
|
-
Best Ask : #{@ask.to_s.rjust(9)} || Best Bid: #{@bid}
|
37
|
-
Last Trade Price: #{@last}
|
38
|
-
Open: #{@open}
|
39
|
-
24-Hour Low: #{@low.to_s.rjust(9)} || 24-Hour High: #{@high}
|
40
|
-
Total 24-Hour Volume (Base): #{@volume} (Quote): #{@volumeQuote}
|
41
|
-
#{@timestamp}
|
42
45
|
|
43
|
-
DOC
|
44
|
-
end
|
45
46
|
end
|
data/lib/bitcoin/trade.rb
CHANGED
@@ -30,7 +30,8 @@ class Bitcoin::Trade
|
|
30
30
|
}
|
31
31
|
end
|
32
32
|
|
33
|
-
|
33
|
+
# Input: currency pair and formatted date range. Output: array of trades from range
|
34
|
+
def self.get_trades_in_range(symbol_name, timestamps = nil)
|
34
35
|
data = JSON.parse RestClient.get "#{Bitcoin::BASE}/public/trades/#{symbol_name}?limit=1000&sort=DESC&from=#{timestamps[0]}&till=#{timestamps[1]}"
|
35
36
|
data.map{|e|
|
36
37
|
Bitcoin::Trade.new_from_object(symbol_name, e)
|
data/lib/bitcoin/version.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
class CoinMarketCap
|
2
|
+
BASE_URL = 'https://pro-api.coinmarketcap.com'
|
3
|
+
# /v1/exchange/map - CoinMarketCap ID map
|
4
|
+
# /v1/exchange/info - Metadata
|
5
|
+
# /v1/exchange/listings/latest - Latest listings
|
6
|
+
# /v1/exchange/listings/historical - Historical listings
|
7
|
+
# /v1/exchange/quotes/latest - Latest quotes
|
8
|
+
# /v1/exchange/quotes/historical - Historical quotes
|
9
|
+
# /v1/exchange/market-pairs/latest - Latest market pairs
|
10
|
+
|
11
|
+
data = JSON.parse(RestClient.get("#{Bitcoin::BASE}/public/candles/#{symbol}?limit=1000"))
|
12
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitcoin-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Nicholls
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-01-
|
11
|
+
date: 2020-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- lib/bitcoin/analyzer.rb
|
35
35
|
- lib/bitcoin/candle.rb
|
36
36
|
- lib/bitcoin/cli.rb
|
37
|
+
- lib/bitcoin/client/account.rb
|
37
38
|
- lib/bitcoin/currency.rb
|
38
39
|
- lib/bitcoin/display.rb
|
39
40
|
- lib/bitcoin/order_book.rb
|
@@ -41,6 +42,7 @@ files:
|
|
41
42
|
- lib/bitcoin/ticker.rb
|
42
43
|
- lib/bitcoin/trade.rb
|
43
44
|
- lib/bitcoin/version.rb
|
45
|
+
- lib/exchanges/coin_market_cap.rb
|
44
46
|
homepage: https://github.com/nichol88/bitcoin_api
|
45
47
|
licenses:
|
46
48
|
- MIT
|