cryptum 0.0.381 → 0.0.383

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -0
  3. data/.rubocop_todo.yml +11 -8
  4. data/Gemfile +1 -2
  5. data/bin/cryptum +2 -2
  6. data/lib/cryptum/api/exchange_rates.rb +0 -2
  7. data/lib/cryptum/api/orders.rb +9 -7
  8. data/lib/cryptum/api/portfolio.rb +0 -2
  9. data/lib/cryptum/api/rest.rb +3 -4
  10. data/lib/cryptum/api/signature.rb +0 -4
  11. data/lib/cryptum/api.rb +1 -40
  12. data/lib/cryptum/bot_conf.rb +14 -6
  13. data/lib/cryptum/event/exit.rb +1 -1
  14. data/lib/cryptum/event/history.rb +4 -1
  15. data/lib/cryptum/event/parse.rb +6 -6
  16. data/lib/cryptum/event.rb +0 -2
  17. data/lib/cryptum/log.rb +18 -4
  18. data/lib/cryptum/open_ai.rb +129 -32
  19. data/lib/cryptum/option/choice.rb +1 -1
  20. data/lib/cryptum/option/environment.rb +0 -2
  21. data/lib/cryptum/option/parser.rb +0 -2
  22. data/lib/cryptum/order_book/generate.rb +3 -8
  23. data/lib/cryptum/order_book.rb +0 -3
  24. data/lib/cryptum/portfolio.rb +0 -2
  25. data/lib/cryptum/ui/command.rb +1 -3
  26. data/lib/cryptum/ui/exit.rb +43 -0
  27. data/lib/cryptum/ui/key_press_event.rb +1 -1
  28. data/lib/cryptum/ui/market_trend.rb +4 -3
  29. data/lib/cryptum/ui/matrix.rb +185 -0
  30. data/lib/cryptum/ui/order/execute.rb +629 -0
  31. data/lib/cryptum/ui/order/execute_details.rb +300 -0
  32. data/lib/cryptum/ui/order/plan.rb +518 -0
  33. data/lib/cryptum/ui/order/plan_details.rb +243 -0
  34. data/lib/cryptum/ui/order/timer.rb +140 -0
  35. data/lib/cryptum/ui/order.rb +21 -0
  36. data/lib/cryptum/ui/portfolio.rb +5 -3
  37. data/lib/cryptum/ui/signal_engine.rb +1 -3
  38. data/lib/cryptum/ui/terminal_window.rb +1 -3
  39. data/lib/cryptum/ui/ticker.rb +4 -3
  40. data/lib/cryptum/ui.rb +17 -22
  41. data/lib/cryptum/version.rb +1 -1
  42. data/lib/cryptum/web_sock/coinbase.rb +1 -6
  43. data/lib/cryptum/web_sock/event_machine.rb +3 -7
  44. data/lib/cryptum.rb +16 -33
  45. data/spec/lib/cryptum/{matrix_spec.rb → ui/exit_spec.rb} +2 -2
  46. data/spec/lib/cryptum/ui/{order_plan_spec.rb → matrix_spec.rb} +2 -2
  47. data/spec/lib/cryptum/ui/{order_execute_details_spec.rb → order/execute_details_spec.rb} +2 -2
  48. data/spec/lib/cryptum/ui/{order_execution_spec.rb → order/execute_spec.rb} +2 -2
  49. data/spec/lib/cryptum/ui/{order_plan_details_spec.rb → order/plan_details_spec.rb} +2 -2
  50. data/spec/lib/cryptum/ui/order/plan_spec.rb +10 -0
  51. data/spec/lib/cryptum/ui/order/timer_spec.rb +10 -0
  52. data/spec/lib/cryptum/ui/{order_timer_spec.rb → order_spec.rb} +2 -2
  53. metadata +20 -30
  54. data/lib/cryptum/matrix.rb +0 -181
  55. data/lib/cryptum/ui/order_execute_details.rb +0 -297
  56. data/lib/cryptum/ui/order_execution.rb +0 -624
  57. data/lib/cryptum/ui/order_plan.rb +0 -514
  58. data/lib/cryptum/ui/order_plan_details.rb +0 -240
  59. data/lib/cryptum/ui/order_timer.rb +0 -136
@@ -1,514 +0,0 @@
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 = "RISK ALLOCATED: $#{order_plan_volume_out} | "
460
- header_str += "PROJECTED PROFIT: $#{order_plan_profit_sum_out} | "
461
- header_str += "#{order_plan_exec_percent}% DONE"
462
- order_plan_win.setpos(
463
- out_line_no,
464
- Cryptum::UI.col_center(str: header_str)
465
- )
466
-
467
- Cryptum::UI.colorize(
468
- ui_win: order_plan_win,
469
- color: header_color,
470
- style: header_style,
471
- string: header_str
472
- )
473
-
474
- # order_plan_win.setpos(out_line_no, Cryptum::UI.col_fourth)
475
- # order_plan_win.clrtoeol
476
- # Cryptum::UI.colorize(
477
- # ui_win: order_plan_win,
478
- # color: header_color,
479
- # style: header_style,
480
- # string: ''.ljust(col_just4, ' ')
481
- # )
482
- end
483
-
484
- # ROW 11
485
- out_line_no += 1
486
- Cryptum::UI.line(
487
- ui_win: order_plan_win,
488
- out_line_no: out_line_no,
489
- color: line_color
490
- )
491
-
492
- order_plan_win.refresh
493
-
494
- event_history
495
- rescue Interrupt
496
- # Exit Gracefully if CTRL+C is Pressed During Session
497
- Cryptum.exit_gracefully(which_self: self)
498
- rescue StandardError => e
499
- raise e
500
- end
501
-
502
- # Display Usage for this Module
503
-
504
- public_class_method def self.help
505
- puts "USAGE:
506
- #{self}.refresh(
507
- order_book: 'required - Order Book Data Structure',
508
- event: 'required - Event from Coinbase Web Socket'
509
- )
510
- "
511
- end
512
- end
513
- end
514
- end