cryptum 0.0.359 → 0.0.360

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. data/.github/workflows/main.yml +16 -0
  3. data/.gitignore +30 -0
  4. data/.rspec +3 -0
  5. data/.rspec_status +0 -0
  6. data/.rubocop.yml +31 -0
  7. data/.rubocop_todo.yml +36 -0
  8. data/.ruby-gemset +1 -0
  9. data/.ruby-version +1 -0
  10. data/CODE_OF_CONDUCT.md +84 -0
  11. data/Gemfile +38 -0
  12. data/LICENSE +674 -0
  13. data/README.md +87 -0
  14. data/Rakefile +19 -0
  15. data/bin/cryptum +73 -0
  16. data/bin/cryptum-forecast +200 -0
  17. data/bin/cryptum-repl +73 -0
  18. data/bin/cryptum_autoinc_version +38 -0
  19. data/build_cryptum_gem.sh +58 -0
  20. data/cryptum.gemspec +52 -0
  21. data/cryptum_container.sh +1 -0
  22. data/docker/cryptum.json +60 -0
  23. data/docker/cryptum_container.sh +59 -0
  24. data/docker/packer_secrets.json.EXAMPLE +7 -0
  25. data/docker/provisioners/cryptum.sh +11 -0
  26. data/docker/provisioners/docker_bashrc.sh +2 -0
  27. data/docker/provisioners/docker_rvm.sh +22 -0
  28. data/docker/provisioners/init_image.sh +28 -0
  29. data/docker/provisioners/post_install.sh +6 -0
  30. data/docker/provisioners/ruby.sh +16 -0
  31. data/docker/provisioners/upload_globals.sh +49 -0
  32. data/etc/bot_confs/.gitkeep +0 -0
  33. data/etc/bot_confs/BOT_CONF.TEMPLATE +10 -0
  34. data/etc/coinbase_pro.yaml.EXAMPLE +8 -0
  35. data/etc/open_ai.yaml.EXAMPLE +1 -0
  36. data/git_commit.sh +22 -0
  37. data/lib/cryptum/api.rb +688 -0
  38. data/lib/cryptum/bot_conf.rb +197 -0
  39. data/lib/cryptum/event/bot_conf.rb +34 -0
  40. data/lib/cryptum/event/buy.rb +145 -0
  41. data/lib/cryptum/event/cancel.rb +35 -0
  42. data/lib/cryptum/event/exit.rb +35 -0
  43. data/lib/cryptum/event/gtfo.rb +36 -0
  44. data/lib/cryptum/event/history.rb +108 -0
  45. data/lib/cryptum/event/key_press.rb +64 -0
  46. data/lib/cryptum/event/order_book.rb +34 -0
  47. data/lib/cryptum/event/pane.rb +65 -0
  48. data/lib/cryptum/event/parse.rb +181 -0
  49. data/lib/cryptum/event/scroll.rb +200 -0
  50. data/lib/cryptum/event/sell.rb +124 -0
  51. data/lib/cryptum/event.rb +27 -0
  52. data/lib/cryptum/log.rb +34 -0
  53. data/lib/cryptum/matrix.rb +181 -0
  54. data/lib/cryptum/open_ai.rb +156 -0
  55. data/lib/cryptum/option/choice.rb +28 -0
  56. data/lib/cryptum/option.rb +206 -0
  57. data/lib/cryptum/order_book/generate.rb +114 -0
  58. data/lib/cryptum/order_book/indicator.rb +15 -0
  59. data/lib/cryptum/order_book/market_trend.rb +137 -0
  60. data/lib/cryptum/order_book/profit_margin.rb +55 -0
  61. data/lib/cryptum/order_book.rb +19 -0
  62. data/lib/cryptum/portfolio/balance.rb +123 -0
  63. data/lib/cryptum/portfolio.rb +15 -0
  64. data/lib/cryptum/ui/command.rb +314 -0
  65. data/lib/cryptum/ui/key_press_event.rb +33 -0
  66. data/lib/cryptum/ui/market_trend.rb +77 -0
  67. data/lib/cryptum/ui/order_execute_details.rb +297 -0
  68. data/lib/cryptum/ui/order_execution.rb +573 -0
  69. data/lib/cryptum/ui/order_plan.rb +512 -0
  70. data/lib/cryptum/ui/order_plan_details.rb +240 -0
  71. data/lib/cryptum/ui/order_timer.rb +136 -0
  72. data/lib/cryptum/ui/portfolio.rb +221 -0
  73. data/lib/cryptum/ui/signal_engine.rb +109 -0
  74. data/lib/cryptum/ui/terminal_window.rb +111 -0
  75. data/lib/cryptum/ui/ticker.rb +319 -0
  76. data/lib/cryptum/ui.rb +343 -0
  77. data/lib/cryptum/version.rb +5 -0
  78. data/lib/cryptum/web_sock/coinbase.rb +104 -0
  79. data/lib/cryptum/web_sock/event_machine.rb +276 -0
  80. data/lib/cryptum/web_sock.rb +16 -0
  81. data/lib/cryptum.rb +120 -0
  82. data/order_books/.gitkeep +0 -0
  83. data/reinstall_cryptum_gemset.sh +29 -0
  84. data/spec/lib/cryptum/api_spec.rb +10 -0
  85. data/spec/lib/cryptum/event_spec.rb +10 -0
  86. data/spec/lib/cryptum/log_spec.rb +10 -0
  87. data/spec/lib/cryptum/option_spec.rb +10 -0
  88. data/spec/lib/cryptum/order_book/generate_spec.rb +10 -0
  89. data/spec/lib/cryptum/order_book/market_trend_spec.rb +10 -0
  90. data/spec/lib/cryptum/order_book_spec.rb +10 -0
  91. data/spec/lib/cryptum/ui/command_spec.rb +10 -0
  92. data/spec/lib/cryptum/ui/ticker_spec.rb +10 -0
  93. data/spec/lib/cryptum/ui_spec.rb +10 -0
  94. data/spec/lib/cryptum/web_sock_spec.rb +10 -0
  95. data/spec/lib/cryptum_spec.rb +10 -0
  96. data/spec/spec_helper.rb +3 -0
  97. data/upgrade_Gemfile_gems.sh +20 -0
  98. data/upgrade_cryptum.sh +13 -0
  99. data/upgrade_gem.sh +4 -0
  100. data/upgrade_ruby.sh +45 -0
  101. metadata +112 -9
