cryptum 0.0.355 → 0.0.356

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.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. metadata +13 -116
  3. data/.github/workflows/main.yml +0 -16
  4. data/.gitignore +0 -30
  5. data/.rspec +0 -3
  6. data/.rspec_status +0 -0
  7. data/.rubocop.yml +0 -31
  8. data/.rubocop_todo.yml +0 -32
  9. data/.ruby-gemset +0 -1
  10. data/.ruby-version +0 -1
  11. data/CODE_OF_CONDUCT.md +0 -84
  12. data/Gemfile +0 -38
  13. data/LICENSE +0 -674
  14. data/README.md +0 -87
  15. data/Rakefile +0 -19
  16. data/bin/cryptum +0 -73
  17. data/bin/cryptum-forecast +0 -200
  18. data/bin/cryptum-repl +0 -73
  19. data/bin/cryptum_autoinc_version +0 -38
  20. data/build_cryptum_gem.sh +0 -58
  21. data/cryptum.gemspec +0 -52
  22. data/cryptum_container.sh +0 -1
  23. data/docker/cryptum.json +0 -60
  24. data/docker/cryptum_container.sh +0 -59
  25. data/docker/packer_secrets.json.EXAMPLE +0 -7
  26. data/docker/provisioners/cryptum.sh +0 -11
  27. data/docker/provisioners/docker_bashrc.sh +0 -2
  28. data/docker/provisioners/docker_rvm.sh +0 -22
  29. data/docker/provisioners/init_image.sh +0 -28
  30. data/docker/provisioners/post_install.sh +0 -6
  31. data/docker/provisioners/ruby.sh +0 -16
  32. data/docker/provisioners/upload_globals.sh +0 -49
  33. data/etc/bot_confs/.gitkeep +0 -0
  34. data/etc/bot_confs/BOT_CONF.TEMPLATE +0 -10
  35. data/etc/coinbase_pro.yaml.EXAMPLE +0 -8
  36. data/etc/open_ai.yaml.EXAMPLE +0 -1
  37. data/git_commit.sh +0 -22
  38. data/lib/cryptum/api.rb +0 -688
  39. data/lib/cryptum/bot_conf.rb +0 -197
  40. data/lib/cryptum/event/bot_conf.rb +0 -34
  41. data/lib/cryptum/event/buy.rb +0 -145
  42. data/lib/cryptum/event/cancel.rb +0 -35
  43. data/lib/cryptum/event/exit.rb +0 -35
  44. data/lib/cryptum/event/gtfo.rb +0 -36
  45. data/lib/cryptum/event/history.rb +0 -105
  46. data/lib/cryptum/event/key_press.rb +0 -64
  47. data/lib/cryptum/event/order_book.rb +0 -34
  48. data/lib/cryptum/event/pane.rb +0 -65
  49. data/lib/cryptum/event/parse.rb +0 -181
  50. data/lib/cryptum/event/scroll.rb +0 -200
  51. data/lib/cryptum/event/sell.rb +0 -124
  52. data/lib/cryptum/event.rb +0 -27
  53. data/lib/cryptum/log.rb +0 -34
  54. data/lib/cryptum/matrix.rb +0 -181
  55. data/lib/cryptum/open_ai.rb +0 -156
  56. data/lib/cryptum/option/choice.rb +0 -28
  57. data/lib/cryptum/option.rb +0 -206
  58. data/lib/cryptum/order_book/generate.rb +0 -114
  59. data/lib/cryptum/order_book/indicator.rb +0 -15
  60. data/lib/cryptum/order_book/market_trend.rb +0 -137
  61. data/lib/cryptum/order_book/profit_margin.rb +0 -55
  62. data/lib/cryptum/order_book.rb +0 -19
  63. data/lib/cryptum/portfolio/balance.rb +0 -123
  64. data/lib/cryptum/portfolio.rb +0 -15
  65. data/lib/cryptum/ui/command.rb +0 -314
  66. data/lib/cryptum/ui/key_press_event.rb +0 -33
  67. data/lib/cryptum/ui/market_trend.rb +0 -74
  68. data/lib/cryptum/ui/order_execute_details.rb +0 -297
  69. data/lib/cryptum/ui/order_execution.rb +0 -573
  70. data/lib/cryptum/ui/order_plan.rb +0 -503
  71. data/lib/cryptum/ui/order_plan_details.rb +0 -240
  72. data/lib/cryptum/ui/order_timer.rb +0 -121
  73. data/lib/cryptum/ui/portfolio.rb +0 -221
  74. data/lib/cryptum/ui/signal_engine.rb +0 -109
  75. data/lib/cryptum/ui/terminal_window.rb +0 -111
  76. data/lib/cryptum/ui/ticker.rb +0 -319
  77. data/lib/cryptum/ui.rb +0 -343
  78. data/lib/cryptum/version.rb +0 -5
  79. data/lib/cryptum/web_sock/coinbase.rb +0 -102
  80. data/lib/cryptum/web_sock/event_machine.rb +0 -274
  81. data/lib/cryptum/web_sock.rb +0 -16
  82. data/lib/cryptum.rb +0 -120
  83. data/order_books/.gitkeep +0 -0
  84. data/reinstall_cryptum_gemset.sh +0 -29
  85. data/spec/lib/cryptum/api_spec.rb +0 -10
  86. data/spec/lib/cryptum/event_spec.rb +0 -10
  87. data/spec/lib/cryptum/log_spec.rb +0 -10
  88. data/spec/lib/cryptum/option_spec.rb +0 -10
  89. data/spec/lib/cryptum/order_book/generate_spec.rb +0 -10
  90. data/spec/lib/cryptum/order_book/market_trend_spec.rb +0 -10
  91. data/spec/lib/cryptum/order_book_spec.rb +0 -10
  92. data/spec/lib/cryptum/ui/command_spec.rb +0 -10
  93. data/spec/lib/cryptum/ui/ticker_spec.rb +0 -10
  94. data/spec/lib/cryptum/ui_spec.rb +0 -10
  95. data/spec/lib/cryptum/web_sock_spec.rb +0 -10
  96. data/spec/lib/cryptum_spec.rb +0 -10
  97. data/spec/spec_helper.rb +0 -3
  98. data/upgrade_Gemfile_gems.sh +0 -20
  99. data/upgrade_cryptum.sh +0 -13
  100. data/upgrade_gem.sh +0 -4
  101. data/upgrade_ruby.sh +0 -45
