-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathclient.py
More file actions
1155 lines (968 loc) · 48.4 KB
/
client.py
File metadata and controls
1155 lines (968 loc) · 48.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
"""Luno API client implementation."""
from .base_client import BaseClient
class Client(BaseClient):
"""
Python SDK for the Luno API.
Example usage:
from luno_python.client import Client
c = Client(api_key_id='key_id', api_key_secret='key_secret')
try:
res = c.get_ticker(pair='XBTZAR')
print(res)
except Exception as e:
print(e)
"""
def cancel_withdrawal(self, id):
"""Make a call to DELETE /api/1/withdrawals/{id}.
Cancel a withdrawal request.
This can only be done if the request is still in state <code>PENDING</code>.
Permissions required: <code>Perm_W_Withdrawals</code>
:param id: ID of the withdrawal to cancel.
:type id: int
"""
req = {
"id": id,
}
return self.do("DELETE", "/api/1/withdrawals/{id}", req=req, auth=True)
def create_account(self, currency, name):
"""Make a call to POST /api/1/accounts.
This request creates an Account for the specified currency. Please note that the balances for the Account will
be displayed based on the <code>asset</code> value, which is the currency the Account is based on.
Permissions required: <code>Perm_W_Addresses</code>
:param currency: The currency code for the Account you want to create. Please see the Currency section for a
detailed list of currencies supported by the Luno platform.
Users must be verified to trade currency in order to be able to create an Account. For more
information on the verification process, please see
<a href="/help/en/articles/1000168396">How do I verify my identity?</a>.
Users have a limit of 10 accounts per currency.
:type currency: str
:param name: The label to use for this account
:type name: str
"""
req = {
"currency": currency,
"name": name,
}
return self.do("POST", "/api/1/accounts", req=req, auth=True)
def create_beneficiary(self, account_type, bank_account_number, bank_name, bank_recipient):
"""Make a call to POST /api/1/beneficiaries.
Create a new beneficiary.
Permissions required: <code>Perm_W_Beneficiaries</code>
:param account_type: Bank account type
:type account_type: str
:param bank_account_number: Beneficiary bank account number
:type bank_account_number: str
:param bank_name: Bank SWIFT code
:type bank_name: str
:param bank_recipient: The owner of the recipient account
:type bank_recipient: str
"""
req = {
"account_type": account_type,
"bank_account_number": bank_account_number,
"bank_name": bank_name,
"bank_recipient": bank_recipient,
}
return self.do("POST", "/api/1/beneficiaries", req=req, auth=True)
def create_funding_address(self, asset, account_id=None, name=None):
"""Make a call to POST /api/1/funding_address.
Allocate a new receive address to your account. There is a rate limit of 1
address per hour, but bursts of up to 10 addresses are allowed. Only 1
Ethereum receive address can be created.
Permissions required: <code>Perm_W_Addresses</code>
:param asset: Currency code of the asset.
:type asset: str
:param account_id: An optional account_id to assign the new Receive Address too
:type account_id: int
:param name: An optional name for the new Receive Address
:type name: str
"""
req = {
"asset": asset,
"account_id": account_id,
"name": name,
}
return self.do("POST", "/api/1/funding_address", req=req, auth=True)
def create_withdrawal(self, amount, type, beneficiary_id=None, external_id=None, fast=None, reference=None):
"""Make a call to POST /api/1/withdrawals.
Create a new withdrawal request to the specified beneficiary.
Permissions required: <code>Perm_W_Withdrawals</code>
:param amount: Amount to withdraw. The currency withdrawn depends on the type setting.
:type amount: float
:param type: Withdrawal method.
:type type: str
:param beneficiary_id: The beneficiary ID of the bank account the withdrawal will be paid out to.
This parameter is required if the user has set up multiple beneficiaries.
The beneficiary ID can be found by selecting on the beneficiary name on the user's
<a href="/wallet/beneficiaries">Beneficiaries</a> page.
:type beneficiary_id: int
:param external_id: Optional unique ID to associate with this withdrawal.
Useful to prevent duplicate sends.
This field supports all alphanumeric characters including "-" and "_".
:type external_id: str
:param fast: If true, it will be a fast withdrawal if possible. Fast withdrawals come with a fee.
Currently fast withdrawals are only available for `type=ZAR_EFT`; for other types, an error is
returned. Fast withdrawals are not possible for Bank of Baroda, Deutsche Bank, Merrill Lynch South
Africa, UBS, Postbank and Tyme Bank.
The fee to be charged is the same as when withdrawing from the UI.
:type fast: bool
:param reference: For internal use.
Deprecated: We don't allow custom references and will remove this soon.
:type reference: str
"""
req = {
"amount": amount,
"type": type,
"beneficiary_id": beneficiary_id,
"external_id": external_id,
"fast": fast,
"reference": reference,
}
return self.do("POST", "/api/1/withdrawals", req=req, auth=True)
def delete_beneficiary(self, id):
"""Make a call to DELETE /api/1/beneficiaries/{id}.
Delete a beneficiary
Permissions required: <code>Perm_W_Beneficiaries</code>
:param id: ID of the Beneficiary to delete.
:type id: int
"""
req = {
"id": id,
}
return self.do("DELETE", "/api/1/beneficiaries/{id}", req=req, auth=True)
def get_balances(self, assets=None, account_id=None):
"""Make a call to GET /api/1/balance.
The list of all Accounts and their respective balances for the requesting user.
Permissions required: <code>Perm_R_Balance</code>
:param assets: Only return balances for wallets with these currencies (if not provided,
all balances will be returned). To request balances for multiple currencies,
pass the parameter multiple times,
e.g. `assets=XBT&assets=ETH`.
:type assets: list
:param account_id: Only return balance for the account with this ID. If provided,
returns a single account object instead of the full response.
:type account_id: str
"""
req = {
"assets": assets,
}
response = self.do("GET", "/api/1/balance", req=req, auth=True)
# If account_id is specified, filter to return only that account
if account_id is not None:
if "balance" in response:
for account in response["balance"]:
if str(account.get("account_id")) == str(account_id):
return account
# If account_id not found, return None
return None
# Return full response if no account_id specified (backward compatibility)
return response
def get_candles(self, duration, pair, since):
"""Make a call to GET /api/exchange/1/candles.
Get candlestick market data from the specified time until now, from the oldest to the most recent.
Permissions required: <code>MP_None</code>
:param duration: Candle duration in seconds.
For example, 300 corresponds to 5m candles. Currently supported
durations are: 60 (1m), 300 (5m), 900 (15m), 1800 (30m), 3600 (1h),
10800 (3h), 14400 (4h), 28800 (8h), 86400 (24h), 259200 (3d), 604800
(7d).
:type duration: int
:param pair: Currency pair
:type pair: str
:param since: Filter to candles starting on or after this timestamp (Unix milliseconds).
Only up to 1000 of the earliest candles are returned.
:type since: int
"""
req = {
"duration": duration,
"pair": pair,
"since": since,
}
return self.do("GET", "/api/exchange/1/candles", req=req, auth=True)
def get_fee_info(self, pair):
"""Make a call to GET /api/1/fee_info.
Return the fees and 30 day trading volume (as of midnight) for a given currency pair. For complete details,
please see <a href="en/countries">Fees & Features</a>.
Permissions required: <code>Perm_R_Orders</code>
:param pair: Get fee information about this pair.
:type pair: str
"""
req = {
"pair": pair,
}
return self.do("GET", "/api/1/fee_info", req=req, auth=True)
def get_funding_address(self, asset, address=None):
"""Make a call to GET /api/1/funding_address.
Return the default receive address associated with your account and the
amount received via the address. Users can specify an optional address parameter to return information for a
non-default receive address.
In the response, <code>total_received</code> is the total confirmed amount received excluding unconfirmed
transactions. <code>total_unconfirmed</code> is the total sum of unconfirmed receive transactions.
Permissions required: <code>Perm_R_Addresses</code>
:param asset: Currency code of the asset.
:type asset: str
:param address: Specific cryptocurrency address to retrieve. If not provided, the
default address will be used.
:type address: str
"""
req = {
"asset": asset,
"address": address,
}
return self.do("GET", "/api/1/funding_address", req=req, auth=True)
def get_move(self, client_move_id=None, id=None):
"""Make a call to GET /api/exchange/1/move.
Get a specific move funds instruction by either <code>id</code> or
<code>client_move_id</code>. If both are provided an API error will be
returned.
Permissions required: <code>MP_None</code>
:param client_move_id: Get by the user defined ID. This is mutually exclusive with <code>id</code> and is
required if <code>id</code> is not provided.
:type client_move_id: str
:param id: Get by the system ID. This is mutually exclusive with <code>client_move_id</code> and is required if
<code>client_move_id</code> is not provided.
:type id: str
"""
req = {
"client_move_id": client_move_id,
"id": id,
}
return self.do("GET", "/api/exchange/1/move", req=req, auth=True)
def get_order(self, id):
"""Make a call to GET /api/1/orders/{id}.
Get an Order's details by its ID.
Permissions required: <code>Perm_R_Orders</code>
:param id: Order reference
:type id: str
"""
req = {
"id": id,
}
return self.do("GET", "/api/1/orders/{id}", req=req, auth=True)
def get_order_book(self, pair):
"""Make a call to GET /api/1/orderbook_top.
This request returns the best 100 `bids` and `asks`, for the currency pair specified, in the Order Book.
`asks` are sorted by price ascending and `bids` are sorted by price descending.
Multiple orders at the same price are aggregated.
:param pair: Currency pair of the Orders to retrieve
:type pair: str
"""
req = {
"pair": pair,
}
return self.do("GET", "/api/1/orderbook_top", req=req, auth=False)
def get_order_book_full(self, pair):
"""Make a call to GET /api/1/orderbook.
This request returns all `bids` and `asks`, for the currency pair specified, in the Order Book.
`asks` are sorted by price ascending and `bids` are sorted by price descending.
Multiple orders at the same price are not aggregated.
<b>WARNING:</b> This may return a large amount of data.
Users are recommended to use the <a href="#operation/getOrderBookTop">top 100 bids and asks</a>
or the <a href="#tag/Streaming-API">Streaming API</a>.
:param pair: Currency pair of the Orders to retrieve
:type pair: str
"""
req = {
"pair": pair,
}
return self.do("GET", "/api/1/orderbook", req=req, auth=False)
def get_order_v2(self, id):
"""Make a call to GET /api/exchange/2/orders/{id}.
Get the details for an order.
Permissions required: <code>Perm_R_Orders</code>
:param id: Order reference
:type id: str
"""
req = {
"id": id,
}
return self.do("GET", "/api/exchange/2/orders/{id}", req=req, auth=True)
def get_order_v3(self, client_order_id=None, id=None):
"""Make a call to GET /api/exchange/3/order.
Get the details for an order by order reference or client order ID.
Exactly one of the two parameters must be provided, otherwise an error is returned.
Permissions required: <code>Perm_R_Orders</code>
:param client_order_id: Client Order ID has the value that was passed in when the Order was posted.
:type client_order_id: str
:param id: Order reference
:type id: str
"""
req = {
"client_order_id": client_order_id,
"id": id,
}
return self.do("GET", "/api/exchange/3/order", req=req, auth=True)
def get_ticker(self, pair):
"""Make a call to GET /api/1/ticker.
Return the latest ticker indicators for the specified currency pair.
Please see the <a href="#tag/currency ">Currency list</a> for the complete list of supported currency pairs.
:param pair: Currency pair
:type pair: str
"""
req = {
"pair": pair,
}
return self.do("GET", "/api/1/ticker", req=req, auth=False)
def get_tickers(self, pair=None):
"""Make a call to GET /api/1/tickers.
Return the latest ticker indicators from all active Luno exchanges.
Please see the <a href="#tag/currency ">Currency list</a> for the complete list of supported currency pairs.
:param pair: Return tickers for multiple markets (if not provided, all tickers will be returned).
To request tickers for multiple markets, pass the parameter multiple times,
e.g. `pair=XBTZAR&pair=ETHZAR`.
:type pair: list
"""
req = {
"pair": pair,
}
return self.do("GET", "/api/1/tickers", req=req, auth=False)
def get_withdrawal(self, id):
"""Make a call to GET /api/1/withdrawals/{id}.
Return the status of a particular withdrawal request.
Permissions required: <code>Perm_R_Withdrawals</code>
:param id: Withdrawal ID to retrieve.
:type id: int
"""
req = {
"id": id,
}
return self.do("GET", "/api/1/withdrawals/{id}", req=req, auth=True)
def list_beneficiaries(self, bank_recipient=None):
"""Make a call to GET /api/1/beneficiaries.
Return a list of bank beneficiaries.
Permissions required: <code>Perm_R_Beneficiaries</code>
:param bank_recipient: :type bank_recipient: str
"""
req = {
"bank_recipient": bank_recipient,
}
return self.do("GET", "/api/1/beneficiaries", req=req, auth=True)
def list_moves(self, before=None, limit=None):
"""Make a call to GET /api/exchange/1/move/list_moves.
Return a list of the most recent moves ordered from newest to oldest.
This endpoint will list up to 100 most recent moves by default.
Permissions required: <code>MP_None</code>
:param before: Filter to moves requested before this timestamp (Unix milliseconds)
:type before: int
:param limit: Limit to this many moves
:type limit: int
"""
req = {
"before": before,
"limit": limit,
}
return self.do("GET", "/api/exchange/1/move/list_moves", req=req, auth=True)
def list_orders(self, created_before=None, limit=None, pair=None, state=None):
"""Make a call to GET /api/1/listorders.
Return a list of the most recently placed Orders.
Users can specify an optional <code>state=PENDING</code> parameter to restrict the results to only open Orders.
Users can also specify the market by using the optional currency pair parameter.
Permissions required: <code>Perm_R_Orders</code>
:param created_before: Filter to orders created before this timestamp (Unix milliseconds)
:type created_before: int
:param limit: Limit to this many orders
:type limit: int
:param pair: Filter to only orders of this currency pair
:type pair: str
:param state: Filter to only orders of this state
:type state: str
"""
req = {
"created_before": created_before,
"limit": limit,
"pair": pair,
"state": state,
}
return self.do("GET", "/api/1/listorders", req=req, auth=True)
def list_orders_v2(self, closed=None, created_before=None, limit=None, pair=None):
"""Make a call to GET /api/exchange/2/listorders.
Return a list of the most recently placed orders ordered from newest to
oldest. This endpoint will list up to 100 most recent open orders by
default.
<b>Please note:</b> This data is archived 100 days after an exchange order is completed.
Permissions required: <Code>Perm_R_Orders</Code>
:param closed: If true, will return closed orders instead of open orders.
:type closed: bool
:param created_before: Filter to orders created before this timestamp (Unix milliseconds)
:type created_before: int
:param limit: Limit to this many orders
:type limit: int
:param pair: Filter to only orders of this currency pair.
:type pair: str
"""
req = {
"closed": closed,
"created_before": created_before,
"limit": limit,
"pair": pair,
}
return self.do("GET", "/api/exchange/2/listorders", req=req, auth=True)
def list_pending_transactions(self, id):
"""Make a call to GET /api/1/accounts/{id}/pending.
Return a list of all transactions that have not completed for the Account.
Pending transactions are not numbered, and may be reordered, deleted or updated at any time.
Permissions required: <code>Perm_R_Transactions</code>
:param id: Account ID
:type id: int
"""
req = {
"id": id,
}
return self.do("GET", "/api/1/accounts/{id}/pending", req=req, auth=True)
def list_trades(self, pair, since=None):
"""Make a call to GET /api/1/trades.
Return a list of recent trades for the specified currency pair. At most
100 trades are returned per call and never trades older than 24h. The
trades are sorted from newest to oldest.
Please see the <a href="#tag/currency ">Currency list</a> for the complete list of supported currency pairs.
:param pair: Currency pair of the market to list the trades from
:type pair: str
:param since: Fetch trades executed after this time, specified as a Unix timestamp in
milliseconds. An error will be returned if this is before 24h ago. Use
this parameter to either restrict to a shorter window or to iterate over
the trades in case you need more than the 100 most recent trades.
:type since: int
"""
req = {
"pair": pair,
"since": since,
}
return self.do("GET", "/api/1/trades", req=req, auth=False)
def list_transactions(self, id, max_row, min_row):
"""Make a call to GET /api/1/accounts/{id}/transactions.
Return a list of transaction entries from an account.
Transaction entry rows are numbered sequentially starting from 1, where 1 is
the oldest entry. The range of rows to return are specified with the
<code>min_row</code> (inclusive) and <code>max_row</code> (exclusive)
parameters. At most 1000 rows can be requested per call.
If <code>min_row</code> or <code>max_row</code> is non-positive, the range
wraps around the most recent row. For example, to fetch the 100 most recent
rows, use <code>min_row=-100</code> and <code>max_row=0</code>.
Permissions required: <code>Perm_R_Transactions</code>
:param id: Account ID - the unique identifier for the specific Account.
:type id: int
:param max_row: Maximum of the row range to return (exclusive)
:type max_row: int
:param min_row: Minimum of the row range to return (inclusive)
:type min_row: int
"""
req = {
"id": id,
"max_row": max_row,
"min_row": min_row,
}
return self.do("GET", "/api/1/accounts/{id}/transactions", req=req, auth=True)
def list_transfers(self, account_id, before=None, limit=None):
"""Make a call to GET /api/exchange/1/transfers.
Return a list of the most recent confirmed transfers ordered from newest to
oldest.
This includes bank transfers, card payments, or on-chain transactions that
have been reflected on your account available balance.
Note that the Transfer `amount` is always a positive value and you should
use the `inbound` flag to determine the direction of the transfer.
If you need to paginate the results you can set the `before` parameter to
the last returned transfer `created_at` field value and repeat the request
until you have all the transfers you need.
This endpoint will list up to 100 transfers at a time by default.
Permissions required: <Code>Perm_R_Transfers</Code>
:param account_id: Unique identifier of the account to list the transfers from.
:type account_id: int
:param before: Filter to transfers created before this timestamp (Unix milliseconds).
The default value (0) will return the latest transfers on the account.
:type before: int
:param limit: Limit to this many transfers.
:type limit: int
"""
req = {
"account_id": account_id,
"before": before,
"limit": limit,
}
return self.do("GET", "/api/exchange/1/transfers", req=req, auth=True)
def list_user_trades(
self,
pair,
after_seq=None,
before=None,
before_seq=None,
limit=None,
since=None,
sort_desc=None,
):
"""Make a call to GET /api/1/listtrades.
Return a list of the recent Trades for a given currency pair for this user, sorted by oldest first.
If <code>before</code> is specified, then Trades are returned sorted by most-recent first.
<code>type</code> in the response indicates the type of Order that was placed to participate in the trade.
Possible types: <code>BID</code>, <code>ASK</code>.
If <code>is_buy</code> in the response is true, then the Order which completed the trade (market taker) was a
Bid Order.
Results of this query may lag behind the latest data.
Permissions required: <code>Perm_R_Orders</code>
:param pair: Filter to trades of this currency pair.
:type pair: str
:param after_seq: Filter to trades from (including) this sequence number.
Default behaviour is not to include this filter.
:type after_seq: int
:param before: Filter to trades before this timestamp (Unix milliseconds).
:type before: int
:param before_seq: Filter to trades before (excluding) this sequence number.
Default behaviour is not to include this filter.
:type before_seq: int
:param limit: Limit to this number of trades (default 100).
:type limit: int
:param since: Filter to trades on or after this timestamp (Unix milliseconds).
:type since: int
:param sort_desc: If set to true, sorts trades in descending order, otherwise ascending
order will be assumed.
:type sort_desc: bool
"""
req = {
"pair": pair,
"after_seq": after_seq,
"before": before,
"before_seq": before_seq,
"limit": limit,
"since": since,
"sort_desc": sort_desc,
}
return self.do("GET", "/api/1/listtrades", req=req, auth=True)
def list_withdrawals(self, before_id=None, limit=None):
"""Make a call to GET /api/1/withdrawals.
Return a list of withdrawal requests.
Permissions required: <code>Perm_R_Withdrawals</code>
:param before_id: Filter to withdrawals requested on or before the withdrawal with this ID.
Can be used for pagination.
:type before_id: int
:param limit: Limit to this many withdrawals
:type limit: int
"""
req = {
"before_id": before_id,
"limit": limit,
}
return self.do("GET", "/api/1/withdrawals", req=req, auth=True)
def markets(self, pair=None):
"""Make a call to GET /api/exchange/1/markets.
List all supported markets parameter information like price scale, min and
max order volumes and market ID.
:param pair: List of market pairs to return. Requesting only the required pairs will improve response times.
:type pair: list
"""
req = {
"pair": pair,
}
return self.do("GET", "/api/exchange/1/markets", req=req, auth=False)
def move(self, amount, credit_account_id, debit_account_id, client_move_id=None):
"""Make a call to POST /api/exchange/1/move.
Move funds between two of your transactional accounts with the same currency
The funds may not be moved by the time the request returns. The GET method
can be used to poll for the move's status.
Note: moves will show as transactions, but not as transfers.
Permissions required: <code>MP_None_Write</code>
:param amount: Amount to transfer. Must be positive.
:type amount: float
:param credit_account_id: The account to credit the funds to.
:type credit_account_id: int
:param debit_account_id: The account to debit the funds from.
:type debit_account_id: int
:param client_move_id: Client move ID.
May only contain alphanumeric (0-9, a-z, or A-Z) and special characters (_ ; , . -).
Maximum length: 255. It will be available in read endpoints, so you can use it to avoid
duplicate moves between the same accounts. Values must be unique across all your
successful calls of this endpoint; trying to create a move request with the same
`client_move_id` as one of your past move requests will result in a HTTP 409 Conflict
response.
:type client_move_id: str
"""
req = {
"amount": amount,
"credit_account_id": credit_account_id,
"debit_account_id": debit_account_id,
"client_move_id": client_move_id,
}
return self.do("POST", "/api/exchange/1/move", req=req, auth=True)
def post_limit_order(
self,
pair,
price,
type,
volume,
base_account_id=None,
client_order_id=None,
counter_account_id=None,
post_only=None,
stop_direction=None,
stop_price=None,
time_in_force=None,
timestamp=None,
ttl=None,
):
"""Make a call to POST /api/1/postorder.
<b>Warning!</b> Orders cannot be reversed once they have executed.
Please ensure your program has been thoroughly tested before submitting Orders.
If no <code>base_account_id</code> or <code>counter_account_id</code> are specified,
your default base currency or counter currency account will be used.
You can find your Account IDs by calling the <a href="#operation/getBalances">Balances</a> API.
Permissions required: <code>Perm_W_Orders</code>
:param pair: The currency pair to trade.
:type pair: str
:param price: Limit price as a decimal string in units of ZAR/BTC.
:type price: float
:param type: <code>BID</code> for a bid (buy) limit order<br>
<code>ASK</code> for an ask (sell) limit order
:type type: str
:param volume: Amount of cryptocurrency to buy or sell as a decimal string in units of the currency.
:type volume: float
:param base_account_id: The base currency Account to use in the trade.
:type base_account_id: int
:param client_order_id: Client order ID.
May only contain alphanumeric (0-9, a-z, or A-Z) and special characters (_ ; , . -).
Maximum length: 255. It will be available in read endpoints, so you can use it to
reconcile Luno with your internal system. Values must be unique across all your
successful order creation endpoint calls; trying to create an order with the same
`client_order_id` as one of your past orders will result in a HTTP 409 Conflict
response.
:type client_order_id: str
:param counter_account_id: The counter currency Account to use in the trade.
:type counter_account_id: int
:param post_only: Post-only Orders will be cancelled if they would otherwise have traded immediately.
For example, if there's a bid at ZAR 100,000 and you place a post-only ask at ZAR 100,000,
your order will be cancelled instead of trading.
If the best bid is ZAR 100,000 and you place a post-only ask at ZAR 101,000,
your order won't trade but will go into the order book.
:type post_only: bool
:param stop_direction: Side of the trigger price to activate the order. This should be set if `stop_price` is
also set.
`RELATIVE_LAST_TRADE` will automatically infer the direction based on the last trade
price and the stop price. If last trade price is less than stop price then stop direction
is ABOVE otherwise is BELOW.
:type stop_direction: str
:param stop_price: Trigger trade price to activate this order as a decimal string. If this
is set then this is treated as a Stop Limit Order and `stop_direction`
is expected to be set too.
:type stop_price: float
:param time_in_force: <code>GTC</code> Good 'Til Cancelled. The order remains open until it is filled or
cancelled by the user.</br>
<code>IOC</code> Immediate Or Cancel. The part of the order that cannot be filled
immediately will be cancelled. Cannot be post-only.</br>
<code>FOK</code> Fill Or Kill. If the order cannot be filled immediately and completely it
will be cancelled before any trade. Cannot be post-only.
:type time_in_force: str
:param timestamp: Unix timestamp in milliseconds of when the request was created and sent.
:type timestamp: int
:param ttl: Specifies the number of milliseconds after timestamp the request is valid for.
If `timestamp` is not specified, `ttl` will not be used.
:type ttl: int
"""
req = {
"pair": pair,
"price": price,
"type": type,
"volume": volume,
"base_account_id": base_account_id,
"client_order_id": client_order_id,
"counter_account_id": counter_account_id,
"post_only": post_only,
"stop_direction": stop_direction,
"stop_price": stop_price,
"time_in_force": time_in_force,
"timestamp": timestamp,
"ttl": ttl,
}
return self.do("POST", "/api/1/postorder", req=req, auth=True)
def post_market_order(
self,
pair,
type,
base_account_id=None,
base_volume=None,
client_order_id=None,
counter_account_id=None,
counter_volume=None,
timestamp=None,
ttl=None,
):
"""Make a call to POST /api/1/marketorder.
A Market Order executes immediately, and either buys as much of the asset that can be bought for a set amount of
fiat currency, or sells a set amount of the asset for as much as possible.
<b>Warning!</b> Orders cannot be reversed once they have executed.
Please ensure your program has been thoroughly tested before submitting Orders.
If no <code>base_account_id</code> or <code>counter_account_id</code> are specified, the default base
currency or counter currency account will be used. Users can find their account IDs by calling the
<a href="#operation/getBalances">Balances</a> request.
Permissions required: <code>Perm_W_Orders</code>
:param pair: The currency pair to trade.
:type pair: str
:param type: <code>BUY</code> to buy an asset<br>
<code>SELL</code> to sell an asset
:type type: str
:param base_account_id: The base currency account to use in the trade.
:type base_account_id: int
:param base_volume: For a <code>SELL</code> order: amount of the base currency to use (e.g. how much BTC to sell
for EUR in the BTC/EUR market)
:type base_volume: float
:param client_order_id: Client order ID.
May only contain alphanumeric (0-9, a-z, or A-Z) and special characters (_ ; , . -).
Maximum length: 255. It will be available in read endpoints, so you can use it to
reconcile Luno with your internal system. Values must be unique across all your
successful order creation endpoint calls; trying to create an order with the same
`client_order_id` as one of your past orders will result in a HTTP 409 Conflict
response.
:type client_order_id: str
:param counter_account_id: The counter currency account to use in the trade.
:type counter_account_id: int
:param counter_volume: For a <code>BUY</code> order: amount of the counter currency to use (e.g. how much EUR to
use to buy BTC in the BTC/EUR market)
:type counter_volume: float
:param timestamp: Unix timestamp in milliseconds of when the request was created and sent.
:type timestamp: int
:param ttl: Specifies the number of milliseconds after timestamp the request is valid for.
If `timestamp` is not specified, `ttl` will not be used.
:type ttl: int
"""
req = {
"pair": pair,
"type": type,
"base_account_id": base_account_id,
"base_volume": base_volume,
"client_order_id": client_order_id,
"counter_account_id": counter_account_id,
"counter_volume": counter_volume,
"timestamp": timestamp,
"ttl": ttl,
}
return self.do("POST", "/api/1/marketorder", req=req, auth=True)
def send(
self,
address,
amount,
currency,
account_id=None,
description=None,
destination_tag=None,
external_id=None,
forex_notice_self_declaration=None,
has_destination_tag=None,
is_drb=None,
is_forex_send=None,
memo=None,
message=None,
):
"""Make a call to POST /api/1/send.
Send assets from an Account. Please note that the asset type sent must match the receive address of the same
cryptocurrency of the same type - Bitcoin to Bitcoin, Ethereum to Ethereum, etc.
Sends can be made to cryptocurrency receive addresses.
<b>Note:</b> This is currently unavailable to users who are verified in countries with money travel rules.
Permissions required: <code>Perm_W_Send</code>
:param address: Destination address or email address.
<b>Note</b>:
<ul>
<li>Ethereum addresses must be
<a href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md" target="_blank"
rel="nofollow">checksummed</a>.</li>
<li>Ethereum sends to email addresses are not supported.</li>
</ul>
:type address: str
:param amount: Amount to send as a decimal string.
:type amount: float
:param currency: Currency to send.
:type currency: str
:param account_id: Optional source account. In case of multiple accounts for a single currency, the source
account that will provide the funds for the transaction may be specified. If omitted, the
default account will be used.
:type account_id: int
:param description: User description for the transaction to record on the account statement.
:type description: str
:param destination_tag: Optional XRP destination tag. Note that HasDestinationTag must be true if this value is
provided.
:type destination_tag: int
:param external_id: Optional unique ID to associate with this withdrawal.
Useful to prevent duplicate sends in case of failure.
This supports all alphanumeric characters, as well as "-" and "_".
:type external_id: str
:param forex_notice_self_declaration: Only required for Foreign Exchange Notification under the Malaysia FEN
rules. ForexNoticeSelfDeclaration must be true if the user has exceeded
his/her annual investment limit in foreign currency assets.
:type forex_notice_self_declaration: bool
:param has_destination_tag: Optional boolean flag indicating that a XRP destination tag is provided (even if
zero).
:type has_destination_tag: bool
:param is_drb: Only required for Foreign Exchange Notification under the Malaysia FEN rules. IsDRB must be true
if the user has Domestic Ringgit Borrowing (DRB).
:type is_drb: bool
:param is_forex_send: Only required for Foreign Exchange Notification under the Malaysia FEN rules. IsForexSend
must be true if sending to an address hosted outside of Malaysia.
:type is_forex_send: bool
:param memo: Optional memo string used to provide account information for ATOM, etc. where it holds "account"
information for a generic address.
:type memo: str
:param message: Message to send to the recipient.
This is only relevant when sending to an email address.
:type message: str
"""
req = {
"address": address,
"amount": amount,
"currency": currency,
"account_id": account_id,
"description": description,
"destination_tag": destination_tag,
"external_id": external_id,
"forex_notice_self_declaration": forex_notice_self_declaration,
"has_destination_tag": has_destination_tag,
"is_drb": is_drb,
"is_forex_send": is_forex_send,
"memo": memo,
"message": message,
}
return self.do("POST", "/api/1/send", req=req, auth=True)
def send_fee(self, address, amount, currency):
"""Make a call to GET /api/1/send_fee.
Calculate fees involved with a crypto send request.
Send address can be to a cryptocurrency receive address, or the email address of another Luno platform user.
Permissions required: <code>MP_None</code>
:param address: Destination address or email address.
<b>Note</b>:
<ul>
<li>Ethereum addresses must be
<a href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md" target="_blank"
rel="nofollow">checksummed</a>.</li>