cryptum 0.0.380 → 0.0.381

Sign up to get free protection for your applications and to get access to all the features.
data/lib/cryptum/api.rb CHANGED
@@ -9,604 +9,14 @@ require 'rest-client'
9
9
  module Cryptum
10
10
  # This plugin is used to interact withbtje Coinbase REST API
11
11
  module API
12
- # Supported Method Parameters::
13
- # Cryptum::API.generate_signature(
14
- # )
15
-
16
- public_class_method def self.generate_signature(opts = {})
17
- api_secret = opts[:api_secret]
18
-
19
- http_method = if opts[:http_method].nil?
20
- :GET
21
- else
22
- opts[:http_method].to_s.upcase.scrub.strip.chomp.to_sym
23
- end
24
-
25
- api_call = opts[:api_call].to_s.scrub.strip.chomp
26
- api_call = '/users/self/verify' if opts[:api_call].nil?
27
-
28
- if opts[:params].nil?
29
- path = api_call
30
- else
31
- uri = Addressable::URI.new
32
- uri.query_values = opts[:params]
33
- params = uri.query
34
- path = "#{api_call}?#{params}"
35
- end
36
-
37
- http_body = opts[:http_body].to_s.scrub.strip.chomp
38
-
39
- api_timestamp = Time.now.utc.to_i.to_s
40
-
41
- api_signature = Base64.strict_encode64(
42
- OpenSSL::HMAC.digest(
43
- 'sha256',
44
- Base64.strict_decode64(api_secret),
45
- "#{api_timestamp}#{http_method}#{path}#{http_body}"
46
- )
47
- )
48
-
49
- if http_body == ''
50
- api_signature = Base64.strict_encode64(
51
- OpenSSL::HMAC.digest(
52
- 'sha256',
53
- Base64.strict_decode64(api_secret),
54
- "#{api_timestamp}#{http_method}#{path}"
55
- )
56
- )
57
- end
58
-
59
- api_signature_response = {}
60
- api_signature_response[:api_timestamp] = api_timestamp
61
- api_signature_response[:api_signature] = api_signature
62
-
63
- api_signature_response
64
- rescue RestClient::ExceptionWithResponse => e
65
- File.open('/tmp/cryptum-errors.txt', 'a') do |f|
66
- f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
67
- f.puts "Module: #{self}"
68
- f.puts "URL: #{api_endpoint}#{api_call}"
69
- f.puts "PARAMS: #{params.inspect}"
70
- f.puts "HTTP POST BODY: #{http_body.inspect}" if http_body != ''
71
- f.puts "#{e}\n#{e.response}\n\n\n"
72
- end
73
- rescue StandardError => e
74
- raise e
75
- end
76
-
77
- private_class_method def self.rest_api_call(opts = {})
78
- env = opts[:env]
79
- option_choice = opts[:option_choice]
80
- order_type = opts[:order_type]
81
- event_notes = opts[:event_notes]
82
- api_endpoint = opts[:api_endpoint]
83
- base_increment = opts[:base_increment].to_f
84
-
85
- api_key = env[:api_key]
86
- api_secret = env[:api_secret]
87
- api_passphrase = env[:api_passphrase]
88
- api_endpoint = 'https://api.exchange.coinbase.com'
89
- api_endpoint = 'https://api-public.sandbox.exchange.coinbase.com' if env[:env] == :sandbox
90
- api_endpoint = opts[:api_endpoint] if opts[:api_endpoint]
91
-
92
- http_method = if opts[:http_method].nil?
93
- :GET
94
- else
95
- opts[:http_method].to_s.upcase.scrub.strip.chomp.to_sym
96
- end
97
- api_call = opts[:api_call].to_s.scrub
98
- params = opts[:params]
99
- http_body = opts[:http_body].to_s.scrub.strip.chomp
100
-
101
- max_conn_attempts = 30
102
- conn_attempt = 0
103
-
104
- begin
105
- conn_attempt += 1
106
- if option_choice.proxy
107
- rest_client = RestClient
108
- rest_client.proxy = option_choice.proxy
109
- rest_client_request = rest_client::Request
110
- else
111
- rest_client_request = RestClient::Request
112
- end
113
-
114
- api_signature_response = generate_signature(
115
- api_secret: api_secret,
116
- http_method: http_method,
117
- api_call: api_call,
118
- params: params,
119
- http_body: http_body
120
- )
121
- api_signature = api_signature_response[:api_signature]
122
- api_timestamp = api_signature_response[:api_timestamp]
123
-
124
- case http_method
125
- when :GET
126
- headers = {
127
- content_type: 'application/json; charset=UTF-8',
128
- CB_ACCESS_TIMESTAMP: api_timestamp,
129
- CB_ACCESS_PASSPHRASE: api_passphrase,
130
- CB_ACCESS_KEY: api_key,
131
- CB_ACCESS_SIGN: api_signature
132
- }
133
-
134
- headers[:params] = params if params
135
- headers[:ORDER_TYPE] = order_type if order_type
136
- headers[:EVENT_NOTES] = event_notes if event_notes
137
-
138
- response = rest_client_request.execute(
139
- method: :GET,
140
- url: "#{api_endpoint}#{api_call}",
141
- headers: headers,
142
- verify_ssl: false
143
- )
144
-
145
- when :DELETE
146
- headers = {
147
- content_type: 'application/json; charset=UTF-8',
148
- CB_ACCESS_TIMESTAMP: api_timestamp,
149
- CB_ACCESS_PASSPHRASE: api_passphrase,
150
- CB_ACCESS_KEY: api_key,
151
- CB_ACCESS_SIGN: api_signature
152
- }
153
-
154
- headers[:params] = params if params
155
- headers[:ORDER_TYPE] = order_type if order_type
156
- headers[:EVENT_NOTES] = event_notes if event_notes
157
-
158
- response = rest_client_request.execute(
159
- method: :DELETE,
160
- url: "#{api_endpoint}#{api_call}",
161
- headers: headers,
162
- verify_ssl: false
163
- )
164
-
165
- when :POST
166
- headers = {
167
- content_type: 'application/json; charset=UTF-8',
168
- CB_ACCESS_TIMESTAMP: api_timestamp,
169
- CB_ACCESS_PASSPHRASE: api_passphrase,
170
- CB_ACCESS_KEY: api_key,
171
- CB_ACCESS_SIGN: api_signature
172
- }
173
-
174
- headers[:params] = params if params
175
- headers[:ORDER_TYPE] = order_type if order_type
176
- headers[:EVENT_NOTES] = event_notes if event_notes
177
-
178
- response = rest_client_request.execute(
179
- method: :POST,
180
- url: "#{api_endpoint}#{api_call}",
181
- headers: headers,
182
- payload: http_body,
183
- verify_ssl: false
184
- )
185
-
186
- else
187
- raise @@logger.error("Unsupported HTTP Method #{http_method} for #{self} Plugin")
188
- end
189
-
190
- JSON.parse(response, symbolize_names: true)
191
- rescue RestClient::Unauthorized => e
192
- File.open('/tmp/cryptum-errors.txt', 'a') do |f|
193
- f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
194
- f.puts "#{self}\n#{e}\n\n\n"
195
- end
196
-
197
- raise e if conn_attempt > max_conn_attempts
198
-
199
- sleep 60
200
- retry
201
- end
202
- rescue RestClient::ExceptionWithResponse => e
203
- File.open('/tmp/cryptum-errors.txt', 'a') do |f|
204
- f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
205
- f.puts "Module: #{self}"
206
- f.puts "URL: #{api_endpoint}#{api_call}"
207
- f.puts "PARAMS: #{params.inspect}"
208
- f.puts "HTTP POST BODY: #{http_body.inspect}" if http_body != ''
209
- f.puts "#{e}\n#{e.response}\n\n\n"
210
- end
211
-
212
- insufficient_funds = '{"message":"Insufficient funds"}'
213
- size -= base_increment if e.response == insufficient_funds
214
-
215
- sleep 0.3
216
- retry
217
- rescue RestClient::TooManyRequests => e
218
- File.open('/tmp/cryptum-errors.txt', 'a') do |f|
219
- f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
220
- f.puts "Module: #{self}"
221
- f.puts "URL: #{api_endpoint}#{api_call}"
222
- f.puts "PARAMS: #{params.inspect}"
223
- f.puts "HTTP POST BODY: #{http_body.inspect}" if http_body != ''
224
- f.puts "#{e}\n#{e.response}\n\n\n"
225
- end
226
-
227
- sleep 1
228
- retry
229
- end
230
-
231
- public_class_method def self.submit_limit_order(opts = {})
232
- option_choice = opts[:option_choice]
233
- env = opts[:env]
234
- price = opts[:price]
235
- size = opts[:size]
236
- buy_or_sell = opts[:buy_or_sell]
237
- event_history = opts[:event_history]
238
- bot_conf = opts[:bot_conf]
239
- buy_order_id = opts[:buy_order_id]
240
-
241
- tpm = bot_conf[:target_profit_margin_percent].to_f
242
- tpm_cast_as_decimal = tpm / 100
243
-
244
- product_id = option_choice.symbol.to_s.gsub('_', '-').upcase
245
-
246
- this_product = event_history.order_book[:this_product]
247
- base_increment = this_product[:base_increment]
248
- quote_increment = this_product[:quote_increment]
249
- # crypto_smallest_decimal = base_increment.to_s.split('.')[-1].length
250
- fiat_smallest_decimal = quote_increment.to_s.split('.')[-1].length
251
-
252
- order_hash = {}
253
-
254
- order_hash[:type] = 'limit'
255
- order_hash[:time_in_force] = 'GTC'
256
-
257
- if buy_or_sell == :buy
258
- order_hash[:time_in_force] = 'GTT'
259
- order_hash[:cancel_after] = 'min'
260
- end
261
-
262
- order_hash[:size] = size
263
- order_hash[:price] = price
264
- order_hash[:side] = buy_or_sell
265
- order_hash[:product_id] = product_id
266
-
267
- http_body = order_hash.to_json
268
-
269
- limit_order_resp = rest_api_call(
270
- option_choice: option_choice,
271
- env: env,
272
- http_method: :POST,
273
- api_call: '/orders',
274
- http_body: http_body,
275
- base_increment: base_increment
276
- )
277
-
278
- # Populate Order ID on the Buy
279
- # to know what to do on the Sell
280
- case buy_or_sell
281
- when :buy
282
- this_order = event_history.order_book[:order_plan].shift
283
- this_order[:buy_order_id] = limit_order_resp[:id]
284
- this_order[:price] = price
285
- targ_price = price.to_f + (price.to_f * tpm_cast_as_decimal)
286
- this_order[:tpm] = format(
287
- '%0.2f',
288
- tpm
289
- )
290
- this_order[:target_price] = format(
291
- "%0.#{fiat_smallest_decimal}f",
292
- targ_price
293
- )
294
-
295
- this_order[:size] = size
296
-
297
- this_order[:color] = :cyan
298
- event_history.order_book[:order_history_meta].push(this_order)
299
- when :sell
300
- sell_order_id = limit_order_resp[:id]
301
- event_history.order_book[:order_history_meta].each do |meta|
302
- if meta[:buy_order_id] == buy_order_id
303
- meta[:sell_order_id] = sell_order_id
304
- meta[:color] = :yellow
305
- end
306
- end
307
- end
308
-
309
- event_history
310
- rescue StandardError => e
311
- raise e
312
- end
313
-
314
- public_class_method def self.gtfo(opts = {})
315
- option_choice = opts[:option_choice]
316
- env = opts[:env]
317
- event_history = opts[:event_history]
318
-
319
- # Cancel all open orders
320
- cancel_all_open_orders(
321
- env: env,
322
- option_choice: option_choice
323
- )
324
-
325
- product_id = option_choice.symbol.to_s.gsub('_', '-').upcase
326
-
327
- this_product = event_history.order_book[:this_product]
328
- base_increment = this_product[:base_increment]
329
- quote_increment = this_product[:quote_increment]
330
- crypto_smallest_decimal = base_increment.to_s.split('.')[-1].length
331
- fiat_smallest_decimal = quote_increment.to_s.split('.')[-1].length
332
-
333
- # TODO: Calculate / Price / Size
334
- last_three_prices_arr = []
335
- last_ticker_price = event_history.order_book[:ticker_price].to_f
336
- second_to_last_ticker_price = event_history.order_book[:ticker_price_second_to_last].to_f
337
- third_to_last_ticker_price = event_history.order_book[:ticker_price_third_to_last].to_f
338
- last_three_prices_arr.push(last_ticker_price)
339
- last_three_prices_arr.push(second_to_last_ticker_price)
340
- last_three_prices_arr.push(third_to_last_ticker_price)
341
- limit_price = last_three_prices_arr.sort[1]
342
- price = format(
343
- "%0.#{fiat_smallest_decimal}f",
344
- limit_price
345
- )
346
-
347
- crypto_currency = option_choice.symbol.to_s.upcase.split('_').first.to_sym
348
- portfolio = event_history.order_book[:portfolio]
349
- this_account = portfolio.select do |account|
350
- account[:currency] == crypto_currency.to_s
351
- end
352
- balance = format(
353
- "%0.#{crypto_smallest_decimal}f",
354
- this_account.first[:balance]
355
- )
356
-
357
- current_crypto_fiat_value = format(
358
- '%0.2f',
359
- balance.to_f * price.to_f
360
- )
361
-
362
- order_hash = {}
363
-
364
- order_hash[:type] = 'limit'
365
- order_hash[:time_in_force] = 'GTT'
366
- order_hash[:cancel_after] = 'min'
367
-
368
- order_hash[:size] = balance
369
- order_hash[:price] = price
370
- order_hash[:side] = :sell
371
- order_hash[:product_id] = product_id
372
-
373
- http_body = order_hash.to_json
374
-
375
- limit_order_resp = rest_api_call(
376
- option_choice: option_choice,
377
- env: env,
378
- http_method: :POST,
379
- api_call: '/orders',
380
- http_body: http_body,
381
- base_increment: base_increment
382
- )
383
-
384
- # Populate Order ID on the Buy
385
- # to know what to do on the Sell
386
- this_order = {}
387
- this_order[:plan_no] = '0.0'
388
- this_order[:fiat_available] = '0.00'
389
- this_order[:risk_alloc] = current_crypto_fiat_value
390
- this_order[:allocation_decimal] = '1.0'
391
- this_order[:allocation_percent] = '100.0'
392
- this_order[:invest] = current_crypto_fiat_value
393
- this_order[:return] = current_crypto_fiat_value
394
- this_order[:profit] = '0.0'
395
- this_order[:buy_order_id] = 'N/A'
396
- this_order[:price] = price
397
- this_order[:tpm] = '0.00'
398
- this_order[:target_price] = current_crypto_fiat_value
399
- this_order[:size] = balance
400
- this_order[:color] = :magenta
401
- this_order[:sell_order_id] = limit_order_resp[:id]
402
-
403
- event_history.order_book[:order_history_meta].push(this_order)
404
-
405
- event_history
406
- rescue StandardError => e
407
- raise e
408
- end
409
-
410
- # public_class_method def self.cancel_open_order(opts = {})
411
- # env = opts[:env]
412
- # option_choice = opts[:option_choice]
413
- # order_id = opts[:order_id]
414
- # order_type = opts[:order_type]
415
-
416
- # product_id = option_choice.symbol.to_s.gsub('_', '-').upcase
417
-
418
- # order_hash = {}
419
- # order_hash[:product_id] = product_id
420
-
421
- # params = order_hash
422
-
423
- # rest_api_call(
424
- # env: env,
425
- # http_method: :DELETE,
426
- # api_call: "/orders/#{order_id}",
427
- # option_choice: option_choice,
428
- # params: params,
429
- # order_type: order_type
430
- # )
431
- # rescue StandardError => e
432
- # raise e
433
- # end
434
-
435
- public_class_method def self.cancel_all_open_orders(opts = {})
436
- env = opts[:env]
437
- option_choice = opts[:option_choice]
438
- event_notes = opts[:event_notes]
439
-
440
- product_id = option_choice.symbol.to_s.gsub('_', '-').upcase
441
-
442
- order_hash = {}
443
- order_hash[:product_id] = product_id
444
-
445
- # http_body = order_hash.to_json
446
- params = order_hash
447
-
448
- canceled_order_id_arr = []
449
- loop do
450
- canceled_order_id_arr = rest_api_call(
451
- env: env,
452
- http_method: :DELETE,
453
- api_call: '/orders',
454
- option_choice: option_choice,
455
- params: params,
456
- event_notes: event_notes
457
- )
458
-
459
- break if canceled_order_id_arr.empty?
460
- end
461
- canceled_order_id_arr
462
- rescue StandardError => e
463
- raise e
464
- end
465
-
466
- public_class_method def self.get_products(opts = {})
467
- option_choice = opts[:option_choice]
468
- env = opts[:env]
469
-
470
- products = rest_api_call(
471
- option_choice: option_choice,
472
- env: env,
473
- http_method: :GET,
474
- api_call: '/products'
475
- )
476
-
477
- if products.length.positive?
478
- supported_products_filter = products.select do |product|
479
- product[:id].match?(/USD$/) &&
480
- product[:status] == 'online' &&
481
- product[:fx_stablecoin] == false
482
- end
483
- sorted_products = supported_products_filter.sort_by { |hash| hash[:id] }
484
- end
485
-
486
- sorted_products
487
- rescue StandardError => e
488
- raise e
489
- end
490
-
491
- # List Supported Cryptum Products and Exit
492
- public_class_method def self.list_products_and_exit(opts = {})
493
- option_choice = opts[:option_choice]
494
- env = opts[:env]
495
-
496
- puts "\n#{option_choice.driver_name} Supports the Following Products:"
497
- products = Cryptum::API.get_products(
498
- option_choice: option_choice,
499
- env: env
500
- )
501
-
502
- products.map do |product|
503
- puts product[:id].downcase
504
- end
505
-
506
- exit 0
507
- rescue StandardError => e
508
- raise e
509
- end
510
-
511
- private_class_method def self.get_exchange_rates(opts = {})
512
- option_choice = opts[:option_choice]
513
- env = opts[:env]
514
-
515
- api_endpoint = 'https://api.coinbase.com/v2'
516
- exchange_rates_api_call = '/exchange-rates'
517
-
518
- # We don't always get fees back from Coinbase...
519
- # This is a hack to ensure we do.
520
- exchange = {}
521
- exchange = rest_api_call(
522
- option_choice: option_choice,
523
- env: env,
524
- http_method: :GET,
525
- api_endpoint: api_endpoint,
526
- api_call: exchange_rates_api_call
527
- )
528
-
529
- exchange[:data][:rates]
530
- rescue StandardError => e
531
- raise e
532
- end
533
-
534
- public_class_method def self.get_portfolio(opts = {})
535
- option_choice = opts[:option_choice]
536
- env = opts[:env]
537
- crypto = opts[:crypto]
538
- fiat = opts[:fiat]
539
- fiat_portfolio_file = opts[:fiat_portfolio_file]
540
- event_notes = opts[:event_notes]
541
-
542
- # Retrieve Exchange Rates
543
- exchange_rates = get_exchange_rates(
544
- option_choice: option_choice,
545
- env: env
546
- )
547
-
548
- portfolio_complete_arr = []
549
- portfolio_complete_arr = rest_api_call(
550
- option_choice: option_choice,
551
- env: env,
552
- http_method: :GET,
553
- api_call: '/accounts',
554
- event_notes: event_notes
555
- )
556
-
557
- all_products = portfolio_complete_arr.select do |products|
558
- products if products[:balance].to_f.positive?
559
- end
560
-
561
- total_holdings = 0.00
562
- all_products.each do |product|
563
- currency = product[:currency].to_sym
564
- this_exchange_rate = exchange_rates[currency].to_f
565
- total_holdings += product[:balance].to_f / this_exchange_rate
566
- end
567
-
568
- crypto_portfolio = portfolio_complete_arr.select do |product|
569
- product if product[:currency] == crypto
570
- end
571
-
572
- fiat_portfolio = portfolio_complete_arr.select do |product|
573
- product if product[:currency] == fiat
574
- end
575
- fiat_portfolio.last[:total_holdings] = format(
576
- '%0.8f',
577
- total_holdings
578
- )
579
-
580
- File.write(
581
- fiat_portfolio_file,
582
- JSON.pretty_generate(fiat_portfolio)
583
- )
584
-
585
- crypto_portfolio
586
- rescue StandardError => e
587
- raise e
588
- end
589
-
590
- public_class_method def self.get_fees(opts = {})
591
- option_choice = opts[:option_choice]
592
- env = opts[:env]
593
-
594
- fees_api_call = '/fees'
595
-
596
- # We don't always get fees back from Coinbase...
597
- # This is a hack to ensure we do.
598
- fees = {}
599
- fees = rest_api_call(
600
- option_choice: option_choice,
601
- env: env,
602
- http_method: :GET,
603
- api_call: fees_api_call
604
- )
605
-
606
- fees
607
- rescue StandardError => e
608
- raise e
609
- end
12
+ require 'cryptum/api/exchange_rates'
13
+ require 'cryptum/api/fees'
14
+ require 'cryptum/api/order_history'
15
+ require 'cryptum/api/orders'
16
+ require 'cryptum/api/portfolio'
17
+ require 'cryptum/api/products'
18
+ require 'cryptum/api/rest'
19
+ require 'cryptum/api/signature'
610
20
 
