binance_api 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 785508bdf812f50b612e6d233114a981993353b8
4
+ data.tar.gz: 00fe1c4241dd4df7eb24bbd102690af7b637a7c5
5
+ SHA512:
6
+ metadata.gz: 5375bed8d041274f3c12a6532c269ec414ebb54226124101757edc81a3b164c22164c9934273f7a01733becf941f799aaacaf1c783bdd38f55820ef116d11a96
7
+ data.tar.gz: d173609427d1132dd71fbee83a29146d5856785c5d228d89364c2826dbf1c150671afe8d991e04712fcf489dc6f615457b5fd181d7aa2a7d80becde790546ae0
data/.gitignore ADDED
@@ -0,0 +1,15 @@
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
12
+
13
+ # Project files
14
+ .idea
15
+ config/config.yml
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.5
5
+ before_install: gem install bundler -v 1.16.0
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at osiutino@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+
6
+ gem 'rest-client', '~> 2.0.0'
7
+ gem 'websocket-client-simple', '~> 0.3.0'
8
+
9
+ # Specify your gem's dependencies in binance_api.gemspec
10
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,59 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ binance_api (1.0.0)
5
+ rest-client (~> 2.0)
6
+ websocket-client-simple (~> 0.3.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ diff-lcs (1.3)
12
+ domain_name (0.5.20170404)
13
+ unf (>= 0.0.5, < 1.0.0)
14
+ event_emitter (0.2.6)
15
+ http-cookie (1.0.3)
16
+ domain_name (~> 0.5)
17
+ mime-types (3.1)
18
+ mime-types-data (~> 3.2015)
19
+ mime-types-data (3.2016.0521)
20
+ netrc (0.11.0)
21
+ rake (10.5.0)
22
+ rest-client (2.0.2)
23
+ http-cookie (>= 1.0.2, < 2.0)
24
+ mime-types (>= 1.16, < 4.0)
25
+ netrc (~> 0.8)
26
+ rspec (3.7.0)
27
+ rspec-core (~> 3.7.0)
28
+ rspec-expectations (~> 3.7.0)
29
+ rspec-mocks (~> 3.7.0)
30
+ rspec-core (3.7.1)
31
+ rspec-support (~> 3.7.0)
32
+ rspec-expectations (3.7.0)
33
+ diff-lcs (>= 1.2.0, < 2.0)
34
+ rspec-support (~> 3.7.0)
35
+ rspec-mocks (3.7.0)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.7.0)
38
+ rspec-support (3.7.1)
39
+ unf (0.1.4)
40
+ unf_ext
41
+ unf_ext (0.0.7.5)
42
+ websocket (1.2.5)
43
+ websocket-client-simple (0.3.0)
44
+ event_emitter
45
+ websocket
46
+
47
+ PLATFORMS
48
+ ruby
49
+
50
+ DEPENDENCIES
51
+ binance_api!
52
+ bundler (~> 1.16)
53
+ rake (~> 10.0)
54
+ rest-client (~> 2.0.0)
55
+ rspec (~> 3.0)
56
+ websocket-client-simple (~> 0.3.0)
57
+
58
+ BUNDLED WITH
59
+ 1.16.0
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 osiutino
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # binance-api-ruby
2
+
3
+ A wrapper written in ruby for Binance API
4
+
5
+ ## Installation
6
+
7
+ Manually install using [RubyGems](http://rubygems.org/):
8
+
9
+ ```
10
+ gem install binance_api
11
+ ```
12
+
13
+ Or add it to your Gemfile:
14
+
15
+ ```
16
+ gem 'binance_api'
17
+ ```
18
+
19
+ ## Examples
20
+
21
+ ### using a REST Client
22
+ ```
23
+ require 'binance_api'
24
+
25
+ # initialize a rest client
26
+ rest_client = BinanceAPI::REST.new
27
+
28
+ result = rest_client.ticker_24hr('BNBBTC')
29
+ #<BinanceAPI::Result:0x000000000220c7c0 ... >
30
+
31
+ >> result.success?
32
+ true
33
+
34
+ # return a response value in Hash
35
+ >> result.value
36
+ { :symbol=>"BNBBTC", :priceChange=>"0.00003640", :priceChangePerce .... }
37
+
38
+ ```
39
+
40
+ ### using a Stream client
41
+
42
+ ```
43
+ require 'binance_api'
44
+
45
+ # initialize a combined stream client
46
+ stream = BinanceAPI::Stream.new(['bnbbtc@aggTrade', 'bnbbtc@trade'], on_message: ->(msg) { puts "message: #{msg.data}" })
47
+
48
+ stream.start
49
+ >> -- websocket open (wss://stream.binance.com:9443/stream?streams=bnbbtc@aggTrade/bnbbtc@trade)
50
+ >> message: {"stream":"bnbbtc@aggTrade","data":{"e":"aggTrade","E":1522436817258,"s":"BNBBTC","a":11744566,"p":"0.00147820","q":"0.15000000","f":13627823,"l":13627823,"T":1522436817255,"m":false,"M":true}}
51
+ >> message: {"stream":"bnbbtc@trade","data":{"e":"trade","E":1522436817257,"s":"BNBBTC","t":13627823,"p":"0.00147820","q":"0.15000000","b":35456123,"a":35456121,"T":1522436817255,"m":false,"M":true}}
52
+ >> message: {"stream":"bnbbtc@trade","data":{"e":"trade","E":1522436819021,"s":"BNBBTC","t":13627824,"p":"0.00147820","q":"2.63000000","b":35456125,"a":35456121,"T":1522436819021,"m":false,"M":true}}
53
+ >> message: {"stream":"bnbbtc@aggTrade","data":{"e":"aggTrade","E":1522436819022,"s":"BNBBTC","a":11744567,"p":"0.00147820","q":"2.63000000","f":13627824,"l":13627824,"T":1522436819021,"m":false,"M":true}}
54
+ >> message: {"stream":"bnbbtc@aggTrade","data":{"e":"aggTrade","E":1522436823612,"s":"BNBBTC","a":11744568,"p":"0.00147660","q":"24.88000000","f":13627825,"l":13627826,"T":1522436823609,"m":true,"M":true}}
55
+ >> message: {"stream":"bnbbtc@trade","data":{"e":"trade","E":1522436823611,"s":"BNBBTC","t":13627825,"p":"0.00147660","q":"0.01000000","b":35456076,"a":35456136,"T":1522436823609,"m":true,"M":true}}
56
+ >> message: {"stream":"bnbbtc@trade","data":{"e":"trade","E":1522436823611,"s":"BNBBTC","t":13627826,"p":"0.00147660","q":"24.87000000","b":35456127,"a":35456136,"T":1522436823609,"m":true,"M":true}}
57
+ >> ...
58
+
59
+
60
+ ```
61
+
62
+ ## Structure
63
+
64
+ API | Class
65
+ ------ | --------
66
+ Rest API | BinanceAPI::REST
67
+ Withdraw API | BinanceAPI::WAPI
68
+ Account Stream | BinanceAPI::Stream
69
+
70
+ ## REST Client Calls
71
+
72
+ #ping
73
+ #server_time
74
+ #exchange_info
75
+ #depth
76
+ #trades
77
+ #historical_trades
78
+ #aggregate_trades_list
79
+ #klines
80
+ #ticker_24hr
81
+ #ticker_price
82
+ #ticker_book
83
+ #order
84
+ #order_test
85
+ #get_order
86
+ #cancel_order
87
+ #open_orders
88
+ #all_orders
89
+ #account
90
+ #my_trades
91
+ #start_user_data_stream
92
+ #keep_alive_user_data_stream
93
+ #close_user_data_stream
94
+
95
+ ## Withdrawal Client Calls
96
+ #withdraw
97
+ #deposit_history
98
+ #withdraw_history
99
+ #deposit_address
100
+ #withdraw_fee
101
+ #account_status
102
+ #system_status
103
+
104
+ ## Stream Client Calls
105
+
106
+ #close
107
+ #start
108
+
109
+ ## License
110
+
111
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
112
+
113
+ Feedback
114
+
115
+ ## Donations
116
+
117
+ If this repo made you feel useful in any way, feel free to donate any amount of the following wallets:
118
+ ```
119
+ BNB: 0x607cb799cb2e9b777e1453d4f2450eae738fd342
120
+ BTC: 1LwjLrBwQtpCiWKCpfJ4JhYq3bkMerdjXU
121
+ ```
data/Rakefile ADDED
@@ -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
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "binance_api"
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__)
data/bin/setup ADDED
@@ -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,38 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "binance_api/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "binance_api"
8
+ spec.version = BinanceAPI::VERSION
9
+ spec.authors = ["osiutino"]
10
+ spec.email = ["osiutino@gmail.com"]
11
+
12
+ spec.summary = %q{unoffical Binance rubygem}
13
+ spec.description = %q{A Binance API wrapper written in ruby}
14
+ spec.homepage = "https://github.com/siutin/binance-api-ruby"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against " \
23
+ "public gem pushes."
24
+ end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.add_development_dependency "bundler", "~> 1.16"
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "rspec", "~> 3.0"
36
+ spec.add_dependency 'rest-client', "~> 2.0"
37
+ spec.add_dependency 'websocket-client-simple', '~> 0.3.0'
38
+ end
@@ -0,0 +1,3 @@
1
+ ---
2
+ API_KEY: --- SOME KEY ---
3
+ API_SECRET: --- SOME SECRET ---
@@ -0,0 +1,32 @@
1
+ require 'binance_api/version'
2
+ require 'binance_api/rest'
3
+ require 'binance_api/wapi'
4
+ require 'binance_api/stream'
5
+ require 'yaml'
6
+
7
+ module BinanceAPI
8
+ class << self
9
+
10
+ def rest
11
+ @rest ||= BinanceAPI::REST.new
12
+ end
13
+
14
+ def wapi
15
+ @wapi ||= BinanceAPI::WAPI.new
16
+ end
17
+
18
+ attr_writer :recv_window
19
+
20
+ def recv_window
21
+ @recv_window || 5000
22
+ end
23
+
24
+ def load_config
25
+ YAML.load_file(File.join(BinanceAPI.root, 'config', 'config.yml'))
26
+ end
27
+
28
+ def root
29
+ File.expand_path('../..', __FILE__)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,39 @@
1
+ require 'rest-client'
2
+ require 'date'
3
+ require 'uri'
4
+ require 'json'
5
+ require 'binance_api/result'
6
+
7
+ module BinanceAPI
8
+ class Base
9
+ BASE_URL = 'https://api.binance.com'.freeze
10
+
11
+ protected
12
+
13
+ def params_with_signature(params, secret)
14
+ params = params.reject { |_k, v| v.nil? }
15
+ query_string = URI.encode_www_form(params)
16
+ signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), secret, query_string)
17
+ params = params.merge(signature: signature)
18
+ end
19
+
20
+ # ensure to return a response object
21
+ def safe
22
+ yield
23
+ rescue RestClient::ExceptionWithResponse => err
24
+ return err.response
25
+ end
26
+
27
+ def config
28
+ @config ||= BinanceAPI.load_config
29
+ end
30
+
31
+ def api_key
32
+ config['API_KEY'].freeze
33
+ end
34
+
35
+ def api_secret
36
+ config['API_SECRET'].freeze
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,311 @@
1
+ require 'rest-client'
2
+ require 'date'
3
+ require 'uri'
4
+ require 'json'
5
+ require 'binance_api/base'
6
+ require 'binance_api/result'
7
+
8
+ module BinanceAPI
9
+ class REST < BinanceAPI::Base
10
+ def ping
11
+ response = safe { RestClient.get("#{BASE_URL}/api/v1/ping") }
12
+ build_result response
13
+ end
14
+
15
+ def server_time
16
+ response = safe { RestClient.get("#{BASE_URL}/api/v1/time") }
17
+ build_result response
18
+ end
19
+
20
+ def exchange_info
21
+ response = safe { RestClient.get("#{BASE_URL}/api/v1/exchangeInfo") }
22
+ build_result response
23
+ end
24
+
25
+ def depth(symbol, limit: 100)
26
+ response = safe { RestClient.get("#{BASE_URL}/api/v1/depth", params: { symbol: symbol, limit: limit }) }
27
+ build_result response
28
+ end
29
+
30
+ def trades(symbol, limit: 500)
31
+ response = safe { RestClient.get("#{BASE_URL}/api/v1/trades", params: { symbol: symbol, limit: limit }) }
32
+ build_result response
33
+ end
34
+
35
+ def historical_trades(symbol, limit: 500, from_id: nil)
36
+ params = { symbol: symbol, limit: limit }
37
+ params = params.merge(fromId: from_id) unless from_id.nil?
38
+ response = safe do
39
+ RestClient.get "#{BASE_URL}/api/v1/historicalTrades",
40
+ params: params,
41
+ 'X-MBX-APIKEY' => api_key
42
+ end
43
+ build_result response
44
+ end
45
+
46
+ def aggregate_trades_list(symbol, from_id: nil, start_time: nil, end_time: nil, limit: 500)
47
+ params = begin
48
+ { symbol: symbol, limit: limit }.tap do |_params|
49
+ _params[:fromId] = from_id unless from_id.nil?
50
+ _params[:startTime] = start_time unless start_time.nil?
51
+ _params[:endTime] = end_time unless end_time.nil?
52
+ end
53
+ end
54
+ response = safe { RestClient.get("#{BASE_URL}/api/v1/aggTrades", params: params) }
55
+ build_result response
56
+ end
57
+
58
+ def klines(symbol, interval, start_time: nil, end_time: nil, limit: 500)
59
+ params = begin
60
+ { symbol: symbol, interval: interval, limit: limit }.tap do |_params|
61
+ _params[:startTime] = start_time unless start_time.nil?
62
+ _params[:endTime] = end_time unless end_time.nil?
63
+ end
64
+ end
65
+
66
+ response = safe { RestClient.get("#{BASE_URL}/api/v1/klines", params: params) }
67
+ build_result response
68
+ end
69
+
70
+ def ticker_24hr(symbol)
71
+ response = safe { RestClient.get("#{BASE_URL}/api/v1/ticker/24hr", params: { symbol: symbol }) }
72
+ build_result response
73
+ end
74
+
75
+ def ticker_price(symbol)
76
+ response = safe { RestClient.get("#{BASE_URL}/api/v3/ticker/price", params: { symbol: symbol }) }
77
+ build_result response
78
+ end
79
+
80
+ def ticker_book(symbol)
81
+ response = safe { RestClient.get("#{BASE_URL}/api/v3/ticker/bookTicker", params: { symbol: symbol }) }
82
+ build_result response
83
+ end
84
+
85
+ # {
86
+ # symbol: 'LTCBTC',
87
+ # side: 'BUY',
88
+ # type: 'LIMIT',
89
+ # timeInForce: 'GTC',
90
+ # quantity: 1,
91
+ # price: 0.1,
92
+ # recvWindow: BinanceAPI.recv_window,
93
+ # timestamp: 1499827319559
94
+ # }
95
+
96
+ def order(symbol, side, type, quantity, options = {})
97
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
98
+ timestamp = options.delete(:timestamp) || Time.now
99
+
100
+ params = {
101
+ symbol: symbol,
102
+ side: side,
103
+ type: type,
104
+ timeInForce: options.fetch(:time_in_force, nil),
105
+ quantity: quantity,
106
+ price: options.fetch(:price, nil),
107
+ newClientOrderId: options.fetch(:new_client_order_id, nil),
108
+ stopPrice: options.fetch(:stop_price, nil),
109
+ icebergQty: options.fetch(:iceberg_qty, nil),
110
+ newOrderRespType: options.fetch(:new_order_resp_type, nil),
111
+ recvWindow: recv_window,
112
+ timestamp: timestamp.to_i * 1000 # to milliseconds
113
+ }
114
+
115
+ response = safe do
116
+ RestClient.post "#{BASE_URL}/api/v3/order",
117
+ params_with_signature(params, api_secret),
118
+ 'X-MBX-APIKEY' => api_key
119
+ end
120
+
121
+ build_result response
122
+ end
123
+
124
+ def order_test(symbol, side, type, quantity, options = {})
125
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
126
+ timestamp = options.delete(:timestamp) || Time.now
127
+
128
+ params = {
129
+ symbol: symbol,
130
+ side: side,
131
+ type: type,
132
+ timeInForce: options.fetch(:time_in_force, nil),
133
+ quantity: quantity,
134
+ price: options.fetch(:price, nil),
135
+ newClientOrderId: options.fetch(:new_client_order_id, nil),
136
+ stopPrice: options.fetch(:stop_price, nil),
137
+ icebergQty: options.fetch(:iceberg_qty, nil),
138
+ newOrderRespType: options.fetch(:new_order_resp_type, nil),
139
+ recvWindow: recv_window,
140
+ timestamp: timestamp.to_i * 1000 # to milliseconds
141
+ }
142
+
143
+ response = safe do
144
+ RestClient.post "#{BASE_URL}/api/v3/order/test",
145
+ params_with_signature(params, api_secret),
146
+ 'X-MBX-APIKEY' => api_key
147
+ end
148
+
149
+ build_result response
150
+ end
151
+
152
+ def get_order(symbol, options = {})
153
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
154
+ timestamp = options.delete(:timestamp) || Time.now
155
+
156
+ params = {
157
+ symbol: symbol,
158
+ orderId: options.fetch(:order_id, nil),
159
+ origClientOrderId: options.fetch(:orig_client_order_id, nil),
160
+ recvWindow: recv_window,
161
+ timestamp: timestamp.to_i * 1000 # to milliseconds
162
+ }
163
+
164
+ response = safe do
165
+ RestClient.get "#{BASE_URL}/api/v3/order",
166
+ params: params_with_signature(params, api_secret),
167
+ 'X-MBX-APIKEY' => api_key
168
+ end
169
+
170
+ build_result response
171
+ end
172
+
173
+ def cancel_order(symbol, options = {})
174
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
175
+ timestamp = options.delete(:timestamp) || Time.now
176
+
177
+ params = {
178
+ symbol: symbol,
179
+ orderId: options.fetch(:order_id, nil),
180
+ origClientOrderId: options.fetch(:orig_client_order_id, nil),
181
+ newClientOrderId: options.fetch(:new_client_order_id, nil),
182
+ recvWindow: recv_window,
183
+ timestamp: timestamp.to_i * 1000 # to milliseconds
184
+ }
185
+
186
+ response = safe do
187
+ RestClient.delete "#{BASE_URL}/api/v3/order",
188
+ params: params_with_signature(params, api_secret),
189
+ 'X-MBX-APIKEY' => api_key
190
+ end
191
+
192
+ build_result response
193
+ end
194
+
195
+ def open_orders(symbol, options = {})
196
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
197
+ timestamp = options.delete(:timestamp) || Time.now
198
+
199
+ params = {
200
+ symbol: symbol,
201
+ recvWindow: recv_window,
202
+ timestamp: timestamp.to_i * 1000 # to milliseconds
203
+ }
204
+
205
+ response = safe do
206
+ RestClient.get "#{BASE_URL}/api/v3/openOrders",
207
+ params: params_with_signature(params, api_secret),
208
+ 'X-MBX-APIKEY' => api_key
209
+ end
210
+
211
+ build_result response
212
+ end
213
+
214
+ def all_orders(symbol, options = {})
215
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
216
+ timestamp = options.delete(:timestamp) || Time.now
217
+ limit = options.delete(:limit) || 500
218
+
219
+ params = {
220
+ symbol: symbol,
221
+ orderId: options.fetch(:order_id, nil),
222
+ limit: limit,
223
+ recvWindow: recv_window,
224
+ timestamp: timestamp.to_i * 1000 # to milliseconds
225
+ }
226
+
227
+ response = safe do
228
+ RestClient.get "#{BASE_URL}/api/v3/allOrders",
229
+ params: params_with_signature(params, api_secret),
230
+ 'X-MBX-APIKEY' => api_key
231
+ end
232
+
233
+ build_result response
234
+ end
235
+
236
+
237
+ def account(options = {})
238
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
239
+ timestamp = options.delete(:timestamp) || Time.now
240
+
241
+ params = {
242
+ recvWindow: recv_window,
243
+ timestamp: timestamp.to_i * 1000 # to milliseconds
244
+ }
245
+
246
+ response = safe do
247
+ RestClient.get "#{BASE_URL}/api/v3/account",
248
+ params: params_with_signature(params, api_secret),
249
+ 'X-MBX-APIKEY' => api_key
250
+ end
251
+
252
+ build_result response
253
+ end
254
+
255
+ def my_trades(symbol, options = {})
256
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
257
+ timestamp = options.delete(:timestamp) || Time.now
258
+ limit = options.delete(:limit) || 500
259
+ params = {
260
+ symbol: symbol,
261
+ limit: limit,
262
+ fromId: options.fetch(:from_id, nil),
263
+ recvWindow: recv_window,
264
+ timestamp: timestamp.to_i * 1000 # to milliseconds
265
+ }
266
+
267
+ response = safe do
268
+ RestClient.get "#{BASE_URL}/api/v3/myTrades",
269
+ params: params_with_signature(params, api_secret),
270
+ 'X-MBX-APIKEY' => api_key
271
+ end
272
+
273
+ build_result response
274
+ end
275
+
276
+ def start_user_data_stream
277
+ response = safe do
278
+ RestClient.post "#{BASE_URL}/api/v1/userDataStream",
279
+ {},
280
+ 'X-MBX-APIKEY' => api_key
281
+ end
282
+ build_result response
283
+ end
284
+
285
+ def keep_alive_user_data_stream(listen_key)
286
+ response = safe do
287
+ RestClient.put "#{BASE_URL}/api/v1/userDataStream",
288
+ {listenKey: listen_key},
289
+ 'X-MBX-APIKEY' => api_key
290
+ end
291
+ build_result response
292
+ end
293
+
294
+ def close_user_data_stream(listen_key)
295
+ response = safe do
296
+ RestClient.delete "#{BASE_URL}/api/v1/userDataStream",
297
+ params: {listenKey: listen_key},
298
+ 'X-MBX-APIKEY' => api_key
299
+ build_result response
300
+ end
301
+ end
302
+
303
+ protected
304
+
305
+ def build_result(response)
306
+ json = JSON.parse(response.body, symbolize_names: true)
307
+ BinanceAPI::Result.new(json, response.code == 200)
308
+ end
309
+
310
+ end
311
+ end
@@ -0,0 +1,14 @@
1
+ module BinanceAPI
2
+ class Result
3
+ def initialize(struct, success)
4
+ @value = struct
5
+ @success = success
6
+ end
7
+
8
+ def success?
9
+ @success
10
+ end
11
+
12
+ attr_reader :value
13
+ end
14
+ end
@@ -0,0 +1,67 @@
1
+ require 'websocket-client-simple'
2
+ module BinanceAPI
3
+ class Stream
4
+ BASE_ENDPOINT = 'wss://stream.binance.com:9443/'.freeze
5
+
6
+ def initialize(endpoints, on_open: nil, on_close: nil, on_error: nil, on_message: nil)
7
+ raise 'on_open can accept a block only' if !on_open.nil? && !on_open.is_a?(Proc)
8
+ raise 'on_close can accept a block only' if !on_close.nil? && !on_close.is_a?(Proc)
9
+ raise 'on_error can accept a block only' if !on_error.nil? && !on_error.is_a?(Proc)
10
+ raise 'on_data can accept a block only' if !on_message.nil? && !on_message.is_a?(Proc)
11
+
12
+ @endpoints = Array(endpoints).reject(&:nil?).reject(&:empty?)
13
+ raise 'endpoints cannot be empty' if @endpoints.empty?
14
+
15
+ @on_open = on_open
16
+ @on_close = on_close
17
+ @on_error = on_error
18
+ @on_message = on_message
19
+ @stream_type = @endpoints.length > 1 ? :combined : :single
20
+ end
21
+
22
+ def start
23
+ @ws = WebSocket::Client::Simple.connect "#{BASE_ENDPOINT}#{stream_url}"
24
+ ws.on :message, &on_message
25
+ ws.on :open, &on_open
26
+ ws.on :close, &on_close
27
+ ws.on :error, &on_error
28
+ ws
29
+ end
30
+
31
+ def close
32
+ ws.close
33
+ end
34
+
35
+ protected
36
+
37
+ attr_reader :ws, :endpoints, :stream_type
38
+
39
+ def stream_url
40
+ stream_type == :combined ? combined_url(endpoints) : single_url(endpoints.first)
41
+ end
42
+
43
+ def single_url(stream_name)
44
+ "ws/#{stream_name}"
45
+ end
46
+
47
+ def combined_url(stream_names)
48
+ "stream?streams=#{stream_names.join('/')}"
49
+ end
50
+
51
+ def on_open
52
+ @on_open || ->() { puts "-- websocket open (#{url})" }
53
+ end
54
+
55
+ def on_close
56
+ @on_close || ->(e) { puts "-- websocket close (#{e.inspect})" }
57
+ end
58
+
59
+ def on_error
60
+ @on_error || ->(e) { puts "-- error (#{e.inspect})" }
61
+ end
62
+
63
+ def on_message
64
+ @on_message || ->(msg) { puts ">> #{msg.data}" }
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ module BinanceAPI
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,146 @@
1
+ require 'rest-client'
2
+ require 'binance_api/base'
3
+ require 'binance_api/result'
4
+
5
+ module BinanceAPI
6
+ class WAPI < BinanceAPI::Base
7
+ def withdraw(asset, address, amount, options = {})
8
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
9
+ timestamp = options.delete(:timestamp) || Time.now
10
+
11
+ params = {
12
+ asset: asset,
13
+ address: address,
14
+ addressTag: options.fetch(:address_tag, nil),
15
+ amount: amount,
16
+ name: options.fetch(:name, nil),
17
+ recvWindow: recv_window,
18
+ timestamp: timestamp.to_i * 1000 # to milliseconds
19
+ }
20
+
21
+ response = safe do
22
+ RestClient.get "#{BASE_URL}/wapi/v3/withdraw.html",
23
+ params: params_with_signature(params, api_secret),
24
+ 'X-MBX-APIKEY' => api_key
25
+ end
26
+
27
+ build_result response
28
+ end
29
+
30
+ def deposit_history(asset, options = {})
31
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
32
+ timestamp = options.delete(:timestamp) || Time.now
33
+
34
+ params = {
35
+ asset: asset,
36
+ status: options.fetch(:status, nil),
37
+ startTime: options.fetch(:start_time, nil),
38
+ endTime: options.fetch(:end_time, nil),
39
+ recvWindow: recv_window,
40
+ timestamp: timestamp.to_i * 1000 # to milliseconds
41
+ }
42
+
43
+ response = safe do
44
+ RestClient.get "#{BASE_URL}/wapi/v3/depositHistory.html",
45
+ params: params_with_signature(params, api_secret),
46
+ 'X-MBX-APIKEY' => api_key
47
+ end
48
+
49
+ build_result response
50
+ end
51
+
52
+ def withdraw_history(asset, options = {})
53
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
54
+ timestamp = options.delete(:timestamp) || Time.now
55
+
56
+ params = {
57
+ asset: asset,
58
+ status: options.fetch(:status, nil),
59
+ startTime: options.fetch(:start_time, nil),
60
+ endTime: options.fetch(:end_time, nil),
61
+ recvWindow: recv_window,
62
+ timestamp: timestamp.to_i * 1000 # to milliseconds
63
+ }
64
+
65
+ response = safe do
66
+ RestClient.get "#{BASE_URL}/wapi/v3/withdrawHistory.html",
67
+ params: params_with_signature(params, api_secret),
68
+ 'X-MBX-APIKEY' => api_key
69
+ end
70
+
71
+ build_result response
72
+ end
73
+
74
+ def deposit_address(asset, options = {})
75
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
76
+ timestamp = options.delete(:timestamp) || Time.now
77
+
78
+ params = {
79
+ asset: asset,
80
+ status: options.fetch(:status, nil),
81
+ recvWindow: recv_window,
82
+ timestamp: timestamp.to_i * 1000 # to milliseconds
83
+ }
84
+
85
+ response = safe do
86
+ RestClient.get "#{BASE_URL}/wapi/v3/depositAddress.html",
87
+ params: params_with_signature(params, api_secret),
88
+ 'X-MBX-APIKEY' => api_key
89
+ end
90
+
91
+ build_result response
92
+ end
93
+
94
+ def withdraw_fee(asset, options = {})
95
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
96
+ timestamp = options.delete(:timestamp) || Time.now
97
+
98
+ params = {
99
+ asset: asset,
100
+ recvWindow: recv_window,
101
+ timestamp: timestamp.to_i * 1000 # to milliseconds
102
+ }
103
+
104
+ response = safe do
105
+ RestClient.get "#{BASE_URL}/wapi/v3/withdrawFee.html",
106
+ params: params_with_signature(params, api_secret),
107
+ 'X-MBX-APIKEY' => api_key
108
+ end
109
+
110
+ build_result response
111
+ end
112
+
113
+ def account_status(options = {})
114
+ recv_window = options.delete(:recv_window) || BinanceAPI.recv_window
115
+ timestamp = options.delete(:timestamp) || Time.now
116
+
117
+ params = {
118
+ recvWindow: recv_window,
119
+ timestamp: timestamp.to_i * 1000 # to milliseconds
120
+ }
121
+
122
+ response = safe do
123
+ RestClient.get "#{BASE_URL}/wapi/v3/accountStatus.html",
124
+ params: params_with_signature(params, api_secret),
125
+ 'X-MBX-APIKEY' => api_key
126
+ end
127
+
128
+ build_result response
129
+ end
130
+
131
+ def system_status
132
+ response = safe { RestClient.get("#{BASE_URL}/wapi/v3/systemStatus.html") }
133
+
134
+ json = JSON.parse(response.body, symbolize_names: true)
135
+ BinanceAPI::Result.new(json, response.code == 200)
136
+ end
137
+
138
+ protected
139
+
140
+ def build_result(response)
141
+ json = JSON.parse(response.body, symbolize_names: true)
142
+ BinanceAPI::Result.new(json, response.code == 200 && json.fetch(:success, false))
143
+ end
144
+
145
+ end
146
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: binance_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - osiutino
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-03-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rest-client
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: websocket-client-simple
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.3.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.3.0
83
+ description: A Binance API wrapper written in ruby
84
+ email:
85
+ - osiutino@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - CODE_OF_CONDUCT.md
94
+ - Gemfile
95
+ - Gemfile.lock
96
+ - LICENSE.txt
97
+ - README.md
98
+ - Rakefile
99
+ - bin/console
100
+ - bin/setup
101
+ - binance_api.gemspec
102
+ - config/config.yml.example
103
+ - lib/binance_api.rb
104
+ - lib/binance_api/base.rb
105
+ - lib/binance_api/rest.rb
106
+ - lib/binance_api/result.rb
107
+ - lib/binance_api/stream.rb
108
+ - lib/binance_api/version.rb
109
+ - lib/binance_api/wapi.rb
110
+ homepage: https://github.com/siutin/binance-api-ruby
111
+ licenses:
112
+ - MIT
113
+ metadata:
114
+ allowed_push_host: https://rubygems.org
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.6.13
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: unoffical Binance rubygem
135
+ test_files: []