cryptum 0.0.230

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  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 +5 -0
  7. data/.rubocop_todo.yml +250 -0
  8. data/.ruby-gemset +1 -0
  9. data/.ruby-version +1 -0
  10. data/CODE_OF_CONDUCT.md +84 -0
  11. data/Gemfile +36 -0
  12. data/LICENSE +674 -0
  13. data/README.md +72 -0
  14. data/Rakefile +19 -0
  15. data/bin/cryptum +72 -0
  16. data/bin/cryptum-forecast +199 -0
  17. data/bin/cryptum-repl +73 -0
  18. data/bin/cryptum_autoinc_version +38 -0
  19. data/build_cryptum_gem.sh +52 -0
  20. data/cryptum.gemspec +50 -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/git_commit.sh +22 -0
  36. data/lib/cryptum/api.rb +693 -0
  37. data/lib/cryptum/bot_conf.rb +76 -0
  38. data/lib/cryptum/event/buy.rb +144 -0
  39. data/lib/cryptum/event/cancel.rb +49 -0
  40. data/lib/cryptum/event/history.rb +64 -0
  41. data/lib/cryptum/event/key_press.rb +64 -0
  42. data/lib/cryptum/event/sell.rb +120 -0
  43. data/lib/cryptum/event.rb +168 -0
  44. data/lib/cryptum/log.rb +34 -0
  45. data/lib/cryptum/matrix.rb +181 -0
  46. data/lib/cryptum/option/choice.rb +26 -0
  47. data/lib/cryptum/option.rb +161 -0
  48. data/lib/cryptum/order_book/generate.rb +111 -0
  49. data/lib/cryptum/order_book/indicator.rb +16 -0
  50. data/lib/cryptum/order_book/market_trend.rb +161 -0
  51. data/lib/cryptum/order_book/profit_margin.rb +55 -0
  52. data/lib/cryptum/order_book/weighted_avg.rb +157 -0
  53. data/lib/cryptum/order_book.rb +156 -0
  54. data/lib/cryptum/portfolio/balance.rb +123 -0
  55. data/lib/cryptum/portfolio.rb +15 -0
  56. data/lib/cryptum/ui/command.rb +274 -0
  57. data/lib/cryptum/ui/key_press_event.rb +22 -0
  58. data/lib/cryptum/ui/market_trend.rb +117 -0
  59. data/lib/cryptum/ui/order_execution.rb +478 -0
  60. data/lib/cryptum/ui/order_plan.rb +376 -0
  61. data/lib/cryptum/ui/order_timer.rb +119 -0
  62. data/lib/cryptum/ui/portfolio.rb +231 -0
  63. data/lib/cryptum/ui/signal_engine.rb +122 -0
  64. data/lib/cryptum/ui/terminal_window.rb +95 -0
  65. data/lib/cryptum/ui/ticker.rb +317 -0
  66. data/lib/cryptum/ui.rb +306 -0
  67. data/lib/cryptum/version.rb +5 -0
  68. data/lib/cryptum/web_sock/coinbase.rb +94 -0
  69. data/lib/cryptum/web_sock/event_machine.rb +182 -0
  70. data/lib/cryptum/web_sock.rb +16 -0
  71. data/lib/cryptum.rb +183 -0
  72. data/order_books/.gitkeep +0 -0
  73. data/reinstall_cryptum_gemset.sh +29 -0
  74. data/spec/lib/cryptum/api_spec.rb +10 -0
  75. data/spec/lib/cryptum/event_spec.rb +10 -0
  76. data/spec/lib/cryptum/log_spec.rb +10 -0
  77. data/spec/lib/cryptum/option_spec.rb +10 -0
  78. data/spec/lib/cryptum/order_book/generate_spec.rb +10 -0
  79. data/spec/lib/cryptum/order_book/market_trend_spec.rb +10 -0
  80. data/spec/lib/cryptum/order_book_spec.rb +10 -0
  81. data/spec/lib/cryptum/ui/command_spec.rb +10 -0
  82. data/spec/lib/cryptum/ui/ticker_spec.rb +10 -0
  83. data/spec/lib/cryptum/ui_spec.rb +10 -0
  84. data/spec/lib/cryptum/web_sock_spec.rb +10 -0
  85. data/spec/lib/cryptum_spec.rb +10 -0
  86. data/spec/spec_helper.rb +3 -0
  87. data/upgrade_Gemfile_gems.sh +20 -0
  88. data/upgrade_cryptum.sh +13 -0
  89. data/upgrade_gem.sh +4 -0
  90. data/upgrade_ruby.sh +46 -0
  91. metadata +472 -0
