cryptum 0.0.320 → 0.0.322

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b1dc9a031f9016aa51791a274952b89497f99019ba4df6b53d3a0f7fc4b928ef
4
- data.tar.gz: fabcdebed66a003cb1e7ac823b10aa5ee547bdf9703aad930d49615358bff579
3
+ metadata.gz: 8ea4631099b7ad8ff94d00136248b662803cfba132ab021303bea8964f89dc78
4
+ data.tar.gz: efa2d3a350d174059f33ce86b6f3d04a6dce885b4c5b7649a185d2c13607c5a4
5
5
  SHA512:
6
- metadata.gz: 8942cf6e920fa3f6172f2987d15163604e9a975dc65290dd883fbbe827a69c6a77333e46e840c1a85e37985e5d720cb4645f6a9d38ea26cdcdac15bf36a23cec
7
- data.tar.gz: 2062bfe9757f0c9babf2df1b98768338d9f13ffa6338fadf90d7bb821d752a337b1af3b9734262f7a0b6529014008159b7c19207fc2ad72df4c8296b2adc080b
6
+ metadata.gz: 0ed9f8234e09f5de2b916cd2769019427d2db893e3498e8e728b7e52b542d617f0766e2dce1d3ba73f7236330780bd306a403205918629beaf253feee0508366
7
+ data.tar.gz: 3c87ccb59b8f82a553d7cb37261490610f979200e858b1892b07c300bf1314d13aafdeace8382562a7f313acc43c8edb27b2c91c8c0d2c4b7feab247d8856d29
data/Gemfile CHANGED
@@ -27,7 +27,7 @@ gem 'rest-client', '2.1.0'
27
27
  gem 'rspec', '3.12.0'
28
28
  gem 'rubocop', '1.40.0'
29
29
  gem 'rubocop-rake', '0.6.0'
30
- gem 'rubocop-rspec', '2.15.0'
30
+ gem 'rubocop-rspec', '2.16.0'
31
31
  gem 'ruby-prof', '1.4.3'
32
32
  gem 'rvm', '1.11.3.9'
33
33
  gem 'sinatra', '3.0.4'
data/README.md CHANGED
@@ -51,7 +51,7 @@ $ rvm use ruby-<VERSION>@cryptum
51
51
  $ cryptum --help
52
52
  $ cryptum --symbol btc-usd \
53
53
  --autotrade \
54
- --repo-root ~/cryptum
54
+ --session-root ~/cryptum
55
55
  ```
56
56
 
57
57
  From an error monitoring perspective, they can be monitored via:
data/bin/cryptum-forecast CHANGED
@@ -11,7 +11,7 @@ class Choice
11
11
  :cycles_complete,
12
12
  :driver_name,
13
13
  :proxy,
14
- :repo_root,
14
+ :session_root,
15
15
  :sandbox,
16
16
  :symbol,
17
17
  :tpm,
@@ -60,9 +60,9 @@ begin
60
60
 
61
61
  options.on(
62
62
  '-rPATH',
63
- '--repo-root=PATH',
63
+ '--session-root=PATH',
64
64
  '<Optional - Directory of Cloned Repo (Defaults to Dir.pwd)">'
65
- ) { |r| option_choice.repo_root = r }
65
+ ) { |r| option_choice.session_root = r }
66
66
 
67
67
  options.on(
68
68
  '-tTPM',
@@ -83,16 +83,16 @@ begin
83
83
  reason = :symbol
84
84
  end
85
85
 
86
- option_choice.repo_root = Dir.pwd if option_choice.repo_root.nil?
86
+ option_choice.session_root = Dir.pwd if option_choice.session_root.nil?
87
87
 
88
88
  if option_choice.autotrade_percent.to_f > 100
89
89
  usage = true
90
90
  reason = :autotrade_percent
91
91
  end
92
92
 
93
- unless Dir.exist?(option_choice.repo_root)
93
+ unless Dir.exist?(option_choice.session_root)
94
94
  usage = true
95
- reason = :repo_root
95
+ reason = :session_root
96
96
  end
97
97
 
98
98
  if usage
@@ -101,8 +101,8 @@ begin
101
101
  puts 'ERROR: --autotrade PERCENT value cannot exceed 100'
102
102
  when :symbol
103
103
  puts "ERROR: --symbol Flag is Required.\n\n"
104
- when :repo_root
105
- puts "ERROR: #{option_choice.repo_root} does not exist.\n\n"
104
+ when :session_root
105
+ puts "ERROR: #{option_choice.session_root} does not exist.\n\n"
106
106
  end
107
107
 
108
108
  puts `#{option_choice.driver_name} --help`
