cryptum 0.0.359 → 0.0.361

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. 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