@@ -0,0 +1,376 @@
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
+ key_press_event = opts[:key_press_event]
20
+ indicator_status = opts[:indicator_status]
21
+ bot_conf = opts[:bot_conf]
22
+ fiat_portfolio_file = opts[:fiat_portfolio_file]
23
+
24
+ ticker_price = event_history.order_book[:ticker_price].to_f
25
+ return unless ticker_price.positive?
26
+
27
+ this_product = event_history.order_book[:this_product]
28
+ symbol_out = this_product[:id]
29
+ quote_increment = this_product[:quote_increment]
30
+ base_increment = this_product[:base_increment]
31
+ base_min_size = this_product[:base_min_size].to_f
32
+
33
+ fiat_smallest_decimal = quote_increment.to_s.split('.')[-1].length
34
+ crypto_smallest_decimal = base_increment.to_s.split('.')[-1].length
35
+
36
+ autotrade_percent = bot_conf[:autotrade_portfolio_percent].to_f
37
+ autotrade_cast_as_decimal = autotrade_percent / 100
38
+
39
+ tpm = bot_conf[:target_profit_margin_percent].to_f
40
+ tpm_cast_as_decimal = tpm / 100
41
+
42
+ crypto_currency = option_choice.symbol.to_s.upcase.split('_').first.to_sym
43
+ portfolio = event_history.order_book[:portfolio]
44
+ this_account = portfolio.select do |account|
45
+ account[:currency] == crypto_currency.to_s
46
+ end
47
+ raise "ID for Crypto Currency, #{crypto_currency} Not Found" if this_account.empty?
48
+
49
+ balance = format("%0.#{crypto_smallest_decimal}f", this_account.first[:balance])
50
+ avail_for_trade = format("%0.#{crypto_smallest_decimal}f", this_account.first[:available])
51
+
52
+ fiat_portfolio = event_history.order_book[:fiat_portfolio]
53
+ total_holdings = format('%0.2f', fiat_portfolio.first[:total_holdings])
54
+ fiat_balance = format('%0.2f', fiat_portfolio.first[:balance])
55
+ fiat_avail_for_trade = format('%0.2f', fiat_portfolio.first[:available])
56
+
57
+ fiat_budget = fiat_avail_for_trade.to_f
58
+ current_fiat_invested_percent = (
59
+ 1 - (fiat_budget / total_holdings.to_f)
60
+ ) * 100
61
+
62
+ order_history = event_history.order_book[:order_history]
63
+ open_orders = order_history.select do |order|
64
+ order[:status] == 'open'
65
+ end
66
+ total_open_orders = open_orders.length
67
+
68
+ order_plan = event_history.order_book[:order_plan]
69
+
70
+ current_crypto_fiat_value = format(
71
+ '%0.2f',
72
+ balance.to_f * ticker_price
73
+ )
74
+
75
+ crypto_invested_percent = format(
76
+ '%0.2f',
77
+ (current_crypto_fiat_value.to_f / total_holdings.to_f) * 100
78
+ )
79
+
80
+ event_history.red_pill = true if crypto_invested_percent.to_f > autotrade_percent
81
+
82
+ if crypto_invested_percent.to_f <= autotrade_percent && (
83
+ order_plan.empty? || (
84
+ indicator_status.action_signal == :buy &&
85
+ indicator_status.last_action_signal == :sell
86
+ )
87
+ )
88
+
89
+ event_history.red_pill = false
90
+ # Reset time between orders when generating new order plan
91
+ event_history.time_between_orders = event_history.time_between_orders_reset if order_plan.empty?
92
+
93
+ order_plan = []
94
+ plan_no_slice = 1
95
+ event_history.plan_no += 1
96
+ plan_no = event_history.plan_no
97
+ # Sum up currently invested amount so we don't
98
+ # exceed autotrade % for next order plan generation
99
+ allocation_decimal = 0.0
100
+ risk_target = fiat_budget * autotrade_cast_as_decimal
101
+ risk_alloc = risk_target
102
+ while order_plan.map { |op| op[:invest].to_f }.sum < risk_target
103
+ # Calculate min order size
104
+ allocation_decimal += 0.0001
105
+ fiat_investing = risk_alloc * allocation_decimal
106
+ min_fiat_allowed_to_invest = base_min_size * ticker_price
107
+
108
+ next unless fiat_investing >= min_fiat_allowed_to_invest
109
+
110
+ risk_alloc = fiat_budget * autotrade_cast_as_decimal
111
+ allocation_percent = allocation_decimal * 100
112
+ fiat_returning = fiat_investing + (
113
+ fiat_investing * tpm_cast_as_decimal
114
+ )
115
+ profit = fiat_returning - fiat_investing
116
+
117
+ order_slice = {}
118
+ order_slice[:plan_no] = "#{plan_no}.#{plan_no_slice}"
119
+ order_slice[:fiat_available] = format('%0.2f', fiat_budget)
120
+ order_slice[:risk_alloc] = format('%0.2f', risk_alloc)
121
+ order_slice[:allocation_decimal] = format(
122
+ '%0.8f',
123
+ allocation_decimal
124
+ )
125
+ order_slice[:allocation_percent] = format(
126
+ '%0.2f',
127
+ allocation_percent
128
+ )
129
+ order_slice[:invest] = format('%0.2f', fiat_investing)
130
+ order_slice[:return] = format('%0.2f', fiat_returning)
131
+ order_slice[:profit] = format('%0.2f', profit)
132
+
133
+ order_plan.push(order_slice)
134
+ fiat_budget -= fiat_investing
135
+ plan_no_slice += 1
136
+ end
137
+ event_history.order_book[:order_plan] = order_plan
138
+ end
139
+
140
+ red_pill_alert = '| RED PILL ALERT |'
141
+ red_pill_msg = "% #{symbol_out} > Autotrade %"
142
+ event_history.red_pill = true if order_plan.empty?
143
+
144
+ if event_history.red_pill
145
+ order_plan_prefix = '--'
146
+ max_order_plan_slices = '0'
147
+ order_plan_volume_out = '0.00'
148
+ order_plan_profit_sum_out = '0.00'
149
+ order_plan_exec_percent = '0.00'
150
+ else
151
+ order_plan_len = order_plan.length
152
+ order_plan_prefix = order_plan.last[:plan_no].split('.').first
153
+ max_order_plan_slices = order_plan.last[:plan_no].split('.').last.to_i
154
+ calc_order_plan_exec = (
155
+ 1 - (order_plan_len / max_order_plan_slices.to_f)
156
+ ) * 100
157
+ order_plan_volume = order_plan.map do |op|
158
+ op[:invest].to_f
159
+ end.sum
160
+ order_plan_volume_out = Cryptum.beautify_large_number(
161
+ value: format(
162
+ '%0.2f',
163
+ order_plan_volume
164
+ )
165
+ )
166
+ order_plan_profit_sum = order_plan.map do |op|
167
+ op[:profit].to_f
168
+ end.sum
169
+ order_plan_profit_sum_out = Cryptum.beautify_large_number(
170
+ value: format(
171
+ '%0.2f',
172
+ order_plan_profit_sum
173
+ )
174
+ )
175
+ order_plan_exec_percent = format('%0.2f', calc_order_plan_exec)
176
+ end
177
+
178
+ # TODO: Everything Above this Line Needs to be Indicators ^
179
+
180
+ # UI
181
+ col_just1 = (Curses.cols - Cryptum::UI.col_first) - 1
182
+ col_just3 = (Curses.cols - Cryptum::UI.col_third) - 1
183
+ col_just4 = Curses.cols - Cryptum::UI.col_fourth
184
+
185
+ Cryptum::UI.detect_key_press_in_ui(
186
+ key_press_event: key_press_event,
187
+ ui_win: order_plan_win
188
+ )
189
+
190
+ # ROW 1
191
+ out_line_no = 0
192
+ Cryptum::UI.line(
193
+ ui_win: order_plan_win,
194
+ out_line_no: out_line_no
195
+ )
196
+
197
+ # ROW 2
198
+ out_line_no += 1
199
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
200
+ order_plan_win.clrtoeol
201
+ Cryptum::UI.colorize(
202
+ ui_win: order_plan_win,
203
+ color: :white,
204
+ style: :bold,
205
+ string: "Order Plan ##{order_plan_prefix} Summary:"
206
+ )
207
+
208
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_third)
209
+ Cryptum::UI.colorize(
210
+ ui_win: order_plan_win,
211
+ color: :white,
212
+ string: "$#{order_plan_volume_out} w #{max_order_plan_slices} Slices | $#{order_plan_profit_sum_out} 2 Gain | #{order_plan_exec_percent}% Done".rjust(
213
+ col_just3,
214
+ '.'
215
+ )
216
+ )
217
+
218
+ # ROW 3
219
+ out_line_no += 1
220
+ Cryptum::UI.line(
221
+ ui_win: order_plan_win,
222
+ out_line_no: out_line_no
223
+ )
224
+
225
+ # ROWS 4-10
226
+ if event_history.red_pill
227
+ out_line_no += 1
228
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
229
+ order_plan_win.clrtoeol
230
+
231
+ Cryptum::UI.colorize(
232
+ ui_win: order_plan_win,
233
+ color: :red,
234
+ style: :highlight,
235
+ string: ''.ljust(col_just1, ' ')
236
+ )
237
+
238
+ order_plan_win.setpos(
239
+ out_line_no,
240
+ Cryptum::UI.col_center(str: red_pill_alert)
241
+ )
242
+ Cryptum::UI.colorize(
243
+ ui_win: order_plan_win,
244
+ color: :red,
245
+ style: :highlight,
246
+ string: red_pill_alert
247
+ )
248
+
249
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_fourth)
250
+ Cryptum::UI.colorize(
251
+ ui_win: order_plan_win,
252
+ color: :red,
253
+ style: :highlight,
254
+ string: ''.ljust(col_just4, ' ')
255
+ )
256
+
257
+ out_line_no += 1
258
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
259
+ order_plan_win.clrtoeol
260
+
261
+ Cryptum::UI.colorize(
262
+ ui_win: order_plan_win,
263
+ color: :yellow,
264
+ string: ''.ljust(col_just1, ' ')
265
+ )
266
+
267
+ order_plan_win.setpos(
268
+ out_line_no,
269
+ Cryptum::UI.col_center(str: red_pill_msg)
270
+ )
271
+ Cryptum::UI.colorize(
272
+ ui_win: order_plan_win,
273
+ color: :yellow,
274
+ style: :bold,
275
+ string: red_pill_msg
276
+ )
277
+
278
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_fourth)
279
+ Cryptum::UI.colorize(
280
+ ui_win: order_plan_win,
281
+ color: :yellow,
282
+ string: ''.ljust(col_just4, ' ')
283
+ )
284
+
285
+ 5.times.each do
286
+ out_line_no += 1
287
+ this_matrix_row = Cryptum::Matrix.generate(cols: Curses.cols)
288
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
289
+ order_plan_win.clrtoeol
290
+ Cryptum::UI.colorize(
291
+ ui_win: order_plan_win,
292
+ color: :red,
293
+ style: :bold,
294
+ string: this_matrix_row
295
+ )
296
+ end
297
+ else
298
+ color = plan_color = :white
299
+ color = indicator_status.market_trend[:color] if indicator_status.market_trend
300
+ plan_color = :cyan if color == :red
301
+ plan_color = :green if color == :green
302
+
303
+ order_plan[0..6].each do |order|
304
+ out_line_no += 1
305
+ style = :normal
306
+ style = :highlight if out_line_no == 1
307
+ fiat_avail_out = Cryptum.beautify_large_number(
308
+ value: order[:fiat_available]
309
+ )
310
+ risk_alloc_out = Cryptum.beautify_large_number(
311
+ value: order[:risk_alloc]
312
+ )
313
+ invest_out = Cryptum.beautify_large_number(
314
+ value: order[:invest]
315
+ )
316
+ profit_out = Cryptum.beautify_large_number(
317
+ value: order[:profit]
318
+ )
319
+ tpm_out = format('%0.2f', tpm)
320
+ return_out = Cryptum.beautify_large_number(
321
+ value: order[:return]
322
+ )
323
+ plan_no = "#{order[:plan_no]}|"
324
+ fiat = "#{autotrade_percent}% of $#{fiat_avail_out} = "
325
+ alloc = "$#{risk_alloc_out} @ #{order[:allocation_percent]}% = "
326
+ invest = "$#{invest_out} + #{tpm_out}% = "
327
+
328
+ returns = "$#{return_out}|"
329
+ profit = "Profit: $#{profit_out}"
330
+
331
+ order_plan_invest = "#{plan_no}#{fiat}#{alloc}#{invest}"
332
+ order_plan_return = "#{returns}#{profit}"
333
+
334
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
335
+ order_plan_win.clrtoeol
336
+ Cryptum::UI.colorize(
337
+ ui_win: order_plan_win,
338
+ color: plan_color,
339
+ style: style,
340
+ string: "#{order_plan_invest}#{order_plan_return}".ljust(col_just1, '.')
341
+ )
342
+ end
343
+
344
+ if order_plan.length < 9
345
+ lines_to_clear = 9 - order_plan.length
346
+ (1..lines_to_clear).each do |_line|
347
+ out_line_no += 1
348
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_first)
349
+ order_plan_win.clrtoeol
350
+ end
351
+ end
352
+ end
353
+
354
+ order_plan_win.refresh
355
+
356
+ # event_history
357
+ rescue Interrupt
358
+ # Exit Gracefully if CTRL+C is Pressed During Session
359
+ Cryptum.exit_gracefully(which_self: self)
360
+ rescue StandardError => e
361
+ raise e
362
+ end
363
+
364
+ # Display Usage for this Module
365
+
366
+ public_class_method def self.help
367
+ puts "USAGE:
368
+ #{self}.refresh(
369
+ order_book: 'required - Order Book Data Structure',
370
+ event: 'required - Event from Coinbase Web Socket'
371
+ )
372
+ "
373
+ end
374
+ end
375
+ end
376
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Cryptum
6
+ module UI
7
+ # This plugin is used to Refresh the Cryptum Status Section UI
8
+ module OrderTimer
9
+ # Supported Method Parameters::
10
+ # Cryptum::UI::Timer.refresh(
11
+ # )
12
+
13
+ public_class_method def self.refresh(opts = {})
14
+ option_choice = opts[:option_choice]
15
+ event_history = opts[:event_history]
16
+ order_timer_win = opts[:order_timer_win]
17
+ indicator_status = opts[:indicator_status]
18
+ key_press_event = opts[:key_press_event]
19
+
20
+ last_trend_reset_time = event_history.order_book[:last_trend_reset]
21
+ last_order_exec_time = event_history.order_book[:last_order_exec]
22
+
23
+ Cryptum::UI.detect_key_press_in_ui(
24
+ key_press_event: key_press_event,
25
+ ui_win: order_timer_win
26
+ )
27
+
28
+ # Market Trend Reset Timer
29
+ time_between_trend_reset = option_choice.market_trend_reset
30
+ trend_timer_begin = Time.parse(last_trend_reset_time)
31
+ trend_timer_end = trend_timer_begin + time_between_trend_reset
32
+ trend_time_remaining = trend_timer_end - Time.now
33
+ trend_countdown = format('%0.4f', trend_time_remaining)
34
+
35
+ # Market Trend Reset Timer
36
+ time_between_order_exec = event_history.time_between_orders
37
+ time_between_order_exec_out = format(
38
+ '%0.4f',
39
+ time_between_order_exec
40
+ )
41
+ order_begin_time = Time.parse(last_order_exec_time)
42
+ order_end_time = order_begin_time + time_between_order_exec
43
+ order_exec_time_remaining = order_end_time - Time.now
44
+ order_countdown = format('%0.4f', order_exec_time_remaining)
45
+
46
+ color = :white
47
+ color = indicator_status.market_trend[:color] if indicator_status.market_trend
48
+ case color
49
+ when :green
50
+ intent = "- Wait for Open Sell Orders -"
51
+ else
52
+ intent = "Next BUY: #{order_countdown} of #{time_between_order_exec_out}"
53
+ intent = '- BUYING PAUSED -' if event_history.red_pill
54
+ end
55
+
56
+ # Have a Clock
57
+ clock = Time.now.strftime('%Y-%m-%d %H:%M:%S%z')
58
+
59
+ # UI
60
+ col_just4 = (Curses.cols - Cryptum::UI.col_fourth) - 1
61
+
62
+ # ROW 1
63
+ out_line_no = 0
64
+ Cryptum::UI.line(
65
+ ui_win: order_timer_win,
66
+ out_line_no: out_line_no
67
+ )
68
+
69
+ # ROW 2
70
+ out_line_no += 1
71
+ order_timer_win.setpos(out_line_no, Cryptum::UI.col_first)
72
+ order_timer_win.clrtoeol
73
+ Cryptum::UI.colorize(
74
+ ui_win: order_timer_win,
75
+ color: :white,
76
+ style: :bold,
77
+ string: "Market Trend Reset: #{trend_countdown}"
78
+ )
79
+
80
+ order_timer_win.setpos(
81
+ out_line_no,
82
+ Cryptum::UI.col_center(str: intent)
83
+ )
84
+ Cryptum::UI.colorize(
85
+ ui_win: order_timer_win,
86
+ color: :white,
87
+ style: :bold,
88
+ string: intent
89
+ )
90
+
91
+ order_timer_win.setpos(out_line_no, Cryptum::UI.col_fourth)
92
+ Cryptum::UI.colorize(
93
+ ui_win: order_timer_win,
94
+ color: :white,
95
+ style: :bold,
96
+ string: clock.rjust(col_just4)
97
+ )
98
+
99
+ order_timer_win.refresh
100
+
101
+ order_countdown.to_f
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
+ raise e
107
+ end
108
+
109
+ # Display Usage for this Module
110
+
111
+ public_class_method def self.help
112
+ puts "USAGE:
113
+ #{self}.refresh(
114
+ )
115
+ "
116
+ end
117
+ end
118
+ end
119
+ end