Stock Market Simulator main e8c3612
A game that provides a realistic stock buying experience with unpredictable trends to test investment strategies.
Loading...
Searching...
No Matches
main.cpp File Reference

file with the main() function More...

#include "controls.h"
#include "draw.h"
#include "events.h"
#include "file_io.h"
#include "format.h"
#include "graph.h"
#include "random_price.h"
#include "stock.h"
#include "nonstdlibs/VariadicTable.h"
#include <cmath>
#include <fstream>
#include <numeric>
Include dependency graph for main.cpp:

Go to the source code of this file.

Macros

#define enableWindowsVTProcessing()
 

Enumerations

enum  mode { normal , dev }
 hiding mean/sd/uplim/lowlim/event_id columns in the table More...
 

Functions

void get_hsi (std::vector< Stock > stocks_list, std::vector< float > &hsi_history)
 
std::vector< Stock_eventget_ongoing_events (std::vector< Stock > stocks_list)
 Get all the ongoing events.
 
void initializePlayerSaves (std::vector< Stock > &stocks_list, std::vector< float > &hsi_history)
 
int main (void)
 
void new_events_next_round (std::vector< Stock > &stocks_list)
 Generate new events and apply them to the stocks.
 
void next_round_routine (unsigned int &_rounds, std::vector< Stock > &stocks_list)
 
void print_table (std::vector< Stock > stocks_list, float _playerBal, mode m=dev)
 Print the table of stocks.
 
std::string vectorToString (const std::vector< unsigned int > &vec)
 

Variables

float balance = 1000.0f
 Player's balance.
 
std::string playerName
 Player's name.
 
unsigned int rounds_played = 1
 Number of rounds played.
 
const float trading_fees_percent = 0.1 / 100
 / 100 means charging % more/portion of the money involved in stock operations.
 

Detailed Description

file with the main() function

Definition in file main.cpp.

Macro Definition Documentation

◆ enableWindowsVTProcessing

#define enableWindowsVTProcessing ( )

Definition at line 58 of file main.cpp.

Referenced by main().

Enumeration Type Documentation

◆ mode

enum mode

hiding mean/sd/uplim/lowlim/event_id columns in the table

Enumerator
normal 
dev 

Definition at line 104 of file main.cpp.

104{ normal, dev };
@ dev
Definition main.cpp:104
@ normal
Definition main.cpp:104

Function Documentation

◆ get_hsi()

void get_hsi ( std::vector< Stock > stocks_list,
std::vector< float > & hsi_history )

Definition at line 82 of file main.cpp.

82 {
83 float hsi = 0;
84 std::string filesave =
86 std::vector<float> total;
87 for (unsigned int i = 0; i < stocks_list.size(); i++) {
88 total.emplace_back(
89 stocks_list[i].get_price() / stocks_list[i].get_initial_price() * 1000 *
90 static_cast<float>(std::pow(2, stocks_list[i].get_split_count())));
91 // HSI formula = (price/initial price) * 1000 * 2^split count
92 }
93 hsi = std::reduce(total.begin(), total.end()) / total.size();
94 hsi_history.emplace_back(hsi);
95 std::ofstream fout;
96 fout.open(filesave.c_str(), std::ios::app);
97 fout << hsi << ' ';
98 fout.close();
99}
const std::string SAVE_FOLDER_PREFIX
Definition file_io.h:45
const std::string SAVE_FILE_EXTENSION_TXT
Definition file_io.h:48
std::string playerName
Player's name.
Definition main.cpp:73

References playerName, SAVE_FILE_EXTENSION_TXT, and SAVE_FOLDER_PREFIX.

Referenced by main().

Here is the caller graph for this function:

◆ get_ongoing_events()

std::vector< Stock_event > get_ongoing_events ( std::vector< Stock > stocks_list)

Get all the ongoing events.

Parameters
stocks_listA vector of stocks.
Returns
A vector of Stock_event

Definition at line 202 of file main.cpp.