@@ -125,7 +125,7 @@ begin
125
125
 
126
126
  # crypto = products.last[:base_currency]
127
127
  fiat = products.last[:quote_currency]
128
- fiat_portfolio_file = "#{option_choice.repo_root}/order_books/#{fiat}_PORTFOLIO.json"
128
+ fiat_portfolio_file = "#{option_choice.session_root}/order_books/#{fiat}_PORTFOLIO.json"
129
129
 
130
130
  # portfolio = Cryptum::API.get_portfolio(
131
131
  # option_choice: option_choice,
@@ -10,10 +10,12 @@ module Cryptum
10
10
  option_choice = opts[:option_choice]
11
11
  event_history = opts[:event_history]
12
12
 
13
- bot_conf_file = "#{option_choice.repo_root}/etc/bot_confs/#{option_choice.symbol}_bot_conf.yaml"
13
+ session_root = option_choice.session_root
14
+ symbol = option_choice.symbol
15
+ bot_conf_file = "#{session_root}/etc/bot_confs/#{symbol}_bot_conf.yaml"
14
16
  unless File.exist?(bot_conf_file)
15
17
  FileUtils.cp(
16
- "#{option_choice.repo_root}/etc/bot_confs/BOT_CONF.TEMPLATE",
18
+ "#{session_root}/etc/bot_confs/BOT_CONF.TEMPLATE",
17
19
  bot_conf_file
18
20
  )
19
21
  end
@@ -50,7 +52,9 @@ module Cryptum
50
52
  raise e
51
53
  end
52
54
 
53
- # Update Key/Value Pair in Bot Conf and Serialize to YAML File
55
+ # SAUCE 1
56
+ # Calculate Target Profit Margin Percent Based Upon
57
+ # Observed Margins of Change in the Past 24hrs.
54
58
  public_class_method def self.recalculate_tpm(opts = {})
55
59
  option_choice = opts[:option_choice]
56
60
  event_history = opts[:event_history]
@@ -159,7 +163,9 @@ module Cryptum
159
163
  key = opts[:key].to_s.to_sym
160
164
  value = opts[:value]
161
165
 
162
- bot_conf_file = "#{option_choice.repo_root}/etc/bot_confs/#{option_choice.symbol}_bot_conf.yaml"
166
+ session_root = option_choice.session_root
167
+ symbol = option_choice.symbol
168
+ bot_conf_file = "#{session_root}/etc/bot_confs/#{symbol}_bot_conf.yaml"
163
169
 
164
170
  bot_conf[key] = value
165
171
  File.write(bot_conf_file, bot_conf.to_yaml)
@@ -11,10 +11,27 @@ module Cryptum
11
11
  :event_type,
12
12
  :first_event,
13
13
  :market_trend_event,
14
+ :open_sell_orders,
15
+ :open_sell_orders_max,
16
+ :open_sell_orders_merge,
14
17
  :order_book,
15
18
  :order_canceled,
16
- :order_submitted,
19
+ :order_execute_win_active,
20
+ :order_execute_details_win_active,
21
+ :order_execute_index_offset,
22
+ :order_execute_max_rows_to_display,
23
+ :order_execute_max_records_available_to_display,
24
+ :order_execute_row_to_select,
25
+ :order_execute_selected_data,
26
+ :order_plan_win_active,
27
+ :order_plan_details_win_active,
28
+ :order_plan_index_offset,
29
+ :order_plan_max_rows_to_display,
30
+ :order_plan_max_records_available_to_display,
31
+ :order_plan_row_to_select,
32
+ :order_plan_selected_data,
17
33
  :order_ready,
