cryptum 0.0.359 → 0.0.361

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 +583 -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 +113 -10
@@ -0,0 +1,583 @@
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 OrderExecution
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_execute_win = opts[:order_execute_win]
18
+ env = opts[:env]
19
+ event_history = opts[:event_history]
20
+ indicator_status = opts[:indicator_status]
21
+ bot_conf = opts[:bot_conf]
22
+
23
+ event_type = event_history.event_type if option_choice.autotrade
24
+ event_side = event_history.event[:side].to_s.to_sym if option_choice.autotrade
25
+ event_reason = event_history.event[:reason].to_s.to_sym if option_choice.autotrade
26
+
27
+ ticker_price = event_history.order_book[:ticker_price].to_f
28
+ open_24h = event_history.order_book[:open_24h].to_f
29
+ this_product = event_history.order_book[:this_product]
30
+ min_market_funds = this_product[:min_market_funds]
31
+ base_increment = this_product[:base_increment]
32
+ quote_increment = this_product[:quote_increment]
33
+ crypto_smallest_decimal = base_increment.to_s.split('.')[-1].length
34
+ fiat_smallest_decimal = quote_increment.to_s.split('.')[-1].length
35
+
36
+ last_three_prices_arr = []
37
+ last_ticker_price = event_history.order_book[:ticker_price].to_f
38
+ second_to_last_ticker_price = event_history.order_book[:ticker_price_second_to_last].to_f
39
+ third_to_last_ticker_price = event_history.order_book[:ticker_price_third_to_last].to_f
40
+ last_three_prices_arr.push(last_ticker_price)
41
+ last_three_prices_arr.push(second_to_last_ticker_price)
42
+ last_three_prices_arr.push(third_to_last_ticker_price)
43
+ limit_price = last_three_prices_arr.sort[1]
44
+ return event_history unless limit_price.positive?
45
+
46
+ tpm = bot_conf[:target_profit_margin_percent].to_f
47
+ tpm_cast_as_decimal = tpm / 100
48
+
49
+ order_history_meta = event_history.order_book[:order_history_meta]
50
+ order_history = event_history.order_book[:order_history] if option_choice.autotrade
51
+
52
+ margin_percent_open_24h = (1 - (open_24h / ticker_price)) * 100
53
+ cast_margin_to_sec = margin_percent_open_24h * 0.1
54
+
55
+ # Reset times to max or default depending on
56
+ # BULL or BEAR market trend
57
+ event_history.bullish_trend = true if cast_margin_to_sec.positive?
58
+ event_history.bullish_trend = false if cast_margin_to_sec.negative?
59
+
60
+ buy_total = event_history.order_book[:market_trend][:buy].to_i
61
+ sell_total = event_history.order_book[:market_trend][:sell].to_i
62
+
63
+ if event_history.order_book[:order_plan].length.positive?
64
+ if event_history.order_ready
65
+ event_history.order_book[:last_order_exec] = Time.now.strftime(
66
+ '%Y-%m-%d %H:%M:%S.%N%z'
67
+ )
68
+ end
69
+
70
+ # BUY
71
+ # Reset times to max or default depending on
72
+ # BULL or BEAR market trend
73
+ event_history.time_between_orders = event_history.time_between_orders_max if buy_total >= sell_total &&
74
+ !event_history.bullish_trend
75
+
76
+ event_history.time_between_orders = event_history.time_between_orders_reset if sell_total > buy_total &&
77
+ !event_history.bullish_trend
78
+
79
+ if event_history.order_ready &&
80
+ indicator_status.action_signal == :buy &&
81
+ !event_history.red_pill
82
+
83
+ if option_choice.autotrade
84
+ this_order = event_history.order_book[:order_plan].first
85
+
86
+ # If price is greater than the previous order,
87
+ # force it to be slightly less
88
+ last_order = order_history_meta.select do |order|
89
+ order if order[:color] == 'yellow'
90
+ end.last
91
+ last_purchase_price = 0.0
92
+ last_purchase_price = last_order[:price].to_f if last_order.any?
93
+
94
+ limit_price = last_purchase_price - fiat_smallest_decimal if last_purchase_price.positive? && last_purchase_price < limit_price
95
+
96
+ price = format(
97
+ "%0.#{fiat_smallest_decimal}f",
98
+ limit_price
99
+ )
100
+
101
+ size = this_order[:invest].to_f / limit_price
102
+
103
+ loop do
104
+ size = size.to_f + base_increment.to_f
105
+ break if (size.to_f * price.to_f) > min_market_funds.to_f
106
+ end
107
+
108
+ size = format(
109
+ "%0.#{crypto_smallest_decimal}f",
110
+ size
111
+ )
112
+
113
+ fiat_invested_this_order = size.to_f * price.to_f
114
+
115
+ fiat_portfolio = event_history.order_book[:fiat_portfolio]
116
+ fiat_avail_to_trade = format('%0.2f', fiat_portfolio.first[:available])
117
+
118
+ event_history.red_pill = true if fiat_invested_this_order > fiat_avail_to_trade.to_f
119
+
120
+ unless event_history.red_pill
121
+ event_history = Cryptum::API.submit_limit_order(
122
+ option_choice: option_choice,
123
+ env: env,
124
+ price: price,
125
+ size: size,
126
+ buy_or_sell: :buy,
127
+ event_history: event_history,
128
+ bot_conf: bot_conf
129
+ )
130
+ end
131
+ else
132
+ this_order = event_history.order_book[:order_plan].shift
133
+ # Mock Order ID
134
+ this_order[:buy_order_id] = format(
135
+ '%0.6i',
136
+ Random.rand(0..999_999)
137
+ )
138
+
139
+ this_order[:price] = limit_price.to_s
140
+ this_order[:size] = format(
141
+ "%0.#{crypto_smallest_decimal}f",
142
+ this_order[:invest].to_f / limit_price
143
+ )
144
+
145
+ targ_price = limit_price + (limit_price * tpm_cast_as_decimal)
146
+ this_order[:tpm] = format(
147
+ '%0.2f',
148
+ tpm
149
+ )
150
+ this_order[:target_price] = format(
151
+ "%0.#{fiat_smallest_decimal}f",
152
+ targ_price
153
+ )
154
+ this_order[:color] = :cyan
155
+ order_history_meta.push(this_order)
156
+ end
157
+
158
+ # SAUCE 3
159
+ # Time between orders
160
+ # Increment n Seconds between buys to
161
+ # account for bearish and bullish trends
162
+ dynamic_time_increment = cast_margin_to_sec * -1
163
+
164
+ # Lets also take balance into play
165
+ balance_as_arbitrary_float = fiat_avail_to_trade.to_f / 1_000_000
166
+ tbo = dynamic_time_increment - balance_as_arbitrary_float
167
+
168
+ event_history.time_between_orders += tbo
169
+
170
+ # Time between orders should never
171
+ # be less than event_history.time_between_orders_min
172
+ event_history.time_between_orders = event_history.time_between_orders_min if event_history.time_between_orders < event_history.time_between_orders_min
173
+ # Time between orders should never
174
+ # be more than event_history.time_between_orders_max
175
+ event_history.time_between_orders = event_history.time_between_orders_max if event_history.time_between_orders > event_history.time_between_orders_max
176
+ end
177
+
178
+ # SELL
179
+ # Once buy arders are fulfilled submit a
180
+ # limit sell order for fulfillment
181
+ unless option_choice.autotrade
182
+ # Testing logic via Mock
183
+ event_type_arr = %i[received open done]
184
+ last_et_index = event_type_arr.length - 1
185
+ rand_et_index = Random.rand(0..last_et_index)
186
+ event_type = event_type_arr[rand_et_index]
187
+
188
+ event_side_arr = %i[buy sell]
189
+ last_es_index = event_side_arr.length - 1
190
+ rand_es_index = Random.rand(0..last_es_index)
191
+ event_side = event_type_arr[rand_es_index].to_s.to_sym
192
+ event_reason = 'mock'
193
+ end
194
+ end
195
+
196
+ # Update Completed Sell Orders w/ Green
197
+ if event_type == :open &&
198
+ event_side == :buy
199
+
200
+ buy_order_id = event_history.event[:order_id]
201
+ order_history_meta.each do |meta|
202
+ meta[:color] = :red if meta[:buy_order_id] == buy_order_id
203
+ end
204
+ end
205
+
206
+ if event_type == :done &&
207
+ event_side == :buy &&
208
+ event_reason == :canceled
209
+
210
+ buy_order_id = event_history.event[:order_id]
211
+ order_history_meta.each do |meta|
212
+ next unless meta[:buy_order_id] == buy_order_id
213
+
214
+ meta[:done_at] = Time.now.strftime('%Y-%m-%d %H:%M:%S.%N%z')
215
+ meta[:color] = :white
216
+ end
217
+ end
218
+
219
+ if event_type == :done &&
220
+ event_side == :buy &&
221
+ event_reason != :canceled
222
+
223
+ if option_choice.autotrade
224
+ order_ready_to_sell_arr = order_history_meta.select do |meta|
225
+ meta[:buy_order_id] == event_history.event[:order_id]
226
+ end
227
+ else
228
+ last_index = order_history_meta.length - 1
229
+ rand_index = Random.rand(0..last_index)
230
+ order_ready_to_sell_arr = [
231
+ order_history_meta[rand_index]
232
+ ]
233
+ end
234
+
235
+ if order_ready_to_sell_arr.length.positive?
236
+ order_ready_to_sell = order_ready_to_sell_arr.first
237
+ buy_order_id = order_ready_to_sell[:buy_order_id]
238
+
239
+ if option_choice.autotrade
240
+ price = format(
241
+ "%0.#{fiat_smallest_decimal}f",
242
+ order_ready_to_sell[:target_price]
243
+ )
244
+
245
+ size = order_ready_to_sell[:size]
246
+
247
+ Cryptum::API.submit_limit_order(
248
+ option_choice: option_choice,
249
+ env: env,
250
+ price: price,
251
+ size: size,
252
+ buy_or_sell: :sell,
253
+ event_history: event_history,
254
+ bot_conf: bot_conf,
255
+ buy_order_id: buy_order_id
256
+ )
257
+ else
258
+ sell_order_id = format(
259
+ '%0.2i',
260
+ Random.rand(0..999_999)
261
+ )
262
+
263
+ event_history.order_book[:order_history_meta].each do |meta|
264
+ if meta[:buy_order_id] == buy_order_id
265
+ meta[:sell_order_id] = sell_order_id
266
+ meta[:color] = :yellow
267
+ end
268
+ end
269
+ end
270
+ end
271
+ end
272
+
273
+ # Update Canceled Sell Orders w/ Black &&
274
+ # Include done_at Timestamp for 24h gain calc
275
+ if event_type == :done &&
276
+ event_side == :sell &&
277
+ event_reason == :canceled
278
+
279
+ sell_order_id = event_history.event[:order_id]
280
+ order_history_meta.each do |meta|
281
+ next unless meta[:sell_order_id] == sell_order_id
282
+
283
+ meta[:done_at] = Time.now.strftime('%Y-%m-%d %H:%M:%S.%N%z')
284
+
285
+ # TODO: Retry sell order if the original sell order expires.
286
+
287
+ # Reinitiate GTFO if the previous GTFO Order Expires.
288
+ terminal_win.key_press_event.key_g = true if meta[:color] == :magenta
289
+ meta[:color] = :white
290
+ end
291
+ end
292
+
293
+ # Update Completed Sell Orders w/ Green &&
294
+ # Include done_at Timestamp for 24h gain calc
295
+ if event_type == :done &&
296
+ event_side == :sell &&
297
+ event_reason != :canceled
298
+
299
+ sell_order_id = event_history.event[:order_id]
300
+ order_history_meta.each do |meta|
301
+ next unless meta[:sell_order_id] == sell_order_id
302
+
303
+ meta[:done_at] = Time.now.strftime('%Y-%m-%d %H:%M:%S.%N%z')
304
+ meta[:color] = :green
305
+ end
306
+ end
307
+
308
+ # OK, now let's tally up everything...
309
+ twenty_four_hrs_ago = Time.now - 86_400
310
+
311
+ # Snag all sold orders
312
+ oh_meta_sold_arr = order_history_meta.select do |ohm|
313
+ ohm[:color].to_sym == :green && ohm.key?(:done_at)
314
+ end
315
+
316
+ # Snag all sold orders within past 24 hrs
317
+ ohm_sold_twenty_four_arr = []
318
+ unless oh_meta_sold_arr.empty?
319
+ ohm_sold_twenty_four_arr = oh_meta_sold_arr.select do |o|
320
+ Time.parse(o[:done_at]) >= twenty_four_hrs_ago
321
+ end
322
+ end
323
+ order_hist_meta_sold = ohm_sold_twenty_four_arr.length
324
+
325
+ # Snag all expired orders
326
+ oh_meta_expired_arr = order_history_meta.select do |ohm|
327
+ ohm[:color].to_sym == :white && ohm.key?(:done_at)
328
+ end
329
+
330
+ # Snag all expired orders within past 24 hrs
331
+ ohm_expire_twenty_four_arr = []
332
+ unless oh_meta_expired_arr.empty?
333
+ ohm_expire_twenty_four_arr = oh_meta_expired_arr.select do |o|
334
+ Time.parse(o[:done_at]) >= twenty_four_hrs_ago
335
+ end
336
+ end
337
+ order_hist_meta_expired = ohm_expire_twenty_four_arr.length
338
+
339
+ # Calculate gains within past 24 hrs
340
+ gains_24h_sum = ohm_sold_twenty_four_arr.map do |ohms|
341
+ ohms[:profit].to_f
342
+ end.sum
343
+
344
+ gains_24h_out = Cryptum.beautify_large_number(
345
+ value: format(
346
+ '%0.2f',
347
+ gains_24h_sum
348
+ )
349
+ )
350
+
351
+ total_to_sell = order_history.select do |oh|
352
+ oh[:status].to_sym == :open && oh[:side].to_sym == :sell
353
+ end.length
354
+ event_history.open_sell_orders = total_to_sell
355
+ # TODO: when event_history.open_sell_orders > event_history.open_sell_orders_max
356
+ # Capture highest amount to sell, cancel all orders, and create _one_ limit sell
357
+ # order set to a price of the previously captured highest amount to sell.
358
+ event_history.open_sell_orders_merge = true if total_to_sell > event_history.open_sell_orders_max
359
+
360
+ # TODO: Everything Above this Line Needs to be Indicators ^
361
+
362
+ # UI
363
+ col_just1 = (Curses.cols - Cryptum::UI.col_first) - 1
364
+ col_just4 = Curses.cols - Cryptum::UI.col_fourth
365
+
366
+ # ROW 1
367
+ out_line_no = 0
368
+ line_color = :white
369
+ header_color = :white
370
+ header_style = :bold
371
+ style = :bold
372
+ if event_history.order_execute_win_active
373
+ line_color = :blue
374
+ header_color = :blue
375
+ header_style = :reverse
376
+ end
377
+
378
+ Cryptum::UI.line(
379
+ ui_win: order_execute_win,
380
+ out_line_no: out_line_no,
381
+ color: line_color
382
+ )
383
+
384
+ # ROW 2
385
+ out_line_no += 1
386
+ order_execute_win.setpos(out_line_no, Cryptum::UI.col_first)
387
+ order_execute_win.clrtoeol
388
+ Cryptum::UI.colorize(
389
+ ui_win: order_execute_win,
390
+ color: header_color,
391
+ style: header_style,
392
+ string: ''.ljust(col_just1, ' ')
393
+ )
394
+
395
+ header_str = '- ORDER HISTORY -'
396
+ order_execute_win.setpos(
397
+ out_line_no,
398
+ Cryptum::UI.col_center(str: header_str)
399
+ )
400
+
401
+ Cryptum::UI.colorize(
402
+ ui_win: order_execute_win,
403
+ color: header_color,
404
+ style: header_style,
405
+ string: header_str
406
+ )
407
+
408
+ order_execute_win.setpos(out_line_no, Cryptum::UI.col_fourth)
409
+ order_execute_win.clrtoeol
410
+ Cryptum::UI.colorize(
411
+ ui_win: order_execute_win,
412
+ color: header_color,
413
+ style: header_style,
414
+ string: ''.ljust(col_just4, ' ')
415
+ )
416
+
417
+ # ROWS 3-10
418
+ remaining_blank_rows = 0
419
+ remaining_blank_rows = max_rows_to_display if order_history_meta.empty?
420
+ max_rows_to_display = event_history.order_execute_max_rows_to_display
421
+ first_row = event_history.order_execute_index_offset
422
+ last_row = first_row + max_rows_to_display
423
+ if last_row >= order_history_meta.length
424
+ last_row = order_history_meta.length - 1
425
+ event_history.order_execute_max_records_available_to_display = last_row if last_row < max_rows_to_display
426
+ first_row = last_row - event_history.order_execute_max_records_available_to_display
427
+ event_history.order_execute_index_offset = first_row
428
+ remaining_blank_rows = max_rows_to_display - last_row
429
+ end
430
+
431
+ if order_history_meta.any?
432
+ selected_order = event_history.order_execute_selected_data
433
+ order_history_meta.reverse[first_row..last_row].each do |meta|
434
+ out_line_no += 1
435
+ current_line = out_line_no - 2
436
+
437
+ style = :normal
438
+ if event_history.order_execute_row_to_select == current_line
439
+ style = :highlight
440
+ selected_order = meta
441
+ selected_order[:color] = meta[:color]
442
+ end
443
+
444
+ invest_out = Cryptum.beautify_large_number(
445
+ value: meta[:invest]
446
+ )
447
+ price_out = Cryptum.beautify_large_number(
448
+ value: meta[:price]
449
+ )
450
+ size_out = Cryptum.beautify_large_number(
451
+ value: meta[:size]
452
+ )
453
+ target_price_out = Cryptum.beautify_large_number(
454
+ value: meta[:target_price]
455
+ )
456
+ plan_no = meta[:plan_no]
457
+
458
+ buy_created_at_hash_arr = order_history.select do |oh|
459
+ oh[:id] == meta[:buy_order_id]
460
+ end
461
+
462
+ buy_created_at = '____-__-__ __:__:__'
463
+ unless buy_created_at_hash_arr.empty?
464
+ buy_created_at = Time.parse(
465
+ buy_created_at_hash_arr.first[:created_at]
466
+ ).strftime('%Y-%m-%d %H:%M:%S')
467
+ end
468
+
469
+ invest = "$#{invest_out} @ "
470
+ tick = "$#{price_out} = "
471
+ size = "*#{size_out} + "
472
+ tpm_out = "#{meta[:tpm]}% = "
473
+ targ_tick = "$#{target_price_out}"
474
+ profit = "|Profit: $#{meta[:profit]}"
475
+
476
+ order_exec_ln = "#{buy_created_at}|#{invest}#{tick}#{size}#{tpm_out}#{targ_tick}#{profit}|#{plan_no}"
477
+
478
+ order_execute_win.setpos(out_line_no, Cryptum::UI.col_first)
479
+ order_execute_win.clrtoeol
480
+ Cryptum::UI.colorize(
481
+ ui_win: order_execute_win,
482
+ color: meta[:color],
483
+ style: style,
484
+ string: order_exec_ln.ljust(col_just1, '.')
485
+ )
486
+
487
+ Cryptum::UI.colorize(
488
+ ui_win: order_execute_win,
489
+ color: meta[:color],
490
+ style: style,
491
+ string: ''.ljust(col_just4, ' ')
492
+ )
493
+ end
494
+ event_history.order_execute_selected_data = selected_order
495
+ end
496
+
497
+ # Clear to SUMMARY
498
+ # (Only Applicable if order_book[:order_history_meta] < max_rows_to_display)
499
+ # out_line_no += 1
500
+ if remaining_blank_rows.positive?
501
+ rows_to_blank = out_line_no + remaining_blank_rows
502
+ out_line_no += 1
503
+ (out_line_no..rows_to_blank).each do |clr_line|
504
+ out_line_no = clr_line
505
+ order_execute_win.setpos(clr_line, Cryptum::UI.col_first)
506
+ order_execute_win.clrtoeol
507
+ Cryptum::UI.colorize(
508
+ ui_win: order_execute_win,
509
+ color: :white,
510
+ style: :normal,
511
+ string: ''.ljust(col_just1, ' ')
512
+ )
513
+ end
514
+ end
515
+
516
+ # ROW 10
517
+ out_line_no += 1
518
+ order_execute_win.setpos(out_line_no, Cryptum::UI.col_first)
519
+ order_execute_win.clrtoeol
520
+ Cryptum::UI.colorize(
521
+ ui_win: order_execute_win,
522
+ color: header_color,
523
+ style: header_style,
524
+ string: ''.ljust(col_just1, ' ')
525
+ )
526
+
527
+ header_str = "24 HR SUMMARY | Open Sell Orders: #{total_to_sell} | Sold: #{order_hist_meta_sold} | Gains: $#{gains_24h_out} | Expired: #{order_hist_meta_expired}"
528
+ order_execute_win.setpos(
529
+ out_line_no,
530
+ Cryptum::UI.col_center(str: header_str)
531
+ )
532
+
533
+ Cryptum::UI.colorize(
534
+ ui_win: order_execute_win,
535
+ color: header_color,
536
+ style: header_style,
537
+ string: header_str
538
+ )
539
+
540
+ order_execute_win.setpos(out_line_no, Cryptum::UI.col_fourth)
541
+ order_execute_win.clrtoeol
542
+ Cryptum::UI.colorize(
543
+ ui_win: order_execute_win,
544
+ color: header_color,
545
+ style: header_style,
546
+ string: ''.ljust(col_just4, ' ')
547
+ )
548
+
549
+ # ROW 11
550
+ out_line_no += 1
551
+ Cryptum::UI.line(
552
+ ui_win: order_execute_win,
553
+ out_line_no: out_line_no,
554
+ color: line_color
555
+ )
556
+
557
+ order_execute_win.refresh
558
+
559
+ # Reset Order Ready && Open Sell Orders Merge (If Applicable) Booleans
560
+ event_history.order_ready = false
561
+ event_history.open_sell_orders_merge = false
562
+
563
+ event_history
564
+ rescue Interrupt
565
+ # Exit Gracefully if CTRL+C is Pressed During Session
566
+ Cryptum.exit_gracefully(which_self: self)
567
+ rescue StandardError => e
568
+ raise e
569
+ end
570
+
571
+ # Display Usage for this Module
572
+
573
+ public_class_method def self.help
574
+ puts "USAGE:
575
+ #{self}.refresh(
576
+ order_book: 'required - Order Book Data Structure',
577
+ event: 'required - Event from Coinbase Web Socket'
578
+ )
579
+ "
580
+ end
581
+ end
582
+ end
583
+ end