611
21
  # public_class_method def self.get_profiles(opts = {})
612
22
  # option_choice = opts[:option_choice]
@@ -618,7 +28,7 @@ module Cryptum
618
28
  # # This is a hack to ensure we do.
619
29
  # profiles = {}
620
30
  # # loop do
621
- # profiles = rest_api_call(
31
+ # profiles = Cryptum::API::Rest.call(
622
32
  # option_choice: option_choice,
623
33
  # env: env,
624
34
  # http_method: :GET,
@@ -635,73 +45,13 @@ module Cryptum
635
45
  # raise e
636
46
  # end
637
47
 
638
- public_class_method def self.get_order_history(opts = {})
639
- option_choice = opts[:option_choice]
640
- env = opts[:env]
641
-
642
- product_id = option_choice.symbol.to_s.gsub('_', '-').upcase
643
-
644
- orders_api_call = '/orders'
645
- params = {}
646
- params[:product_id] = product_id
647
- params[:status] = 'all'
648
-
649
- # We don't always get order_history back from Coinbase...
650
- # This is a hack to ensure we do.
651
- order_history = []
652
- order_history = rest_api_call(
653
- option_choice: option_choice,
654
- env: env,
655
- http_method: :GET,
656
- api_call: orders_api_call,
657
- params: params
658
- )
659
-
660
- # Cast UTC Timestamps as local times
661
- order_history.each do |order|
662
- order[:created_at] = Time.parse(
663
- order[:created_at]
664
- ).localtime.to_s
665
-
666
- next unless order[:done_at]
667
-
668
- order[:done_at] = Time.parse(
669
- order[:done_at]
670
- ).localtime.to_s
671
- end
672
-
673
- order_history
674
- rescue StandardError => e
675
- raise e
676
- end
677
-
678
48
  # Display Usage for this Module
