hitbtc 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 +7 -0
- data/.gitignore +3 -0
- data/Gemfile +6 -0
- data/README.md +249 -0
- data/hitbtc.gemspec +27 -0
- data/key.yml.example +2 -0
- data/lib/hitbtc.rb +2 -0
- data/lib/hitbtc/client.rb +240 -0
- data/lib/hitbtc/version.rb +3 -0
- metadata +135 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 288b1ba6e06ecc47a81cdf1f0914447c092063db
|
|
4
|
+
data.tar.gz: 40fc742b57d7501897a123a2a2f5c6e08fb511a4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 749a1ef4ad43b2d88ec7a006c5b4bf40f972ff7d6de4da8b1b0adc51d8d9abfff927f1e00b78f048fc600dfacfdf6d6f3af84bc1ad46ddac7da618d9f870f314
|
|
7
|
+
data.tar.gz: 8cbdeef9e634273e7a2a7b0a20eb4f81c44b5e2bd10c457b2a35a2976dde01fbda37dedb4ce53b80429b1af41de03f205d40541684f01037e043e2c87b76b60c
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
This document provides the complete reference for [hitbtc](https://hitbtc.com) API in the wrapper.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
The following symbols are traded on hitbtc exchange.
|
|
7
|
+
|
|
8
|
+
| Symbol | Lot size | Price step
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| BTCUSD | 0.01 BTC | 0.01 |
|
|
11
|
+
| BTCEUR | 0.01 BTC | 0.01 |
|
|
12
|
+
| LTCBTC | 0.1 LTC | 0.00001 |
|
|
13
|
+
| LTCUSD | 0.1 LTC | 0.001 |
|
|
14
|
+
| LTCEUR | 0.1 LTC | 0.001 |
|
|
15
|
+
| EURUSD | 1 EUR | 0.0001 |
|
|
16
|
+
|
|
17
|
+
Size representation:
|
|
18
|
+
* Size values in streaming messages are represented in lots.
|
|
19
|
+
* Size values in RESTful market data are represented in money (e.g. in coins or in USD).
|
|
20
|
+
* Size values in RESTful trade are represented in lots (e.g. 1 means 0.01 BTC for BTCUSD)
|
|
21
|
+
|
|
22
|
+
### Pending Future Updates
|
|
23
|
+
|
|
24
|
+
- Solid trade execution functionality
|
|
25
|
+
- payment api
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Add this line to your application's Gemfile:
|
|
30
|
+
|
|
31
|
+
gem 'hitbtc'
|
|
32
|
+
|
|
33
|
+
And then execute:
|
|
34
|
+
|
|
35
|
+
$ bundle
|
|
36
|
+
|
|
37
|
+
Or install it yourself as:
|
|
38
|
+
|
|
39
|
+
$ gem install hitbtc
|
|
40
|
+
|
|
41
|
+
## Usage
|
|
42
|
+
|
|
43
|
+
Create a Kraken client:
|
|
44
|
+
|
|
45
|
+
```ruby
|
|
46
|
+
API_KEY = '3bH+M/nLp......'
|
|
47
|
+
API_SECRET = 'wQG+7Lr9b.....'
|
|
48
|
+
|
|
49
|
+
hitbtc = Hitbtc::Client.new(API_KEY, API_SECRET)
|
|
50
|
+
|
|
51
|
+
time = hitbtc.server_time
|
|
52
|
+
time #=> 1393056191
|
|
53
|
+
```
|
|
54
|
+
### Public Data Methods
|
|
55
|
+
|
|
56
|
+
#### Server Time
|
|
57
|
+
```ruby
|
|
58
|
+
time = hitbtc.server_time
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
#### Symbol info
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
symbol = hitbtc.symbols("BTCEUR")
|
|
65
|
+
symbols = hitbtc.symbols(["BTCEUR", "BTCUSD"])
|
|
66
|
+
all_symbols = hitbtc.symbols
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
#### Ticker
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
ticker_data = hitbtc.ticker('BTCEUR')
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
* 24h means last 24h + last incomplete minute
|
|
76
|
+
* high - highest trade price / 24 h
|
|
77
|
+
* low - lowest trade price / 24 h
|
|
78
|
+
* volume - volume / 24h
|
|
79
|
+
|
|
80
|
+
#### Order Book
|
|
81
|
+
|
|
82
|
+
```ruby
|
|
83
|
+
order_book = hitbtc.order_book('BTCEUR')
|
|
84
|
+
order_book = hitbtc.order_book('BTCEUR', {format_amount_unit: "lot"})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
| Parameter | Type | Description |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| format_price | optional, "string" (default) or "number" | |
|
|
90
|
+
| format_amount | optional, "string" (default) or "number" | |
|
|
91
|
+
| format_amount_unit | optional, "currency" (default) or "lot" | |
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
#### Trades
|
|
95
|
+
|
|
96
|
+
```ruby
|
|
97
|
+
trades = hitbtc.trades "BTCEUR" (default from 1 day ago, by timestamp, index 0, max_result 1000)
|
|
98
|
+
trades = hitbtc.trades 'BTCEUR', (Time.now - 1.day).to_i, "ts", 0, 1000)
|
|
99
|
+
trades = hitbtc.trades 'BTCEUR', (Time.now - 1.day).to_i, "ts", 0, 1000, {format_amount_unit: "lot"})
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Parameters:
|
|
103
|
+
|
|
104
|
+
| Parameter | Type | Description |
|
|
105
|
+
| --- | --- | --- |
|
|
106
|
+
| from | required, int, trade_id or timestamp | returns trades with trade_id > specified trade_id <br> returns trades with timestamp >= specified timestamp |
|
|
107
|
+
| till | optional, int, trade_id or timestamp | returns trades with trade_id < specified trade_id <br> returns trades with timestamp < specified timestamp |
|
|
108
|
+
| by | required, filter and sort by `trade_id` or `ts` (timestamp) | |
|
|
109
|
+
| sort | optional, `asc` (default) or `desc` | |
|
|
110
|
+
| start_index | required, int | zero-based |
|
|
111
|
+
| max_results | required, int, max value = 1000 | |
|
|
112
|
+
| format_item | optional, "array" (default) or "object" | |
|
|
113
|
+
| format_price | optional, "string" (default) or "number" | |
|
|
114
|
+
| format_amount | optional, "string" (default) or "number" | |
|
|
115
|
+
| format_amount_unit | optional, "currency" (default) or "lot" | |
|
|
116
|
+
| format_tid | optional, "string" or "number" (default) | |
|
|
117
|
+
| format_timestamp | optional, "millisecond" (default) or "second" | |
|
|
118
|
+
| format_wrap | optional, "true" (default) or "false" | |
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
### Private Data Methods
|
|
122
|
+
|
|
123
|
+
#### Error codes
|
|
124
|
+
|
|
125
|
+
RESTful Trading API can return the following errors:
|
|
126
|
+
|
|
127
|
+
| HTTP code | Text | Description |
|
|
128
|
+
| --- | --- | --- |
|
|
129
|
+
| 403 | Invalid apikey | API key doesn't exist or API key is currently used on another endpoint (max last 15 min) |
|
|
130
|
+
| 403 | Nonce has been used | nonce is not monotonous |
|
|
131
|
+
| 403 | Nonce is not valid | too big number or not a number |
|
|
132
|
+
| 403 | Wrong signature | |
|
|
133
|
+
|
|
134
|
+
#### Execution reports
|
|
135
|
+
|
|
136
|
+
The API uses `ExecutionReport` as an object that represents change of order status.
|
|
137
|
+
|
|
138
|
+
The following fields are used in this object:
|
|
139
|
+
|
|
140
|
+
| Field | Description | Type / Enum | Required |
|
|
141
|
+
| --- | --- | --- | --- |
|
|
142
|
+
| orderId | Order ID on the Exchange | string | required |
|
|
143
|
+
| clientOrderId | clientOrderId sent in NewOrder message | string | required |
|
|
144
|
+
| execReportType | execution report type | `new` <br> `canceled` <br> `rejected` <br> `expired` <br> `trade` <br> `status` | required |
|
|
145
|
+
| orderStatus | order status | `new` <br> `partiallyFilled` <br> `filled` <br> `canceled` <br> `rejected` <br> `expired` | required |
|
|
146
|
+
| orderRejectReason | Relevant only for the orders in rejected state | `unknownSymbol` <br> `exchangeClosed` <br>`orderExceedsLimit` <br> `unknownOrder` <br> `duplicateOrder` <br> `unsupportedOrder` <br> `unknownAccount` <br> `other`| for rejects |
|
|
147
|
+
| symbol | | string, e.g. `BTCUSD` | required |
|
|
148
|
+
| side | | `buy` or `sell` | required |
|
|
149
|
+
| timestamp | UTC timestamp in milliseconds | | |
|
|
150
|
+
| price | | decimal | |
|
|
151
|
+
| quantity | | integer | required |
|
|
152
|
+
| type | | only `limit` orders are currently supported | required |
|
|
153
|
+
| timeInForce | time in force | `GTC` - Good-Til-Canceled <br>`IOK` - Immediate-Or-Cancel<br>`FOK` - Fill-Or-Kill<br>`DAY` - day orders< | required |
|
|
154
|
+
| tradeId | Trade ID on the exchange | | for trades |
|
|
155
|
+
| lastQuantity | | integer | for trades |
|
|
156
|
+
| lastPrice | | decimal | for trades |
|
|
157
|
+
| leavesQuantity | | integer | |
|
|
158
|
+
| cumQuantity | | integer | |
|
|
159
|
+
| averagePrice | | decimal, will be 0 if 'cumQuantity'=0 | |
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
#### Balance
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
all_balance = hitbtc.balance
|
|
166
|
+
one_balance = hitbtc.balance("BTC")
|
|
167
|
+
many_balances = hitbtc.balance(["BTC", "EUR"])
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### List of active orders
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
all_active_orders = hitbtc.active_orders
|
|
174
|
+
symbol_specific_orders = hitbtc.active_orders({symbols: "BTCEUR"})
|
|
175
|
+
symbols_specific_orders = hitbtc.active_orders({symbols: "BTCEUR,BTCUSD"})
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Parameters:
|
|
179
|
+
|
|
180
|
+
| Parameter | Type | Description |
|
|
181
|
+
| --- | --- | --- |
|
|
182
|
+
| symbols | string, comma-delimeted list of symbols, optional, default - all symbols | |
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
#### Create Order
|
|
186
|
+
|
|
187
|
+
price should be specified even for market execution (haven't tested on a real order yet)
|
|
188
|
+
|
|
189
|
+
```ruby
|
|
190
|
+
hitbtc.create_order({symbol: "BTCEUR", side: "buy", quantity: 1, type: "market", timeInForce: "GTC", price: 320.000})
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Parameters:
|
|
194
|
+
|
|
195
|
+
| Parameter | Type | Description |
|
|
196
|
+
| --- | --- | --- |
|
|
197
|
+
| symbol | string, required | e.g. `BTCUSD` |
|
|
198
|
+
| side | `buy` or `sell`, required | |
|
|
199
|
+
| price | decimal, required | order price, required for limit orders |
|
|
200
|
+
| quantity | int | order quantity in lots |
|
|
201
|
+
| type | `limit` or `market` | order type |
|
|
202
|
+
| timeInForce | `GTC` - Good-Til-Canceled <br>`IOK` - Immediate-Or-Cancel<br>`FOK` - Fill-Or-Kill<br>`DAY` - day | use `GTC` by default |
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
#### Cancel Order
|
|
207
|
+
|
|
208
|
+
You only need your order id (haven't been tested on real order yet)
|
|
209
|
+
|
|
210
|
+
```ruby
|
|
211
|
+
hitbtc.cancel_order("1398804347")
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
#### Trades History
|
|
215
|
+
|
|
216
|
+
```ruby
|
|
217
|
+
default = hitbtc.trade_history
|
|
218
|
+
custom = hitbtc.trade_history({by: "ts", start_index: 0, max_results: 10, symbols: "BTCEUR,BTCUSD"})
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Parameters:
|
|
222
|
+
|
|
223
|
+
| Parameter | Type | Description |
|
|
224
|
+
| --- | --- | --- |
|
|
225
|
+
| `by` | `trade_id` or `ts` (timestamp) | |
|
|
226
|
+
| `start_index` | int, optional, default(0) | zero-based index |
|
|
227
|
+
| `max_results` | int, required, <=1000 | |
|
|
228
|
+
| `symbols` | string, comma-delimited | |
|
|
229
|
+
| `sort` | `asc` (default) or `desc` | |
|
|
230
|
+
| `from` | optional | start `trade_id` or `ts`, see `by` |
|
|
231
|
+
| `till` | optional | end `trade_id` or `ts`, see `by` |
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
#### Recent Orders
|
|
235
|
+
|
|
236
|
+
```ruby
|
|
237
|
+
default = hitbtc.recent_orders
|
|
238
|
+
custom = hitbtc.trade_history({start_index: 0, max_results: 10, symbols: "BTCEUR,BTCUSD", statuses: "new,filled"})
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Parameters:
|
|
242
|
+
|
|
243
|
+
| Parameter | Type | Description |
|
|
244
|
+
| --- | --- | --- |
|
|
245
|
+
| `start_index` | int, optional, default(0) | zero-based index |
|
|
246
|
+
| `max_results` | int, required, <=1000 | |
|
|
247
|
+
| `symbols` | string, comma-delimited | |
|
|
248
|
+
| `statuses` | string, comma-delimited, `new`, `partiallyFilled`, `filled`, `canceled`, `expired`, `rejected` | |
|
|
249
|
+
|
data/hitbtc.gemspec
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'hitbtc/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "hitbtc"
|
|
8
|
+
spec.version = HitbtcRuby::VERSION
|
|
9
|
+
spec.authors = ["Julien Hobeika"]
|
|
10
|
+
spec.email = ["julien.hobeika@gmail.com"]
|
|
11
|
+
spec.description = %q{"Wrapper for hitbtc Exchange API"}
|
|
12
|
+
spec.summary = %q{"Wrapper for hitbtc Exchange API"}
|
|
13
|
+
spec.homepage = "https://github.com/jhk753/hitbtc_ruby"
|
|
14
|
+
|
|
15
|
+
spec.files = `git ls-files`.split($/)
|
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
18
|
+
spec.require_paths = ["lib"]
|
|
19
|
+
|
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
|
21
|
+
spec.add_development_dependency "rake"
|
|
22
|
+
spec.add_development_dependency "rspec"
|
|
23
|
+
|
|
24
|
+
spec.add_dependency "httparty"
|
|
25
|
+
spec.add_dependency "hashie"
|
|
26
|
+
spec.add_dependency "addressable"
|
|
27
|
+
end
|
data/key.yml.example
ADDED
data/lib/hitbtc.rb
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
require 'httparty'
|
|
2
|
+
require 'hashie'
|
|
3
|
+
require 'Base64'
|
|
4
|
+
require 'addressable/uri'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module Hitbtc
|
|
8
|
+
class Client
|
|
9
|
+
include HTTParty
|
|
10
|
+
|
|
11
|
+
def initialize(api_key=nil, api_secret=nil, options={})
|
|
12
|
+
@api_key = api_key || YAML.load_file("key.yml")["key"]
|
|
13
|
+
@api_secret = api_secret || YAML.load_file("key.yml")["secret"]
|
|
14
|
+
@api_version = options[:version] ||= '1'
|
|
15
|
+
@base_uri = options[:base_uri] ||= 'api.hitbtc.com'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
###########################
|
|
19
|
+
###### Public Data ########
|
|
20
|
+
###########################
|
|
21
|
+
|
|
22
|
+
def server_time
|
|
23
|
+
mash = get_public 'time'
|
|
24
|
+
mash.try(:timestamp)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def symbols(opts={}) #can specify array of string symbols
|
|
28
|
+
mash = get_public 'symbols'
|
|
29
|
+
m = mash.try(:symbols)
|
|
30
|
+
if (opts.length == 1 || opts.class == String) && m != mash
|
|
31
|
+
m.select{|h| opts.include?(h.symbol)}.first
|
|
32
|
+
elsif !opts.empty? && m != mash
|
|
33
|
+
m.select{|h| opts.include?(h.symbol)}
|
|
34
|
+
else
|
|
35
|
+
m
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def ticker symbol
|
|
40
|
+
checked_symbol = check_symbol(symbol)
|
|
41
|
+
get_public(checked_symbol+"/ticker")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def order_book symbol, opts={}
|
|
45
|
+
checked_symbol = check_symbol(symbol)
|
|
46
|
+
#opts optional
|
|
47
|
+
#format_price: "string" (default) or "number"
|
|
48
|
+
#format_amount: "string" (default) or "number"
|
|
49
|
+
#format_amount_unit: "currency" (default) or "lot"
|
|
50
|
+
get_public(checked_symbol+"/orderbook", opts)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def trades symbol, from = (Time.now - 1.day).to_i, by = "ts", start_index = 0, max_results = 1000, opts={}
|
|
54
|
+
checked_symbol = check_symbol(symbol)
|
|
55
|
+
#Parameter Type Description
|
|
56
|
+
#from required int = trade_id or timestamp returns trades with trade_id > specified trade_id or returns trades with timestamp >= specified timestamp
|
|
57
|
+
#till optional int = trade_id or timestamp returns trades with trade_id < specified trade_id or returns trades with timestamp < specified timestamp
|
|
58
|
+
#by required filter and sort by trade_id or ts (timestamp)
|
|
59
|
+
#sort optional asc (default) or desc
|
|
60
|
+
#start_index required int zero-based
|
|
61
|
+
#max_results required int, max value = 1000
|
|
62
|
+
#format_item optional "array" (default) or "object"
|
|
63
|
+
#format_price optional "string" (default) or "number"
|
|
64
|
+
#format_amount optional "string" (default) or "number"
|
|
65
|
+
#format_amount_unit optional "currency" (default) or "lot"
|
|
66
|
+
#format_tid optional "string" or "number" (default)
|
|
67
|
+
#format_timestamp optional "millisecond" (default) or "second"
|
|
68
|
+
#format_wrap optional "true" (default) or "false"
|
|
69
|
+
if by != "trade_id" && by != "ts"
|
|
70
|
+
raise "3rd parameter by, should be 'trade_id' or 'ts'"
|
|
71
|
+
end
|
|
72
|
+
opts[:from] = from
|
|
73
|
+
opts[:start_index] = start_index
|
|
74
|
+
opts[:max_results] = max_results
|
|
75
|
+
opts[:by] = by
|
|
76
|
+
mash= get_public(checked_symbol+'/trades', opts)
|
|
77
|
+
mash.try(:trades)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def get_public(method, opts={})
|
|
81
|
+
url = 'http://'+ @base_uri + '/api/' + @api_version + '/public/' + method
|
|
82
|
+
r = self.class.get(url, query: opts)
|
|
83
|
+
Hashie::Mash.new(JSON.parse(r.body))
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
######################
|
|
87
|
+
##### Private Data ###
|
|
88
|
+
######################
|
|
89
|
+
|
|
90
|
+
def balance opts={} #array of string currency
|
|
91
|
+
mash = get_private 'balance'
|
|
92
|
+
m = mash.try(:balance)
|
|
93
|
+
if opts.class == String
|
|
94
|
+
o = []
|
|
95
|
+
o << opts
|
|
96
|
+
opts = o
|
|
97
|
+
end
|
|
98
|
+
if m != mash && opts.length > 0
|
|
99
|
+
r= m.select{|c| opts.include?(c.currency_code)}
|
|
100
|
+
(r.length==1 ? r.first : r)
|
|
101
|
+
else
|
|
102
|
+
m
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def active_orders opts={} #symbols: string comma-delimeted list of symbols, optional, default - all symbols
|
|
107
|
+
#example {:symbols=> "BTCEUR,BTCUSD"}
|
|
108
|
+
mash = get_private 'orders/active', opts
|
|
109
|
+
mash.try(:orders)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def cancel_order client_order_id
|
|
113
|
+
orders = active_orders
|
|
114
|
+
order = orders.select{|o| o.orderId == client_order_id}.try(:first)
|
|
115
|
+
if order.nil?
|
|
116
|
+
"We didn't find the order for the specified ID"
|
|
117
|
+
else
|
|
118
|
+
opts = {}
|
|
119
|
+
opts[:clientOrderId] = order.orderId
|
|
120
|
+
opts[:cancelRequestClientOrderId] = Time.now.to_i.to_s
|
|
121
|
+
opts[:symbol] = order.symbol
|
|
122
|
+
opts[:side] = order.side
|
|
123
|
+
opts[:price] = order.orderPrice
|
|
124
|
+
opts[:quantity] = order.orderQuantity
|
|
125
|
+
opts[:type] = order.limit
|
|
126
|
+
opts[:timeInForce] = order.timeInForce
|
|
127
|
+
|
|
128
|
+
get_private 'cancel_order', opts
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def trade_history opts={by:"ts", start_index: 0, max_results: 10}
|
|
133
|
+
mash= get_private 'trades', opts
|
|
134
|
+
mash.try(:trades)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def recent_orders opts={max_results: 10, start_index: 0, statuses: "new,partiallyFilled,filled,canceled,expired,rejected"}
|
|
138
|
+
mash = get_private 'orders/recent', opts
|
|
139
|
+
mash.try(:orders)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
#### Private User Trading (Still experimental!) ####
|
|
143
|
+
def create_order opts={}
|
|
144
|
+
opts[:clientOrderId] = Time.now.to_i.to_s
|
|
145
|
+
post_private 'new_order', opts
|
|
146
|
+
end
|
|
147
|
+
######################
|
|
148
|
+
##### Payment Data ###
|
|
149
|
+
######################
|
|
150
|
+
|
|
151
|
+
# to be written
|
|
152
|
+
|
|
153
|
+
#######################
|
|
154
|
+
#### Generate Signed ##
|
|
155
|
+
##### Post Request ####
|
|
156
|
+
#######################
|
|
157
|
+
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
def post_private(method, opts={})
|
|
161
|
+
post_data = encode_options(opts)
|
|
162
|
+
uri = "/api/"+ @api_version + "/trading/" + method +"?" + "apikey=" + @api_key + "&nonce=" + nonce
|
|
163
|
+
url = "https://" + @base_uri + uri
|
|
164
|
+
signature = generate_signature(uri, post_data)
|
|
165
|
+
headers = {'X-Signature' => signature}
|
|
166
|
+
r = self.class.post(url, {headers: headers, body: post_data}).parsed_response
|
|
167
|
+
Hashie::Mash.new(r)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def get_private(method, opts={})
|
|
171
|
+
opts = complete_opts(opts)
|
|
172
|
+
uri = "/api/"+ @api_version + "/trading/" + method +"?" + encode_options(opts)
|
|
173
|
+
url = "https://" + @base_uri + uri
|
|
174
|
+
signature = generate_signature(uri, "")
|
|
175
|
+
headers = {'X-Signature' => signature}
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
r = self.class.get(url, {headers: headers})
|
|
180
|
+
mash = Hashie::Mash.new(JSON.parse(r.body))
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def complete_opts opts
|
|
184
|
+
opts[:apikey] = @api_key
|
|
185
|
+
opts[:nonce] = nonce
|
|
186
|
+
opts
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def nonce
|
|
190
|
+
Time.now.to_i.to_s
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def encode_options(opts)
|
|
194
|
+
uri = Addressable::URI.new
|
|
195
|
+
uri.query_values = opts
|
|
196
|
+
uri.query
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def generate_signature(uri, post_data)
|
|
200
|
+
message = generate_message(uri, post_data)
|
|
201
|
+
generate_hmac(@api_secret, message)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def generate_message(uri, data)
|
|
205
|
+
uri + data
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def generate_hmac(key, message)
|
|
209
|
+
OpenSSL::HMAC.hexdigest('SHA512', key, message).downcase
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def check_symbol symbol
|
|
213
|
+
if symbol.length != 6 || symbol.class != String
|
|
214
|
+
raise "You didn't enter a correct symbol, check symbols method to see list and enter symbol as a string"
|
|
215
|
+
end
|
|
216
|
+
symbol.upcase
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def random_string
|
|
220
|
+
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
##################################
|
|
224
|
+
##### Realtime with web socket ###
|
|
225
|
+
##################################
|
|
226
|
+
|
|
227
|
+
# to be written
|
|
228
|
+
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
class Hashie::Mash
|
|
233
|
+
def try key
|
|
234
|
+
if self.key?(key.to_s)
|
|
235
|
+
self[key]
|
|
236
|
+
else
|
|
237
|
+
self
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: hitbtc
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Julien Hobeika
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-04-29 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.3'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ~>
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.3'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '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: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: httparty
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - '>='
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: hashie
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - '>='
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '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'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: addressable
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - '>='
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - '>='
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
description: '"Wrapper for hitbtc Exchange API"'
|
|
98
|
+
email:
|
|
99
|
+
- julien.hobeika@gmail.com
|
|
100
|
+
executables: []
|
|
101
|
+
extensions: []
|
|
102
|
+
extra_rdoc_files: []
|
|
103
|
+
files:
|
|
104
|
+
- .gitignore
|
|
105
|
+
- Gemfile
|
|
106
|
+
- README.md
|
|
107
|
+
- hitbtc.gemspec
|
|
108
|
+
- key.yml.example
|
|
109
|
+
- lib/hitbtc.rb
|
|
110
|
+
- lib/hitbtc/client.rb
|
|
111
|
+
- lib/hitbtc/version.rb
|
|
112
|
+
homepage: https://github.com/jhk753/hitbtc_ruby
|
|
113
|
+
licenses: []
|
|
114
|
+
metadata: {}
|
|
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.2.2
|
|
132
|
+
signing_key:
|
|
133
|
+
specification_version: 4
|
|
134
|
+
summary: '"Wrapper for hitbtc Exchange API"'
|
|
135
|
+
test_files: []
|