File Coverage

lib/Finance/GDAX/API/Order.pm
Criterion Covered Total %
statement 17 69 24.6
branch 0 38 0.0
condition 0 3 0.0
subroutine 6 11 54.5
pod 5 5 100.0
total 28 126 22.2


line stmt bran cond sub pod time code
1             package Finance::GDAX::API::Order;
2             our $VERSION = '0.02';
3 1     1   24100 use 5.20.0;
  1         3  
4 1     1   4 use warnings;
  1         2  
  1         24  
5 1     1   393 use Moose;
  1         404140  
  1         6  
6 1     1   6990 use Finance::GDAX::API::TypeConstraints;;
  1         3  
  1         42  
7 1     1   411 use Finance::GDAX::API;
  1         3  
  1         38  
8 1     1   8 use namespace::autoclean;
  1         1  
  1         10  
9              
10             extends 'Finance::GDAX::API';
11              
12             our @body_attributes = ('client_oid',
13             'type',
14             'side',
15             'product_id',
16             'stp',
17             'price',
18             'size',
19             'time_in_force',
20             'cancel_after',
21             'post_only',
22             'funds',
23             'overdraft_enabled',
24             'funding_amount');
25              
26             ## Common t all order types
27             #
28             has 'client_oid' => (is => 'rw',
29             isa => 'Str',
30             );
31             has 'type' => (is => 'rw',
32             isa => 'OrderType',
33             default => 'limit',
34             );
35             has 'side' => (is => 'rw',
36             isa => 'OrderSide',
37             );
38             has 'product_id' => (is => 'rw',
39             isa => 'Str',
40             );
41             has 'stp' => (is => 'rw',
42             isa => 'OrderSelfTradePreventionFlag',
43             );
44              
45             ## Limit orders
46             #
47             has 'price' => (is => 'rw',
48             isa => 'PositiveNum',
49             );
50             has 'size' => (is => 'rw',
51             isa => 'PositiveNum',
52             );
53             has 'time_in_force' => (is => 'rw',
54             isa => 'OrderTimeInForce',
55             );
56             has 'cancel_after' => (is => 'rw',
57             isa => 'Str',
58             );
59             has 'post_only' => (is => 'rw',
60             isa => 'Bool',
61             );
62              
63             ## Market orders
64             #
65             has 'funds' => (is => 'rw',
66             isa => 'PositiveNum',
67             );
68              
69             ## Stop orders
70             #
71             has 'overdraft_enabled' => (is => 'rw',
72             isa => 'Bool',
73             );
74             has 'funding_amount' => (is => 'rw',
75             isa => 'PositiveNum',
76             );
77              
78             sub initiate {
79 0     0 1   my $self = shift;
80 0 0         die 'Orders need side, "buy" or "sell"' unless $self->side;
81 0 0         die 'Orders need a product_id' unless $self->product_id;
82 0 0         if ($self->type eq 'limit') {
83 0 0         die 'Limit orders need price' unless $self->price;
84 0 0         die 'Limit orders need size' unless $self->size;
85 0 0         if ($self->cancel_after) {
86 0 0         unless ($self->time_in_force eq 'GTT') {
87 0           die 'time_in_force must be "GTT" when using cancel_after';
88             }
89             }
90 0 0         if ($self->post_only) {
91 0 0         if ($self->time_in_force =~ /^(IOC|FOK)$/) {
92 0           die 'post_only is invalid with time_in_force IOC or FOK';
93             }
94             }
95             }
96 0 0         if ($self->type =~ /^(market|stop)$/) {
97 0 0 0       unless ($self->size or $self->funds) {
98 0           die 'market and stop orders must specify either size or funds';
99             }
100             }
101 0           my %body;
102 0 0         map { $body{$_} = $self->$_ if defined $self->$_ } @body_attributes;
  0            
103 0           $self->body(\%body);
104 0           $self->method('POST');
105 0           $self->path('/orders');
106 0           return $self->send;
107             }
108              
109             sub cancel {
110 0     0 1   my ($self, $order_id) = @_;
111 0 0         die 'Order ID is required' unless $order_id;
112 0           $self->method('DELETE');
113 0           $self->path("/orders/$order_id");
114 0           return $self->send;
115             }
116              
117             sub cancel_all {
118 0     0 1   my ($self, $product_id) = @_;
119 0           my $path = '/orders';
120 0 0         $path .= "?product_id=$product_id" if $product_id;
121 0           $self->method('DELETE');
122 0           $self->path($path);
123 0           return $self->send;
124             }
125              
126             sub list {
127 0     0 1   my ($self, $status, $product_id) = @_;
128 0           my $path = '/orders';
129 0           my @qparams;
130 0 0         if ($status) {
131 0 0         if (ref($status) ne 'ARRAY') {
132 0           $status = [$status];
133             }
134 0           map { push @qparams, "status=$_" } @$status;
  0            
135             }
136 0 0         push @qparams, "product_id=$product_id" if $product_id;
137 0 0         if (scalar @qparams) {
138 0           $path .= '?' . join('&', @qparams);
139             }
140 0           $self->method('GET');
141 0           $self->path($path);
142 0           return $self->send;
143             }
144              
145             sub get {
146 0     0 1   my ($self, $order_id) = @_;
147 0 0         die 'Order ID is required' unless $order_id;
148 0           $self->method('GET');
149 0           $self->path("/orders/$order_id");
150 0           return $self->send;
151             }
152              
153             __PACKAGE__->meta->make_immutable;
154             1;
155              
156             =head1 NAME
157              
158             Finance::GDAX::API::Order - Perl interface to the GDAX Order API
159              
160             =head1 SYNOPSIS
161              
162             use Finance::GDAX::API::Order;
163              
164             $order = Finance::GDAX::API::Order->new;
165             $order->side('buy');
166             $order->type('market');
167             $order->product_id('BTC-USD');
168             $order->funds(500.00);
169             $response = $order->initiate;
170             if ($order->error) { die "Error: ".$order->error };
171            
172              
173             =head1 DESCRIPTION
174              
175             Basic interface to the GDAX API for orders.
176              
177             The API shows the response should look something like this for orders
178             intiated:
179              
180             {
181             "id": "d0c5340b-6d6c-49d9-b567-48c4bfca13d2",
182             "price": "0.10000000",
183             "size": "0.01000000",
184             "product_id": "BTC-USD",
185             "side": "buy",
186             "stp": "dc",
187             "type": "limit",
188             "time_in_force": "GTC",
189             "post_only": false,
190             "created_at": "2016-12-08T20:02:28.53864Z",
191             "fill_fees": "0.0000000000000000",
192             "filled_size": "0.00000000",
193             "executed_value": "0.0000000000000000",
194             "status": "pending",
195             "settled": false
196             }
197              
198             =head1 ATTRIBUTES (common to all order types)
199              
200             =head2 C<client_oid>
201              
202             [optional] Order ID selected by you to identify your order
203              
204             The optional client_oid field must be a UUID generated by your trading
205             application. This field value will be broadcast in the public feed for
206             received messages. You can use this field to identify your orders in
207             the public feed.
208              
209             The client_oid is different than the server-assigned order id. If you
210             are consuming the public feed and see a received message with your
211             client_oid, you should record the server-assigned order_id as it will
212             be used for future order status updates. The client_oid will NOT be
213             used after the received message is sent.
214              
215             The server-assigned order id is also returned as the id field to this
216             HTTP POST request.
217              
218             =head2 C<type>
219              
220             [optional] limit, market, or stop (default is limit)
221              
222             limit orders are both the default and basic order type. A limit order
223             requires specifying a price and size. The size is the number of
224             bitcoin to buy or sell, and the price is the price per bitcoin. The
225             limit order will be filled at the price specified or better. A sell
226             order can be filled at the specified price per bitcoin or a higher
227             price per bitcoin and a buy order can be filled at the specified price
228             or a lower price depending on market conditions. If market conditions
229             cannot fill the limit order immediately, then the limit order will
230             become part of the open order book until filled by another incoming
231             order or canceled by the user.
232              
233             market orders differ from limit orders in that they provide no pricing
234             guarantees. They however do provide a way to buy or sell specific
235             amounts of bitcoin or fiat without having to specify the price. Market
236             orders execute immediately and no part of the market order will go on
237             the open order book. Market orders are always considered takers and
238             incur taker fees. When placing a market order you can specify funds
239             and/or size. Funds will limit how much of your quote currency account
240             balance is used and size will limit the bitcoin amount transacted.
241              
242             stop orders become active and wait to trigger based on the movement of
243             the last trade price. There are two types of stop orders, sell stop
244             and buy stop.
245              
246             =head2 C<side>
247              
248             buy or sell
249              
250             side: 'sell': Place a sell stop order, which triggers when the last
251             trade price changes to a value at or below the price.
252              
253             side: 'buy': Place a buy stop order, which triggers when the last
254             trade price changes to a value at or above price.
255              
256             =head2 C<product_id>
257              
258             A valid product id
259              
260             The product_id must match a valid product. The products list is
261             available via the /products endpoint.
262              
263             =head2 C<stp>
264              
265             [optional] Self-trade prevention flag
266              
267             Self-trading is not allowed on GDAX. Two orders from the same user
268             will not be allowed to match with one another. To change the
269             self-trade behavior, specify the stp flag.
270              
271             Flag Name
272             dc Decrease and Cancel (default)
273             co Cancel oldest
274             cn Cancel newest
275             cb Cancel both
276              
277             =head1 ATTRIBUTES (limit orders)
278              
279             =head2 C<price>
280              
281             Price per bitcoin
282              
283             The price must be specified in quote_increment product units. The
284             quote increment is the smallest unit of price. For the BTC-USD
285             product, the quote increment is 0.01 or 1 penny. Prices less than 1
286             penny will not be accepted, and no fractional penny prices will be
287             accepted. Not required for market orders.
288              
289             =head2 C<size>
290              
291             Amount of BTC to buy or sell
292              
293             The size must be greater than the base_min_size for the product and no
294             larger than the base_max_size. The size can be in any increment of the
295             base currency (BTC for the BTC-USD product), which includes satoshi
296             units. size indicates the amount of BTC (or base currency) to buy or
297             sell.
298              
299             =head2 C<time_in_force>
300              
301             [optional] GTC, GTT, IOC, or FOK (default is GTC)
302              
303             =head2 C<cancel_after>
304              
305             [optional] min, hour, day
306              
307             Requires time_in_force to be GTT
308              
309             Time in force policies provide guarantees about the lifetime of an
310             order. There are four policies: good till canceled GTC, good till time
311             GTT, immediate or cancel IOC, and fill or kill FOK.
312              
313             GTC Good till canceled orders remain open on the book until
314             canceled. This is the default behavior if no policy is specified.
315              
316             GTT Good till time orders remain open on the book until canceled or
317             the allotted cancel_after is depleted on the matching engine. GTT
318             orders are guaranteed to cancel before any other order is processed
319             after the cancel_after timestamp which is returned by the API. A day
320             is considered 24 hours.
321              
322             IOC Immediate or cancel orders instantly cancel the remaining size of
323             the limit order instead of opening it on the book.
324              
325             FOK Fill or kill orders are rejected if the entire size cannot be
326             matched.
327              
328             * Note, match also refers to self trades.
329              
330             =head2 C<post_only>
331              
332             [optional] Post only flag
333              
334             Invalid when time_in_force is IOC or FOK
335              
336             The post-only flag indicates that the order should only make
337             liquidity. If any part of the order results in taking liquidity, the
338             order will be rejected and no part of it will execute.
339              
340             =head1 ATTRIBUTES (market orders)
341              
342             =head2 C<size>
343              
344             [optional]* Desired amount in BTC
345              
346             The size must be greater than the base_min_size for the product and no
347             larger than the base_max_size. The size can be in any increment of the
348             base currency (BTC for the BTC-USD product), which includes satoshi
349             units. size indicates the amount of BTC (or base currency) to buy or
350             sell.
351              
352             * One of size or funds is required.
353              
354             =head2 C<funds>
355              
356             [optional]* Desired amount of quote currency to use
357              
358             The funds field is optionally used for market orders. When specified
359             it indicates how much of the product quote currency to buy or
360             sell. For example, a market buy for BTC-USD with funds specified as
361             150.00 will spend 150 USD to buy BTC (including any fees). If the
362             funds field is not specified for a market buy order, size must be
363             specified and GDAX will use available funds in your account to buy
364             bitcoin.
365              
366             A market sell order can also specify the funds. If funds is specified,
367             it will limit the sell to the amount of funds specified. You can use
368             funds with sell orders to limit the amount of quote currency funds
369             received.
370              
371             * One of size or funds is required.
372              
373             =head1 ATTRIBUTES (stop order)
374              
375             =head2 C<price>
376              
377             Desired price at which the stop order triggers
378              
379             =head2 C<size>
380              
381             [optional]* Desired amount in BTC
382              
383             =head2 C<funds>
384              
385             [optional]* Desired amount of quote currency to use
386              
387             * One of size or funds is required.
388              
389             =head1 ATTRIBUTES (margin parameters)
390              
391             =head2 C<overdraft_enabled>
392              
393             * If true funding will be provided if the order's cost cannot be
394             covered by the account's balance
395              
396             =head2 C<funding_amount>
397              
398             * Amount of funding to be provided for the order
399              
400             * Margin can be used to receive funding by specifying either
401             overdraft_enabled or funding_amount.
402              
403             =head1 METHODS
404              
405             =head2 C<initiate>
406              
407             Initiates the REST order request and returns the result, according to
408             the current API docs, like
409              
410             {
411             "id": "d0c5340b-6d6c-49d9-b567-48c4bfca13d2",
412             "price": "0.10000000",
413             "size": "0.01000000",
414             "product_id": "BTC-USD",
415             "side": "buy",
416             "stp": "dc",
417             "type": "limit",
418             "time_in_force": "GTC",
419             "post_only": false,
420             "created_at": "2016-12-08T20:02:28.53864Z",
421             "fill_fees": "0.0000000000000000",
422             "filled_size": "0.00000000",
423             "executed_value": "0.0000000000000000",
424             "status": "pending",
425             "settled": false
426             }
427              
428             If $order->error exists, then it will contain the error message.
429              
430             =head2 C<cancel> $order_id
431              
432             Cancels the $order_id, where $order_id is the server-assigned order_id
433             and not the client-selected client_oid.
434              
435             Probelms will be reported in ->error
436              
437             =head2 C<cancel_all> ($product_id)
438              
439             Cancels all orders, or if $product_id is specified, cancels only
440             orders within those prodcuts.
441              
442             An array will be returned, according to current API docs:
443              
444             [
445             "144c6f8e-713f-4682-8435-5280fbe8b2b4",
446             "debe4907-95dc-442f-af3b-cec12f42ebda",
447             "cf7aceee-7b08-4227-a76c-3858144323ab",
448             "dfc5ae27-cadb-4c0c-beef-8994936fde8a",
449             "34fecfbf-de33-4273-b2c6-baf8e8948be4"
450             ]
451              
452             =head2 C<list> ($status, $product_id)
453              
454             Returns a list of orders. You can limit the list by specifying order
455             status and product_id. These are positional parameters, so status must
456             come first even if undefined (or 0).
457              
458             $list = $order->list;
459              
460             $status can be an arrayref, in which case it will list each of the
461             given status.
462              
463             $list = $order->list(['open','settled'], 'BTC-USD');
464              
465             To quote from the API:
466              
467             =over
468              
469             Orders which are no longer resting on the order book, will be marked
470             with the done status. There is a small window between an order being
471             done and settled. An order is settled when all of the fills have
472             settled and the remaining holds (if any) have been removed.
473              
474             =back
475              
476             By default open, pending and active orders are returned.
477              
478             =head2 C<get> $order_id
479              
480             Returns a hash of the specified $order_id
481              
482             =cut
483              
484              
485             =head1 AUTHOR
486              
487             Mark Rushing <mark@orbislumen.net>
488              
489             =head1 COPYRIGHT AND LICENSE
490              
491             This software is copyright (c) 2017 by Home Grown Systems, SPC.
492              
493             This is free software; you can redistribute it and/or modify it under
494             the same terms as the Perl 5 programming language system itself.
495              
496             =cut
497