202 {
203 // Return a vector of ongoing events without duplicates
204 std::vector<Stock_event> ongoing_events = {};
205 for (unsigned int i = 0; i < stocks_list.size(); i++) {
206 std::list<Stock_event> events = stocks_list[i].get_events();
207 for (const Stock_event & event : events) {
208 // Side note: Events with duration <= 0 are automatically removed from the
209 // stock's event list. By stock.cpp Stock::next_round() which uses
210 // Stock::remove_obselete_event()
211 if (event.duration > 0) {
212 // If the event is not in the ongoing_events, add it.
213 if (std::find(ongoing_events.begin(), ongoing_events.end(), event) ==
214 ongoing_events.end()) {
215 ongoing_events.emplace_back(event);
216 }
217 }
218 }
219 }
220 return ongoing_events;
221}
The data structure of an event that will be applied to the stocks.
Definition events.h:104

Referenced by main(), and new_events_next_round().

Here is the caller graph for this function:

◆ initializePlayerSaves()

void initializePlayerSaves ( std::vector< Stock > & stocks_list,
std::vector< float > & hsi_history )

Definition at line 290 of file main.cpp.

291 {
292 std::string EMPTY_INPUT = "";
293 std::string loadsave = EMPTY_INPUT;
294 while (loadsave.compare(EMPTY_INPUT) == 0) {
295 std::cout << USER_SAVE_OPTION_PROMPT;
296 std::cin >> loadsave;
297 while (!checkValidInput(loadsave)) {
298 std::cout << "Invalid input.\n" << USER_SAVE_OPTION_PROMPT;
299 std::cin >> loadsave; // choose new file or load previous file
300 }
301 if (loadsave.compare(USER_SAVE_OPTION::NEW_GAME) == 0) {
304 }
305 if (loadsave.compare(USER_SAVE_OPTION::LOAD_GAME) == 0) {
306 loadstatus(rounds_played, stocks_list, balance, playerName, hsi_history);
307 }
308 if (loadsave.compare(USER_SAVE_OPTION::DELETE_GAME) == 0) {
309 delsave(loadsave);
310 loadsave = EMPTY_INPUT;
311 }
312 if (loadsave.compare(USER_SAVE_OPTION::EXIT_GAME) == 0) {
313 std::cout << "Goodbye! Hope you had a good luck in the stock market!"
314 << std::endl;
315 exit(EXIT_SUCCESS);
316 }
317 }
318}
static const std::string DELETE_GAME
Definition file_io.h:25
static const std::string EXIT_GAME
Definition file_io.h:26
static const std::string NEW_GAME
Definition file_io.h:23
static const std::string LOAD_GAME
Definition file_io.h:24
void loadstatus(unsigned int &rounds_played, vector< Stock > &stocks_list, float &balance, string &playerName, vector< float > &hsi_history)
Load an existing game status from .save files.
Definition file_io.cpp:120
const std::string USER_SAVE_OPTION_PROMPT
Definition file_io.cpp:28
void delsave(string &mode)
Delete a save.
Definition file_io.cpp:158
void createplayer(string &playerName)
Create a player folder.
Definition file_io.cpp:69
void savestatus(unsigned int rounds_played, vector< Stock > stocks_list, float balance, const string &playerName)
Save the game status into *.save files.
Definition file_io.cpp:104
bool checkValidInput(const std::string &input)
Check if the input is valid.
Definition file_io.h:37
float balance
Player's balance.
Definition main.cpp:68
unsigned int rounds_played
Number of rounds played.
Definition main.cpp:70

References balance, checkValidInput(), createplayer(), USER_SAVE_OPTION::DELETE_GAME, delsave(), USER_SAVE_OPTION::EXIT_GAME, USER_SAVE_OPTION::LOAD_GAME, loadstatus(), USER_SAVE_OPTION::NEW_GAME, playerName, rounds_played, savestatus(), and USER_SAVE_OPTION_PROMPT.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( void )

Definition at line 320 of file main.cpp.

