bitmex-api 0.0.2 → 0.0.3
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 +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +36 -1
- data/README.md +104 -15
- data/TODOs.org +12 -3
- data/bin/chat.rb +11 -0
- data/bin/whales-watching.rb +2 -2
- data/bitmex.gemspec +3 -0
- data/lib/bitmex.rb +16 -1
- data/lib/bitmex/apikey.rb +45 -0
- data/lib/bitmex/base.rb +26 -0
- data/lib/bitmex/chat.rb +57 -0
- data/lib/bitmex/client.rb +186 -61
- data/lib/bitmex/instrument.rb +53 -0
- data/lib/bitmex/order.rb +78 -0
- data/lib/bitmex/position.rb +77 -0
- data/lib/bitmex/quote.rb +32 -0
- data/lib/bitmex/stats.rb +35 -0
- data/lib/bitmex/trade.rb +41 -0
- data/lib/bitmex/user.rb +37 -11
- data/lib/bitmex/version.rb +1 -1
- data/lib/bitmex/websocket.rb +67 -0
- metadata +55 -2
data/lib/bitmex/client.rb
CHANGED
@@ -8,91 +8,176 @@ module Bitmex
|
|
8
8
|
include HTTParty
|
9
9
|
# logger ::Logger.new(STDOUT), :debug, :curl
|
10
10
|
|
11
|
-
ANNOUNCEMENT_ARGS = %w(urgent).freeze
|
12
|
-
APIKEY_ARGS = %w().freeze
|
13
|
-
CHAT_ARGS = %w(channels connected).freeze
|
14
|
-
EXECUTION_ARGS = %w(tradehistory).freeze
|
15
|
-
FUNDING_ARGS = %w().freeze
|
16
|
-
GLOBALNOTIFICATION_ARGS = %w().freeze
|
17
|
-
INSTRUMENT_ARGS = %w(active activeandindices activeintervals compositeindex indices).freeze
|
18
|
-
INSURANCE_ARGS = %w().freeze
|
19
|
-
LEADERBOARD_ARGS = %w().freeze
|
20
|
-
LIQUIDATION_ARGS = %w().freeze
|
21
|
-
ORDER_ARGS = %w().freeze
|
22
|
-
ORDERBOOK_ARGS = %w(L2).freeze
|
23
|
-
POSITION_ARGS = %w().freeze
|
24
|
-
QUOTE_ARGS = %w(bucketed).freeze
|
25
|
-
SCHEMA_ARGS = %w(websockethelp).freeze
|
26
|
-
SETTLEMENT_ARGS = %w().freeze
|
27
|
-
STATS_ARGS = %w(history historyusd).freeze
|
28
|
-
TRADE_ARGS = %w(bucketed).freeze
|
29
|
-
|
30
|
-
TESTNET_HOST = 'testnet.bitmex.com'.freeze
|
31
|
-
MAINNET_HOST = 'www.bitmex.com'.freeze
|
32
|
-
|
33
11
|
AUTHORIZATIONS = %w(apikey execution position globalnotification order leaderboard quote user userevent)
|
34
12
|
|
35
13
|
attr_reader :host, :api_key, :api_secret
|
36
14
|
|
15
|
+
# Create new client instance
|
16
|
+
# @param testnet [Boolean] true for testnet network
|
17
|
+
# @param api_key [String] the api key
|
18
|
+
# @param api_secret [String] the api secret
|
37
19
|
def initialize(testnet: false, api_key: nil, api_secret: nil)
|
38
20
|
@host = testnet ? TESTNET_HOST : MAINNET_HOST
|
39
21
|
@api_key = api_key
|
40
22
|
@api_secret = api_secret
|
41
23
|
end
|
42
24
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
25
|
+
# Get site announcements
|
26
|
+
# @return [Array] the public announcements
|
27
|
+
def announcements
|
28
|
+
get base_path(:announcement) do |response|
|
29
|
+
response_handler response
|
48
30
|
end
|
49
31
|
end
|
50
32
|
|
51
|
-
#
|
52
|
-
#
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
def listen(options, &ablock)
|
57
|
-
EM.run do
|
58
|
-
ws = Faye::WebSocket::Client.new realtime_url
|
33
|
+
# Persistent API Keys for Developers
|
34
|
+
# @return [Bitmex::Apikey] the apikey instance
|
35
|
+
def apikey(api_key = nil)
|
36
|
+
Bitmex::Apikey.new self, api_key
|
37
|
+
end
|
59
38
|
|
60
|
-
|
61
|
-
|
62
|
-
|
39
|
+
# Trollbox Data
|
40
|
+
# @return [Bitmex::Chat] the chat instance
|
41
|
+
def chat
|
42
|
+
Bitmex::Chat.new self
|
43
|
+
end
|
63
44
|
|
64
|
-
|
65
|
-
|
66
|
-
|
45
|
+
# Tradeable Contracts, Indices, and History
|
46
|
+
# @return [Bitmex::Instrument] the instrument model
|
47
|
+
def instrument
|
48
|
+
Bitmex::Instrument.new self
|
49
|
+
end
|
67
50
|
|
68
|
-
|
69
|
-
|
70
|
-
|
51
|
+
# Get funding history
|
52
|
+
# @!macro bitmex.filters
|
53
|
+
# @return [Array] the history
|
54
|
+
def funding(filters = {})
|
55
|
+
get base_path(:funding), params: filters do |response|
|
56
|
+
response_handler response
|
57
|
+
end
|
58
|
+
end
|
71
59
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
60
|
+
# Get insurance fund history
|
61
|
+
# @!macro bitmex.filters
|
62
|
+
# @return [Array] the history
|
63
|
+
def insurance(filters = {})
|
64
|
+
get base_path(:insurance), params: filters do |response|
|
65
|
+
response_handler response
|
66
|
+
end
|
67
|
+
end
|
80
68
|
|
81
|
-
|
82
|
-
|
83
|
-
|
69
|
+
# Get current leaderboard
|
70
|
+
# @param ranking [notional ROE] the ranking type
|
71
|
+
# @return [Array] current leaders
|
72
|
+
def leaderboard(ranking = 'notional')
|
73
|
+
get base_path(:leaderboard), params: { method: ranking } do |response|
|
74
|
+
response_handler response
|
75
|
+
end
|
76
|
+
end
|
84
77
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
78
|
+
# Get liquidation orders
|
79
|
+
# @!macro bitmex.filters
|
80
|
+
# @return [Array] the liquidations
|
81
|
+
def liquidations(filters = {})
|
82
|
+
get base_path(:liquidation), params: filters do |response|
|
83
|
+
response_handler response
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Order Placement, Cancellation, Amending, and History
|
88
|
+
# @return [Bitmex::Order] the order model
|
89
|
+
def orders
|
90
|
+
# TODO: use class method
|
91
|
+
Bitmex::Order.new(self)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Get an order by id
|
95
|
+
# @param orderID [String] the order #
|
96
|
+
# @param clOrdID [String] the client order #
|
97
|
+
# @return [Bitmex::Order] the order model
|
98
|
+
def order(orderID: nil, clOrdID: nil)
|
99
|
+
raise ArgumentError, 'either orderID or clOrdID is required' if orderID.nil? && clOrdID.nil?
|
100
|
+
|
101
|
+
Bitmex::Order.new(self, orderID, clOrdID)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Get current orderbook in vertical format
|
105
|
+
# @param symbol [String] instrument symbol, send a series (e.g. XBT) to get data for the nearest contract in that series
|
106
|
+
# @param depth [Integer] orderbook depth per side. send 0 for full depth.
|
107
|
+
# @return [Array] the orderbook
|
108
|
+
def orderbook(symbol, depth: 25)
|
109
|
+
params = { symbol: symbol, depth: depth }
|
110
|
+
get base_path('orderbook/L2'), params: params do |response|
|
111
|
+
response_handler response
|
89
112
|
end
|
90
113
|
end
|
91
114
|
|
115
|
+
# Summary of Open and Closed Positions
|
116
|
+
# @return [Array] the list of positions
|
117
|
+
def positions
|
118
|
+
# TODO: use class method
|
119
|
+
Bitmex::Position.new(self).all
|
120
|
+
end
|
121
|
+
|
122
|
+
# Get an open position
|
123
|
+
# @param symbol [String] symbol of position
|
124
|
+
# @return [Bitmex::Position] open position
|
125
|
+
def position(symbol)
|
126
|
+
Bitmex::Position.new(self, symbol)
|
127
|
+
end
|
128
|
+
|
129
|
+
# Best Bid/Offer Snapshots & Historical Bins
|
130
|
+
# @return [Bitmex::Quote] the quote model
|
131
|
+
def quotes
|
132
|
+
# TODO: use class method
|
133
|
+
Bitmex::Quote.new self
|
134
|
+
end
|
135
|
+
|
136
|
+
# Get model schemata for data objects returned by this AP
|
137
|
+
# @return [Hash] the schema
|
138
|
+
def schema
|
139
|
+
get base_path(:schema) do |response|
|
140
|
+
response_handler response
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Get settlement history
|
145
|
+
# @return [Array] the settlement history
|
146
|
+
def settlement
|
147
|
+
get base_path(:settlement) do |response|
|
148
|
+
response_handler response
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Exchange statistics
|
153
|
+
# @return [Bitmex::Stats] the stats model
|
154
|
+
def stats
|
155
|
+
Bitmex::Stats.new self
|
156
|
+
end
|
157
|
+
|
158
|
+
# Individual and bucketed trades
|
159
|
+
# @return [Bitmex::Trade] the trade model
|
160
|
+
def trades
|
161
|
+
Bitmex::Trade.new self
|
162
|
+
end
|
163
|
+
|
164
|
+
# Account operations
|
165
|
+
# @return [Bitmex::User] the user model
|
92
166
|
def user
|
93
167
|
Bitmex::User.new self
|
94
168
|
end
|
95
169
|
|
170
|
+
# Listen to generic topics
|
171
|
+
# @param topics [Hash] topics to listen to e.g. { trade: "XBTUSD" }
|
172
|
+
# @yield [data] data pushed via websocket
|
173
|
+
def listen(topics, &ablock)
|
174
|
+
EM.run do
|
175
|
+
topics.each do |topic, symbol|
|
176
|
+
websocket.subscribe topic, symbol, &ablock
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
96
181
|
#
|
97
182
|
# Stop websocket listener
|
98
183
|
#
|
@@ -100,7 +185,12 @@ module Bitmex
|
|
100
185
|
EM.stop_event_loop
|
101
186
|
end
|
102
187
|
|
103
|
-
def
|
188
|
+
def websocket
|
189
|
+
@websocket ||= Websocket.new realtime_url
|
190
|
+
end
|
191
|
+
|
192
|
+
# TODO: move these methods into rest client
|
193
|
+
def get(path, params: {}, auth: false, &ablock)
|
104
194
|
options = {}
|
105
195
|
options[:query] = params unless params.empty?
|
106
196
|
options[:headers] = headers 'GET', path, '' if auth
|
@@ -117,10 +207,45 @@ module Bitmex
|
|
117
207
|
options[:headers] = headers 'PUT', path, body, json: json if auth
|
118
208
|
|
119
209
|
response = self.class.put "#{domain_url}#{path}", options
|
120
|
-
puts response.body
|
121
210
|
yield response
|
122
211
|
end
|
123
212
|
|
213
|
+
def post(path, params: {}, auth: true, json: true)
|
214
|
+
body = json ? params.to_json.to_s : URI.encode_www_form(params)
|
215
|
+
|
216
|
+
options = {}
|
217
|
+
options[:body] = body
|
218
|
+
options[:headers] = headers 'POST', path, body, json: json if auth
|
219
|
+
|
220
|
+
response = self.class.post "#{domain_url}#{path}", options
|
221
|
+
yield response
|
222
|
+
end
|
223
|
+
|
224
|
+
def delete(path, params: {}, auth: true, json: true)
|
225
|
+
body = json ? params.to_json.to_s : URI.encode_www_form(params)
|
226
|
+
|
227
|
+
options = {}
|
228
|
+
options[:body] = body
|
229
|
+
options[:headers] = headers 'DELETE', path, body, json: json if auth
|
230
|
+
|
231
|
+
response = self.class.delete "#{domain_url}#{path}", options
|
232
|
+
yield response
|
233
|
+
end
|
234
|
+
|
235
|
+
def base_path(resource, action = '')
|
236
|
+
"/api/v1/#{resource}/#{action}"
|
237
|
+
end
|
238
|
+
|
239
|
+
def response_handler(response)
|
240
|
+
fail response.body unless response.success?
|
241
|
+
|
242
|
+
if response.parsed_response.is_a? Array
|
243
|
+
response.to_a.map { |s| Bitmex::Mash.new s }
|
244
|
+
else
|
245
|
+
Bitmex::Mash.new response
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
124
249
|
private
|
125
250
|
|
126
251
|
def method_missing(m, *args, &ablock)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Bitmex
|
2
|
+
# Tradeable Contracts, Indices, and History
|
3
|
+
# @author Iulian Costan
|
4
|
+
class Instrument < Base
|
5
|
+
# Get all instruments
|
6
|
+
# @!macro bitmex.filters
|
7
|
+
# @return [Array] all instruments
|
8
|
+
def all(filters = {})
|
9
|
+
client.get instrument_path, params: filters do |response|
|
10
|
+
response_handler response
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get all active instruments and instruments that have expired in <24hrs.
|
15
|
+
# @return [Array] active instruments
|
16
|
+
def active
|
17
|
+
client.get instrument_path('active') do |response|
|
18
|
+
response_handler response
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Return all active contract series and interval pairs
|
23
|
+
# @return [Bitmex::Mash] active intervals and symbols
|
24
|
+
def intervals
|
25
|
+
client.get instrument_path('activeIntervals') do |response|
|
26
|
+
response_handler response
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Show constituent parts of an index.
|
31
|
+
# @!macro bitmex.filters
|
32
|
+
# @return [Array] the parts of an index
|
33
|
+
def composite_index(filters = { symbol: '.XBT' })
|
34
|
+
client.get instrument_path('compositeIndex'), params: filters do |response|
|
35
|
+
response_handler response
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get all price indices
|
40
|
+
# @return [Array] all indices
|
41
|
+
def indices
|
42
|
+
client.get instrument_path('indices') do |response|
|
43
|
+
response_handler response
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def instrument_path(action = '')
|
50
|
+
base_path :instrument, action
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/bitmex/order.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
module Bitmex
|
2
|
+
# Order Placement, Cancellation, Amending, and History
|
3
|
+
# @author Iulian Costan
|
4
|
+
class Order < Base
|
5
|
+
attr_reader :orderID, :clOrdID
|
6
|
+
|
7
|
+
def initialize(client, orderID = nil, clOrdID = nil)
|
8
|
+
super client
|
9
|
+
@orderID = orderID
|
10
|
+
@clOrdID = clOrdID
|
11
|
+
end
|
12
|
+
|
13
|
+
# Get your orders
|
14
|
+
# @!macro bitmex.filters
|
15
|
+
# @return [Array] the orders
|
16
|
+
def all(filters = {})
|
17
|
+
client.get order_path, params: filters, auth: true do |response|
|
18
|
+
response_handler response
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Amend the quantity or price of an open order
|
23
|
+
# @param attributes [Hash] the fields to update
|
24
|
+
# @option attributes [Integer] :orderQty Optional order quantity in units of the instrument (i.e. contracts)
|
25
|
+
# @option attributes [Integer] :leavesQty Optional leaves quantity in units of the instrument (i.e. contracts). Useful for amending partially filled orders.
|
26
|
+
# @option attributes [Double] :price Optional limit price for 'Limit', 'StopLimit', and 'LimitIfTouched' orders.
|
27
|
+
# @option attributes [Double] :stopPx Optional trigger price for 'Stop', 'StopLimit', 'MarketIfTouched', and 'LimitIfTouched' orders. Use a price below the current price for stop-sell orders and buy-if-touched orders.
|
28
|
+
# @option attributes [Double] :pegOffsetValue Optional trailing offset from the current price for 'Stop', 'StopLimit', 'MarketIfTouched', and 'LimitIfTouched' orders; use a negative offset for stop-sell orders and buy-if-touched orders. Optional offset from the peg price for 'Pegged' orders.
|
29
|
+
# @option attributes [String] :text Optional amend annotation. e.g. 'Adjust skew'
|
30
|
+
# @return [Bitmex::Mash] the updated order
|
31
|
+
def update(attributes)
|
32
|
+
params = attributes.merge orderID: orderID, origClOrdID: clOrdID
|
33
|
+
client.put order_path, params: params do |response|
|
34
|
+
response_handler response
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Place new order
|
39
|
+
# @param symbol [String] instrument symbol
|
40
|
+
# @param attributes [Hash] order attributes
|
41
|
+
# @option attributes [Buy, Sell] :side Order side. Defaults to 'Buy' unless orderQty is negative
|
42
|
+
# @option attributes [Integer] :orderQty Order quantity in units of the instrument (i.e. contracts)
|
43
|
+
# @option attributes [Double] :price Optional limit price for 'Limit', 'StopLimit', and 'LimitIfTouched' orders
|
44
|
+
# @option attributes [Double] :displayQty Optional quantity to display in the book. Use 0 for a fully hidden order.
|
45
|
+
# @option attributes [Double] :stopPx Optional trigger price for 'Stop', 'StopLimit', 'MarketIfTouched', and 'LimitIfTouched' orders. Use a price below the current price for stop-sell orders and buy-if-touched orders. Use execInst of 'MarkPrice' or 'LastPrice' to define the current price used for triggering.
|
46
|
+
# @option attributes [String] :clOrdID Optional Client Order ID. This clOrdID will come back on the order and any related executions.
|
47
|
+
# @option attributes [Double] :pegOffsetValue Optional trailing offset from the current price for 'Stop', 'StopLimit', 'MarketIfTouched', and 'LimitIfTouched' orders; use a negative offset for stop-sell orders and buy-if-touched orders. Optional offset from the peg price for 'Pegged' orders.
|
48
|
+
# @option attributes [LastPeg, MidPricePeg, MarketPeg, PrimaryPeg, TrailingStopPeg] :pegPriceType Optional peg price type.
|
49
|
+
# @option attributes [Market, Limit, Stop, StopLimit, MarketIfTouched, LimitIfTouched, MarketWithLeftOverAsLimit, Pegged] :ordType Order type. Defaults to 'Limit' when price is specified. Defaults to 'Stop' when stopPx is specified. Defaults to 'StopLimit' when price and stopPx are specified.
|
50
|
+
# @option attributes [Day, GoodTillCancel, ImmediateOrCancel, FillOrKill] :timeInForce Time in force. Defaults to 'GoodTillCancel' for 'Limit', 'StopLimit', 'LimitIfTouched', and 'MarketWithLeftOverAsLimit' orders.
|
51
|
+
# @option attributes [ParticipateDoNotInitiate, AllOrNone, MarkPrice, IndexPrice, LastPrice, Close, ReduceOnly, Fixed] :execInst Optional execution instructions. AllOrNone' instruction requires displayQty to be 0. 'MarkPrice', 'IndexPrice' or 'LastPrice' instruction valid for 'Stop', 'StopLimit', 'MarketIfTouched', and 'LimitIfTouched' orders.
|
52
|
+
# @option attributes [String] :text Optional amend annotation. e.g. 'Take profit'
|
53
|
+
# @return [Bitmex::Mash] the created order
|
54
|
+
def create(symbol, attributes)
|
55
|
+
params = attributes.merge symbol: symbol
|
56
|
+
client.post order_path, params: params do |response|
|
57
|
+
response_handler response
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Cancel an order
|
62
|
+
# @param text [String] Optional cancellation annotation. e.g. 'Spread Exceeded'.
|
63
|
+
# @return [Bitmex::Mash] the canceled order
|
64
|
+
def cancel(text = nil)
|
65
|
+
params = { orderID: orderID, clOrdID: clOrdID, text: text }
|
66
|
+
client.delete order_path, params: params do |response|
|
67
|
+
# a single order only
|
68
|
+
response_handler(response).first
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def order_path(action = '')
|
75
|
+
client.base_path 'order', action
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Bitmex
|
2
|
+
# Summary of Open and Closed Positions
|
3
|
+
# @author Iulian Costan
|
4
|
+
class Position < Base
|
5
|
+
attr_reader :symbol
|
6
|
+
|
7
|
+
# A new instance of Position
|
8
|
+
# @param client [Bitmex::Client] the HTTP client
|
9
|
+
# @param symbol [String] the symbol of the underlying position
|
10
|
+
def initialize(client, symbol = 'XBTUSD')
|
11
|
+
super client
|
12
|
+
@symbol = symbol
|
13
|
+
end
|
14
|
+
|
15
|
+
# Get your positions
|
16
|
+
# @return [Array] the list of positions
|
17
|
+
def all
|
18
|
+
client.get position_path, auth: true do |response|
|
19
|
+
response_handler response
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Enable isolated margin or cross margin per-position
|
24
|
+
# @param enabled [true, false] true for isolated margin, false cross margin
|
25
|
+
# @return [Hash] the updated position
|
26
|
+
def isolate(enabled: true)
|
27
|
+
path = position_path(:isolate)
|
28
|
+
params = { symbol: symbol, enabled: enabled }
|
29
|
+
client.post path, params: params do |response|
|
30
|
+
response_handler response
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Choose leverage for a position
|
35
|
+
# @param leverage [0-100] leverage value. send a number between 0.01 and 100 to enable isolated margin with a fixed leverage. send 0 to enable cross margin
|
36
|
+
# @return [Hash] the updated position
|
37
|
+
def leverage(leverage)
|
38
|
+
raise ArgumentError, "leverage #{leverage} is outside of [0..100] range" unless (0..100).include? leverage
|
39
|
+
|
40
|
+
path = position_path(:leverage)
|
41
|
+
params = { symbol: symbol, leverage: leverage }
|
42
|
+
client.post path, params: params do |response|
|
43
|
+
response_handler response
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Update your risk limit
|
48
|
+
# @param risk_limit [Double] new risk limit, in Satoshis.
|
49
|
+
# @return [Hash] the updated position
|
50
|
+
def risk_limit(risk_limit)
|
51
|
+
path = position_path(:riskLimit)
|
52
|
+
params = { symbol: symbol, riskLimit: risk_limit }
|
53
|
+
client.post path, params: params do |response|
|
54
|
+
response_handler response
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Transfer equity in or out of a position
|
59
|
+
# @example Transfer 1000 Satoshi
|
60
|
+
# position = client.position('XBTUSD').transfer_margin 1000
|
61
|
+
# @param amount [Double] amount to transfer, in Satoshis. may be negative.
|
62
|
+
# @return [Hash] the updated position
|
63
|
+
def transfer_margin(amount)
|
64
|
+
path = position_path(:transferMargin)
|
65
|
+
params = { symbol: symbol, amount: amount }
|
66
|
+
client.post path, params: params do |response|
|
67
|
+
response_handler response
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def position_path(action = '')
|
74
|
+
client.base_path :position, action
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|