@@ -0,0 +1,512 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Cryptum
6
+ # This plugin is used to Refresh the Cryptum console UI
7
+ module UI
8
+ module OrderPlan
9
+ # Supported Method Parameters::
10
+ # Cryptum::UI::Candle.refresh(
11
+ # order_book: 'required - Order Book Data Structure',
12
+ # event: 'required - Event from Coinbase Web Socket'
13
+ # )
14
+
15
+ public_class_method def self.refresh(opts = {})
16
+ option_choice = opts[:option_choice]
17
+ order_plan_win = opts[:order_plan_win]
18
+ event_history = opts[:event_history]
19
+ indicator_status = opts[:indicator_status]
20
+ bot_conf = opts[:bot_conf]
21
+
22
+ ticker_price = event_history.order_book[:ticker_price].to_f
23
+ return event_history unless ticker_price.positive?
24
+
25
+ market_trend_color = plan_color = :white
26
+
27
+ this_product = event_history.order_book[:this_product]
28
+ base_increment = this_product[:base_increment]
29
+ min_market_funds = this_product[:min_market_funds]
30
+
31
+ crypto_smallest_decimal = base_increment.to_s.split('.')[-1].length
32
+
33
+ autotrade_percent = bot_conf[:autotrade_portfolio_percent].to_f
34
+ autotrade_cast_as_decimal = autotrade_percent / 100
35
+
36
+ tpm = bot_conf[:target_profit_margin_percent].to_f
37
+ tpm_cast_as_decimal = tpm / 100
38
+
39
+ crypto_currency = option_choice.symbol.to_s.upcase.split('_').first.to_sym
40
+ portfolio = event_history.order_book[:portfolio]
41
+ this_account = portfolio.select do |account|
42
+ account[:currency] == crypto_currency.to_s
43
+ end
44
+ raise "ID for Crypto Currency, #{crypto_currency} Not Found" if this_account.empty?
45
+
46
+ balance = format("%0.#{crypto_smallest_decimal}f", this_account.first[:balance])
47
+ fiat_portfolio = event_history.order_book[:fiat_portfolio]
48
+ total_holdings = format('%0.2f', fiat_portfolio.first[:total_holdings])
49
+ fiat_avail_for_trade = format('%0.2f', fiat_portfolio.first[:available])
50
+
51
+ fiat_budget = fiat_avail_for_trade.to_f
52
+
53
+ order_plan = event_history.order_book[:order_plan]
54
+
55
+ current_crypto_fiat_value = format(
56
+ '%0.2f',
57
+ balance.to_f * ticker_price
58
+ )
59
+
60
+ crypto_invested_percent = format(
61
+ '%0.2f',
62
+ current_crypto_fiat_value.to_f.fdiv(total_holdings.to_f) * 100
63
+ )
64
+
65
+ event_history.red_pill = true if crypto_invested_percent.to_f > autotrade_percent
66
+
67
+ # SAUCE 2
68
+ # Generating and/or recalculating order plan
69
+ if event_history.recalculate_order_plan || (
70
+ crypto_invested_percent.to_f <= autotrade_percent &&
71
+ autotrade_percent.positive? && (
72
+ order_plan.empty? || (
73
+ indicator_status.action_signal == :buy &&
74
+ indicator_status.last_action_signal == :sell
75
+ )
76
+ )
77
+ )
78
+
79
+ event_history.red_pill = false
80
+ if indicator_status.action_signal == :buy &&
81
+ indicator_status.last_action_signal == :sell
82
+
83
+ order_plan = []
84
+ # Reset time between orders
85
+ event_history.time_between_orders = event_history.time_between_orders_reset
86
+ event_history.plan_no += 1
87
+ end
88
+
89
+ plan_no_slice = 1
90
+ plan_no = event_history.plan_no
91
+ # Sum up currently invested amount so we don't
92
+ # exceed autotrade % for next order plan generation
93
+ allocation_decimal = 0.0
94
+ risk_target = fiat_budget * autotrade_cast_as_decimal
95
+ risk_alloc = risk_target
96
+
97
+ # TODO: Order Plan <= event_history.max_open_sell_orders
98
+ previous_slice_fiat_investing = 0.00
99
+ last_slice_detected = false
100
+ loop do
101
+ # Calculate min order size
102
+ allocation_decimal += 0.0001
103
+ fiat_investing = risk_alloc * allocation_decimal
104
+
105
+ next unless fiat_investing > min_market_funds.to_f
106
+
107
+ # Increase amount invested in each slice as we increment
108
+ # plan numbers (i.e. slices) in the order plan cycle
109
+ slice_alloc = fiat_budget * allocation_decimal
110
+ fiat_investing = slice_alloc + previous_slice_fiat_investing
111
+
112
+ risk_alloc = fiat_budget * autotrade_cast_as_decimal
113
+ allocation_percent = allocation_decimal * 100
114
+
115
+ break if order_plan.map { |op| op[:invest].to_f }.sum > risk_target ||
116
+ allocation_percent > 100 ||
117
+ last_slice_detected
118
+
119
+ next unless fiat_budget >= min_market_funds.to_f
120
+
121
+ if fiat_investing > fiat_budget
122
+ last_slice_detected = true
123
+ fiat_investing = fiat_budget
124
+ end
125
+
126
+ fiat_returning = fiat_investing + (
127
+ fiat_investing * tpm_cast_as_decimal
128
+ )
129
+ profit = fiat_returning - fiat_investing
130
+
131
+ this_plan_no = "#{plan_no}.#{plan_no_slice}"
132
+ if event_history.recalculate_order_plan
133
+ order_slice = order_plan.find do |order|
134
+ order[:plan_no] == this_plan_no
135
+ end
136
+ end
137
+ order_slice ||= {}
138
+ order_slice[:plan_no] = this_plan_no
139
+ order_slice[:fiat_available] = format('%0.2f', fiat_budget)
140
+ order_slice[:risk_alloc] = format('%0.2f', risk_alloc)
141
+ order_slice[:allocation_decimal] = format(
142
+ '%0.8f',
143
+ allocation_decimal
144
+ )
145
+ order_slice[:allocation_percent] = format(
146
+ '%0.2f',
147
+ allocation_percent
148
+ )
149
+ order_slice[:slice_alloc] = format('%0.2f', slice_alloc)
150
+ order_slice[:risk_target] = format('%0.2f', risk_target)
151
+ order_slice[:previous_slice_invest] = format(
152
+ '%0.2f',
153
+ previous_slice_fiat_investing
154
+ )
155
+ order_slice[:invest] = format('%0.2f', fiat_investing)
156
+ order_slice[:return] = format('%0.2f', fiat_returning)
157
+ order_slice[:profit] = format('%0.2f', profit)
158
+ order_slice[:tpm] = tpm
159
+ order_slice[:autotrade_percent] = autotrade_percent
160
+ order_slice[:color] = plan_color
161
+ order_slice[:last_slice] = false
162
+
163
+ order_plan.push(order_slice) unless event_history.recalculate_order_plan
164
+ fiat_budget -= fiat_investing
165
+ previous_slice_fiat_investing = fiat_investing
166
+ plan_no_slice += 1
167
+ end
168
+ order_plan.last[:last_slice] = true if order_plan.any?
169
+ op_last_slice_invest = order_plan.last[:invest].to_f if order_plan.any?
170
+ order_plan.last[:invest] = fiat_budget if order_plan.any? &&
171
+ op_last_slice_invest > fiat_budget &&
172
+ fiat_budget > min_market_funds.to_f
173
+
174
+ event_history.order_book[:order_plan] = order_plan
175
+ end
176
+
177
+ red_pill_alert = '| RED PILL ALERT |'
178
+ red_pill_msg = '- Autotrade % Exhausted -'
179
+ event_history.red_pill = true if order_plan.empty?
180
+
181
+ if event_history.red_pill
182
+ order_plan_prefix = '--'
183
+ # max_order_plan_slices = '0'
184
+ order_plan_volume_out = '0.00'
185
+ order_plan_profit_sum_out = '0.00'
186
+ order_plan_exec_percent = '0.00'
187
+ else
188
+ order_plan_len = order_plan.length
189
+ order_plan_prefix = order_plan.last[:plan_no].split('.').first
190
+ max_order_plan_slices = order_plan.last[:plan_no].split('.').last.to_i
191
+ calc_order_plan_exec = (
192
+ 1 - (order_plan_len / max_order_plan_slices.to_f)
193
+ ) * 100
194
+ order_plan_volume = order_plan.map do |op|
195
+ op[:invest].to_f
196
+ end.sum
197
+ order_plan_volume_out = Cryptum.beautify_large_number(
198
+ value: format(
199
+ '%0.2f',
200
+ order_plan_volume
201
+ )
202
+ )
203
+ order_plan_profit_sum = order_plan.map do |op|
204
+ op[:profit].to_f
205
+ end.sum
206
+ order_plan_profit_sum_out = Cryptum.beautify_large_number(
207
+ value: format(
208
+ '%0.2f',
209
+ order_plan_profit_sum
210
+ )
211
+ )
212
+ order_plan_exec_percent = format('%0.2f', calc_order_plan_exec)
213
+ end
214
+
215
+ # TODO: Everything Above this Line Needs to be Indicators ^
216
+
217
+ # UI
218
+ col_just1 = (Curses.cols - Cryptum::UI.col_first) - 1
219
+ col_just4 = Curses.cols - Cryptum::UI.col_fourth
220
+
221
+ # ROW 1
222
+ out_line_no = 0
223
+ line_color = :white
224
+ header_color = :white
225
+ header_style = :bold
226
+ style = :bold
227
+ if event_history.order_plan_win_active
228
+ line_color = :blue
229
+ header_color = :blue
230
+ header_style = :reverse
231
+ end
232
+
233
+ Cryptum::UI.line(
234
+ ui_win: order_plan_win,
235
+ out_line_no: out_line_no,
236
+ color: line_color
237
+ )
238
+
239
+ # ROW 2
240
+ out_line_no += 1
241
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
242
+ order_plan_win.clrtoeol
243
+ Cryptum::UI.colorize(
244
+ ui_win: order_plan_win,
245
+ color: header_color,
246
+ style: header_style,
247
+ string: ''.ljust(col_just1, ' ')
248
+ )
249
+
250
+ header_str = "- ORDER PLAN | CYCLE ##{order_plan_prefix} -"
251
+ header_str = '- ORDER PLAN | UNAVAILABLE -' if event_history.red_pill
252
+ order_plan_win.setpos(
253
+ out_line_no,
254
+ Cryptum::UI.col_center(str: header_str)
255
+ )
256
+
257
+ Cryptum::UI.colorize(
258
+ ui_win: order_plan_win,
259
+ color: header_color,
260
+ style: header_style,
261
+ string: header_str
262
+ )
263
+
264
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_fourth)
265
+ Cryptum::UI.colorize(
266
+ ui_win: order_plan_win,
267
+ color: header_color,
268
+ style: header_style,
269
+ string: ''.ljust(col_just4, ' ')
270
+ )
271
+
272
+ # ROWS 3-10
273
+ remaining_blank_rows = 0
274
+ max_rows_to_display = event_history.order_plan_max_rows_to_display
275
+ remaining_blank_rows = max_rows_to_display if order_plan.empty?
276
+ if event_history.red_pill
277
+ out_line_no += 1
278
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
279
+ order_plan_win.clrtoeol
280
+
281
+ Cryptum::UI.colorize(
282
+ ui_win: order_plan_win,
283
+ color: :red,
284
+ style: :highlight,
285
+ string: ''.ljust(col_just1, ' ')
286
+ )
287
+
288
+ order_plan_win.setpos(
289
+ out_line_no,
290
+ Cryptum::UI.col_center(str: red_pill_alert)
291
+ )
292
+ Cryptum::UI.colorize(
293
+ ui_win: order_plan_win,
294
+ color: :red,
295
+ style: :highlight,
296
+ string: red_pill_alert
297
+ )
298
+
299
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_fourth)
300
+ Cryptum::UI.colorize(
301
+ ui_win: order_plan_win,
302
+ color: :red,
303
+ style: :highlight,
304
+ string: ''.ljust(col_just4, ' ')
305
+ )
306
+
307
+ out_line_no += 1
308
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
309
+ order_plan_win.clrtoeol
310
+
311
+ Cryptum::UI.colorize(
312
+ ui_win: order_plan_win,
313
+ color: :yellow,
314
+ string: ''.ljust(col_just1, ' ')
315
+ )
316
+
317
+ order_plan_win.setpos(
318
+ out_line_no,
319
+ Cryptum::UI.col_center(str: red_pill_msg)
320
+ )
321
+ Cryptum::UI.colorize(
322
+ ui_win: order_plan_win,
323
+ color: :yellow,
324
+ style: :bold,
325
+ string: red_pill_msg
326
+ )
327
+
328
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_fourth)
329
+ Cryptum::UI.colorize(
330
+ ui_win: order_plan_win,
331
+ color: :yellow,
332
+ string: ''.ljust(col_just4, ' ')
333
+ )
334
+
335
+ max_rows_to_display.times.each do
336
+ out_line_no += 1
337
+ this_matrix_row = Cryptum::Matrix.generate(cols: Curses.cols)
338
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
339
+ order_plan_win.clrtoeol
340
+ Cryptum::UI.colorize(
341
+ ui_win: order_plan_win,
342
+ color: :red,
343
+ style: :bold,
344
+ string: this_matrix_row
345
+ )
346
+ end
347
+ else
348
+ market_trend_color = indicator_status.market_trend[:color] if indicator_status.market_trend
349
+ plan_color = :cyan if market_trend_color == :red
350
+ plan_color = :green if market_trend_color == :green
351
+
352
+ # ROWS 3-10
353
+ max_rows_to_display = event_history.order_plan_max_rows_to_display
354
+ first_row = event_history.order_plan_index_offset
355
+ last_row = first_row + max_rows_to_display
356
+ if last_row >= order_plan.length
357
+ last_row = order_plan.length - 1
358
+ event_history.order_plan_max_records_available_to_display = last_row if last_row < max_rows_to_display
359
+ first_row = last_row - event_history.order_plan_max_records_available_to_display
360
+ event_history.order_plan_index_offset = first_row
361
+ remaining_blank_rows = max_rows_to_display - last_row
362
+ end
363
+
364
+ selected_order = event_history.order_plan_selected_data
365
+ order_plan[first_row..last_row].each do |order|
366
+ out_line_no += 1
367
+ current_line = out_line_no - 2
368
+
369
+ style = :normal
370
+ if event_history.order_plan_row_to_select == current_line
371
+ style = :highlight
372
+ selected_order = order
373
+ selected_order[:color] = plan_color
374
+ end
375
+
376
+ fiat_avail_out = Cryptum.beautify_large_number(
377
+ value: order[:fiat_available]
378
+ )
379
+ risk_alloc_out = Cryptum.beautify_large_number(
380
+ value: order[:risk_alloc]
381
+ )
382
+ slice_alloc_out = Cryptum.beautify_large_number(
383
+ value: order[:slice_alloc]
384
+ )
385
+ previous_slice_invest_out = Cryptum.beautify_large_number(
386
+ value: order[:previous_slice_invest]
387
+ )
388
+ invest_out = Cryptum.beautify_large_number(
389
+ value: order[:invest]
390
+ )
391
+ profit_out = Cryptum.beautify_large_number(
392
+ value: order[:profit]
393
+ )
394
+ tpm_out = format('%0.2f', tpm)
395
+ return_out = Cryptum.beautify_large_number(
396
+ value: order[:return]
397
+ )
398
+ plan_no = "#{order[:plan_no]}|"
399
+ fiat = "#{autotrade_percent}% of $#{fiat_avail_out} = "
400
+ alloc = "$#{risk_alloc_out} @ #{order[:allocation_percent]}% = "
401
+ alloc = "$#{risk_alloc_out}" if order[:last_slice]
402
+ invest = "$#{slice_alloc_out} + $#{previous_slice_invest_out} = $#{invest_out} + #{tpm_out}% = "
403
+ invest = " + #{tpm_out}% = " if order[:last_slice]
404
+
405
+ returns = "$#{return_out}|"
406
+ profit = "Profit: $#{profit_out}"
407
+
408
+ order_plan_invest = "#{plan_no}#{fiat}#{alloc}#{invest}"
409
+ order_plan_return = "#{returns}#{profit}"
410
+
411
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
412
+ order_plan_win.clrtoeol
413
+ Cryptum::UI.colorize(
414
+ ui_win: order_plan_win,
415
+ color: plan_color,
416
+ style: style,
417
+ string: "#{order_plan_invest}#{order_plan_return}".ljust(col_just1, '.')
418
+ )
419
+
420
+ Cryptum::UI.colorize(
421
+ ui_win: order_plan_win,
422
+ color: plan_color,
423
+ style: style,
424
+ string: ''.ljust(col_just4, ' ')
425
+ )
426
+ end
427
+ event_history.order_plan_selected_data = selected_order
428
+
429
+ # Clear to SUMMARY
430
+ # (Only Applicable if order_book[:order_plan] < max_rows_to_display)
431
+ # out_line_no += 1
432
+ if remaining_blank_rows.positive?
433
+ rows_to_blank = (out_line_no + remaining_blank_rows)
434
+ out_line_no += 1
435
+ (out_line_no..rows_to_blank).each do |clr_line|
436
+ out_line_no = clr_line
437
+ order_plan_win.setpos(clr_line, Cryptum::UI.col_first)
438
+ order_plan_win.clrtoeol
439
+ Cryptum::UI.colorize(
440
+ ui_win: order_plan_win,
441
+ color: :white,
442
+ style: :normal,
443
+ string: ''.ljust(col_just1, ' ')
444
+ )
445
+ end
446
+ end
447
+
448
+ # ROW 10
449
+ out_line_no += 1
450
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
451
+ order_plan_win.clrtoeol
452
+ Cryptum::UI.colorize(
453
+ ui_win: order_plan_win,
454
+ color: header_color,
455
+ style: header_style,
456
+ string: ''.ljust(col_just1, ' ')
457
+ )
458
+
459
+ header_str = "CYCLE SUMMARY | Risk Allocated: $#{order_plan_volume_out} | Profit: $#{order_plan_profit_sum_out} | #{order_plan_exec_percent}% Done"
460
+ order_plan_win.setpos(
461
+ out_line_no,
462
+ Cryptum::UI.col_center(str: header_str)
463
+ )
464
+
465
+ Cryptum::UI.colorize(
466
+ ui_win: order_plan_win,
467
+ color: header_color,
468
+ style: header_style,
469
+ string: header_str
470
+ )
471
+
472
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_fourth)
473
+ order_plan_win.clrtoeol
474
+ Cryptum::UI.colorize(
475
+ ui_win: order_plan_win,
476
+ color: header_color,
477
+ style: header_style,
478
+ string: ''.ljust(col_just4, ' ')
479
+ )
480
+ end
481
+
482
+ # ROW 11
483
+ out_line_no += 1
484
+ Cryptum::UI.line(
485
+ ui_win: order_plan_win,
486
+ out_line_no: out_line_no,
487
+ color: line_color
488
+ )
489
+
490
+ order_plan_win.refresh
491
+
492
+ event_history
493
+ rescue Interrupt
494
+ # Exit Gracefully if CTRL+C is Pressed During Session
495
+ Cryptum.exit_gracefully(which_self: self)
496
+ rescue StandardError => e
497
+ raise e
498
+ end
499
+
500
+ # Display Usage for this Module
501
+
502
+ public_class_method def self.help
503
+ puts "USAGE:
504
+ #{self}.refresh(
505
+ order_book: 'required - Order Book Data Structure',
506
+ event: 'required - Event from Coinbase Web Socket'
507
+ )
508
+ "
509
+ end
510
+ end
511
+ end
512
+ end