679
49
 
680
50
  public_class_method def self.help
681
51
  puts "USAGE:
682
- signature = #{self}.generate_signature(
683
- api_secret: 'required - Coinbase Pro API Secret',
684
- http_method: 'optional - Defaults to :GET',
685
- api_call: 'optional - Defaults to /users/self/verify',
686
- params: 'optional - HTTP GET Parameters',
687
- http_body: 'optional HTTP POST Body'
688
- )
689
-
690
52
  profiles = #{self}.get_profiles(
691
53
  env: 'required - Coinbase::Option::Environment.get Object'
692
54
  )
693
-
694
- products = #{self}.get_products(
695
- env: 'required - Coinbase::Option::Environment.get Object'
696
- )
697
-
698
- portfolio = #{self}.get_portfolio(
699
- env: 'required - Coinbase::Option::Environment.get Object'
700
- )
701
-
702
- order_history = #{self}.get_order_history(
703
- env: 'required - Coinbase::Option::Environment.get Object'
704
- )
705
55
  "
706
56
  end
707
57
  end
@@ -117,7 +117,7 @@ module Cryptum
117
117
  event_history.order_submitted = true
118
118
  event_history.event_notes = "{ \"event_type\": \"#{event_history.event_type}\", \"cancel\": \"#{event_history.order_canceled}\", \"submitted\": \"#{event_history.order_submitted}\" }" if option_choice.proxy
119
119
 
120
- event_history = Cryptum::API.submit_limit_order(
120
+ event_history = Cryptum::API::Orders.submit_limit_order(
121
121
  option_choice: option_choice,
122
122
  env: env,
123
123
  price: price,
@@ -16,7 +16,7 @@ module Cryptum
16
16
  # order_action = opts[:order_action]
17
17
 
18
18
  terminal_win.key_press_event.key_c = false
19
- Cryptum::API.cancel_all_open_orders(
19
+ Cryptum::API::Orders.cancel_all_open_orders(
20
20
  env: env,
21
21
  option_choice: option_choice
22
22
  )