data/lib/cryptum/api.rb DELETED
@@ -1,688 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'addressable'
4
- require 'base64'
5
- require 'json'
6
- require 'openssl'
7
- require 'rest-client'
8
-
9
- module Cryptum
10
- # This plugin is used to interact withbtje Coinbase REST API
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
- private_class_method def self.get_exchange_rates(opts = {})
492
- option_choice = opts[:option_choice]
493
- env = opts[:env]
494
-
495
- api_endpoint = 'https://api.coinbase.com/v2'
496
- exchange_rates_api_call = '/exchange-rates'
497
-
498
- # We don't always get fees back from Coinbase...
499
- # This is a hack to ensure we do.
500
- exchange = {}
501
- exchange = rest_api_call(
502
- option_choice: option_choice,
503
- env: env,
504
- http_method: :GET,
505
- api_endpoint: api_endpoint,
506
- api_call: exchange_rates_api_call
507
- )
508
-
509
- exchange[:data][:rates]
510
- rescue StandardError => e
511
- raise e
512
- end
513
-
514
- public_class_method def self.get_portfolio(opts = {})
515
- option_choice = opts[:option_choice]
516
- env = opts[:env]
517
- crypto = opts[:crypto]
518
- fiat = opts[:fiat]
519
- fiat_portfolio_file = opts[:fiat_portfolio_file]
520
- event_notes = opts[:event_notes]
521
-
522
- # Retrieve Exchange Rates
523
- exchange_rates = get_exchange_rates(
524
- option_choice: option_choice,
525
- env: env
526
- )
527
-
528
- portfolio_complete_arr = []
529
- portfolio_complete_arr = rest_api_call(
530
- option_choice: option_choice,
531
- env: env,
532
- http_method: :GET,
533
- api_call: '/accounts',
534
- event_notes: event_notes
535
- )
536
-
537
- all_products = portfolio_complete_arr.select do |products|
538
- products if products[:balance].to_f.positive?
539
- end
540
-
541
- total_holdings = 0.00
542
- all_products.each do |product|
543
- currency = product[:currency].to_sym
544
- this_exchange_rate = exchange_rates[currency].to_f
545
- total_holdings += product[:balance].to_f / this_exchange_rate
546
- end
547
-
548
- crypto_portfolio = portfolio_complete_arr.select do |product|
549
- product if product[:currency] == crypto
550
- end
551
-
552
- fiat_portfolio = portfolio_complete_arr.select do |product|
553
- product if product[:currency] == fiat
554
- end
555
- fiat_portfolio.last[:total_holdings] = format(
556
- '%0.8f',
557
- total_holdings
558
- )
559
-
560
- File.write(
561
- fiat_portfolio_file,
562
- JSON.pretty_generate(fiat_portfolio)
563
- )
564
-
565
- crypto_portfolio
566
- rescue StandardError => e
567
- raise e
568
- end
569
-
570
- public_class_method def self.get_fees(opts = {})
571
- option_choice = opts[:option_choice]
572
- env = opts[:env]
573
-
574
- fees_api_call = '/fees'
575
-
576
- # We don't always get fees back from Coinbase...
577
- # This is a hack to ensure we do.
578
- fees = {}
579
- fees = rest_api_call(
580
- option_choice: option_choice,
581
- env: env,
582
- http_method: :GET,
583
- api_call: fees_api_call
584
- )
585
-
586
- fees
587
- rescue StandardError => e
588
- raise e
589
- end
590
-
591
- # public_class_method def self.get_profiles(opts = {})
592
- # option_choice = opts[:option_choice]
593
- # env = opts[:env]
594
-
595
- # profiles_api_call = '/profiles'
596
-
597
- # # We don't always get fees back from Coinbase...
598
- # # This is a hack to ensure we do.
599
- # profiles = {}
600
- # # loop do
601
- # profiles = rest_api_call(
602
- # option_choice: option_choice,
603
- # env: env,
604
- # http_method: :GET,
605
- # api_call: profiles_api_call
606
- # )
607
-
608
- # # break unless fees.empty?
609
-
610
- # # sleep 0.3
611
- # # end
612
-
613
- # profiles
614
- # rescue StandardError => e
615
- # raise e
616
- # end
617
-
618
- public_class_method def self.get_order_history(opts = {})
619
- option_choice = opts[:option_choice]
620
- env = opts[:env]
621
-
622
- product_id = option_choice.symbol.to_s.gsub('_', '-').upcase
623
-
624
- orders_api_call = '/orders'
625
- params = {}
626
- params[:product_id] = product_id
627
- params[:status] = 'all'
628
-
629
- # We don't always get order_history back from Coinbase...
630
- # This is a hack to ensure we do.
631
- order_history = []
632
- order_history = rest_api_call(
633
- option_choice: option_choice,
634
- env: env,
635
- http_method: :GET,
636
- api_call: orders_api_call,
637
- params: params
638
- )
639
-
640
- # Cast UTC Timestamps as local times
641
- order_history.each do |order|
642
- order[:created_at] = Time.parse(
643
- order[:created_at]
644
- ).localtime.to_s
645
-
646
- next unless order[:done_at]
647
-
648
- order[:done_at] = Time.parse(
649
- order[:done_at]
650
- ).localtime.to_s
651
- end
652
-
653
- order_history
654
- rescue StandardError => e
655
- raise e
656
- end
657
-
658
- # Display Usage for this Module
659
-
660
- public_class_method def self.help
661
- puts "USAGE:
662
- signature = #{self}.generate_signature(
663
- api_secret: 'required - Coinbase Pro API Secret',
664
- http_method: 'optional - Defaults to :GET',
665
- api_call: 'optional - Defaults to /users/self/verify',
666
- params: 'optional - HTTP GET Parameters',
667
- http_body: 'optional HTTP POST Body'
668
- )
669
-
670
- profiles = #{self}.get_profiles(
671
- env: 'required - Coinbase::Option.get_env Object'
672
- )
673
-
674
- products = #{self}.get_products(
675
- env: 'required - Coinbase::Option.get_env Object'
676
- )
677
-
678
- portfolio = #{self}.get_portfolio(
679
- env: 'required - Coinbase::Option.get_env Object'
680
- )
681
-
682
- order_history = #{self}.get_order_history(
683
- env: 'required - Coinbase::Option.get_env Object'
684
- )
685
- "
686
- end
687
- end
688
- end