34
+ :order_submitted,
18
35
  :plan_no,
19
36
  :reconnected,
20
37
  :red_pill,
@@ -24,20 +41,6 @@ module Cryptum
24
41
  :time_between_orders_max,
25
42
  :time_between_orders_min,
26
43
  :time_between_orders_reset,
27
- :order_plan_win_active,
28
- :order_plan_details_win_active,
29
- :order_plan_index_offset,
30
- :order_plan_max_rows_to_display,
31
- :order_plan_max_records_available_to_display,
32
- :order_plan_row_to_select,
33
- :order_plan_selected_data,
34
- :order_execute_win_active,
35
- :order_execute_details_win_active,
36
- :order_execute_index_offset,
37
- :order_execute_max_rows_to_display,
38
- :order_execute_max_records_available_to_display,
39
- :order_execute_row_to_select,
40
- :order_execute_selected_data,
41
44
  :recalculate_order_plan
42
45
 
43
46
  def initialize(opts = {})
@@ -47,21 +50,11 @@ module Cryptum
47
50
 
48
51
  self.bullish_trend = true
49
52
  self.first_event = true
50
- self.order_canceled = false
51
- self.order_submitted = false
52
- self.order_ready = false
53
+ self.open_sell_orders = 0
54
+ self.open_sell_orders_max = 500
55
+ self.open_sell_orders_merge = false
53
56
  self.order_book = order_book
54
- self.plan_no = 1
55
- self.start_time = start_time
56
- self.reconnected = false
57
- self.red_pill = false
58
- self.order_plan_win_active = true
59
- self.order_plan_details_win_active = false
60
- self.order_plan_index_offset = 0
61
- self.order_plan_max_rows_to_display = 6
62
- self.order_plan_max_records_available_to_display = 6
63
- self.order_plan_row_to_select = order_plan_index_offset
64
- self.order_plan_selected_data = { color: :white }
57
+ self.order_canceled = false
65
58
  self.order_execute_win_active = false
66
59
  self.order_execute_details_win_active = false
67
60
  self.order_execute_index_offset = 0
@@ -69,14 +62,26 @@ module Cryptum
69
62
  self.order_execute_max_records_available_to_display = 6
70
63
  self.order_execute_row_to_select = order_execute_index_offset
71
64
  self.order_execute_selected_data = { color: :white }
65
+ self.order_plan_win_active = true
66
+ self.order_plan_details_win_active = false
67
+ self.order_plan_index_offset = 0
68
+ self.order_plan_max_rows_to_display = 6
69
+ self.order_plan_max_records_available_to_display = 6
70
+ self.order_plan_row_to_select = order_plan_index_offset
71
+ self.order_plan_selected_data = { color: :white }
72
+ self.order_ready = false
73
+ self.order_submitted = false
74
+ self.plan_no = 1
75
+ self.reconnected = false
76
+ self.red_pill = false
72
77
  self.recalculate_order_plan = false
78
+ self.start_time = start_time
73
79
 
74
- # TODO: Implement market_trend_reset / 144
75
- # Default = 10 minutes
80
+ # FAST BUY = 10 minutes
76
81
  self.time_between_orders = 600
77
82
  self.time_between_orders_reset = time_between_orders
78
83
 
79
- # 1 hour
84
+ # SLOW BUY = 1 hour
80
85
  self.time_between_orders_max = 3_600
81
86
 
82
87
  # 5 seconds
data/lib/cryptum/event.rb CHANGED
@@ -35,7 +35,7 @@ module Cryptum
35
35
  # order_history = event_history.order_book[:order_history]
36
36
  this_product = event_history.order_book[:this_product]
37
37
  fiat = this_product[:quote_currency]
38
- fiat_portfolio_file = "#{option_choice.repo_root}/order_books/#{fiat}_PORTFOLIO.json"
38
+ fiat_portfolio_file = "#{option_choice.session_root}/order_books/#{fiat}_PORTFOLIO.json"
39
39
 
