cryptum 0.0.355 → 0.0.356

Sign up to get free protection for your applications and to get access to all the features.
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