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,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Cryptum
6
+ module UI
7
+ # This Class is Used by Cryptum::Event to
8
+ # Detect when the Terminal Window is Resized
9
+ class TerminalWindow
10
+ attr_accessor :cols,
11
+ :key_press_event,
12
+ :ticker_ui_resize,
13
+ :ticker_section,
14
+ :portfolio_section,
15
+ :order_plan_section,
16
+ :order_plan_details_section,
17
+ :order_timer_section,
18
+ :market_trend_section,
19
+ :market_trend_ui_resize,
20
+ :signal_engine_section,
21
+ :order_execute_section,
22
+ :order_execute_details_section,
23
+ :command_section
24
+
25
+ def initialize
26
+ # Persist the column width of the terminal window
27
+ # for resize detection in Cryptum::Event
28
+ self.cols = Curses.cols
29
+
30
+ self.key_press_event = Cryptum::UI::KeyPressEvent.new
31
+
32
+ self.ticker_section = Cryptum::UI.window(
33
+ height: 7,
34
+ width: 0,
35
+ top: 0,
36
+ left: 0
37
+ )
38
+
39
+ self.portfolio_section = Cryptum::UI.window(
40
+ height: 6,
41
+ width: 0,
42
+ top: 7,
43
+ left: 0
44
+ )
45
+
46
+ self.order_plan_section = Cryptum::UI.window(
47
+ height: 11,
48
+ width: 0,
49
+ top: 13,
50
+ left: 0
51
+ )
52
+
53
+ self.order_plan_details_section = Cryptum::UI.window(
54
+ height: 11,
55
+ width: 0,
56
+ top: 13,
57
+ left: 0
58
+ )
59
+
60
+ self.order_timer_section = Cryptum::UI.window(
61
+ height: 1,
62
+ width: 0,
63
+ top: 24,
64
+ left: 0
65
+ )
66
+
67
+ self.market_trend_section = Cryptum::UI.window(
68
+ height: 2,
69
+ width: 0,
70
+ top: 25,
71
+ left: 0
72
+ )
73
+
74
+ self.signal_engine_section = Cryptum::UI.window(
75
+ height: 2,
76
+ width: 0,
77
+ top: 27,
78
+ left: 0
79
+ )
80
+
81
+ self.order_execute_section = Cryptum::UI.window(
82
+ height: 11,
83
+ width: 0,
84
+ top: 29,
85
+ left: 0
86
+ )
87
+
88
+ self.order_execute_details_section = Cryptum::UI.window(
89
+ height: 11,
90
+ width: 0,
91
+ top: 29,
92
+ left: 0
93
+ )
94
+
95
+ self.command_section = Cryptum::UI.window(
96
+ height: 3,
97
+ width: 0,
98
+ top: 40,
99
+ left: 0
100
+ )
101
+ end
102
+ rescue Interrupt
103
+ # Exit Gracefully if CTRL+C is Pressed During Session
104
+ Cryptum.exit_gracefully(which_self: self)
105
+ rescue StandardError => e
106
+ # Produce a Stacktrace for anything else
107
+ Curses.close_screen
108
+ raise e
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,319 @@
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 Ticker
9
+ public_class_method def self.refresh(opts = {})
10
+ start_time = opts[:start_time]
11
+ ticker_win = opts[:ticker_win]
12
+ event_history = opts[:event_history]
13
+ event = opts[:event]
14
+
15
+ order_book = event_history.order_book
16
+ this_product = order_book[:this_product]
17
+ quote_increment = this_product[:quote_increment]
18
+ fiat_smallest_decimal = quote_increment.to_s.split('.')[-1].length
19
+
20
+ symbol_out = this_product[:id]
21
+ fiat = this_product[:quote_currency].to_sym
22
+ fiat_symbol = '?'
23
+ fiat_symbol = '$' if fiat == :USD
24
+ fiat_symbol = "\u20ac" if fiat == :EUR
25
+
26
+ last_ticker_price = order_book[:ticker_price].to_f
27
+ second_to_last_ticker_price = order_book[:ticker_price_second_to_last].to_f
28
+
29
+ sequence = event[:sequence].to_i
30
+ last_sequence = order_book[:sequence].to_i
31
+ order_book[:sequence] = sequence
32
+
33
+ return unless sequence >= last_sequence
34
+
35
+ # Useful for detecting dropped messages but it's usually a lot.
36
+ # if last_sequence + 1 < sequence
37
+ # sequence_diff = sequence - last_sequence
38
+ # File.open('/tmp/cryptum-errors.txt', 'a') do |f|
39
+ # f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
40
+ # f.puts "Module: #{self}"
41
+ # f.puts 'Messages likely dropped:'
42
+ # f.puts "This Sequence: #{sequence}"
43
+ # f.puts "Last Sequence: #{last_sequence}"
44
+ # f.puts "Sequence Diff: #{sequence_diff}\n\n\n"
45
+ # end
46
+ # end
47
+
48
+ open_24h = event[:open_24h].to_f
49
+ order_book[:open_24h] = open_24h
50
+
51
+ open_24h_out = "#{Cryptum.open_symbol} #{fiat_symbol}#{Cryptum.beautify_large_number(value: format("%0.#{fiat_smallest_decimal}f", open_24h))}"
52
+
53
+ beautify_ticker = Cryptum.beautify_large_number(
54
+ value: format("%0.#{fiat_smallest_decimal}f", event[:price].to_f)
55
+ )
56
+ ticker_fmt = "#{fiat_symbol}#{beautify_ticker}"
57
+ if last_ticker_price.zero?
58
+ ticker_price_color = :white
59
+ ticker_price_out = "#{Cryptum.flat_arrow} #{ticker_fmt}"
60
+ elsif last_ticker_price < event[:price].to_f
61
+ ticker_price_color = :green
62
+ ticker_price_out = "#{Cryptum.up_arrow} #{ticker_fmt}"
63
+ elsif last_ticker_price > event[:price].to_f
64
+ ticker_price_color = :red
65
+ ticker_price_out = "#{Cryptum.down_arrow} #{ticker_fmt}"
66
+ else
67
+ ticker_price_color = :yellow
68
+ ticker_price_out = "#{Cryptum.flat_arrow} #{ticker_fmt}"
69
+ end
70
+
71
+ order_book[:ticker_price_third_to_last] = format("%0.#{fiat_smallest_decimal}f", second_to_last_ticker_price)
72
+ order_book[:ticker_price_second_to_last] = format("%0.#{fiat_smallest_decimal}f", last_ticker_price)
73
+ order_book[:ticker_price] = format("%0.#{fiat_smallest_decimal}f", event[:price].to_f)
74
+
75
+ volume_24h = format('%0.7f', event[:volume_24h])
76
+ volume_24h_out = Cryptum.beautify_large_number(
77
+ value: volume_24h
78
+ )
79
+ order_book[:volume_24h] = volume_24h
80
+
81
+ volume_30d = format('%0.7f', event[:volume_30d])
82
+ volume_30d_out = Cryptum.beautify_large_number(
83
+ value: volume_30d
84
+ )
85
+
86
+ # TODO: Potential for RACE CONDITIONS - MIGRATE TO
87
+ # Cryptum::Event.parse
88
+ # Indicate if 24 Hour High is Reached During Sesssion
89
+ high_24h = format(
90
+ "%0.#{fiat_smallest_decimal}f",
91
+ event[:high_24h]
92
+ )
93
+ high_24h_out = Cryptum.beautify_large_number(
94
+ value: high_24h
95
+ )
96
+ order_book[:high_24h] = high_24h
97
+
98
+ low_24h = format(
99
+ "%0.#{fiat_smallest_decimal}f",
100
+ event[:low_24h]
101
+ )
102
+ low_24h_out = Cryptum.beautify_large_number(
103
+ value: low_24h
104
+ )
105
+ order_book[:low_24h] = low_24h
106
+ margin_percent_open_24h = (1 - (open_24h / order_book[:ticker_price].to_f)) * 100
107
+
108
+ beautify_margin_percent_open_24h = Cryptum.beautify_large_number(
109
+ value: format('%0.4f', margin_percent_open_24h)
110
+ )
111
+ if margin_percent_open_24h.positive?
112
+ margin_percent_open_24h_color = :green
113
+ trend = 'BULL'
114
+ margin_percent_open_24h_out = "#{Cryptum.up_arrow} #{beautify_margin_percent_open_24h}% (#{trend})"
115
+ elsif margin_percent_open_24h.negative?
116
+ # Space removed to account for negative number.
117
+ margin_percent_open_24h_color = :red
118
+ trend = 'BEAR'
119
+ margin_percent_open_24h_out = "#{Cryptum.down_arrow}#{beautify_margin_percent_open_24h}% (#{trend})"
120
+ else
121
+ trend = 'FLAT'
122
+ margin_percent_open_24h_color = :yellow
123
+ margin_percent_open_24h_out = "#{Cryptum.flat_arrow} #{beautify_margin_percent_open_24h}% (#{trend})"
124
+ end
125
+
126
+ order_history = order_book[:order_history]
127
+ open_sell_orders = order_history.select do |order|
128
+ order[:status] == 'open' && order[:side] == 'sell'
129
+ end
130
+
131
+ sorted_open_sell_orders = open_sell_orders.sort_by do |order|
132
+ order[:price].to_f
133
+ end
134
+
135
+ lowest_selling_price = '0.00'
136
+ highest_selling_price = '0.00'
137
+ lowest_selling_price = sorted_open_sell_orders.first[:price] unless sorted_open_sell_orders.empty?
138
+ highest_selling_price = sorted_open_sell_orders.last[:price] unless sorted_open_sell_orders.empty?
139
+ lowest_selling_price_out = Cryptum.beautify_large_number(
140
+ value: format(
141
+ "%0.#{fiat_smallest_decimal}f",
142
+ lowest_selling_price
143
+ )
144
+ )
145
+
146
+ highest_selling_price_out = Cryptum.beautify_large_number(
147
+ value: format(
148
+ "%0.#{fiat_smallest_decimal}f",
149
+ highest_selling_price
150
+ )
151
+ )
152
+
153
+ event_history.order_book = order_book
154
+ # TODO: Everything Above this Line Needs to be Indicators ^
155
+
156
+ # UI
157
+ col_just1 = 15
158
+ col_just2 = 14
159
+ col_just3 = 21
160
+ col_just3_alt = (Curses.cols - Cryptum::UI.col_third) - 1
161
+ col_just4 = (Curses.cols - Cryptum::UI.col_fourth) - 1
162
+
163
+ # ROW 1
164
+ out_line_no = 0
165
+ Cryptum::UI.line(
166
+ ui_win: ticker_win,
167
+ out_line_no: out_line_no
168
+ )
169
+
170
+ out_line_no += 1
171
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
172
+ ticker_win.clrtoeol
173
+ Cryptum::UI.colorize(
174
+ ui_win: ticker_win,
175
+ color: :yellow,
176
+ style: :bold,
177
+ string: symbol_out.ljust(col_just1)
178
+ )
179
+
180
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_second)
181
+ Cryptum::UI.colorize(
182
+ ui_win: ticker_win,
183
+ color: margin_percent_open_24h_color,
184
+ style: :bold,
185
+ string: margin_percent_open_24h_out.ljust(col_just2)
186
+ )
187
+
188
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
189
+ Cryptum::UI.colorize(
190
+ ui_win: ticker_win,
191
+ color: :blue,
192
+ style: :bold,
193
+ string: open_24h_out.ljust(col_just3)
194
+ )
195
+
196
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_fourth)
197
+ Cryptum::UI.colorize(
198
+ ui_win: ticker_win,
199
+ color: ticker_price_color,
200
+ style: :bold,
201
+ string: ticker_price_out.rjust(col_just4)
202
+ )
203
+
204
+ # ROW 2
205
+ out_line_no += 1
206
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
207
+ ticker_win.clrtoeol
208
+ Cryptum::UI.colorize(
209
+ ui_win: ticker_win,
210
+ color: :white,
211
+ style: :bold,
212
+ string: 'High | Low Limit Sell Prices:'
213
+ )
214
+
215
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
216
+ Cryptum::UI.colorize(
217
+ ui_win: ticker_win,
218
+ color: :white,
219
+ style: :bold,
220
+ string: "$#{highest_selling_price_out} | $#{lowest_selling_price_out}".rjust(
221
+ col_just3_alt,
222
+ '.'
223
+ )
224
+ )
225
+
226
+ # ROW 2
227
+ out_line_no += 1
228
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
229
+ ticker_win.clrtoeol
230
+ Cryptum::UI.colorize(
231
+ ui_win: ticker_win,
232
+ color: :green,
233
+ style: :bold,
234
+ string: '24 Hr High:'
235
+ )
236
+
237
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
238
+ Cryptum::UI.colorize(
239
+ ui_win: ticker_win,
240
+ color: :green,
241
+ string: "#{Cryptum.up_arrow} #{fiat_symbol}#{high_24h_out}".rjust(col_just3_alt, '.')
242
+ )
243
+
244
+ # ROW 3
245
+ out_line_no += 1
246
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
247
+ ticker_win.clrtoeol
248
+ Cryptum::UI.colorize(
249
+ ui_win: ticker_win,
250
+ color: :red,
251
+ string: '24 Hr Low:'
252
+ )
253
+
254
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
255
+ Cryptum::UI.colorize(
256
+ ui_win: ticker_win,
257
+ color: :red,
258
+ string: "#{Cryptum.down_arrow} #{fiat_symbol}#{low_24h_out}".rjust(col_just3_alt, '.')
259
+ )
260
+
261
+ # ROW 4
262
+ out_line_no += 1
263
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
264
+ ticker_win.clrtoeol
265
+ Cryptum::UI.colorize(
266
+ ui_win: ticker_win,
267
+ color: :blue,
268
+ style: :bold,
269
+ string: '24 Hr | 30 Day Market Volume:'
270
+ )
271
+
272
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
273
+ Cryptum::UI.colorize(
274
+ ui_win: ticker_win,
275
+ color: :blue,
276
+ string: "#{volume_24h_out} | #{volume_30d_out}".rjust(col_just3_alt, '.')
277
+ )
278
+
279
+ # ROW 5
280
+ out_line_no += 1
281
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_first)
282
+ ticker_win.clrtoeol
283
+ Cryptum::UI.colorize(
284
+ ui_win: ticker_win,
285
+ color: :cyan,
286
+ style: :bold,
287
+ string: 'Start Time:'
288
+ )
289
+
290
+ ticker_win.setpos(out_line_no, Cryptum::UI.col_third)
291
+ Cryptum::UI.colorize(
292
+ ui_win: ticker_win,
293
+ color: :cyan,
294
+ string: start_time.rjust(col_just3_alt, '.')
295
+ )
296
+
297
+ ticker_win.refresh
298
+
299
+ event_history
300
+ rescue Interrupt
301
+ # Exit Gracefully if CTRL+C is Pressed During Session
302
+ Cryptum.exit_gracefully(which_self: self)
303
+ rescue StandardError => e
304
+ raise e
305
+ end
306
+
307
+ # Display Usage for this Module
308
+ public_class_method def self.help
309
+ puts "USAGE:
310
+ #{self}.refresh(
311
+ symbol: 'required - Symbol for this Session (e.g. btc-usd)',
312
+ order_book: 'required - Order Book Data Structure',
313
+ event: 'required - Event from Coinbase Web Socket'
314
+ )
315
+ "
316
+ end
317
+ end
318
+ end
319
+ end