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,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Cryptum
6
+ # This plugin is used to read and update bot conf files.
7
+ module BotConf
8
+ # Deserialize Cryptum Bot Conf
9
+ public_class_method def self.read(opts = {})
10
+ option_choice = opts[:option_choice]
11
+
12
+ bot_conf_file = "#{option_choice.repo_root}/etc/bot_confs/#{option_choice.symbol}_bot_conf.yaml"
13
+ unless File.exist?(bot_conf_file)
14
+ FileUtils.cp(
15
+ "#{option_choice.repo_root}/etc/bot_confs/BOT_CONF.TEMPLATE",
16
+ bot_conf_file
17
+ )
18
+ end
19
+
20
+ YAML.load_file(
21
+ bot_conf_file,
22
+ symbolize_names: true
23
+ )
24
+ rescue Errno::ENOENT, NoMethodError => e
25
+ File.open('/tmp/cryptum-errors.txt', 'a') do |f|
26
+ f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
27
+ f.puts "Module: #{self}"
28
+ f.puts "#{e}\n\n\n"
29
+ end
30
+
31
+ retry
32
+ rescue Interrupt
33
+ # Exit Gracefully if CTRL+C is Pressed During Session
34
+ Cryptum.exit_gracefully(which_self: self)
35
+ rescue StandardError => e
36
+ # Produce a Stacktrace for anything else
37
+ Curses.close_screen
38
+ raise e
39
+ end
40
+
41
+ # Update Key/Value Pair in Bot Conf and Serialize to YAML File
42
+ public_class_method def self.update(opts = {})
43
+ option_choice = opts[:option_choice]
44
+ bot_conf = opts[:bot_conf]
45
+ key = opts[:key].to_s.to_sym
46
+ value = opts[:value]
47
+
48
+ bot_conf_file = "#{option_choice.repo_root}/etc/bot_confs/#{option_choice.symbol}_bot_conf.yaml"
49
+
50
+ bot_conf[key] = value
51
+ File.write(bot_conf_file, bot_conf.to_yaml)
52
+ rescue Errno::ENOENT, NoMethodError => e
53
+ File.open('/tmp/cryptum-errors.txt', 'a') do |f|
54
+ f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
55
+ f.puts "Module: #{self}"
56
+ f.puts "#{e}\n\n\n"
57
+ end
58
+
59
+ retry
60
+ rescue Interrupt
61
+ # Exit Gracefully if CTRL+C is Pressed During Session
62
+ Cryptum.exit_gracefully(which_self: self)
63
+ rescue StandardError => e
64
+ # Produce a Stacktrace for anything else
65
+ Curses.close_screen
66
+ raise e
67
+ end
68
+ # Display Usage for this Module
69
+
70
+ public_class_method def self.help
71
+ puts "USAGE:
72
+ logger = #{self}.create()
73
+ "
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cryptum
4
+ # This plugin is used to Submit a Limit Order
5
+ # to Buy Crypto Currency
6
+
7
+ module Event
8
+ module Buy
9
+ # Supported Method Parameters::
10
+ # Cryptum::Event::Buy.crypto(
11
+ # )
12
+ public_class_method def self.crypto(opts = {})
13
+ option_choice = opts[:option_choice]
14
+ env = opts[:env]
15
+ bot_conf = opts[:bot_conf]
16
+ event_history = opts[:event_history]
17
+ order_type = opts[:order_type]
18
+ fiat_smallest_decimal = opts[:fiat_smallest_decimal]
19
+ fiat_portfolio_file = opts[:fiat_portfolio_file]
20
+ order_history = opts[:order_history]
21
+ crypto_smallest_decimal = opts[:crypto_smallest_decimal]
22
+ base_min_size = opts[:base_min_size]
23
+ indicator_status = opts[:indicator_status]
24
+
25
+ # Initialize some bot_conf variables
26
+ pie_in_sky_buy_percent = bot_conf[:pie_in_sky_buy_percent].to_f
27
+ autotrade_portfolio_percent = bot_conf[:autotrade_portfolio_percent].to_f
28
+ target_profit_margin_percent = bot_conf[:target_profit_margin_percent].to_f
29
+
30
+ crypto_currency = option_choice.symbol.to_s.upcase.split('_').first
31
+ portfolio = event_history.order_book[:portfolio]
32
+ symbol_portfolio = portfolio.select do |this_portfolio|
33
+ this_portfolio if this_portfolio[:currency] == crypto_currency
34
+ end
35
+
36
+ symbol_balance = format(
37
+ '%0.8f',
38
+ symbol_portfolio.first[:balance].to_f
39
+ ).to_f
40
+
41
+ # 2. Calculate Price, Size, Fees
42
+ # Get the middle of last 3 ticker prices
43
+ # to avoid over purcase blips.
44
+ last_three_prices_arr = []
45
+ last_ticker_price = event_history.order_book[:ticker_price].to_f
46
+ second_to_last_ticker_price = event_history.order_book[:ticker_price_second_to_last].to_f
47
+ third_to_last_ticker_price = event_history.order_book[:ticker_price_third_to_last].to_f
48
+ last_three_prices_arr.push(last_ticker_price)
49
+ last_three_prices_arr.push(second_to_last_ticker_price)
50
+ last_three_prices_arr.push(third_to_last_ticker_price)
51
+
52
+ case order_type
53
+ when :pie
54
+ limit_price = last_three_prices_arr.sort[1]
55
+ pie_in_sky_buy_percent_cast_as_decimal = format(
56
+ '%0.2f',
57
+ pie_in_sky_buy_percent * 0.01
58
+ ).to_f
59
+
60
+ limit_price -= (limit_price * pie_in_sky_buy_percent_cast_as_decimal)
61
+ when :tpm
62
+ limit_price = last_three_prices_arr.sort[1]
63
+ when :gtfo
64
+ # price = format("%0.#{fiat_smallest_decimal}f", limit_price)
65
+ raise "ERROR: Why is a Buy Submitted for #{order_type}?"
66
+ else
67
+ raise "ERROR: Unknown order_type: #{order_type}"
68
+ end
69
+
70
+ price = format("%0.#{fiat_smallest_decimal}f", limit_price)
71
+
72
+ # TODO: Determine if our N% Autotrade
73
+ # Threshold has already been met
74
+ # Buying Crypto w/ Fiat
75
+ autotrade_portfolio_percent_cast_as_decimal = format(
76
+ '%0.7f',
77
+ autotrade_portfolio_percent * 0.01
78
+ ).to_f
79
+
80
+ fiat_portfolio = event_history.order_book[:fiat_portfolio]
81
+ fiat_balance_available = format(
82
+ "%0.#{fiat_smallest_decimal}f",
83
+ fiat_portfolio.first[:available]
84
+ ).to_f
85
+
86
+ # Make sure size is within constraints
87
+ # of autotrade_portfolio_percent
88
+ total_limit_buy_orders_open = order_history.select do |orders|
89
+ orders[:type] == 'limit' &&
90
+ orders[:side] == 'buy' &&
91
+ orders[:status] == 'open'
92
+ end
93
+
94
+ total_limit_buy_order_open_tot = total_limit_buy_orders_open.length
95
+ total_limit_buy_orders_open_size = total_limit_buy_orders_open.inject(0) do |sum, hash|
96
+ sum + hash[:size].to_f
97
+ end.to_f
98
+
99
+ fiat_to_autotrade = fiat_balance_available * autotrade_portfolio_percent_cast_as_decimal
100
+ calc_fiat_to_buy = (fiat_to_autotrade / last_ticker_price) - symbol_balance
101
+ size = format(
102
+ "%0.#{crypto_smallest_decimal}f",
103
+ calc_fiat_to_buy - total_limit_buy_orders_open_size
104
+ )
105
+
106
+ if base_min_size.to_i >= 1
107
+ size = (
108
+ (calc_fiat_to_buy - total_limit_buy_orders_open_size).to_i - base_min_size.to_i
109
+ ).to_s
110
+ end
111
+
112
+ if size.to_f >= base_min_size.to_f &&
113
+ total_limit_buy_order_open_tot.zero? &&
114
+ price.to_f.positive?
115
+ # SUBMIT BUY ORDER
116
+ event_history.order_submitted = true
117
+ event_history.event_notes = "{ \"event_type\": \"#{event_history.event_type}\", \"cancel\": \"#{event_history.order_canceled}\", \"submitted\": \"#{event_history.order_submitted}\" }" if option_choice.proxy
118
+
119
+ event_history = Cryptum::API.submit_limit_order(
120
+ option_choice: option_choice,
121
+ env: env,
122
+ price: price,
123
+ size: size,
124
+ buy_or_sell: :buy,
125
+ order_type: order_type,
126
+ event_history: event_history,
127
+ indicator_status: indicator_status
128
+ )
129
+ end
130
+
131
+ event_history
132
+ rescue StandardError => e
133
+ raise e
134
+ end
135
+
136
+ # Display Usage for this Module
137
+ public_class_method def self.help
138
+ puts "USAGE:
139
+ event_history = #{self}.crypto()
140
+ "
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cryptum
4
+ # This plugin is used to Cancel Open Limit Orders
5
+ module Event
6
+ module Cancel
7
+ # Supported Method Parameters::
8
+ # Cryptum::Event::Cancel.open_orders(
9
+ # )
10
+ public_class_method def self.open_orders(opts = {})
11
+ option_choice = opts[:option_choice]
12
+ env = opts[:env]
13
+ event_history = opts[:event_history]
14
+ order_type = opts[:order_type]
15
+ order_action = opts[:order_action]
16
+
17
+ # Consume Latest Order History Justification from
18
+ # Order Book & cancel orders tagged as pie
19
+ # event_history = Cryptum::API.cancel_synced_oj_and_oh(
20
+ # option_choice: option_choice,
21
+ # env: env,
22
+ # event_history: event_history,
23
+ # order_type: order_type,
24
+ # order_action: order_action
25
+ # )
26
+
27
+ # event_history
28
+ event_history.order_canceled = true
29
+ event_history.event_notes = "{ \"event_type\": \"#{event_history.event_type}\", \"cancel\": \"#{event_history.order_canceled}\", \"submitted\": \"#{event_history.order_submitted}\" }" if option_choice.proxy
30
+
31
+ Cryptum::API.cancel_all_open_orders(
32
+ env: env,
33
+ option_choice: option_choice,
34
+ order_type: order_type,
35
+ event_notes: event_history.event_notes
36
+ )
37
+ rescue StandardError => e
38
+ raise e
39
+ end
40
+
41
+ # Display Usage for this Module
42
+ public_class_method def self.help
43
+ puts "USAGE:
44
+ event_history = #{self}.crypto()
45
+ "
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cryptum
4
+ # This plugin is used to Cancel Open Limit Orders
5
+ module Event
6
+ # Keep Last Event History When Terminal Resize Occuers
7
+ class History
8
+ attr_accessor :bullish_trend,
9
+ :event,
10
+ :event_notes,
11
+ :event_type,
12
+ :first_event,
13
+ :market_trend_event,
14
+ :order_book,
15
+ :order_canceled,
16
+ :order_submitted,
17
+ :order_ready,
18
+ :plan_no,
19
+ :reconnected,
20
+ :red_pill,
21
+ :reset_market_trend,
22
+ :start_time,
23
+ :ticker_event,
24
+ :time_between_orders,
25
+ :time_between_orders_max,
26
+ :time_between_orders_min,
27
+ :time_between_orders_reset
28
+
29
+ def initialize(opts = {})
30
+ option_choice = opts[:option_choice]
31
+ start_time = opts[:start_time]
32
+ order_book = opts[:order_book]
33
+
34
+ self.bullish_trend = false
35
+ self.first_event = true
36
+ self.order_canceled = false
37
+ self.order_submitted = false
38
+ self.order_ready = false
39
+ self.order_book = order_book
40
+ self.plan_no = 0
41
+ self.start_time = start_time
42
+ self.reconnected = false
43
+ self.red_pill = false
44
+ self.reset_market_trend = false
45
+
46
+ # 60 seconds
47
+ self.time_between_orders = option_choice.market_trend_reset
48
+ self.time_between_orders_reset = self.time_between_orders
49
+
50
+ # 60 minutes
51
+ self.time_between_orders_max = self.time_between_orders_reset * 60
52
+
53
+ # 5 seconds
54
+ self.time_between_orders_min = 5
55
+ end
56
+ rescue Interrupt
57
+ # Exit Gracefully if CTRL+C is Pressed During Session
58
+ Cryptum.exit_gracefully(which_self: self)
59
+ rescue StandardError => e
60
+ # Produce a Stacktrace for anything else
61
+ raise e
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cryptum
4
+ # This plugin is used to Cancel Open Limit Orders
5
+ module Event
6
+ module KeyPress
7
+ # Supported Method Parameters::
8
+ # Cryptum::Event::KeyPress.detect(
9
+ # )
10
+ public_class_method def self.detect(opts = {})
11
+ terminal_win = opts[:terminal_win]
12
+
13
+ Cryptum::UI.detect_key_press_in_ui(
14
+ key_press_event: terminal_win.key_press_event,
15
+ ui_win: terminal_win.ticker_section
16
+ )
17
+
18
+ Cryptum::UI.detect_key_press_in_ui(
19
+ key_press_event: terminal_win.key_press_event,
20
+ ui_win: terminal_win.portfolio_section
21
+ )
22
+
23
+ Cryptum::UI.detect_key_press_in_ui(
24
+ key_press_event: terminal_win.key_press_event,
25
+ ui_win: terminal_win.order_plan_section
26
+ )
27
+
28
+ Cryptum::UI.detect_key_press_in_ui(
29
+ key_press_event: terminal_win.key_press_event,
30
+ ui_win: terminal_win.order_timer_section
31
+ )
32
+
33
+ Cryptum::UI.detect_key_press_in_ui(
34
+ key_press_event: terminal_win.key_press_event,
35
+ ui_win: terminal_win.market_trend_section
36
+ )
37
+
38
+ Cryptum::UI.detect_key_press_in_ui(
39
+ key_press_event: terminal_win.key_press_event,
40
+ ui_win: terminal_win.signal_engine_section
41
+ )
42
+
43
+ Cryptum::UI.detect_key_press_in_ui(
44
+ key_press_event: terminal_win.key_press_event,
45
+ ui_win: terminal_win.order_execute_section
46
+ )
47
+
48
+ Cryptum::UI.detect_key_press_in_ui(
49
+ key_press_event: terminal_win.key_press_event,
50
+ ui_win: terminal_win.command_section
51
+ )
52
+ rescue StandardError => e
53
+ raise e
54
+ end
55
+
56
+ # Display Usage for this Module
57
+ public_class_method def self.help
58
+ puts "USAGE:
59
+ order_book = #{self}.crypto()
60
+ "
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cryptum
4
+ # This plugin is used to Submit a Limit Order
5
+ # to Sell Crypto Currency
6
+
7
+ module Event
8
+ module Sell
9
+ # Supported Method Parameters::
10
+ # Cryptum::Event::Sell.crypto(
11
+ # )
12
+ public_class_method def self.crypto(opts = {})
13
+ option_choice = opts[:option_choice]
14
+ env = opts[:env]
15
+ bot_conf = opts[:bot_conf]
16
+ stuck_in_pos_status = opts[:stuck_in_pos_status]
17
+ event_history = opts[:event_history]
18
+ order_type = opts[:order_type]
19
+ fiat_smallest_decimal = opts[:fiat_smallest_decimal]
20
+ crypto_smallest_decimal = opts[:crypto_smallest_decimal]
21
+ base_min_size = opts[:base_min_size]
22
+ indicator_status = opts[:indicator_status]
23
+ quote_increment = opts[:quote_increment]
24
+
25
+ # Initialize some bot_conf variables
26
+ pie_in_sky_sell_percent = bot_conf[:pie_in_sky_sell_percent].to_f
27
+
28
+ crypto_currency = option_choice.symbol.to_s.upcase.split('_').first
29
+ portfolio = event_history.order_book[:portfolio]
30
+ symbol_portfolio = portfolio.select do |this_portfolio|
31
+ this_portfolio if this_portfolio[:currency] == crypto_currency
32
+ end
33
+
34
+ symbol_balance_available = format(
35
+ '%0.8f',
36
+ symbol_portfolio.first[:available].to_f
37
+ ).to_f
38
+
39
+ # 2. Calculate Price, Size, Fees
40
+ # Get the middle of last 3 ticker prices
41
+ # to avoid over purcase blips.
42
+ last_three_prices_arr = []
43
+ last_ticker_price = event_history.order_book[:ticker_price].to_f
44
+ second_to_last_ticker_price = event_history.order_book[:ticker_price_second_to_last].to_f
45
+ third_to_last_ticker_price = event_history.order_book[:ticker_price_third_to_last].to_f
46
+ last_three_prices_arr.push(last_ticker_price)
47
+ last_three_prices_arr.push(second_to_last_ticker_price)
48
+ last_three_prices_arr.push(third_to_last_ticker_price)
49
+ # limit_price = last_three_prices_arr.min
50
+ # limit_price = last_three_prices_arr.max
51
+
52
+ # Obtain our Target Price based on TPM configurations
53
+ target_symbol_price = stuck_in_pos_status[:target_symbol_price].to_f
54
+
55
+ case order_type
56
+ when :pie
57
+ pie_in_sky_sell_percent_cast_as_decimal = format(
58
+ '%0.2f',
59
+ pie_in_sky_sell_percent * 0.01
60
+ ).to_f
61
+
62
+ target_profit = target_symbol_price * pie_in_sky_sell_percent_cast_as_decimal
63
+ limit_price = target_symbol_price + target_profit
64
+
65
+ when :tpm
66
+ limit_price = target_symbol_price
67
+ order_type = :tpm
68
+ when :gtfo
69
+ # Attempt to get in front of falling price.
70
+ limit_price = last_three_prices_arr.sort[1]
71
+ gtfo_price = limit_price -= quote_increment.to_f
72
+ limit_price = gtfo_price if gtfo_price.positive?
73
+ else
74
+ raise "ERROR: Unknown order_type: #{order_type}"
75
+ end
76
+
77
+ price = format("%0.#{fiat_smallest_decimal}f", limit_price)
78
+
79
+ # Selling Available Crytpo Balance in its Entirety
80
+ # We Will Likely Want to Change this in the Future.
81
+ size = format(
82
+ "%0.#{crypto_smallest_decimal}f",
83
+ symbol_balance_available.floor(crypto_smallest_decimal)
84
+ )
85
+
86
+ size = symbol_balance_available if base_min_size.to_i == 1
87
+
88
+ if size.to_f >= base_min_size.to_f &&
89
+ price.to_f.positive?
90
+
91
+ # SUBMIT SELL ORDER
92
+ event_history.order_submitted = true
93
+ event_history.event_notes = "{ \"event_type\": \"#{event_history.event_type}\", \"cancel\": \"#{event_history.order_canceled}\", \"submitted\": \"#{event_history.order_submitted}\" }" if option_choice.proxy
94
+
95
+ event_history = Cryptum::API.submit_limit_order(
96
+ option_choice: option_choice,
97
+ env: env,
98
+ price: price,
99
+ size: size,
100
+ buy_or_sell: :sell,
101
+ order_type: order_type,
102
+ event_history: event_history,
103
+ indicator_status: indicator_status
104
+ )
105
+ end
106
+
107
+ event_history
108
+ rescue StandardError => e
109
+ raise e
110
+ end
111
+
112
+ # Display Usage for this Module
113
+ public_class_method def self.help
114
+ puts "USAGE:
115
+ order_book = #{self}.crypto()
116
+ "
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,168 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module Cryptum
6
+ # This plugin is used to parse Coinbase Pro Web Socket Events in the HTTP Response
7
+ module Event
8
+ autoload :Buy, 'cryptum/event/buy'
9
+ autoload :Cancel, 'cryptum/event/cancel'
10
+ autoload :History, 'cryptum/event/history'
11
+ autoload :KeyPress, 'cryptum/event/key_press'
12
+ autoload :Sell, 'cryptum/event/sell'
13
+
14
+ # Supported Method Parameters::
15
+ # Cryptum::Event.parse(
16
+ # )
17
+
18
+ public_class_method def self.parse(opts = {})
19
+ option_choice = opts[:option_choice]
20
+ env = opts[:env]
21
+ terminal_win = opts[:terminal_win]
22
+ event_history = opts[:event_history]
23
+ indicator_status = opts[:indicator_status]
24
+ indicator_history = opts[:indicator_history]
25
+ bot_conf = opts[:bot_conf]
26
+ ai_enabled = opts[:ai_enabled]
27
+
28
+ candles = event_history.order_book[:candles]
29
+ order_history = event_history.order_book[:order_history]
30
+ this_product = event_history.order_book[:this_product]
31
+ fiat = this_product[:quote_currency]
32
+ fiat_portfolio_file = "#{option_choice.repo_root}/order_books/#{fiat}_PORTFOLIO.json"
33
+
34
+ # Detect Key Press Events
35
+ Cryptum::Event::KeyPress.detect(terminal_win: terminal_win)
36
+
37
+ # Determine if Summary UI needs updated data
38
+ event_history = Cryptum::Portfolio::Balance.refresh(
39
+ env: env,
40
+ option_choice: option_choice,
41
+ terminal_win: terminal_win,
42
+ event_history: event_history,
43
+ fiat_portfolio_file: fiat_portfolio_file
44
+ )
45
+
46
+ # If the Terminal Window has been Resized, Resize the UI
47
+ if Curses.cols != terminal_win.cols
48
+ terminal_win.cols = Curses.cols
49
+ terminal_win.ticker_ui_resize = true
50
+ terminal_win.market_trend_ui_resize = true
51
+ end
52
+
53
+ Cryptum::UI::Portfolio.refresh(
54
+ option_choice: option_choice,
55
+ portfolio_win: terminal_win.portfolio_section,
56
+ event_history: event_history,
57
+ key_press_event: terminal_win.key_press_event,
58
+ indicator_status: indicator_status,
59
+ bot_conf: bot_conf,
60
+ fiat_portfolio_file: fiat_portfolio_file
61
+ )
62
+
63
+ if event_history.event_type == :ticker ||
64
+ terminal_win.ticker_ui_resize
65
+
66
+ ticker_event = event_history.ticker_event = event_history.event if event_history.event_type == :ticker
67
+ ticker_event = event_history.ticker_event if terminal_win.ticker_ui_resize
68
+ Cryptum::UI::Ticker.refresh(
69
+ option_choice: option_choice,
70
+ start_time: event_history.start_time,
71
+ ticker_win: terminal_win.ticker_section,
72
+ key_press_event: terminal_win.key_press_event,
73
+ order_book: event_history.order_book,
74
+ event: ticker_event
75
+ )
76
+ end
77
+
78
+ order_countdown = Cryptum::UI::OrderTimer.refresh(
79
+ option_choice: option_choice,
80
+ event_history: event_history,
81
+ order_timer_win: terminal_win.order_timer_section,
82
+ indicator_status: indicator_status,
83
+ key_press_event: terminal_win.key_press_event
84
+ )
85
+
86
+ if event_history.event_type == :l2update ||
87
+ terminal_win.market_trend_ui_resize
88
+
89
+ market_trend_event = event_history.market_trend_event = event_history.event if event_history.event_type == :l2update
90
+ market_trend_event = event_history.market_trend_event if terminal_win.market_trend_ui_resize
91
+ Cryptum::UI::MarketTrend.refresh(
92
+ option_choice: option_choice,
93
+ market_trend_win: terminal_win.market_trend_section,
94
+ event_history: event_history,
95
+ key_press_event: terminal_win.key_press_event,
96
+ event: market_trend_event,
97
+ indicator_status: indicator_status,
98
+ bot_conf: bot_conf
99
+ )
100
+ end
101
+
102
+ indicator_status = Cryptum::UI::SignalEngine.refresh(
103
+ option_choice: option_choice,
104
+ signal_engine_win: terminal_win.signal_engine_section,
105
+ event_history: event_history,
106
+ key_press_event: terminal_win.key_press_event,
107
+ indicator_status: indicator_status,
108
+ bot_conf: bot_conf,
109
+ fiat_portfolio_file: fiat_portfolio_file
110
+ )
111
+
112
+ Cryptum::UI::OrderPlan.refresh(
113
+ option_choice: option_choice,
114
+ order_plan_win: terminal_win.order_plan_section,
115
+ event_history: event_history,
116
+ key_press_event: terminal_win.key_press_event,
117
+ indicator_status: indicator_status,
118
+ bot_conf: bot_conf,
119
+ fiat_portfolio_file: fiat_portfolio_file
120
+ )
121
+
122
+ event_history = Cryptum::UI::OrderExecution.refresh(
123
+ option_choice: option_choice,
124
+ order_execute_win: terminal_win.order_execute_section,
125
+ env: env,
126
+ event_history: event_history,
127
+ key_press_event: terminal_win.key_press_event,
128
+ indicator_status: indicator_status,
129
+ bot_conf: bot_conf,
130
+ fiat_portfolio_file: fiat_portfolio_file
131
+ )
132
+
133
+ # Refresh Command Section for Cryptum Session Usage
134
+ Cryptum::UI::Command.refresh(
135
+ command_win: terminal_win.command_section,
136
+ key_press_event: terminal_win.key_press_event
137
+ )
138
+
139
+ last_ticker_price = event_history.order_book[:ticker_price].to_f
140
+ second_to_last_ticker_price = event_history.order_book[:ticker_price_second_to_last].to_f
141
+ third_to_last_ticker_price = event_history.order_book[:ticker_price_third_to_last].to_f
142
+
143
+ event_history
144
+ rescue LoadError => e
145
+ # This happens when autoloading modules fail.
146
+ File.open('/tmp/cryptum-errors.txt', 'a') do |f|
147
+ f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
148
+ f.puts "Module: #{self}"
149
+ f.puts "#{e}\n\n\n"
150
+ end
151
+
152
+ retry
153
+ rescue Interrupt
154
+ # Exit Gracefully if CTRL+C is Pressed During Session
155
+ Cryptum.exit_gracefully(which_self: self)
156
+ rescue StandardError => e
157
+ raise e
158
+ ensure
159
+ $stdout.flush
160
+ end
161
+
162
+ # Display Usage for this Module
163
+
164
+ public_class_method def self.help
165
+ constants.sort
166
+ end
167
+ end
168
+ end