320 {
322 std::cout << "The game was compiled on " << __DATE__ << " at " << __TIME__
323 << std::endl;
324
325 bool advance; // Whether to advance to the next round
326 bool gameQuit = false; // Whether the player wants to quit the game
327 bool viewMode = false; // 0 to view table, 1 to view graph
328 bool overlayEvent; // Whether the event bar is being shown
329 bool flush; // Whether the screen needs updating
330 int row; // Number of characters to fit in a column
331 int col; // Number of characters to fit in a row
332 fetchConsoleDimensions(row, col);
333
334 std::vector<Stock> stocks_list;
335 stocks_list.reserve(initial_stock_count);
336 for (int i = 0; i < initial_stock_count; i++) {
337 stocks_list.emplace_back();
338 }
339
340 sortStocksList(stocks_list, by_category, ascending);
341
344 exit(1);
345 }
346
347 drawLogo(row, col);
349 std::vector<float> hsi_history;
350
351 initializePlayerSaves(stocks_list, hsi_history);
352
353 if (hsi_history.empty()) {
354 get_hsi(stocks_list, hsi_history);
355 }
356
357 // Done loading/creating a new file.
358 std::cout << "Current trading fees are charged at " << trading_fees_percent * 100
359 << " %" << std::endl;
361
362 while (!gameQuit) {
363 advance = false;
364 overlayEvent = false;
365 flush = false;
366 if (viewMode) {
367 int indexGraph =
368 integerInput(row, col, "Select stock index to display (0 for HSI): ");
369 while (
370 indexGraph < 0 || indexGraph > static_cast<int>(stocks_list.size())) {
371 std::cout << setCursorPosition(row, 3) << "\x1b[2K";
372 std::cout << "Index out of range!";
374 indexGraph = integerInput(
375 row, col, "Select stock index to display (0 for HSI): ");
376 }
377 std::cout << textClear << setCursorPosition(6, 0);
378 graph_plotting(playerName, indexGraph - 1, col * 2 / 3, row - 10);
379 }
380 else {
381 std::cout << textClear << setCursorPosition(6, 0);
382 print_table(stocks_list, balance); // Print the table of stocks
383 }
385 hsi_history[hsi_history.size() - 1]);
386 drawEventBar(row, col);
387 drawButton(row, col);
388 while (!flush) {
389 optionsInput(row, col, balance, trading_fees_percent, stocks_list,
390 get_ongoing_events(stocks_list), viewMode, advance, overlayEvent, flush,
391 gameQuit);
392 }
393
394 if (advance) {
395 next_round_routine(rounds_played, stocks_list);
396 get_hsi(stocks_list, hsi_history);
398 viewMode = false;
400 }
401 }
402 return EXIT_SUCCESS;
403}
static void sleep(int dur)
Definition format.cpp:52
int integerInput(int row, int col, const std::string &message)
Definition controls.cpp:71
void optionsInput(int row, int col, float &balance, float tax, std::vector< Stock > &stocks, const std::vector< Stock_event > &events, bool &viewMode, bool &advance, bool &overlayEvent, bool &flush, bool &gameQuit)
Definition controls.cpp:17
void drawEventBar(int row, int col)
Definition draw.cpp:73
void drawButton(int row, int col)
Definition draw.cpp:156
void drawRoundInfo(int row, int col, int round, float balance, std::string player, float indexHSI)
Definition draw.cpp:52
void drawLogo(int row, int col)
Definition draw.cpp:19
bool assertion_check_mutual_exclusivity(void)
Check if there are mutual exclusivity violations in all_stock_events.
Definition events.cpp:1331
void assertion_check_uniq_events(void)
Definition events.cpp:1416
const int sleepMedium
Definition format.cpp:49
void fetchConsoleDimensions(int &row, int &col)
Definition format.cpp:62
string setCursorPosition(int offsetY, int offsetX)
Definition format.cpp:56
const string textClear
Definition format.cpp:20
const int sleepLong
Definition format.cpp:50
void graph_plotting(const string &player, int stocknum, int width, int height)
Plot the graph of the stock price history to std::cout.
Definition graph.cpp:135
#define enableWindowsVTProcessing()
Definition main.cpp:58
const float trading_fees_percent
/ 100 means charging % more/portion of the money involved in stock operations.
Definition main.cpp:65
void get_hsi(std::vector< Stock > stocks_list, std::vector< float > &hsi_history)
Definition main.cpp:82
void initializePlayerSaves(std::vector< Stock > &stocks_list, std::vector< float > &hsi_history)
Definition main.cpp:290
void print_table(std::vector< Stock > stocks_list, float _playerBal, mode m=dev)
Print the table of stocks.
Definition main.cpp:111
void next_round_routine(unsigned int &_rounds, std::vector< Stock > &stocks_list)
Definition main.cpp:281
std::vector< Stock_event > get_ongoing_events(std::vector< Stock > stocks_list)
Get all the ongoing events.
Definition main.cpp:202
void sortStocksList(std::vector< Stock > &stocks_list, SortingMethods sortMethod, SortingDirections sortDirection)
Sorts the stocks.
Definition stock.cpp:321
@ by_category
Definition stock.h:311
const int initial_stock_count
Initial stock count.
Definition stock.h:28
@ ascending
Definition stock.h:319

