gemini-rb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f8b6bdb4c745a5e128399dc907263c45cc246494
4
+ data.tar.gz: 51b0da98bbe215bd3f98d97cf181b50eefc6fa92
5
+ SHA512:
6
+ metadata.gz: e58aad70668f996a1ed5eba5b50615c25a739601dce52bb86cd3bbdadde40d13cdb514d700af39cf4c80d56ab963ad32921a05b7f738b1f283df67c365ca3bf5
7
+ data.tar.gz: 773a41a59776f1702ba415555aa215e255fab65e85fdefaa0dad47c0d240ef35eb72837546cb832431993e68dd1afb7cc435b2b0dc01d497c092b0eb8a9f20e9
@@ -0,0 +1,7 @@
1
+ module Gemini
2
+ # API logic for Version 1
3
+ module V1; end
4
+
5
+ # API logic for Version 2
6
+ module V2; end
7
+ end
@@ -0,0 +1,58 @@
1
+ module Gemini
2
+ module AuthenticatedConnection
3
+
4
+ private
5
+ def authenticated_post(url, options = {})
6
+ raise Gemini::InvalidAuthKeyError unless valid_key?
7
+ complete_url = build_url(url)
8
+ body = options[:params] || {}
9
+ nonce = new_nonce
10
+
11
+ payload = if config.api_version == 1
12
+ build_payload("/v1/#{url}", options[:params], nonce)
13
+ else
14
+ "/api#{complete_url}#{nonce}#{body.to_json}"
15
+ end
16
+
17
+ response = rest_connection.post do |req|
18
+ req.url complete_url
19
+ req.body = body.to_json
20
+ req.options.timeout = config.rest_timeout
21
+ req.options.open_timeout = config.rest_open_timeout
22
+ req.headers['Content-Type'] = 'application/json'
23
+ req.headers['Accept'] = 'application/json'
24
+
25
+ if config.api_version == 1
26
+ req.headers['X-GEMINI-PAYLOAD'] = payload
27
+ req.headers['X-GEMINI-SIGNATURE'] = sign(payload)
28
+ req.headers['X-GEMINI-APIKEY'] = config.api_key
29
+ else
30
+ # TODO: Verify if this applies to Gemini.
31
+ req.headers['gemini-nonce'] = nonce
32
+ req.headers['gemini-signature'] = sign(payload)
33
+ req.headers['gemini-apikey'] = config.api_key
34
+ end
35
+ end
36
+ end
37
+
38
+ def build_payload(url, params = {}, nonce)
39
+ payload = {}
40
+ payload['nonce'] = nonce
41
+ payload['request'] = url
42
+ payload.merge!(params) if params
43
+ Base64.strict_encode64(payload.to_json)
44
+ end
45
+
46
+ def new_nonce
47
+ (Time.now.to_f * 10_000).to_i.to_s
48
+ end
49
+
50
+ def sign(payload)
51
+ OpenSSL::HMAC.hexdigest('sha384', config.secret, payload)
52
+ end
53
+
54
+ def valid_key?
55
+ !! (config.api_key && config.secret)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,38 @@
1
+ module Gemini
2
+ class Client
3
+ include Gemini::RestConnection
4
+ include Gemini::WebsocketConnection
5
+ include Gemini::AuthenticatedConnection
6
+ include Gemini::Configurable
7
+
8
+
9
+ def initialize
10
+ if config.api_version == 1
11
+ extend Gemini::V1::TickerClient
12
+ extend Gemini::V1::TradesClient
13
+ extend Gemini::V1::FundingBookClient
14
+ extend Gemini::V1::OrderbookClient
15
+ extend Gemini::V1::StatsClient
16
+ extend Gemini::V1::LendsClient
17
+ extend Gemini::V1::SymbolsClient
18
+ extend Gemini::V1::AccountInfoClient
19
+ extend Gemini::V1::DepositClient
20
+ extend Gemini::V1::OrdersClient
21
+ extend Gemini::V1::PositionsClient
22
+ extend Gemini::V1::HistoricalDataClient
23
+ extend Gemini::V1::MarginFundingClient
24
+ extend Gemini::V1::WalletClient
25
+ else
26
+ extend Gemini::V2::TickerClient
27
+ extend Gemini::V2::StatsClient
28
+ extend Gemini::V2::UtilsClient
29
+ extend Gemini::V2::PersonalClient
30
+ extend Gemini::V2::TradingClient
31
+ extend Gemini::V2::MarginClient
32
+ end
33
+
34
+ @mutex = Mutex.new
35
+ @c_counter = 1
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,48 @@
1
+ module Gemini
2
+ module Configurable
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ def config
8
+ self.class.config
9
+ end
10
+
11
+ module ClassMethods
12
+ def configure
13
+ yield config
14
+ end
15
+
16
+ def config
17
+ @configuration ||= Configuration.new
18
+ end
19
+ end
20
+ end
21
+
22
+ class Configuration
23
+ attr_accessor :api_endpoint, :debug, :debug_connection, :secret
24
+ attr_accessor :api_key, :websocket_api_endpoint, :rest_timeout
25
+ attr_accessor :reconnect, :reconnect_after, :rest_open_timeout
26
+ attr_accessor :api_version
27
+
28
+ def initialize
29
+ self.api_endpoint = "https://api.gemini.com/v1/"
30
+ self.websocket_api_endpoint = "wss://api.gemini.com/ws"
31
+ self.debug = false
32
+ self.reconnect = true
33
+ self.reconnect_after = 60
34
+ self.rest_timeout = 30
35
+ self.rest_open_timeout = 30
36
+ self.debug_connection = false
37
+ self.api_version = 1
38
+ end
39
+
40
+ # Helper that configure to version 2
41
+ def use_api_v2
42
+ self.api_version = 2
43
+ self.api_endpoint = "https://api.gemini.com/v2/"
44
+ self.websocket_api_endpoint = "wss://api.gemini.com/ws/2/"
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,52 @@
1
+ require 'logger'
2
+ module Gemini
3
+ # Network Layer for API Rest client
4
+ module RestConnection
5
+ private
6
+ # Make an HTTP GET request
7
+ def get(url, params={})
8
+ rest_connection.get do |req|
9
+ req.url build_url(url)
10
+ req.headers['Content-Type'] = 'application/json'
11
+ req.headers['Accept'] = 'application/json'
12
+ params.each do |k,v|
13
+ req.params[k] = v
14
+ end
15
+ req.options.timeout = config.rest_timeout
16
+ req.options.open_timeout = config.rest_open_timeout
17
+ end
18
+ end
19
+
20
+ # Make sure parameters are allowed for the HTTP call
21
+ def check_params(params, allowed_params)
22
+ if (params.keys - allowed_params).empty?
23
+ return params
24
+ else
25
+ raise Gemini::ParamsError
26
+ end
27
+ end
28
+
29
+ def rest_connection
30
+ @conn ||= new_rest_connection
31
+ end
32
+
33
+ def build_url(url)
34
+ URI.join(config.api_endpoint, url).path
35
+ end
36
+
37
+ def new_rest_connection
38
+ Faraday.new(url: base_api_endpoint) do |conn|
39
+ conn.use Gemini::CustomErrors
40
+ conn.response :logger, Logger.new(STDOUT) , bodies: true if config.debug_connection
41
+ conn.use FaradayMiddleware::ParseJson, :content_type => /\bjson$/
42
+ conn.adapter :net_http
43
+ end
44
+ end
45
+
46
+ def base_api_endpoint
47
+ url = URI.parse config.api_endpoint
48
+ "#{url.scheme}://#{url.host}:#{url.port}"
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,35 @@
1
+ require 'faraday'
2
+
3
+ module Gemini
4
+ class ClientError < Exception; end
5
+ class ParamsError < ClientError; end
6
+ class InvalidAuthKeyError < ClientError; end
7
+ class BlockMissingError < ParamsError; end
8
+ class ServerError < Exception; end # Error reported back by Binfinex server
9
+ class ConnectionClosed < Exception; end
10
+ class BadRequestError < ServerError; end
11
+ class NotFoundError < ServerError; end
12
+ class ForbiddenError < ServerError; end
13
+ class UnauthorizedError < ServerError; end
14
+ class InternalServerError < ServerError; end
15
+ class WebsocketError < ServerError; end
16
+
17
+ class CustomErrors < Faraday::Response::Middleware
18
+ def on_complete(env)
19
+ case env[:status]
20
+ when 400
21
+ raise BadRequestError, env.body['message']
22
+ when 401
23
+ raise UnauthorizedError, env.body['message']
24
+ when 403
25
+ raise ForbiddenError, env.body['message']
26
+ when 404
27
+ raise NotFoundError, env.body['message']
28
+ when 500
29
+ raise InternalServerError, env.body['message']
30
+ else
31
+ super
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ module Gemini
2
+ module V1::AccountInfoClient
3
+
4
+ # Get account information
5
+ #
6
+ # @return [Hash] your account information
7
+ # @example:
8
+ # client.account_info
9
+ def account_info
10
+ resp = authenticated_post("account_infos")
11
+ resp.body
12
+ end
13
+
14
+
15
+ # Call block passing all account related specific messages sent via websocket
16
+ #
17
+ # @param block [Block] The code to be executed when new message is received
18
+ # @example:
19
+ # client.listen_account do |message|
20
+ # puts message.inspect
21
+ # end
22
+ def listen_account(&block)
23
+ raise BlockMissingError unless block_given?
24
+ ws_auth(&block)
25
+ end
26
+
27
+ # See the fees applied to your withdrawals
28
+ #
29
+ # @return [Hash]
30
+ # @example:
31
+ # client.fees
32
+ def fees
33
+ resp = authenticated_post("fees")
34
+ resp.body
35
+ end
36
+ end
37
+
38
+ end
@@ -0,0 +1,23 @@
1
+ module Gemini
2
+ module V1::DepositClient
3
+
4
+ # Return your deposit address to make a new deposit.
5
+ #
6
+ # @param method [string] Method of deposit (methods accepted: “bitcoin”, “litecoin”, “darkcoin”, “mastercoin” (tethers)).
7
+ # @param wallet_name [string] Wallet to deposit in (accepted: “trading”, “exchange”, “deposit”). Your wallet needs to already exist
8
+ # @params renew [integer] (optional) Default is 0. If set to 1, will return a new unused deposit address
9
+ #
10
+ # @return [Hash] confirmation of your deposit
11
+ # @example:
12
+ # client.deposit("bitcoin", "exchange")
13
+ def deposit method, wallet_name, renew=0
14
+ params = {
15
+ method: method,
16
+ wallet_name: wallet_name,
17
+ renew: renew
18
+ }
19
+
20
+ authenticated_post("deposit/new", params: params).body
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ module Gemini
2
+ module V1::FundingBookClient
3
+
4
+ # Get the full margin funding book
5
+
6
+ # @param currency [string] (optional) Speficy the currency, default "USD"
7
+ # @param params :limit_bids [int] (optional) Limit the number of funding bids returned. May be 0 in which case the array of bids is empty.
8
+ # @param params :limit_asks [int] (optional) Limit the number of funding offers returned. May be 0 in which case the array of asks is empty.
9
+ # @return [Hash] of :bids and :asks arrays
10
+ # @example:
11
+ # client.funding_book
12
+ def funding_book(currency="usd", params = {})
13
+ check_params(params, %i{limit_bids limit_asks})
14
+ get("lendbook/#{currency}", params: params).body
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,53 @@
1
+ module Gemini
2
+ module V1::HistoricalDataClient
3
+
4
+ # View all of your balance ledger entries.
5
+ #
6
+ # @param currency [string] (optional) Specify the currency, default "USD"
7
+ # @param params :since [time] (optional) Return only the history after this timestamp.
8
+ # @param params :until [time] (optional) Return only the history before this timestamp.
9
+ # @param params :limit [int] (optional) Limit the number of entries to return. Default is 500.
10
+ # @param params :wallet [string] (optional) Return only entries that took place in this wallet. Accepted inputs are: “trading”, “exchange”, “deposit”
11
+ # @return [Array]
12
+ # @example:
13
+ # client.history
14
+ def history(currency="usd", params = {})
15
+ check_params(params, %i{since until limit wallet})
16
+ params.merge!({currency: currency})
17
+ authenticated_post("history", params: params).body
18
+ end
19
+
20
+ # View your past deposits/withdrawals.
21
+ #
22
+ # @param currency [string] (optional) Specify the currency, default "USD"
23
+ # @param params :method (optional) The method of the deposit/withdrawal (can be “bitcoin”, “litecoin”, “darkcoin”, “wire”)
24
+ # @param params :since (optional) Return only the history after this timestamp
25
+ # @param params :until [time] (optional) Return only the history before this timestamp.
26
+ # @param params :limit [int] (optional) Limit the number of entries to return. Default is 500.
27
+ # @return [Array]
28
+ # @example:
29
+ # client.movements
30
+ def movements(currency="usd", params = {})
31
+ check_params(params, %i{method since until limit})
32
+ params.merge!({currency: currency})
33
+ authenticated_post("history/movements", params: params).body
34
+ end
35
+
36
+ # View your past trades.
37
+ #
38
+ # @param symbol The pair traded (BTCUSD, LTCUSD, LTCBTC)
39
+ # @param params :until [time] (optional) Return only the history before this timestamp.
40
+ # @param params :timestamp [time] (optional) Trades made before this timestamp won’t be returned
41
+ # @param params :until [time] (optional) Trades made after this timestamp won’t be returned
42
+ # @param params :limit_trades [int] Limit the number of trades returned. Default is 50.
43
+ # @param params :reverse [int] Return trades in reverse order (the oldest comes first). Default is returning newest trades first.
44
+ # @return [Array]
45
+ # @example:
46
+ # client.mytrades
47
+ def mytrades(symbol, params = {})
48
+ check_params(params, %i{until limit_trades reverse timestamp})
49
+ params.merge!({symbol: symbol})
50
+ authenticated_post("mytrades", params: params).body
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ module Gemini
2
+ module V1::LendsClient
3
+
4
+ # Get a list of the most recent funding data for the given currency: total amount provided and Flash Return Rate (in % by 365 days) over time.
5
+ #
6
+ # @param currency [string] (optional) Specify the currency, default "USD"
7
+ # @param params :timestamp [time] (optional) Only show data at or after this timestamp
8
+ # @param params :limit_lends [int] (optional) Limit the amount of funding data returned. Must be > 1, default 50
9
+ # @return [Array]
10
+ # @example:
11
+ # client.lends
12
+ def lends(currency = "usd", params = {})
13
+ check_params(params, %i{timestamp limit_lends})
14
+ get("lends/#{currency}", params: params).body
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,103 @@
1
+ module Gemini
2
+ module V1::MarginFundingClient
3
+
4
+ # Submit a new offer
5
+ #
6
+ # @param currency [string] The name of the currency, es: 'USD'
7
+ # @param amount [decimal] Offer size: how much to lend or borrow
8
+ # @param rate [decimal] Rate to lend or borrow at. In percentage per 365 days.
9
+ # Set to 0 for FRR, ±delta for FRR±delta.
10
+ # @param period [integer] Number of days of the funding contract (in days)
11
+ # @param direction [string] Either “lend” or “loan”
12
+ # @param frrdelta [bool] If true, the rate represents ±delta to FRR.
13
+ # @return [Hash]
14
+ # @example:
15
+ # client.new_offer("btc", 10.0, 20, 365, "lend")
16
+ def new_offer(currency, amount, rate, period, direction, frrdelta=false)
17
+ params = {
18
+ currency: currency,
19
+ amount: amount.to_s,
20
+ rate: rate.to_s,
21
+ period: period.to_i,
22
+ direction: direction,
23
+ frrdelta: !!frrdelta
24
+ }
25
+ authenticated_post("offer/new", params: params).body
26
+ end
27
+
28
+ # Cancel an offer
29
+ #
30
+ # @param offer_id [int] The offer ID given by `#new_offer`
31
+ # @return [Hash]
32
+ # @example:
33
+ # client.cancel_offer(1000)
34
+ def cancel_offer(offer_id)
35
+ authenticated_post("offer/cancel", params: {offer_id: offer_id.to_i}).body
36
+ end
37
+
38
+ # Get the status of an offer. Is it active? Was it cancelled? To what extent has it been executed? etc.
39
+ #
40
+ # @param offer_id [int] The offer ID give by `#new_offer`
41
+ # @return [Hash]
42
+ # @example:
43
+ # client.offer_status(1000)
44
+ def offer_status(offer_id)
45
+ authenticated_post("offer/status", params: {offer_id: offer_id.to_i}).body
46
+ end
47
+
48
+ # View your funds currently taken (active credits)
49
+ #
50
+ # @return [Array]
51
+ # @example:
52
+ # client.credits
53
+ def credits
54
+ authenticated_post("credits").body
55
+ end
56
+
57
+ # View your active offers
58
+ #
59
+ # @return [Array] An array of the results of /offer/status for all your live offers (lending or borrowing
60
+ # @example:
61
+ # client.offers
62
+ def offers
63
+ authenticated_post("offers").body
64
+ end
65
+
66
+ # View your funding currently borrowed and used in a margin position
67
+ #
68
+ # @return [Array] An array of your active margin funds
69
+ # @example:
70
+ # client.taken_funds
71
+ def taken_funds
72
+ authenticated_post("taken_funds").body
73
+ end
74
+
75
+ # View your funding currently borrowed and not used (available for a new margin position).
76
+ #
77
+ # @return [Array] An array of your active unused margin funds
78
+ # @example:
79
+ # client.unused_taken_funds
80
+ def unused_taken_funds
81
+ authenticated_post("unused_taken_funds").body
82
+ end
83
+
84
+ # View the total of your active funding used in your position(s).
85
+ #
86
+ # @return [Array] An array of your active funding
87
+ # @example:
88
+ # client.total_taken_funds
89
+ def total_taken_funds
90
+ authenticated_post("total_taken_funds").body
91
+ end
92
+
93
+ # Allow you to close an unused or used taken fund
94
+ #
95
+ # @param swap_id [int] The ID given by `#taken_funds` or `#unused_taken_funds
96
+ # @return [Hash]
97
+ # @example:
98
+ # client.close_funding(1000)
99
+ def close_funding(swap_id)
100
+ authenticated_post("funding/close", params: {swap_id: swap_id.to_i}).body
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ module Gemini
3
+ module V1::OrderbookClient
4
+
5
+ # Get the full order book
6
+ #
7
+ # @param symbol [string]
8
+ # @param params :limit_bids [int] (optional) Limit the number of bids returned. May be 0 in which case the array of bids is empty. Default 50.
9
+ # @param params :limit_asks [int] (optional) Limit the number of asks returned. May be 0 in which case the array of asks is empty. Default 50.
10
+ # @param params :group [0/1] (optional) If 1, orders are grouped by price in the orderbook. If 0, orders are not grouped and sorted individually. Default 1
11
+ # @return [Hash] :bids [Array], :asks [Array]
12
+ # @example:
13
+ # client.orderbook("btcusd")
14
+ def orderbook(symbol="btcusd", params = {})
15
+ check_params(params, %i{limit_bids limit_asks group})
16
+ get("book/#{symbol}", params: params).body
17
+ end
18
+
19
+
20
+ # Get the order book changes using websocket
21
+ #
22
+ # @param pair [string]
23
+ # @param prec [string] Level of price aggregation (P0, P1, P2, P3). The default is P0.
24
+ # @param freq [string] Frequency of updates (F0, F1, F2, F3). F0=realtime / F1=2sec / F2=5sec / F3=10sec
25
+ # @param len [int] Number of price points (“25”, “100”) [default=“25”]
26
+ # @param block [Block] The code to be executed when a new order is submitted
27
+ # @example:
28
+ # client.listen_book do |order|
29
+ # puts order.inspect
30
+ # end
31
+ def listen_book(pair="BTCUSD", prec='P0', freq='F0',len=25, &block)
32
+ raise BlockMissingError unless block_given?
33
+ register_channel pair:pair, channel: 'book', prec: prec, freq: freq, len: len, &block
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,121 @@
1
+ module Gemini
2
+ module V1::OrdersClient
3
+
4
+ # Submit a new order
5
+ # @param symbol [string] The name of the symbol (see `#symbols`)
6
+ # @param amount [decimal] Order size: how much to buy or sell
7
+ # @param type [string] Either “market” / “limit” / “stop” / “trailing-stop” / “fill-or-kill” / “exchange market” / “exchange limit” / “exchange stop” / “exchange trailing-stop” / “exchange fill-or-kill”. (type starting by “exchange ” are exchange orders, others are margin trading orders)
8
+ # @param side [string] Either “buy” or “sell”
9
+ # @param price [decimal] Price to buy or sell at. Must be positive. Use random number for market orders.
10
+ # @param params :is_hidden [bool] (optional) true if the order should be hidden. Default is false
11
+ # @param params :is_postonly [bool] (optional) true if the order should be post only. Default is false. Only relevant for limit orders
12
+ # @param params :ocoorder [bool] Set an additional STOP OCO order that will be linked with the current order
13
+ # @param params :buy_price_oco [decimal] If ocoorder is true, this field represent the price of the OCO stop order to place
14
+ # @return [Hash]
15
+ # @example:
16
+ # client.new_order("usdbtc", 100, "market", "sell", 0)
17
+ def new_order(symbol, amount, type, side, price = nil, params = {})
18
+ check_params(params, %i{is_hidden is_postonly ocoorder buy_price_oco})
19
+
20
+ # for 'market' order, we need to pass a random positive price, not nil
21
+ price ||= 0.001 if type == "market" || type == "exchange market"
22
+
23
+ params.merge!({
24
+ symbol: symbol,
25
+ amount: amount.to_s,
26
+ type: type,
27
+ side: side,
28
+ exchange: 'gemini',
29
+ price: "%.10f" % price.to_f.round(10) # Decimalize float price (necessary for small numbers)
30
+ })
31
+ authenticated_post("order/new", params: params).body
32
+ end
33
+
34
+ # Submit several new orders at once
35
+ #
36
+ # @param orders [Array] Array of Hash with the following elements
37
+ # @param orders :symbol [string] The name of the symbol
38
+ # @param orders :amount [decimal] Order size: how much to buy or sell
39
+ # @param orders :price [decimal] Price to buy or sell at. May omit if a market order
40
+ # @param orders :exchange [string] "gemini"
41
+ # @param orders :side [string] Either “buy” or “sell”
42
+ # @param orders :type [string] Either “market” / “limit” / “stop” / “trailing-stop” / “fill-or-kill”
43
+ # @return [Hash] with a `object_id` that is an `Array`
44
+ # @example:
45
+ # client.multiple_orders([{symbol: "usdbtc", amount: 10, price: 0, exchange: "gemini", side: "buy", type: "market"}])
46
+ def multiple_orders(orders)
47
+ authenticated_post("order/new/multi", params: orders).body
48
+ end
49
+
50
+ # Cancel an order
51
+ #
52
+ # @param ids [Array] or [integer] or nil
53
+ # if it's Array it's supposed to specify a list of IDS
54
+ # if it's an integer it's supposed to be a single ID
55
+ # if it's not specified it deletes all the orders placed
56
+ # @return [Hash]
57
+ # @example
58
+ # client.cancel_orders([100,231,400])
59
+ def cancel_orders(ids=nil)
60
+ case ids
61
+ when Array
62
+ authenticated_post("order/cancel/multi", params: {order_ids: ids.map(&:to_i)}).body
63
+ when Numeric, String
64
+ authenticated_post("order/cancel", params: {order_id: ids.to_i}).body
65
+ when NilClass
66
+ authenticated_post("order/cancel/all").body
67
+ else
68
+ raise ParamsError
69
+ end
70
+ end
71
+
72
+ # Replace an orders with a new one
73
+ #
74
+ # @param id [int] the ID of the order to replace
75
+ # @param symbol [string] the name of the symbol
76
+ # @param amount [decimal] Order size: how much to buy or sell
77
+ # @param type [string] Either “market” / “limit” / “stop” / “trailing-stop” / “fill-or-kill” / “exchange market” / “exchange limit” / “exchange stop” / “exchange trailing-stop” / “exchange fill-or-kill”. (type starting by “exchange ” are exchange orders, others are margin trading orders)
78
+ # @param side [string] Either “buy” or “sell”
79
+ # @param price [decimal] Price to buy or sell at. May omit if a market order
80
+ # @param is_hidden [bool] (optional) true if the order should be hidden. Default is false
81
+ # @param use_remaining [bool] (optional) will use the amount remaining of the canceled order as the amount of the new order. Default is false
82
+ # @return [Hash] the order
83
+ # @example:
84
+ # client.replace_order(100,"usdbtc", 10, "market", "buy", 0)
85
+ def replace_order(id, symbol, amount, type, side, price, is_hidden=false, use_remaining=false)
86
+ params = {
87
+ order_id: id.to_i,
88
+ symbol: symbol,
89
+ amount: amount.to_s,
90
+ type: type,
91
+ side: side,
92
+ exchange: 'gemini',
93
+ is_hidden: is_hidden,
94
+ use_remaining: use_remaining,
95
+ price: price.to_s
96
+ }
97
+ authenticated_post("order/cancel/replace", params: params).body
98
+ end
99
+
100
+ # Get the status of an order. Is it active? Was it cancelled? To what extent has it been executed? etc.
101
+ #
102
+ # @param id
103
+ # @return [Hash]
104
+ # @exmaple:
105
+ # client.order_status(100)
106
+ def order_status(id)
107
+ authenticated_post("order/status", params: {order_id: id.to_i}).body
108
+ end
109
+
110
+
111
+ # View your active orders.
112
+ #
113
+ # @return [Hash]
114
+ # @example:
115
+ # client.orders
116
+ def orders
117
+ authenticated_post("orders").body
118
+ end
119
+
120
+ end
121
+ end