Day Trading Tracker

Hello Programmers,

I am trying to create a program that helps me track all my day trading statistics. I have made an attempt at starting the project but after many days and much frustration, have decided to ask for some tips and help.
I have decided to take the approach of extracting the statistics from a text file and make the program do the calculations needed from the information in the text file. I don't know if this is the best approach or maybe it would be better to have the user input the information for each trade, that then writes it to a text file.

Here is the information I am looking for in my output;

Trades separated by bias; i.e. long & short:
All long trades listed from biggest win to smallest:
All short trades listed from biggest win to smallest:
Most Used Strategy:
Total $ Gains:
Total $ Losses
Total Number of Trades:
Average Winning Trade $ amount:
Average Losing Trade $ amount:
Number of Winning Trades:
Number of Losing Trades:
Largest $ Gain:
Largest $ Loss:
Winning Percentage:
Remaining capital:

This is what my text file looks like; (It only shows four trades as of now, I will add more once I get the program working)

October 2021
Starting Capital: $2500.00

trade 1
Strategy: FGD
bias: long
entryPrice:$3.25, exitPrice:$3.75, shares: 500
trade 2
Strategy: FRD
bias: short
entryPrice:$35.25, exitPrice:$34.75, shares: 100
trade 3
Strategy: AVH
bias: long
entryPrice:$15.25, exitPrice:$15.18, shares: 150
trade 4
Strategy: FRD
bias: short
entryPrice:$9.85, exitPrice:$9.92, shares: 300

This is coming from a text file from notepad. Is it possible to use an excel file instead?


Here is the code I have so far (not nearly complete). I am assuming its no where near correct and I am not even sure its going in the right direction. I have been studying D S Malik's book, "C++ Programming: Program Design Including Data Structures" for help but I'm still struggling with this project. If anyone could help me with this or give me tips, that would be highly appreciated.

// Trading Data Tracker.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;

int main()
{
//declare variables to manipulate data

string trades;
string strategy;
string month;
char bias = ' ';
char ch;
double initCap = 0;
double entryPrice = 0;
double exitPrice = 0;
double shares = 0;
double sumLongTrades = 0;
double sumShortTrades = 0;
double remainingCap = 0;
int winningTrades = 0;
int losingTrades = 0;
double totalEarned = 0;
double totalLost = 0;
int winPerc = 0;
int lossPerc = 0;
double sum = 0;
double num = 0;
double trade1, trade2, trade3 = 0;


//Declare stream variables

ifstream infile;
ofstream outfile;

//Open input file
infile.open("tradingData.txt");

if (!infile)
{
cout << "Cannot open input file."
<< "Program is terminated." << endl;
return 1;
}
//Open output file
outfile.open("tradingData.out");
outfile << fixed << showpoint << setprecision(2);
{

infile>>num;
while (infile)
{
//code to sum the trading data
infile.get(ch);
getline(infile, strategy);
sum = 0;
infile >> num;
}
while (num != -999)
{
sum = sum - entryPrice * shares;
infile >> num;
}

cout << "trade1: "<<sum <<endl;
}


return 0;

}
Last edited on
A lot of comments recently have quite rightly recommended working in cents as integers rather than dollars.cents as doubles.
Last edited on
Do you have control over the format of the file? A shown, that is not conducive to easy parsing. You don't need al the text stuff - just the data

You can use an exported Excel file as type csv.

Using the above data, one possible improved format could be:


10 2021 2500.00
FGD l 3.25 3.75 500
FRD s 35.25 34.75 100
AVH l 5.25 15.18 150
FRD s 9.85 9.92 300


which is much easier to parse!
I do have control of the format. I manually export my trades from my broker. Excel is what I prefer, I just am not sure how to export data from excel into C++.
I did not think of using the format you have shown. I am ok with doing it that way because it definitely would be easier to parse.
What would be the correct way to code it with this format?
Thanks for your input!
the correct way is what gets you the result you want.
this seems complicated enough to justify some simple OOP to organize the data and make it easier to deal with.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
enum strategy{what, are, these};
struct trade
{
   bool isLong{}; //long or short.  you can also use an enum{long, short} or whatever here. 
   strategy Strat{};
   unsigned int  BuyPrice; //in cents   
   unsigned int SellPrice; //cents
   some date type BuyDate; //you can use various ways to track date. a 64bit integer format YYYYMMDDHHMMSS will fit for example. 
  datetype SellDate; //as above
  unsigned int numshares;
  string serialize(); //return a formatted string of the fields with commas etc suitable for a cout or setwindowtext or whatever call. 
};