References ascending, assertion_check_mutual_exclusivity(), assertion_check_uniq_events(), balance, by_category, drawButton(), drawEventBar(), drawLogo(), drawRoundInfo(), enableWindowsVTProcessing, fetchConsoleDimensions(), get_hsi(), get_ongoing_events(), graph_plotting(), initial_stock_count, initializePlayerSaves(), integerInput(), next_round_routine(), optionsInput(), playerName, print_table(), rounds_played, savestatus(), setCursorPosition(), time::sleep(), sleepLong, sleepMedium, sortStocksList(), textClear, and trading_fees_percent.

Here is the call graph for this function:

◆ new_events_next_round()

void new_events_next_round ( std::vector< Stock > & stocks_list)

Generate new events and apply them to the stocks.

Should be called at the beginning of each round.

Parameters
stocks_listA vector of stocks. Pass by reference to modify the stocks.
Note
numEvents is the sum of these three values:
  • 1
  • A random integer between 0 and 1 (uniform distribution)
  • 1 if more than 10 rounds have been played If there was already more than 5 events, we will not generate more events.

Definition at line 228 of file main.cpp.

228 {
229 /** @note numEvents is the sum of these three values:
230 * - 1
231 * - A random integer between 0 and 1 (uniform distribution)
232 * - 1 if more than 10 rounds have been played
233 * If there was already more than 5 events, we will not generate more events.
234 */
235 unsigned int numEvents = 1 + random_integer(1) + (rounds_played / 5 > 2) * 1;
236 if (get_ongoing_events(stocks_list).size() > 5) {
237 return;
238 }
239 std::vector<Stock_event> picked_events = pick_events(all_stock_events, numEvents);
240 for (const Stock_event & event : picked_events) {
241 switch (event.type_of_event) {
242 case all_stocks:
243 for (unsigned int i = 0; i < stocks_list.size(); i++) {
244 stocks_list[i].add_event(event);
245 }
246 break;
247 case category:
248 for (unsigned int i = 0; i < stocks_list.size(); i++) {
249 if (stocks_list[i].get_category() == event.category) {
250 stocks_list[i].add_event(event);
251 }
252 }
253 break;
254 case pick_random_stock: {
255 std::vector<unsigned int> stocks_indices_not_suitable = {};
256 while (!stocks_list.empty() &&
257 stocks_list.size() < stocks_indices_not_suitable.size()) {
258 // Pick a random stock
259 unsigned int choice = random_integer(stocks_list.size());
260 Stock lucky_stock = stocks_list[choice];
261 if (!lucky_stock.can_add_event(event)) {
262 stocks_indices_not_suitable.emplace_back(choice);
263 }
264 else {
265 Stock_event modified_event = event;
266 modified_event.text = lucky_stock.get_name() + " " + event.text;
267 lucky_stock.add_event(modified_event);
268 break;
269 }
270 }
271 break;
272 }
273 default:
274 // Should not reach here, but if it does, break the loop
275 // so that the player can continue playing the game.
276 break;
277 }
278 }
279}
A class that represents a stock object in the game.
Definition stock.h:55
void add_event(const Stock_event &event)
Add an event to the stock.
Definition stock.cpp:210
std::string get_name(void)
Get the name of the stock.
Definition stock.h:159
bool can_add_event(const Stock_event &event)
Check if we can add the event to the stock.
Definition stock.cpp:231
const std::vector< Stock_event > all_stock_events
The list of all events that can be applied to the stocks.
Definition events.cpp:49
std::vector< Stock_event > pick_events(const std::vector< Stock_event > &all_events, unsigned int num_events)
Pick a random event from the list of events.
Definition events.cpp:1348
@ pick_random_stock
This event will apply to a randomly selected stock from all of the stocks available currently.
Definition events.h:95
@ category
This event will apply to stocks within the specified category.
Definition events.h:92
@ all_stocks
This event will apply to all stocks.
Definition events.h:90
unsigned int random_integer(unsigned int max_integer)
python randint like function
std::string text
The text that will be displayed to the player.
Definition events.h:116

