gemini-rb 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.
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