struct symbol
{
   string symbol; //name, "FRD" etc
   vector<trade> trades;
   ///other fields as needed
   string serialize(); //as above, format output.  this one may need to compute things from <trades> like win/loss etc
}

then down in main you have 
vector <symbol> mydata //or a map maybe? this seems like a good place for a map..
that you can load up, process, save, etc.  you can sort by symbol name, filter by trade type (long/short), whatever here. 


the key design component here is deciding what you will do in your program and what you will offload to excel (if anything). Unless you are using excel to draw charts, I would do all this in c++. But to me everything except graphing for this task seems easy in c++, if you are new to the language it may be easier to rig some of it into excel. IIRC you can write text formulae in csv and excel understands it, eg =sum(... type formula in a cell will work.. letting the c++ tell excel what to do
Last edited on
This is what I am trying to get the program to do:
Trades separated by bias; i.e. long & short:
All long trades listed from biggest win to smallest:
All short trades listed from biggest win to smallest:
Most Used Strategy:
Total $ Gains:
Total $ Losses
Total Number of Trades:
Average Winning Trade $ amount:
Average Losing Trade $ amount:
Number of Winning Trades:
Number of Losing Trades:
Largest $ Gain:
Largest $ Loss:
Winning Percentage:
Remaining capital:

I am new to C++ so I would be completely fine with having C++ do everything. I just wasn’t sure if that would be easier than reading from a file.
If I could code a program that gives me the above information all in c++ I would be happy with that start!
This should give you a start (not tested):

trades.csv
10 2021 2500.00
FGD 1 1 10  3.25 11  3.75 500
FRD 0 2 12 35.25 15 34.75 100
AVH 0 2 16  5.25 18 15.18 150
FRD 1 3 20  9.85 24  9.92 300


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
using namespace std;

struct Trade
{
	string Symbol{}; 
	bool isLong{};			//if true, then long, else short   
	int Strat{};
	double BuyPrice{};
	double SellPrice{};
	int BuyDayOfMonth{};		//  1-31 . 
	int SellDayOfMonth{};
	unsigned int numshares{};
	double NetAmount{};
};

//	Globals
int				month;
int				year;
double			starting_capital;
vector<Trade>	trades;

//	Expected file format
//	mm yyyy aaaaa.aa
//		where	mm is the month
//				yyyy is the year
//				aaaa.aa is the starting capital 
//	sym ls bd ba sd sa ns
//		where	sym is the stock symbol
//				ls is 1 for long 0 for short
//				st is integer representing strategy
//				bd is the buy day of the month
//				ba is the buy price per share
//				sd is the sell day of the month
//				sa is the sell price per share
//				ns is the number of shares
//
bool read_csv_file()
{
	ifstream		is;
	Trade			temp;

	is.open("trades.csv");
	if (!is.is_open())
		return false;		//	File failed to open

	//	Read the header
	is >> month;
	is >> year;
	is >> starting_capital;

	//	Read the trades
	while (is >> temp.Symbol)
	{
		is >> temp.isLong;
		is >> temp.Strat;
		is >> temp.BuyDayOfMonth;
		is >> temp.BuyPrice;
		is >> temp.SellDayOfMonth;
		is >> temp.SellPrice;
		is >> temp.numshares;
		temp.NetAmount = (temp.SellPrice - temp.BuyPrice) * temp.numshares;
                trades.push_back (temp);
	}
	is.close();		// not needed; just being pedantic
	return true;
}

//	List one Trade (raw)
void ListTrade(const Trade& t)
{
	cout << setw(5) << t.Symbol << "  ";
	cout << setw(2) << t.Strat << "  ";
	cout << setw(2) << t.BuyDayOfMonth << "  ";
	cout << setw(7) << t.BuyPrice << "  ";
	cout << setw(2) << t.SellDayOfMonth << " ";
	cout << setw(7) << t.SellPrice << "  ";
	cout << setw(6) << t.numshares << "  ";
	cout << setw(6) << t.NetAmount;
	cout << endl;
}

//	List all trades that match the long or short argument
void ListRawTrades(bool ls)
{
	if (ls)
		cout << "All long trades" << endl;
	else
		cout << "All short trades" << endl;
	cout << endl;
//			 ....+....2....+....3....+....4....+....5....+....6....+
//			 sssss  st  bd  bbbbb.bb  sd  sssss.ss  nnnnnn  aaaaa.aa
	cout << "Symbl  ST  BD  BuyPrice  SD  SellPric  Shares" << endl;
	for (auto t : trades)
	{
		if (t.isLong == ls)
			ListTrade(t);	//	List one matching trade
	}
	cout << endl;
}

//	Calculate total gains and losses
void TotalGainsandLosses()
{
	double total_gains = 0;
	double total_losses = 0;

	for (auto t : trades)
	{
		if (t.NetAmount > 0)
			total_gains += t.NetAmount;
		else
			total_losses += t.NetAmount;
	}
	cout << "Total Gains = " << total_gains << endl;
	cout << "Total Losses = " << total_losses << endl;
	cout << endl;
}
int main()
{
	if (!read_csv_file())
		return 1;
	//	Sort vector biggest to smallest net amount
	ListRawTrades(true);		//	List all long trades
	ListRawTrades(false);		//	List all short trades
	TotalGainsandLosses();
}


edit added after line 65:
 
              trades.push_back (temp);


Edit #2: Fixed the >> in read_csv_file to be from is rather than cin.
Last edited on
I really appreciate the input! This is definitely a huge help and I think it will get me the started on the right track!
I missed a very important line.
Added after line 65:
 
            trades.push_back (temp);
Thank you so much!! this has been a huge help to me! I really appreciate you taking the time to answer my questions and put in all this work!
@dwizz011
If @AbstractionAnon's work solves your problem then that's all to the well and good, possibly the end of the story. I have no comment to make about it or criticize it.

However it would be a good idea for you to also incorporate the advice from @Jonnin above. Not the code so much but the principles involved to avoid some pretty standard traps - particularly 'spaghetti code' that goes on and on forever in more and more convolutions of if's whiles and flags.

The key issue to consider surrounds the source of the data and what your final intended outcome is. If you already have the info on a personal spreadsheet (a database is better suited anyway) then why not stick with that. If it's a download from a stockbroker then why not stick with what the stockbroker has, a decent broker will have comprehensive reporting.

Downloading the data is only a snapshot, so why not just enter buy and sell trades to your program yourself. Entries can be timestamped with real times, and saved/retrieved from disk as required with updates as part of your program.

Probably a bit early in your programming career by the sound of it but struct's and classes towards an object-oriented approach is definitely the way to go.

The structs/classes could be Portfolio( <vectors>, reports), Transaction (Buy/Sell), Company (code, name) along with a menu and input.
Here's a fully working code that covers all your requirements.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <map>
using namespace std;

//
//	Objectives:
//	*	Trades separated by bias; i.e. long & short:
//	*	All long trades listed from biggest win to smallest :
//	*	All short trades listed from biggest win to smallest :
//	*	Most Used Strategy :
//	*	Total $ Gains :
//	*	Total $ Losses
//	*	Total Number of Trades :
//	*	Average Winning Trade $ amount :
//	*	Average Losing Trade $ amount :
//	*	Number of Winning Trades :
//	*	Number of Losing Trades :
//	*	Largest $ Gain :
//	*	Largest $ Loss :
//	*	Winning Percentage :
//	*	Remaining capital :
//

struct Trade
{
	string Symbol{}; 
	bool isLong{};				// 1 = long, 0 = short   
	int Strat{};
	double BuyPrice{};
	double SellPrice{};
	int BuyDayOfMonth{};		//  1-31 . 
	int SellDayOfMonth{};
	unsigned int numshares{};
	//	The following is calculated
	double NetProfit{};	
};

typedef map<int, int>	strat_map_t;

//	Globals
int				month;
int				year;
double			starting_capital;
vector<Trade>	trades;

//	Expected file format
//	mm yyyy aaaaa.aa
//		where	mm is the month
//				yyyy is the year
//				aaaa.aa is the starting capital 
//	sym ls bd ba sd sa ns
//		where	sym is the stock symbol
//				ls is 1 for long 0 for short
//				st is integer representing strategy
//				bd is the buy day of the month
//				ba is the buy price per share
//				sd is the sell day of the month
//				sa is the sell price per share
//				ns is the number of shares
//
bool read_csv_file()
{
	ifstream		is;
	Trade			temp;

	is.open("trades.csv");
	if (!is.is_open())
		return false;		//	File failed to open

	//	Read the header
	is >> month;
	is >> year;
	is >> starting_capital;

	//	Read the trades
	while (is >> temp.Symbol)
	{	is >> temp.isLong;
		is >> temp.Strat;
		is >> temp.BuyDayOfMonth;
		is >> temp.BuyPrice;
		is >> temp.SellDayOfMonth;
		is >> temp.SellPrice;
		is >> temp.numshares;
		temp.NetProfit = (temp.SellPrice - temp.BuyPrice) * temp.numshares;
		trades.push_back(temp);
	}
	is.close();		// not needed; just being pedantic
	return true;
}

//	List one Trade (raw)
void ListTrade(const Trade& t)
{
	cout << setw(5) << t.Symbol << "  ";
	cout << setw(2) << t.Strat << "  ";
	cout << setw(2) << t.BuyDayOfMonth << "  ";
	cout << setw(7) << t.BuyPrice << "  ";
	cout << setw(2) << t.SellDayOfMonth << " ";
	cout << setw(7) << t.SellPrice << "  ";
	cout << setw(6) << t.numshares << "  ";
	cout << setw(6) << t.NetProfit;
	cout << endl;
}

void ListTradeHeader()
{	//		 ...+....2....+....3....+....4....+....5....+....6....+
	//		 sssss  st  bd  bbbbb.bb  sd  sssss.ss  nnnnnn  aaaaa.aa
	cout << "Symbl  ST  BD  BuyPrice  SD  SellPric  Shares  Profit" << endl;
}

//	List all trades that match the long or short argument
void ListRawTrades(bool ls)
{
	int cnt = 0;

	if (ls)
		cout << "All long trades" << endl;
	else
		cout << "All short trades" << endl;
	cout << endl;
	ListTradeHeader();
	for (auto t : trades)
	{
		if (t.isLong == ls)
		{
			ListTrade(t);	//	List one matching trade
			cnt++;
		}
	}
	if (cnt == 0)
		cout << "No matching trades" << endl;
	cout << endl;
}

//	Calculate total gains and losses
void TotalGainsandLosses()
{	
	int num_trades = 0;
	int winning_trade_count = 0;
	int losing_trade_count = 0;
	double avg_winning_trade = 0;
	double avg_losing_trade = 0;
	double sum_winning_trades = 0;
	double sum_losing_trades = 0;
	Trade  largest_winning_trade{};
	double largest_win = 0;
	Trade  largest_losing_trade{};
	double largest_loss = 0;
	double winning_percent = 0;
	double balance = starting_capital;

	for (auto t : trades)
	{
		if (t.NetProfit > 0)
		{
			sum_winning_trades += t.NetProfit;
			winning_trade_count++;
			if (t.NetProfit > largest_win)
			{
				largest_win = t.NetProfit;
				largest_winning_trade = t;
			}
		}
		else
		{
			sum_losing_trades += t.NetProfit;
			losing_trade_count++;
			if (t.NetProfit < largest_loss)
			{
				largest_loss = t.NetProfit;
				largest_losing_trade = t;
			}
		}
		balance += t.NetProfit;
		num_trades++;
	}
	avg_winning_trade = sum_winning_trades / (double)winning_trade_count;
	avg_losing_trade = sum_losing_trades / (double)losing_trade_count;
	winning_percent = (double)winning_trade_count / (double)num_trades * 100;
	cout << "Total Gains = " << sum_winning_trades << endl;
	cout << "Total Losses = " << sum_losing_trades << endl;
	cout << "Winning trades = " << winning_trade_count << endl;
	cout << "Losing trades = " << losing_trade_count << endl;
	cout << "Total number of trades = " << num_trades << endl;
	cout << "Average winning trade = " << avg_winning_trade << endl;
	cout << "Average_losing_trade = " << avg_losing_trade << endl;
	if (largest_win == 0)
		cout << "There were no winning trades" << endl;
	else
	{
		cout << "Largest winning trade" << endl;
		ListTradeHeader();
		ListTrade(largest_winning_trade);
	}
	if (largest_loss == 0)
		cout << "There were no losing trades" << endl;
	else
	{
		cout << "Largest losing trade" << endl;
		ListTradeHeader();
		ListTrade(largest_losing_trade);
	}
	cout << "Winning percent = " << winning_percent << endl;
	cout << "Remaining capital = " << balance << endl;
	cout << endl;
}

//	Find most used strategy 
//	Does not account for ties
void FindMostUsedStrategy()
{
	strat_map_t					strat_map; 
	strat_map_t::iterator		iter;
	int							most_used_cnt = 0;
	int							most_used_strat = 0;

	//	Iterate throught the trades
	for (auto t : trades)
	{	//	Have we seen this strategy before?
		iter = strat_map.find(t.Strat);
		if (iter != strat_map.end())
		{	//	Yes, increment the count
			iter->second++;
			continue;
		}
		else
		{	//	No, new strategy
			pair<int, int>	item(t.Strat, 1);
			strat_map.insert(item);
		}
	}
	//	Find the most used	
	for (auto s : strat_map)
	{
		if (s.second > most_used_cnt)
		{
			most_used_strat = s.first;
			most_used_cnt = s.second;
		}
	}
	cout << "Most used strategy = " << most_used_strat << endl;
	cout << "It was used " << most_used_cnt << " times." << endl;
	cout << endl;
}

//	Sort trades from biggest profit to smallest profit
bool OrderByNetProfit(const Trade& t1, const Trade& t2)
{
	return t1.NetProfit > t2.NetProfit;
}

int main()
{
	if (!read_csv_file())
		return 1;	
	//	Sort vector biggest to smallest net amount
	//	We only need one sort for both short and long trades
	sort(trades.begin(), trades.end(), OrderByNetProfit);
	ListRawTrades(true);		//	List all long trades
	ListRawTrades(false);		//	List all short trades
	TotalGainsandLosses();
	FindMostUsedStrategy();
}



All long trades

Symbl  ST  BD  BuyPrice  SD  SellPric  Shares  Profit
  FGD   1  10     3.25  11    3.75     500     250
  FRD   3  20     9.85  24    9.92     300      21

All short trades

Symbl  ST  BD  BuyPrice  SD  SellPric  Shares  Profit
  AVH   2  16     5.25  18   15.18     150  1489.5
  FRD   2  12    35.25  15   34.75     100     -50

Total Gains = 1760.5
Total Losses = -50
Winning trades = 3
Losing trades = 1
Total number of trades = 4
Average winning trade = 586.833
Average_losing_trade = -50
Largest winning trade
Symbl  ST  BD  BuyPrice  SD  SellPric  Shares  Profit
  AVH   2  16     5.25  18   15.18     150  1489.5
Largest losing trade
Symbl  ST  BD  BuyPrice  SD  SellPric  Shares  Profit
  FRD   2  12    35.25  15   34.75     100     -50
Winning percent = 75
Remaining capital = 4210.5

Most used strategy = 2
It was used 2 times.


BTW, the first record of the posted CSV file has an "l" in the long/short position.
Change this to a "1" or you will hang up on the input.
This is incredible! Excel has primarily been used for my tracking system. I just started learning C++ as I'm sure you can tell. I have been interested in quant trading and I am learning C++ with the goal in mind to create my own trading algorithm. I wanted to started with a Day Trading tracking system and build from there. I have been working on much simpler projects and decided to take a shot at the tracker. I really appreciate you taking time to explain it and thanks a lot for taking the time to write this out!
The code still needs a few things:
- Editing on the input to make sure it's reasonable
- Better formatting
if its going to handle real data, you need to track your fees. selling for $5 profit after paying $15 or whatever twice (once to buy, once to sell) is a $25 loss not a $5 gain.
not sure what else you need, it looks close. Time == money they say, so I still think you may want to also display profit per time unit (per day? week? whatever) between buy and sell. A decent profit years later is eaten up by inflation and missed chances... but what I don't know about all this stuff would fill a library. I let the experts invest mine most of the time. I took the money and ran on a covid prediction though ... Ag :)
if its going to handle real data, you need to track your fees. selling for $5 profit after paying $15 or whatever twice (once to buy, once to sell) is a $25 loss not a $5 gain.

Any system would indeed need to take into account costs of trades.
However, brokerage applies to the parcel of stocks being traded not each one individually. If the $5 profit was on selling 1000 shares then brokerage at $15 (x2) is a pittance. Depending on local tax rules that would be a sweet $4970. ( or a sour <$5030> if each sold was a $5 down )
Topic archived. No new replies allowed.