40
40
  # Determine if Summary UI needs updated data
41
41
  event_history = Cryptum::Portfolio::Balance.refresh(
@@ -9,7 +9,7 @@ module Cryptum
9
9
  :driver_name,
10
10
  :list_products,
11
11
  :proxy,
12
- :repo_root,
12
+ :session_root,
13
13
  :sandbox,
14
14
  :symbol,
15
15
  :market_trend_reset,
@@ -43,9 +43,9 @@ module Cryptum
43
43
 
44
44
  options.on(
45
45
  '-rPATH',
46
- '--repo-root=PATH',
47
- '<Optional - Directory of Cloned Repo (Defaults to ~/cryptum)>'
48
- ) { |r| option_choice.repo_root = r }
46
+ '--session-root=PATH',
47
+ '<Optional - Directory with etc && order_books (Defaults to ~/cryptum)>'
48
+ ) { |r| option_choice.session_root = r }
49
49
 
50
50
  options.on(
51
51
  '-S',
@@ -82,11 +82,11 @@ module Cryptum
82
82
  reason = :symbol
83
83
  end
84
84
 
85
- option_choice.repo_root = "#{Dir.home}/cryptum" if option_choice.repo_root.nil?
85
+ option_choice.session_root = "#{Dir.home}/cryptum" if option_choice.session_root.nil?
86
86
 
87
- unless Dir.exist?(option_choice.repo_root)
87
+ unless Dir.exist?(option_choice.session_root)
88
88
  usage = true
89
- reason = :repo_root
89
+ reason = :session_root
90
90
  end
91
91
 
92
92
  option_choice.market_trend_reset = 86_400 if option_choice.market_trend_reset.to_i.zero?
@@ -130,8 +130,8 @@ module Cryptum
130
130
  case reason
131
131
  when :symbol
132
132
  puts "ERROR: --symbol Flag is Required.\n\n"
133
- when :repo_root
134
- puts "ERROR: #{option_choice.repo_root} does not exist.\n\n"
133
+ when :session_root
134
+ puts "ERROR: #{option_choice.session_root} does not exist.\n\n"
135
135
  when :market_trend_reset
136
136
  puts "ERROR: #{option_choice.market_trend_reset} - Possible values are: 604_800 || 86_400 || 14_400 || 10_800 || 7_200 || 3_600 || 2_700 || 1_800 || 900 || 300 || 180 || 60\n\n"
137
137
  end
@@ -168,7 +168,7 @@ module Cryptum
168
168
  public_class_method def self.get_env(opts = {})
169
169
  option_choice = opts[:option_choice]
170
170
 
171
- yaml_conf_file = "#{option_choice.repo_root}/etc/coinbase_pro.yaml"
171
+ yaml_conf_file = "#{option_choice.session_root}/etc/coinbase_pro.yaml"
172
172
  yaml_conf = YAML.load_file(
173
173
  yaml_conf_file,
174
174
  symbolize_names: true
@@ -20,16 +20,9 @@ module Cryptum
20
20
  option_choice = opts[:option_choice]
21
21
  env = opts[:env]
22
22
 
23
- order_book_file = "#{option_choice.repo_root}/order_books/#{option_choice.symbol}.ORDER_BOOK.json"
24
-
25
- order_history_meta = []
26
- if File.exist?(order_book_file)
27
- last_order_book = Cryptum::OrderBook.analyze(
28
- order_book_file: order_book_file,
29
- option_choice: option_choice
30
- )
31
- order_history_meta = last_order_book[:order_history_meta] unless last_order_book[:order_history_meta].empty?
32
- end
23
+ session_root = option_choice.session_root
24
+ symbol = option_choice.symbol
25
+ order_book_file = "#{session_root}/order_books/#{symbol}.ORDER_BOOK.json"
33
26
 
34
27
  # Only need to retrieve a product list once / session.
35
28
  products = Cryptum::API.get_products(
@@ -43,7 +36,7 @@ module Cryptum
43
36
 
44
37
  order_book = {
45
38
  path: order_book_file,
46
- symbol: option_choice.symbol,
39
+ symbol: symbol,
47
40
  open_24h: 0.00,
48
41
  high_24h: 0.00,
49
42
  low_24h: 0.00,
@@ -51,8 +44,6 @@ module Cryptum
51
44
  ticker_price: 0.00,
52
45
  ticker_price_second_to_last: 0.00,
53
46
  ticker_price_third_to_last: 0.00,
54
- highest_pie_in_sky_buy_percent: 0.00,
55
- highest_pie_in_sky_sell_percent: 0.00,
56
47
  sequence: -1,
57
48
  this_product: this_product,
58
49
  portfolio: [],
@@ -70,7 +61,7 @@ module Cryptum
70
61
  sell_end: '--'
71
62
  },
72
63
  order_history: [],
73
- order_history_meta: order_history_meta
64
+ order_history_meta: []
74
65
  }
75
66
 
76
67
  # Order History Retention ---------------------------------------#
@@ -83,6 +74,13 @@ module Cryptum
83
74
  order_book: order_book
84
75
  )
85
76
 
77
+ if File.exist?(order_book_file)
78
+ order_book = JSON.parse(
79
+ File.read(order_book_file),
80
+ symbolize_names: true
81
+ )
82
+ end
83
+
86
84
  event_history.order_book = order_book
87
85
 
88
86
  event_history
@@ -112,42 +112,6 @@ module Cryptum
112
112
  raise e
113
113
  end
114
114
 
115
- # Supported Method Parameters::
116
- # Cryptum::OrderBook.analyze(
117
- # order_book_file: 'required - path to order book file'
118
- # )
119
- public_class_method def self.analyze(opts = {})
120
- order_book_file = opts[:order_book_file]
121
- option_choice = opts[:option_choice]
122
- # TODO: Handle File that exists
123
- # w/ Zero size...N number of
124
- # attempts? Timeout may be better.
125
- order_book = JSON.parse(
126
- File.read(order_book_file),
127
- symbolize_names: true
128
- )
129
-
130
- order_book[:option_choice] = option_choice
131
-
132
- bot_conf = Cryptum::BotConf.read(option_choice: option_choice)
133
- order_book[:bot_conf] = bot_conf
134
-
135
- env = Cryptum::Option.get_env(option_choice: option_choice)
136
- order_book[:env] = env
137
-
138
- order_book
139
- rescue JSON::ParserError => e
140
- File.open('/tmp/cryptum-errors.txt', 'a') do |f|
141
- f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N %z')
142
- f.puts "Module: #{self}"
143
- f.puts "#{e}\n\n\n"
144
- end
145
-
146
- retry
147
- rescue StandardError => e
148
- raise e
149
- end
150
-
151
115
  # Display Usage for this Module
152
116
  public_class_method def self.help
153
117
  constants.sort
@@ -157,6 +157,9 @@ module Cryptum
157
157
  this_order[:color] = :cyan
158
158
  order_history_meta.push(this_order)
159
159
  end
160
+
161
+ # SAUCE 3
162
+ # Time between orders
160
163
  # Increment n Seconds between buys to
161
164
  # account for bearish and bullish trends
162
165
  dynamic_time_increment = cast_margin_to_sec * -1
@@ -361,7 +364,11 @@ module Cryptum
361
364
  total_to_sell = order_history.select do |oh|
362
365
  oh[:status].to_sym == :open && oh[:side].to_sym == :sell
363
366
  end.length
364
- total_to_sell = "#{total_to_sell}+" if total_to_sell == 1000
367
+ event_history.open_sell_orders = total_to_sell
368
+ # TODO: when event_history.open_sell_orders > event_history.open_sell_orders_max
369
+ # Capture highest amount to sell, cancel all orders, and create _one_ limit sell
370
+ # order set to a price of the previously captured highest amount to sell.
371
+ event_history.open_sell_orders_merge = true if total_to_sell > event_history.open_sell_orders_max
365
372
 
366
373
  # TODO: Everything Above this Line Needs to be Indicators ^
367
374
 
@@ -566,8 +573,9 @@ module Cryptum
566
573
 
567
574
  order_execute_win.refresh
568
575
 
569
- # Reset Order Ready Boolean
576
+ # Reset Order Ready && Open Sell Orders Merge (If Applicable) Booleans
570
577
  event_history.order_ready = false
578
+ event_history.open_sell_orders_merge = false
571
579
 
572
580
  event_history
573
581
  rescue Interrupt
@@ -16,10 +16,8 @@ module Cryptum
16
16
  option_choice = opts[:option_choice]
17
17
  order_plan_win = opts[:order_plan_win]
18
18
  event_history = opts[:event_history]
19
- # key_press_event = opts[:key_press_event]
20
19
  indicator_status = opts[:indicator_status]
21
20
  bot_conf = opts[:bot_conf]
22
- # fiat_portfolio_file = opts[:fiat_portfolio_file]
23
21
 
24
22
  ticker_price = event_history.order_book[:ticker_price].to_f
25
23
  return event_history unless ticker_price.positive?
@@ -27,13 +25,9 @@ module Cryptum
27
25
  market_trend_color = plan_color = :white
28
26
 
29
27
  this_product = event_history.order_book[:this_product]
30
- # symbol_out = this_product[:id]
31
- # quote_increment = this_product[:quote_increment]
32
28
  base_increment = this_product[:base_increment]
33
- # base_min_size = this_product[:base_min_size].to_f
34
29
  min_market_funds = this_product[:min_market_funds]
35
30
 
36
- # fiat_smallest_decimal = quote_increment.to_s.split('.')[-1].length
37
31
  crypto_smallest_decimal = base_increment.to_s.split('.')[-1].length
38
32
 
39
33
  autotrade_percent = bot_conf[:autotrade_portfolio_percent].to_f
@@ -50,23 +44,11 @@ module Cryptum
50
44
  raise "ID for Crypto Currency, #{crypto_currency} Not Found" if this_account.empty?
51
45
 
52
46
  balance = format("%0.#{crypto_smallest_decimal}f", this_account.first[:balance])
53
- # avail_for_trade = format("%0.#{crypto_smallest_decimal}f", this_account.first[:available])
54
-
55
47
  fiat_portfolio = event_history.order_book[:fiat_portfolio]
56
48
  total_holdings = format('%0.2f', fiat_portfolio.first[:total_holdings])
57
- # fiat_balance = format('%0.2f', fiat_portfolio.first[:balance])
58
49
  fiat_avail_for_trade = format('%0.2f', fiat_portfolio.first[:available])
59
50
 
60
51
  fiat_budget = fiat_avail_for_trade.to_f
61
- # current_fiat_invested_percent = (
62
- # 1 - (fiat_budget / total_holdings.to_f)
63
- # ) * 100
64
-
65
- # order_history = event_history.order_book[:order_history]
66
- # open_orders = order_history.select do |order|
67
- # order[:status] == 'open'
68
- # end
69
- # total_open_orders = open_orders.length
70
52
 
71
53
  order_plan = event_history.order_book[:order_plan]
72
54
 
@@ -75,10 +57,6 @@ module Cryptum
75
57
  balance.to_f * ticker_price
76
58
  )
