andrewroth-btce 0.1.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/btce.rb +295 -0
  2. metadata +82 -0
data/lib/btce.rb ADDED
@@ -0,0 +1,295 @@
1
+ # Copyright (c) 2013, Christopher Mark Gore,
2
+ # Soli Deo Gloria,
3
+ # All rights reserved.
4
+ #
5
+ # 8729 Lower Marine Road, Saint Jacob, Illinois 62281 USA.
6
+ # Web: http://cgore.com
7
+ # Email: cgore@cgore.com
8
+ #
9
+ # Redistribution and use in source and binary forms, with or without
10
+ # modification, are permitted provided that the following conditions are met:
11
+ #
12
+ # * Redistributions of source code must retain the above copyright
13
+ # notice, this list of conditions and the following disclaimer.
14
+ #
15
+ # * Redistributions in binary form must reproduce the above copyright
16
+ # notice, this list of conditions and the following disclaimer in the
17
+ # documentation and/or other materials provided with the distribution.
18
+ #
19
+ # * Neither the name of Christopher Mark Gore nor the names of other
20
+ # contributors may be used to endorse or promote products derived from
21
+ # this software without specific prior written permission.
22
+ #
23
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
+ # POSSIBILITY OF SUCH DAMAGE.
34
+
35
+ require 'json'
36
+ require 'monkey-patch'
37
+ require 'net/http'
38
+ require 'net/https'
39
+ require 'openssl'
40
+ require 'uri'
41
+ require 'yaml'
42
+ require 'cgi'
43
+
44
+
45
+ module Btce
46
+ class API
47
+ BTCE_DOMAIN = "btc-e.com"
48
+ CURRENCIES = %w(btc
49
+ usd
50
+ rur
51
+ ltc
52
+ nmc
53
+ eur
54
+ nvc
55
+ trc
56
+ ppc
57
+ fnc)
58
+ CURRENCY_PAIRS = %w(btc_usd
59
+ btc_eur
60
+ btc_rur
61
+ ltc_btc
62
+ ltc_usd
63
+ ltc_rur
64
+ nmc_btc
65
+ usd_rur
66
+ eur_usd
67
+ nvc_btc
68
+ trc_btc
69
+ ppc_btc
70
+ ftc_btc)
71
+ MAX_DIGITS = {
72
+ "btc_usd" => 3,
73
+ "btc_eur" => 3,
74
+ "btc_rur" => 4,
75
+ "ltc_btc" => 5,
76
+ "ltc_usd" => 6,
77
+ "ltc_rur" => 4,
78
+ "nmc_btc" => 4,
79
+ "usd_rur" => 4,
80
+ "eur_usd" => 4,
81
+ "nvc_btc" => 4,
82
+ "trc_btc" => 4,
83
+ "ppc_btc" => 4,
84
+ "ftc_btc" => 4
85
+ }
86
+ KEY = YAML::load File.open 'btce-api-key.yml'
87
+
88
+ class << self
89
+ def get_https(url, params = nil, sign = nil)
90
+ raise ArgumentError if not url.is_a? String
91
+ uri = URI.parse url
92
+ http = Net::HTTP.new uri.host, uri.port
93
+ http.use_ssl = true
94
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
95
+ if params.nil?
96
+ request = Net::HTTP::Get.new uri.request_uri
97
+ else
98
+ # If sending params, then we want a post request for authentication.
99
+ request = Net::HTTP::Post.new uri.request_uri
100
+ request.add_field "Key", API::KEY['key']
101
+ request.add_field "Sign", sign
102
+ request.set_form_data params
103
+ end
104
+ response = http.request request
105
+ response.body
106
+ end
107
+
108
+ def get_json(url, params = nil, sign = nil)
109
+ result = get_https(url, params, sign)
110
+ if not result.is_a? String or not result.valid_json?
111
+ raise RuntimeError, "Server returned invalid data."
112
+ end
113
+ JSON.load result
114
+ end
115
+ end
116
+ end
117
+
118
+ class PublicAPI < API
119
+ OPERATIONS = %w(fee ticker trades depth)
120
+
121
+ class << self
122
+
123
+ def get_pair_operation_json(pair, operation)
124
+ raise ArgumentError if not API::CURRENCY_PAIRS.include? pair
125
+ raise ArgumentError if not OPERATIONS.include? operation
126
+ get_json "https://#{API::BTCE_DOMAIN}/api/2/#{pair}/#{operation}"
127
+ end
128
+
129
+ OPERATIONS.each do |operation|
130
+ class_eval %{
131
+ def get_pair_#{operation}_json(pair)
132
+ get_pair_operation_json pair, "#{operation}"
133
+ end
134
+ }
135
+
136
+ API::CURRENCY_PAIRS.each do |pair|
137
+ class_eval %{
138
+ def get_#{pair}_#{operation}_json
139
+ get_pair_#{operation}_json "#{pair}"
140
+ end
141
+ }
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ class PublicOperation
148
+ attr_reader :json, :operation, :pair
149
+
150
+ def initialize(operation, pair)
151
+ @operation = operation
152
+ @pair = pair
153
+ load_json
154
+ end
155
+
156
+ def load_json
157
+ @json = PublicAPI.get_pair_operation_json pair, operation
158
+ end
159
+ end
160
+
161
+ class Fee < PublicOperation
162
+ def initialize(pair)
163
+ super 'fee', pair
164
+ end
165
+
166
+ def trade
167
+ json["trade"]
168
+ end
169
+ end
170
+
171
+ class Ticker < PublicOperation
172
+ def initialize(pair)
173
+ super 'ticker', pair
174
+ end
175
+
176
+ JSON_METHODS = %w(high low avg vol vol_cur last buy sell server_time)
177
+
178
+ JSON_METHODS.each do |method|
179
+ class_eval %{
180
+ def #{method}
181
+ json["ticker"]["#{method}"] if json["ticker"] and json["ticker"].is_a? Hash
182
+ end
183
+ }
184
+ end
185
+
186
+ alias_method :bid, :buy
187
+ alias_method :offer, :sell
188
+ alias_method :ask, :sell
189
+ alias_method :average, :avg
190
+ alias_method :volume, :vol
191
+ alias_method :volume_current, :vol_cur
192
+
193
+ def spread
194
+ (offer - bid) / offer
195
+ end
196
+
197
+ def spread_percent
198
+ spread * 100.0
199
+ end
200
+ end
201
+
202
+ class Trade
203
+ attr_accessor :json
204
+
205
+ JSON_METHODS = %w(date price amount tid price_currency item trade_type)
206
+
207
+ attr_accessor *JSON_METHODS.map(&:to_sym)
208
+
209
+ class << self
210
+ def new_from_json(json)
211
+ result = Trade.new
212
+ result.json = json
213
+ if json.is_a? Hash
214
+ JSON_METHODS.each do |method|
215
+ instance_eval %{
216
+ result.#{method} = json["#{method}"]
217
+ }
218
+ end
219
+ end
220
+ result
221
+ end
222
+ end
223
+ end
224
+
225
+ class Trades < PublicOperation
226
+ attr_reader :all
227
+
228
+ def initialize(pair)
229
+ super 'trades', pair
230
+ load_trades
231
+ end
232
+
233
+ def load_trades
234
+ @all = json.map {|trade| Trade.new_from_json trade} if json.is_a? Array
235
+ end
236
+ private :load_trades
237
+
238
+ def [] *rest
239
+ all[*rest]
240
+ end
241
+ end
242
+
243
+ class Depth < PublicOperation
244
+ def initialize(pair)
245
+ super 'depth', pair
246
+ end
247
+ end
248
+
249
+ class TradeAPI < API
250
+ OPERATIONS = %w(getInfo
251
+ TransHistory
252
+ TradeHistory
253
+ OrderList
254
+ Trade
255
+ CancelOrder)
256
+
257
+ class << self
258
+ def sign(params)
259
+ data = params.collect do |key, value|
260
+ "#{key}=#{CGI::escape(value.to_s)}"
261
+ end.join('&')
262
+
263
+ # Sign data with the HMAC SHA-512 algorhythm
264
+ # Read https://btc-e.com/defines/documentation
265
+ OpenSSL::HMAC.hexdigest('sha512', API::KEY['secret'], data)
266
+ end
267
+
268
+ def trade_api_call(method, extra)
269
+ params = {"method" => method, "nonce" => nonce}
270
+ if ! extra.empty?
271
+ extra.each do |k,v|
272
+ params[k.to_s] = v
273
+ end
274
+ end
275
+ signed = sign params
276
+ get_json "https://#{API::BTCE_DOMAIN}/tapi", params, signed
277
+ end
278
+
279
+ def nonce
280
+ @nonce = 0 if @nonce.nil?
281
+ @nonce += 1
282
+ Time::now.to_i + @nonce
283
+ end
284
+ private :nonce
285
+
286
+ OPERATIONS.each do |operation|
287
+ class_eval %{
288
+ def #{operation.camelcase_to_snakecase} extra={}
289
+ trade_api_call "#{operation}", extra
290
+ end
291
+ }
292
+ end
293
+ end
294
+ end
295
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: andrewroth-btce
3
+ version: !ruby/object:Gem::Version
4
+ hash: 97
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 9
10
+ - 1
11
+ version: 0.1.9.1
12
+ platform: ruby
13
+ authors:
14
+ - Christopher Mark Gore
15
+ - Andrew Roth
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2013-07-26 00:00:00 -04:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: monkey-patch
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ hash: 3
32
+ segments:
33
+ - 0
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ description: A simple library to interface with the API for btc-e.com in Ruby.
38
+ email: andrewroth@gmail.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - lib/btce.rb
47
+ has_rdoc: true
48
+ homepage: https://github.com/cgore/ruby-btce
49
+ licenses: []
50
+
51
+ post_install_message:
52
+ rdoc_options: []
53
+
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ requirements: []
75
+
76
+ rubyforge_project:
77
+ rubygems_version: 1.5.3
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: A simple library to interface with the API for btc-e.com in Ruby.
81
+ test_files: []
82
+