References Stock::add_event(), all_stock_events, all_stocks, Stock::can_add_event(), category, Stock::get_name(), get_ongoing_events(), pick_events(), pick_random_stock, random_integer(), rounds_played, and Stock_event::text.

Referenced by next_round_routine().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ next_round_routine()

void next_round_routine ( unsigned int & _rounds,
std::vector< Stock > & stocks_list )

Definition at line 281 of file main.cpp.

281 {
282 _rounds++; // Increment the round number
284 stocks_list); // Generate new events and apply them to the stocks
285 for (unsigned int i = 0; i < stocks_list.size(); i++) {
286 stocks_list[i].next_round(); // Update the stock price
287 }
288}
void new_events_next_round(std::vector< Stock > &stocks_list)
Generate new events and apply them to the stocks.
Definition main.cpp:228

References new_events_next_round().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ print_table()

void print_table ( std::vector< Stock > stocks_list,
float _playerBal,
mode m = dev )

Print the table of stocks.

We put it in a function so we can call it multiple times.

Parameters
stocks_listA vector of stocks. The stocks to be printed.
_playerBalHow much money the player has.
mmode to hide mean/sd/uplim/lowlim/event_id columns in the table

Definition at line 111 of file main.cpp.

111 {
112 std::vector<std::string> defaultColumns = {
113 "#", "Category", "Name", "$Price", "Change", R"(%Change)", "#Has", "#Max"};
114 VariadicTable<unsigned int, std::string, std::string, float, float, float,
115 unsigned int, unsigned int>
116 defaultTable(defaultColumns);
117 if (m == dev) {
118 defaultColumns.emplace_back(" Mean ");
119 defaultColumns.emplace_back(" SD ");
120 defaultColumns.emplace_back(" up ");
121 defaultColumns.emplace_back(" low ");
122 defaultColumns.emplace_back("event_id");
123 // Create a table, note that R"(% Change)" is a raw string literal (C++11
124 // feature).
125 VariadicTable<unsigned int, std::string, std::string, float, float, float,
126 unsigned int, unsigned int, float, float, float, float, std::string>
127 devTable({defaultColumns});
128 /* Set the precision and format of the columns.
129 * Note: Precision and Format is ignored for std::string columns. */
130 devTable.setColumnPrecision({0, 0, 0, 2, 2, 2, 0, 0, 1, 0, 0, 0, 0});
131 devTable.setColumnFormat({VariadicTableColumnFormat::AUTO,
132 VariadicTableColumnFormat::AUTO, VariadicTableColumnFormat::AUTO,
133 VariadicTableColumnFormat::FIXED, VariadicTableColumnFormat::FIXED,
134 VariadicTableColumnFormat::FIXED, VariadicTableColumnFormat::FIXED,
135 VariadicTableColumnFormat::FIXED, VariadicTableColumnFormat::FIXED,
136 VariadicTableColumnFormat::FIXED, VariadicTableColumnFormat::FIXED,
137 VariadicTableColumnFormat::FIXED, VariadicTableColumnFormat::AUTO});
138 for (unsigned int i = 0; i < stocks_list.size(); i++) {
139 std::map<stock_modifiers, float> modifiers =
140 getProcessedModifiers(stocks_list[i]);
141 devTable.addRow(i + 1, stocks_list[i].category_name(),
142 stocks_list[i].get_name(), stocks_list[i].get_price(),
143 stocks_list[i].delta_price(),
144 stocks_list[i].delta_price_percentage() * 100,
145 stocks_list[i].get_quantity(),
146 stocks_list[i].num_stocks_affordable(_playerBal, trading_fees_percent),
147 modifiers[mean], modifiers[standard_deviation], modifiers[upper_limit],
148 modifiers[lower_limit], vectorToString(stocks_list[i].get_event_ids()));
149 }
150 devTable.print(std::cout);
151 }
152 else {
153 /* Set the precision and format of the columns.
154 * Note: Precision and Format is ignored for std::string columns. */
155 defaultTable.setColumnPrecision({0, 0, 0, 2, 2, 2, 0, 0});
156 defaultTable.setColumnFormat(
157 {VariadicTableColumnFormat::AUTO, VariadicTableColumnFormat::AUTO,
158 VariadicTableColumnFormat::AUTO, VariadicTableColumnFormat::FIXED,
159 VariadicTableColumnFormat::FIXED, VariadicTableColumnFormat::FIXED,
160 VariadicTableColumnFormat::FIXED, VariadicTableColumnFormat::FIXED});
161 for (unsigned int i = 0; i < stocks_list.size(); i++) {
162 defaultTable.addRow(i + 1, stocks_list[i].category_name(),
163 stocks_list[i].get_name(), stocks_list[i].get_price(),
164 stocks_list[i].delta_price(),
165 stocks_list[i].delta_price_percentage() * 100,
166 stocks_list[i].get_quantity(),
167 stocks_list[i].num_stocks_affordable(_playerBal, trading_fees_percent));
168 }
169 defaultTable.print(std::cout);
170 }
171 // Modify the stringstream so that for the column "Change", the text
172 // "Increase" is green and "Decrease" is red.
173 // @note This is a workaround because VariadicTable does not support
174 // modifying the text color of a specific cell.
175 // Warning: This is a hack and may not work in the future!
176 for (unsigned int i = 0; i < stocks_list.size(); i++) {
177 std::string index = std::to_string(i + 1);
178 if (i < 10 - 1) {
179 index = " " + index;
180 }
181 if (stocks_list[i].delta_price() > 0) {
182 std::cout << setCursorPosition(i + 9, 3) << textGreen << index;
183 }
184 else if (stocks_list[i].delta_price() < 0) {
185 std::cout << setCursorPosition(i + 9, 3) << textRed << index;
186 }
187 }
188 std::cout << textWhite;
189 /* Display 2 decimal places for balance.
190 * This line reverts the precision back to default after the table is printed.
191 * Since the table uses std::auto (VariadicTableColumnFormat::AUTO), we need to
192 * revert it back to default.
193 */
194 std::cout << std::fixed << std::setprecision(2);
195}
@ upper_limit
The upper limit of the stock price percentage change.
Definition events.h:48
@ standard_deviation
Amount of variation of the stock price percentage change.
Definition events.h:32
@ mean
The expectation of the stock price percentage change.
Definition events.h:36
@ lower_limit
The lower limit of the stock price percentage change.
Definition events.h:42
const string textGreen
Definition format.cpp:31
const string textWhite
Definition format.cpp:36
const string textRed
Definition format.cpp:30
std::string vectorToString(const std::vector< unsigned int > &vec)
Definition main.cpp:75
std::map< stock_modifiers, float > getProcessedModifiers(Stock stock)
Get the processed modifiers for the stock.