77
59
 
78
- # crypto_invested_percent = format(
79
- # '%0.2f',
80
- # (current_crypto_fiat_value.to_f / total_holdings.to_f) * 100
81
- # )
82
60
  crypto_invested_percent = format(
83
61
  '%0.2f',
84
62
  current_crypto_fiat_value.to_f.fdiv(total_holdings.to_f) * 100
@@ -86,6 +64,8 @@ module Cryptum
86
64
 
87
65
  event_history.red_pill = true if crypto_invested_percent.to_f > autotrade_percent
88
66
 
67
+ # SAUCE 2
68
+ # Generating and/or recalculating order plan
89
69
  if event_history.recalculate_order_plan || (
90
70
  crypto_invested_percent.to_f <= autotrade_percent &&
91
71
  autotrade_percent.positive? && (
@@ -114,6 +94,9 @@ module Cryptum
114
94
  risk_target = fiat_budget * autotrade_cast_as_decimal
115
95
  risk_alloc = risk_target
116
96
 
97
+ # TODO: Order Plan <= event_history.max_open_sell_orders
98
+ previous_slice_fiat_investing = 0.00
99
+ last_slice_detected = false
117
100
  loop do
118
101
  # Calculate min order size
119
102
  allocation_decimal += 0.0001
@@ -121,21 +104,30 @@ module Cryptum
121
104
 
122
105
  next unless fiat_investing > min_market_funds.to_f
123
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
+
124
112
  risk_alloc = fiat_budget * autotrade_cast_as_decimal
125
113
  allocation_percent = allocation_decimal * 100
126
- fiat_returning = fiat_investing + (
127
- fiat_investing * tpm_cast_as_decimal
128
- )
129
- profit = fiat_returning - fiat_investing
130
114
 
131
115
  break if order_plan.map { |op| op[:invest].to_f }.sum > risk_target ||
132
- allocation_percent > 100
116
+ allocation_percent > 100 ||
117
+ last_slice_detected
133
118
 
134
- # Avoid a bogus single order at the end when tradeable balances are low.
135
- # TODO: Add remaining amount to last order
136
119
  next unless fiat_budget >= min_market_funds.to_f
137
120
 
138
- slice_alloc = risk_alloc * allocation_decimal
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
+
139
131
  this_plan_no = "#{plan_no}.#{plan_no_slice}"
140
132
  if event_history.recalculate_order_plan
141
133
  order_slice = order_plan.find do |order|
@@ -156,19 +148,24 @@ module Cryptum
156
148
  )
157
149
  order_slice[:slice_alloc] = format('%0.2f', slice_alloc)
158
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
+ )
159
155
  order_slice[:invest] = format('%0.2f', fiat_investing)
160
156
  order_slice[:return] = format('%0.2f', fiat_returning)
161
157
  order_slice[:profit] = format('%0.2f', profit)
162
158
  order_slice[:tpm] = tpm
163
159
  order_slice[:autotrade_percent] = autotrade_percent
164
160
  order_slice[:color] = plan_color
161
+ order_slice[:last_slice] = last_slice_detected
165
162
 
166
163
  order_plan.push(order_slice) unless event_history.recalculate_order_plan
167
164
  fiat_budget -= fiat_investing
165
+ previous_slice_fiat_investing = fiat_investing
168
166
  plan_no_slice += 1
169
167
  end
170
168
  event_history.order_book[:order_plan] = order_plan
171
- # event_history.recalculate_order_plan = false
172
169
  end
173
170
 
174
171
  red_pill_alert = '| RED PILL ALERT |'
@@ -213,7 +210,6 @@ module Cryptum
213
210
 
214
211
  # UI
215
212
  col_just1 = (Curses.cols - Cryptum::UI.col_first) - 1
216
- # col_just3 = (Curses.cols - Cryptum::UI.col_third) - 1
217
213
  col_just4 = Curses.cols - Cryptum::UI.col_fourth
218
214
 
219
215
  # ROW 1
@@ -294,6 +290,7 @@ module Cryptum
294
290
  string: red_pill_alert
295
291
  )
