excoin 0.0.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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +32 -0
  3. data/Gemfile +13 -0
  4. data/LICENSE.txt +674 -0
  5. data/README.md +278 -0
  6. data/Rakefile +9 -0
  7. data/config/config.example.yml +16 -0
  8. data/excoin.gemspec +26 -0
  9. data/lib/account/account.rb +116 -0
  10. data/lib/account/deposit.rb +20 -0
  11. data/lib/account/order.rb +43 -0
  12. data/lib/account/orders.rb +138 -0
  13. data/lib/account/trade.rb +26 -0
  14. data/lib/account/trades.rb +59 -0
  15. data/lib/account/wallet.rb +72 -0
  16. data/lib/account/withdrawal.rb +27 -0
  17. data/lib/exchange/candlestick_chart.rb +33 -0
  18. data/lib/exchange/candlestick_data.rb +20 -0
  19. data/lib/exchange/exchange.rb +75 -0
  20. data/lib/exchange/market.rb +50 -0
  21. data/lib/exchange/order.rb +23 -0
  22. data/lib/exchange/order_depth_chart.rb +41 -0
  23. data/lib/exchange/order_depth_data.rb +23 -0
  24. data/lib/exchange/orders.rb +119 -0
  25. data/lib/exchange/trade.rb +26 -0
  26. data/lib/exchange/trades.rb +68 -0
  27. data/lib/excoin.rb +45 -0
  28. data/lib/excoin/api.rb +212 -0
  29. data/lib/excoin/version.rb +10 -0
  30. data/spec/fixtures/cassette_library/account_cancel_order_erb.yml +59 -0
  31. data/spec/fixtures/cassette_library/account_issue_order_erb.yml +59 -0
  32. data/spec/fixtures/cassette_library/account_view_order_erb.yml +59 -0
  33. data/spec/fixtures/cassette_library/exc_recent_trades.yml +157 -0
  34. data/spec/fixtures/cassette_library/exc_recent_trades_count.yml +62 -0
  35. data/spec/fixtures/cassette_library/exc_recent_trades_timestamp.yml +142 -0
  36. data/spec/fixtures/cassette_library/exchange_candlestick_chart_data.yml +58 -0
  37. data/spec/fixtures/cassette_library/exchange_candlestick_chart_data_duration.yml +58 -0
  38. data/spec/fixtures/cassette_library/exchange_open_orders.yml +58 -0
  39. data/spec/fixtures/cassette_library/exchange_open_orders_type.yml +58 -0
  40. data/spec/fixtures/cassette_library/exchange_order_depth_chart_data.yml +58 -0
  41. data/spec/fixtures/cassette_library/excoin_wallet_reserves.yml +59 -0
  42. data/spec/fixtures/cassette_library/excoin_wallets_summary.yml +65 -0
  43. data/spec/fixtures/cassette_library/excoin_wallets_summary_coin.yml +59 -0
  44. data/spec/fixtures/cassette_library/multi_exchange_summ.yml +58 -0
  45. data/spec/fixtures/cassette_library/multi_exchange_summ_currency.yml +58 -0
  46. data/spec/fixtures/cassette_library/single_exchange_summ.yml +58 -0
  47. data/spec/fixtures/cassette_library/single_exchange_summary.yml +58 -0
  48. data/spec/lib/account/account_spec.rb +136 -0
  49. data/spec/lib/account/orders_spec.rb +51 -0
  50. data/spec/lib/account/trades_spec.rb +52 -0
  51. data/spec/lib/account/wallet_spec.rb +67 -0
  52. data/spec/lib/exchange/candlestick_chart_spec.rb +23 -0
  53. data/spec/lib/exchange/exchange_spec.rb +38 -0
  54. data/spec/lib/exchange/market_spec.rb +23 -0
  55. data/spec/lib/exchange/order_depth_chart_spec.rb +20 -0
  56. data/spec/lib/exchange/orders_spec.rb +47 -0
  57. data/spec/lib/exchange/trades_spec.rb +50 -0
  58. data/spec/lib/excoin/api_spec.rb +228 -0
  59. data/spec/lib/excoin_spec.rb +28 -0
  60. data/spec/spec_helper.rb +46 -0
  61. data/spec/support/vcr.rb +21 -0
  62. metadata +209 -0