References dev, getProcessedModifiers(), lower_limit, mean, setCursorPosition(), standard_deviation, textGreen, textRed, textWhite, trading_fees_percent, upper_limit, and vectorToString().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ vectorToString()

std::string vectorToString ( const std::vector< unsigned int > & vec)

Definition at line 75 of file main.cpp.

75 {
76 return std::accumulate(
77 vec.begin(), vec.end(), std::string(), [](const std::string & s, int v) {
78 return s.empty() ? std::to_string(v) : s + " " + std::to_string(v);
79 });
80}

Referenced by print_table().

Here is the caller graph for this function:

Variable Documentation

◆ balance

◆ playerName

std::string playerName

Player's name.

Definition at line 73 of file main.cpp.

Referenced by createplayer(), get_hsi(), initializePlayerSaves(), Stock::load(), load_hsi(), loadstatus(), main(), Stock::save(), and savestatus().

◆ rounds_played

unsigned int rounds_played = 1

Number of rounds played.

Definition at line 70 of file main.cpp.

Referenced by initializePlayerSaves(), loadstatus(), main(), new_events_next_round(), and savestatus().

◆ trading_fees_percent

const float trading_fees_percent = 0.1 / 100

/ 100 means charging % more/portion of the money involved in stock operations.

Definition at line 65 of file main.cpp.

Referenced by Stock::calculateStockValue(), Stock::calculateTradingFeesLost(), main(), Stock::num_stocks_affordable(), print_table(), Stock::purchase(), and Stock::sell().