296
292
 
293
+ order_plan_win.setpos(out_line_no, Cryptum::UI.col_fourth)
297
294
  Cryptum::UI.colorize(
298
295
  ui_win: order_plan_win,
299
296
  color: :red,
@@ -380,6 +377,9 @@ module Cryptum
380
377
  slice_alloc_out = Cryptum.beautify_large_number(
381
378
  value: order[:slice_alloc]
382
379
  )
380
+ previous_slice_invest_out = Cryptum.beautify_large_number(
381
+ value: order[:previous_slice_invest]
382
+ )
383
383
  invest_out = Cryptum.beautify_large_number(
384
384
  value: order[:invest]
385
385
  )
@@ -393,7 +393,9 @@ module Cryptum
393
393
  plan_no = "#{order[:plan_no]}|"
394
394
  fiat = "#{autotrade_percent}% of $#{fiat_avail_out} = "
395
395
  alloc = "$#{risk_alloc_out} @ #{order[:allocation_percent]}% = "
396
- invest = "$#{slice_alloc_out} OR MIN OF $#{invest_out} + #{tpm_out}% = "
396
+ alloc = "$#{risk_alloc_out}" if order[:last_slice]
397
+ invest = "$#{slice_alloc_out} + $#{previous_slice_invest_out} = $#{invest_out} + #{tpm_out}% = "
398
+ invest = " + #{tpm_out}% = " if order[:last_slice]
397
399
 
398
400
  returns = "$#{return_out}|"
399
401
  profit = "Profit: $#{profit_out}"
@@ -32,6 +32,9 @@ module Cryptum
32
32
  slice_alloc_out = Cryptum.beautify_large_number(
33
33
  value: order[:slice_alloc]
34
34
  )
35
+ previous_slice_invest_out = Cryptum.beautify_large_number(
36
+ value: order[:previous_slice_invest]
37
+ )
35
38
  invest_out = Cryptum.beautify_large_number(
36
39
  value: order[:invest]
37
40
  )
@@ -44,8 +47,13 @@ module Cryptum
44
47
  )