@@ -0,0 +1,278 @@
1
+ # ExcoinWrapper
2
+
3
+ A wrapper for accessing the exchange and account API at exco.in.
4
+
5
+ ## Installation
6
+
7
+ To install with Bundler, add this line to your application's Gemfile:
8
+
9
+ gem 'excoin_wrapper', git: "https://github.com/excoinexchange/excoin_wrapper_ruby.git"
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or build and it install it yourself:
16
+
17
+ $ git clone https://github.com/excoinexchange/excoin_wrapper_ruby.git
18
+ $ cd excoin_wrapper_ruby
19
+ $ gem build excoin.gemspec
20
+ $ gem install ./excoin-0.0.1.gem
21
+
22
+ Finally, `require 'excoin'` in your application.
23
+
24
+ ## Usage
25
+
26
+ #### Basic Functions
27
+
28
+ Start by connecting to the API and setting your API key, secret, replay attack prevention strategy ("expire" or "nonce"), and replay attack prevention strategy parameter (expire time in seconds for expire, multiplier for nonce) : `Excoin.api(api_key, secret, replay_strategy, strategy_parameter)`. If you set your API authentication information in `~/.excoin/config.yml` or you aren't using a key (for example, if you're only pulling down general exchange data), you can skip this step and go straight to:
29
+
30
+ `Excoin.account` (API authentication required) to initialize a new Excoin::Account object and populate its data
31
+ `Excoin.market` to initialize a new Excoin::Market object with all associated exchanges and data
32
+ `Excoin.exchange(exchange_name)` to initialize a new Excoin::Market::Exchange object with data from a single trading pair
33
+
34
+ #### Account Functions
35
+
36
+ a = Excoin.account
37
+ => #<Excoin::Account:0x007f0000000000>
38
+
39
+ ##### Useful attributes and functions of the account class:
40
+ __class Excoin::Account__
41
+
42
+ attr_reader :name, :active_wallet_count, :active_wallets,
43
+ :inactive_wallet_count, :inactive_wallets,
44
+ :deposit_count, :withdrawal_count, :withdrawals,
45
+ :orders, :trades
46
+
47
+ order(order_id) # returns account order object with specified id
48
+ wallets # returns a hash of all wallets
49
+ wallet(currency) # returns the hash of the specified wallet
50
+ deposits(currency = nil) # returns a hash of all deposits, or all deposits
51
+ # matching currency
52
+
53
+ add_deposit(deposit_data) # adds new Deposit object to account.deposits
54
+ unconfirmed_deposits # returns a hash of all unconfirmed deposits
55
+ withdrawals(currency = nil) # returns a hash of all withdrawals, or all
56
+ # withdrawals matching currency
57
+
58
+ unconfirmed_withdrawals # returns a hash of all unconfirmed withdrawals
59
+ add_withdrawal(withdrawal_data)
60
+ # adds new Withdrawal object to account.withdrawals
61
+
62
+ update # updates account summary, orders, and trades
63
+ populate_account_summary # updates account summary data only
64
+
65
+ __class Excoin::Account::Deposit__
66
+
67
+ attr_reader :timestamp, :currency, :id, :address,
68
+ :amount, :confirmations, :confirmed
69
+
70
+ __class Excoin::Account::Withdrawal__
71
+
72
+ attr_reader :id, :timestamp, :currency, :address, :amount, :confirmed
73
+
74
+ __class Excoin::Account::Orders < Array__
75
+ An array of open account orders, grouped by exchange
76
+
77
+ add(order) # adds Account::Order object to Account::Orders object
78
+ delete(order_data) # deletes Order object matching order_data
79
+
80
+ all # returns all orders in one dimensional array
81
+ filter(attr, value, operator = :==)
82
+ # returns an array of all orders matching criteria
83
+
84
+ count(attr = nil, value = nil, operator = :==)
85
+ # returns count of all orders matching criteria
86
+
87
+ update(exchange_name = nil) # updates all account orders or orders
88
+ # on specified exchange
89
+
90
+ refresh # clears orders array and updates
91
+
92
+ >> a.orders.filter("currency_amount",0.01,:<)
93
+ => # returns all orders with currency_amount less than 0.01
94
+
95
+ __class Excoin::Account::Order__
96
+
97
+ attr_reader :currency, :commodity, :type, :id, :timestamp, :price,
98
+ :commodity_amount, :currency_amount, :status
99
+
100
+ exchange # returns associated Exchange object
101
+ refresh # refreshes single order data
102
+ cancel # cancels order
103
+
104
+ __class Excoin::Account::Trades < Array__
105
+ An array of the most recent trades on account (count default 100, up to 750)
106
+
107
+ buys # all buy trades in Trades object
108
+ sells # all sell trades in Trades object
109
+ highest(type = nil) # highest trade, or highest trade of *type*
110
+ lowest(type = nil) # lowest trade, or lowest trade of *type*
111
+ update(count = nil) # update Trades object with most recent trades
112
+ add(trade_data) # add new Trade object to Trades array
113
+ trim(n) # removes the n oldest trades from the Trades object
114
+
115
+ __class Excoin::Account::Trade__
116
+
117
+ attr_reader :timestamp, :currency, :commodity, :type, :price, :sent,
118
+ :received, :fee, :net_received
119
+
120
+ exchange # returns associated Exchange object
121
+
122
+ __class Excoin::Account::Wallet__
123
+
124
+ attr_reader :status, :currency, :deposit_address, :confirmed_balance,
125
+ :available_balance, :order_balance,
126
+ :pending_deposit_balance, :pending_withdrawal_balance,
127
+ :deposits, :withdrawals
128
+
129
+ update(wallet_data) # updates wallet with wallet_data
130
+ unconfirmed_deposits # returns hash of all unconfirmed deposits
131
+ unconfirmed_withdrawals # returns hash of all unconfirmed withdrawls
132
+ add_deposit(deposit_data) # adds new Deposit object to deposits hash
133
+ add_withdrawal(withdrawal_data) # adds new Withdrawal to withdrawals hash
134
+ withdraw(address, amount) # initiates withdrawal and adds it to
135
+ # Wallet object
136
+
137
+ #### Exchange Functions
138
+
139
+ >> e = Excoin.market.exchange("BTCBLK")
140
+ >> e = Excoin.exchange("BTCBLK")
141
+ => #<Excoin::Market::Exchange:0x007f8e13a71db0 @name="BTCBLK" ...>
142
+
143
+ ##### Useful attributes and functions of the exchange class:
144
+
145
+ __class Excoin::Market < Array__
146
+ An array of all Exchange objects on the Excoin market
147
+
148
+ exchanges(currency) # an array of all exchanges denomiated in currency
149
+ exchange(exchange_name) # selects Exchange object
150
+ update # updates all exchanges in Market array
151
+ update_orders # updates orders on all exchanges
152
+ refresh_all_data # clears and reinitializes all exchanges
153
+
154
+
155
+ __class Excoin::Market::Exchange__
156
+
157
+ attr_reader :name, :currency, :commodity, :last_price, :daily_high,
158
+ :daily_low, :daily_volume, :top_bid, :lowest_ask, :orders,
159
+ :trades, :spread
160
+
161
+ update # update exchange summary, orders, and trades
162
+ update_summary # update exchange summary only
163
+ issue_order(type, amount, price)
164
+ # place order of type "bid" or "ask"
165
+ # amount in units of currency for bids, and
166
+ # units of commodity for asks, price in units
167
+ # of currency
168
+
169
+ >> e.issue_order("bid", "0.25", "0.0003")
170
+ => # places bid order of 0.25 BTC for BLK at a price of 0.0003 BTC/BLK
171
+ # and adds order to e.orders and a.orders
172
+
173
+ >> e.issue_order("ask", 100, "0.00035")
174
+ => # places ask order selling 100 BLK at a price of 0.00035 BTC/BLK
175
+ # and adds order to e.orders and a.orders
176
+
177
+ __class Excoin::Market::Exchange::Orders__
178
+
179
+ attr_reader :bids, :asks, :all, :orders
180
+
181
+ add(order) # adds Exchange::Order object to Exchange::Orders object
182
+ remove(order_data) # removes an order matching order_data from Orders object
183
+ update(type = nil) # update all orders on exchange, or all orders
184
+ # of type
185
+ filter(attr, value, operator = :==)
186
+ # returns an array of all orders matching criteria
187
+ count(attr, value, operator = :==)
188
+ # returns the count of all orders matching criteria
189
+
190
+ __class Excoin::Market::Exchange::Order__
191
+
192
+ attr_reader :currency, :commodity, :type, :price,
193
+ :commodity_amount, :currency_amount
194
+
195
+ exchange # returns associated Exchange object
196
+
197
+ __class Excoin::Market::Exchange::Trades < Array__
198
+ An array of the most recent trades on exchange (count default 100, up to 750)
199
+
200
+ buys # all buy trades in Trades object
201
+ sells # all sell trades in Trades object
202
+ highest(type = nil) # highest trade, or highest trade of *type*
203
+ lowest(type = nil) # lowest trade, or lowest trade of *type*
204
+ update(limit_type = "count", limit = 100)
205
+ # update all trades on exchange, limited by
206
+ # limit_type: "count" or "timestamp"
207
+ # limit:
208
+ # integer <= 750 for "count"
209
+ # (time in UTC).to_i for "timestamp"
210
+ add(trade_data) # add new Trade object to Trades array
211
+ trim(n) # removes the n oldest trades from the Trades object
212
+
213
+ __class Excoin::Market::Exchange::Trade__
214
+
215
+ attr_reader :timestamp, :currency, :commodity, :type, :price,
216
+ :commodity_amount, :currency_amount
217
+
218
+ exchange # returns associated Exchange object
219
+
220
+ __class Excoin::Market::Exchange::OrderDepthChart__
221
+
222
+ attr_reader :currency, :commodity, :bid_orders, :ask_orders
223
+
224
+ update # updates all chart order data
225
+ exchange # returns associated Exchange object
226
+
227
+ __class Excoin::Market::Exchange::OrderDepthChart::DataPoint__
228
+
229
+ attr_reader :type, :currency_amount, :price
230
+
231
+ __class Excoin::Market::Exchange::CandlestickChart__
232
+
233
+ attr_reader :currency, :commodity, :datapoints
234
+
235
+ update # update datapoints
236
+ exchange # returns associated Exchange object
237
+
238
+ __class Excoin::Market::Exchange::CandlestickChart::DataPoint__
239
+
240
+ attr_reader :timestamp, :open, :close, :high, :low, :commodity_volume,
241
+ :currency_volume
242
+
243
+ #### API Functions
244
+ These are the base methods used by the wrapper to import the Excoin API's JSON data.
245
+
246
+ __class Excoin::API__
247
+
248
+ multiple_exchange_summary(currency = nil)
249
+ exchange_summary(currency, commodity)
250
+ exchange_recent_trades(currency, commodity, limit_type = "count", limit = 100)
251
+ exchange_open_orders(currency, commodity, type_or_count = nil)
252
+ exchange_candlestick_chart_data(currency, commodity, duration = nil)
253
+ exchange_order_depth_chart_data(currency, commodity)
254
+
255
+ account_summary
256
+ account_withdraw(currency, address, amount)
257
+ account_generate_deposit_address(coin)
258
+ account_trades(count = 100)
259
+ account_open_orders(currency = nil, commodity = nil, type = nil)
260
+ account_issue_order(currency, commodity, type, amount, price)
261
+ account_view_order(order_id)
262
+ account_view_order(order_id)
263
+
264
+ excoin_wallets_summary(coin = nil)
265
+ excoin_wallet_reserves(coin)
266
+
267
+ ### Troubleshooting
268
+ __Problem:__ Excoin.api.account_issue_order returns a 404.
269
+
270
+ __Solution:__ If the amount or price is very small, Ruby converts the number to scientific notation (i.e 1.809E-6). Passing the number as a string avoids this.
271
+
272
+ ## Contributing
273
+
274
+ 1. Fork it ( https://github.com/[my-github-username]/excoin_wrapper/fork )
275
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
276
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
277
+ 4. Push to the branch (`git push origin my-new-feature`)
278
+ 5. Create a new Pull Request
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ desc "Default: run specs."
5
+ task :default => :spec
6
+
7
+ desc "Run specs"
8
+ RSpec::Core::RakeTask.new
9
+
@@ -0,0 +1,16 @@
1
+ # Store application setting variables and sensitive information here.
2
+ # Rename this file to "config.yml" and move it to ~/.excoin/.
3
+
4
+ api_version: "1"
5
+ #api_key: "uncomment this line and paste your API key here"
6
+ #api_secret: "uncomment this line and paste your API secret here"
7
+ #live_api_key: "uncomment this line and paste your live API key here"
8
+
9
+ # API replay attack prevention strategy, can be "nonce" or "expire"
10
+ #api_replay_strategy: "expire"
11
+
12
+ # Multiplier for nonce, can be any positive integer
13
+ #nonce_multiplier: "uncomment and enter nonce multiplier if using nonce"
14
+
15
+ # Expire interval in seconds
16
+ #expire_interval: "uncomment and enter expire interval if using expire"
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'excoin/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "excoin"
8
+ spec.version = Excoin::VERSION
9
+ spec.authors = ["YT"]
10
+ spec.email = ["yt@exco.in"]
11
+ spec.summary = %q{A sophisticiated ruby wrapper for the excoin crypto currency exchange.}
12
+ spec.description = %q{Excoin wrapper provides all the basic API functionality with an additional abstraction to make accessing the data easier and more efficient. This will be used as a library for writing bots for the Excoin crypto currency exchange.}
13
+ spec.homepage = "https://exco.in"
14
+ spec.license = "GPL"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib","config"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rspec", "~> 3.1"
23
+ spec.add_development_dependency "rake", "~> 10.3"
24
+ spec.add_development_dependency "webmock", ">= 1.20.4"
25
+ spec.add_development_dependency "vcr", ">= 2.9.3"
26
+ end
@@ -0,0 +1,116 @@
1
+ class Excoin::Account
2
+ attr_reader :name, :active_wallet_count, :active_wallets,
3
+ :inactive_wallet_count, :inactive_wallets,
4
+ :deposit_count, :withdrawal_count, :orders, :trades
5
+
6
+ def initialize
7
+ self.populate_account_summary
8
+ self.orders
9
+ self.trades
10
+ end
11
+
12
+ def orders
13
+ @orders ||= Orders.new
14
+ end
15
+
16
+ def order(order_id)
17
+ self.orders.all.select{|order| order.id == order_id}[0]
18
+ end
19
+
20
+ def trades
21
+ @trades ||= Trades.new
22
+ end
23
+
24
+ def update
25
+ self.populate_account_summary
26
+ @orders.update
27
+ @trades.update
28
+ end
29
+
30
+ def populate_account_summary
31
+ begin
32
+ account_data = self.get_summary
33
+ @name = account_data['username']
34
+
35
+ @active_wallet_count = account_data['active_wallet_count']
36
+
37
+ @active_wallets = Hash.new
38
+ account_data['active_wallets'].each do |w|
39
+ @active_wallets.merge!({w['currency'] => Wallet.new(true, w)})
40
+ end
41
+
42
+ @inactive_wallet_count = account_data['inactive_wallet_count']
43
+
44
+ @inactive_wallets = Hash.new
45
+ account_data['inactive_wallets'].each do |w|
46
+ @inactive_wallets.merge!({w['currency'] => Wallet.new(false, w)})
47
+ end
48
+
49
+ @deposit_count = account_data['deposit_count']
50
+
51
+ account_data['deposits'].each do |deposit_data|
52
+ self.wallet(deposit_data['currency']).add_deposit(deposit_data)
53
+ end
54
+
55
+ @withdrawal_count = account_data['withdrawal_count']
56
+
57
+ account_data['withdrawals'].each do |withdrawal_data|
58
+ self.wallet(withdrawal_data['currency']).add_withdrawal(withdrawal_data)
59
+ end
60
+ rescue
61
+ puts "Error in Excoin::Account.populate_account_summary"
62
+ puts account_data
63
+ end
64
+ end
65
+
66
+ def wallets
67
+ if @inactive_wallets.size > 0
68
+ return @active_wallets.merge(@inactive_wallets)
69
+ else
70
+ return @active_wallets
71
+ end
72
+ end
73
+
74
+ def wallet(currency)
75
+ self.wallets[currency]
76
+ end
77
+
78
+ def deposits(currency = nil)
79
+ if currency
80
+ return self.wallet(currency).deposits
81
+ else
82
+ deposits = Hash.new
83
+ @active_wallets.each_pair do |wallet_currency, wallet|
84
+ deposits.merge!(wallet.deposits)
85
+ end
86
+ return deposits
87
+ end
88
+ end
89
+
90
+ def withdrawals(currency = nil)
91
+ if currency
92
+ return self.wallet(currency).withdrawals
93
+ else
94
+ withdrawals = Hash.new
95
+ @active_wallets.each_pair do |wallet_currency, wallet|
96
+ withdrawals.merge!(wallet.withdrawals)
97
+ end
98
+ return withdrawals
99
+ end
100
+ end
101
+
102
+ def unconfirmed_deposits
103
+ return self.deposits.select{|id, deposit_object| deposit_object.confirmed == false}
104
+ end
105
+
106
+ def unconfirmed_withdrawals
107
+ return self.withdrawals.select{|id, withdrawal_object| withdrawal_object.confirmed == false}
108
+ end
109
+
110
+ protected
111
+
112
+ def get_summary
113
+ Excoin.api.account_summary
114
+ end
115
+
116
+ end