45
48
  autotrade_ln1_details = "1. Autotrade is set to #{autotrade_percent}% of $#{fiat_avail_out}, making $#{risk_alloc_out} available for this slice in"
46
49
  autotrade_ln2_details = ' the order plan.'
47
- slice_alloc_ln1_details = "2. With $#{risk_alloc_out} available and a slice allocation of #{order[:allocation_percent]}%, $#{slice_alloc_out} OR AN ORDER MINIMUM"
48
- slice_alloc_ln2_details = " of $#{invest_out} will be allocated for this slice (whichever is highest)."
50
+ if order[:last_slice]
51
+ slice_alloc_ln1_details = "2. Since $#{risk_alloc_out} is the remaining amount within the criteria defined in the Autotrade % above,"
52
+ slice_alloc_ln2_details = " $#{invest_out} will be allocated for this slice."
53
+ else
54
+ slice_alloc_ln1_details = "2. With $#{risk_alloc_out} available and a slice allocation of #{order[:allocation_percent]}%, $#{slice_alloc_out} plus the previous"
55
+ slice_alloc_ln2_details = " slice of $#{previous_slice_invest_out} results in $#{invest_out} being allocated for this slice."
56
+ end
49
57
  profit_ln1_details = "3. With a slice allocation of $#{invest_out}, plus a TPM equal to #{tpm_out}%, $#{return_out} will be returned"
50
58
  profit_ln2_details = " once sold. With $#{invest_out} invested, the gross profit equals $#{profit_out}, minus any Maker &"
51
59
  profit_ln3_details = ' Taker (transaction) fees.'
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cryptum
4
- VERSION = '0.0.320'
4
+ VERSION = '0.0.322'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cryptum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.320
4
+ version: 0.0.322
5
5
  platform: ruby
6
6
  authors:
7
7
  - 0day Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-12 00:00:00.000000000 Z
11
+ date: 2022-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -240,14 +240,14 @@ dependencies:
240
240
  requirements:
241
241
  - - '='
242
242
  - !ruby/object:Gem::Version
243
- version: 2.15.0
243
+ version: 2.16.0
244
244
  type: :runtime
245
245
  prerelease: false
246
246
  version_requirements: !ruby/object:Gem::Requirement
247
247
  requirements:
248
248
  - - '='
249
249
  - !ruby/object:Gem::Version
250
- version: 2.15.0
250
+ version: 2.16.0
251
251
  - !ruby/object:Gem::Dependency
252
252
  name: ruby-prof
253
253
  requirement: !ruby/object:Gem::Requirement