I am working on a project to upload my trades directly to an app I am building, by consuming a CSV file produced by my broker, instead of having to manually enter trades in a journal or paying for one.
My problem is that the data is represented as transactions not trades, therefore I have to match transactions (Buys/sells) and create another object from that. The reason I want to create a "Trade" Object is to store a list of them in a database and pass those objects to other methods to calculate stuff.
Here is what the data looks like from my broker:
Here is the Header for the CSV file:
Account,T/D,S/D,Currency,Type,Side,Symbol,Qty,Price,Exec Time,Comm,SEC,TAF,NSCC,Nasdaq,ECN Remove,ECN Add,Gross Proceeds,Net Proceeds,Clr Broker,Liq,Note
Sample data of the CSV file containing multiple examples of transactions:
FAKEACCOUNT,12/22/2020,12/23/2020,USD,2,B,MSFT201224P00222500,1,0.77,09:50:45,0.59,0,0,0.033,0.09,0,0,-77,-77.713,LAMP,,
FAKEACCOUNT,12/23/2020,12/24/2020,USD,2,S,MSFT201224P00222500,7,1.3,09:47:32,4.13,0.03,0.01,0.033,0.63,0,0,910,905.167,VOLANT,,
FAKEACCOUNT,12/24/2020,12/29/2020,USD,2,B,COCP,450,1.7,07:31:58,2.25,0,0,0.033,0.007065,0,0,-765,-767.290065,LAMP,e,
FAKEACCOUNT,12/24/2020,12/29/2020,USD,2,B,COCP,75,1.65,08:08:06,0.99,0,0,0.033,0.0011775,0,0,-123.75,-124.7741775,LAMP,X,
FAKEACCOUNT,12/24/2020,12/29/2020,USD,2,B,COCP,15,1.63,09:29:23,0.99,0,0,0.033,0.0002355,0,0,-24.45,-25.4732355,LAMP,,
FAKEACCOUNT,12/28/2020,12/30/2020,USD,2,S,COCP,540,1.4709,10:30:36,2.7,0.02,0.07,0.033,0.008478,0,0,794.286,791.454522,MNGD,,
FAKEACCOUNT,12/29/2020,12/30/2020,USD,2,B,PYPL210108P00235000,1,5.35,09:34:21,0.59,0,0,0.033,0.09,0,0,-535,-535.713,VOLANT,,
FAKEACCOUNT,12/29/2020,12/30/2020,USD,2,S,PYPL210108P00235000,1,5.95,09:36:47,0.59,0.02,0.01,0.033,0.09,0,0,595,594.257,VOLANT,,
FAKEACCOUNT,12/29/2020,12/30/2020,USD,2,B,NFLX201231P00535000,1,5.68,11:58:17,0.59,0,0,0.033,0.09,0,0,-568,-568.713,VOLANT,,
FAKEACCOUNT,12/29/2020,12/30/2020,USD,2,B,SPY201230P00372000,1,0.91,12:01:26,0.59,0,0,0.033,0.09,0,0,-91,-91.713,VOLANT,,
FAKEACCOUNT,12/29/2020,12/30/2020,USD,2,S,SPY201230P00372000,1,0.97,12:07:18,0.59,0.01,0.01,0.033,0.09,0,0,97,96.267,VOLANT,,
FAKEACCOUNT,12/29/2020,12/30/2020,USD,2,S,NFLX201231P00535000,1,6.02,12:21:55,0.59,0.02,0.01,0.033,0.09,0,0,602,601.257,VOLANT,,
Here, I matched the same transactions per color to better explain the concept. In yellow are two transactions forming 1 trade. The opening transaction is a "Buy" (B), therefore to close it, the matching transaction should be a "Sell" (S).
Same concept, slightly more complicated in green. The opening trade is a "Buy" with 450 as quantity. The subsequent transactions are also "Buy" with the same symbol, therefore adding to the position (450 + 75 + 15 = 540 quantity). A matching transaction to close the trade should be "Sell", but it could also be in increments. So I should keep track of quantity once a trade is initialized. See how the last green transaction is a sell of 540 quantity with the same symbol, bringing the total quantity to zero for the trade, meaning the trade is completed (Closed).
I have made a Transaction class with all the required fields, a constructor, getters and setters, as well as a Trade class.
public class Transaction {
private String account;
private LocalDate transactionDate;
private LocalDate settledDate;
private String currency;
private int type;
private char side;
private String symbol;
private int quantity;
private double price;
private LocalTime executionTime;
private double commission;
private double secFee;
private double tafFee;
private double nsccFee;
private double nasdaqFee;
private double ecnRemove;
private double ecnAdd;
private double grossProceeds;
private double netProceeds;
public Transaction(String account, LocalDate transactionDate, LocalDate settledDate, String currency,
int type, char side, String symbol, int quantity, double price, LocalTime executionTime,
double commission, double secFee, double tafFee, double nsccFee, double nasdaqFee,
double ecnRemove, double ecnAdd, double grossProceeds, double netProceeds) {
this.account = account;
this.transactionDate = transactionDate;
this.settledDate = settledDate;
this.currency = currency;
this.type = type;
this.side = side;
this.symbol = symbol;
this.quantity = quantity;
this.price = price;
this.executionTime = executionTime;
this.commission = commission;
this.secFee = secFee;
this.tafFee = tafFee;
this.nsccFee = nsccFee;
this.nasdaqFee = nasdaqFee;
this.ecnRemove = ecnRemove;
this.ecnAdd = ecnAdd;
this.grossProceeds = grossProceeds;
this.netProceeds = netProceeds;
}
// Getters, setters and toString()
}
Trade Class:
public Trade(String symbol, String side, LocalDate openDate, LocalTime openTime, LocalDate closeDate,
LocalTime closeTime,
double averageOpenPrice, int shares, double averageClosingPrice, double risk, String setup,
String comments) {
//Geting unique ID based on time
Date date = Calendar.getInstance().getTime();
this.id = date.getTime();
this.symbol = symbol;
this.side = side;
this.openDate = openDate;
this.openTime = openTime;
this.closeDate = closeDate;
this.closeTime = closeTime;
this.averageOpenPrice = averageOpenPrice;
this.shares = shares;
this.averageClosingPrice = averageClosingPrice;
this.risk = risk;
this.setup = setup;
this.comments = comments;
pnl = calculatePnL(averageOpenPrice, averageClosingPrice, shares, side);
percentGain = calculatePercentGain(averageOpenPrice, averageClosingPrice, side);
}
}
My problem: I am stuck at iterating through the list of transactions and matching them, for two reasons:
Sometimes I scale out of positions meaning that I do not sell in 1 transactions (Multiple transactions to close trades), which means I would have to match multiple transactions.
There is the possibility of a trade being still partially opened in the list passed. I do not know how to handle that possibility.
Symbol could either be a "Ticker" Symbol or an Option symbol, not sure if relevant.
What I have tried:
From the consumed file I get a list of Transaction objects, and I though I would match transactions by symbol, side (Buy/sell) and quantity. The problem with that approach is that it might not be the same trade.
public ObservableList<Trade> parseTradesFromTransactions(ObservableList<Transaction> list) {
for(Transaction transaction : list) {
int closedTradecount = 0;
// Iterating through the list
String symbol = transaction.getSymbol();
LocalDate transactionDate = transaction.getTransactionDate();
int quantity = transaction.getQuantity();
char side = transaction.getSide();
// iterate through the rest and match
for(int i = 0; i < list.size(); i ++) {
if(symbol.equals(list.get(i).getSymbol())){
if(transaction.getSide() == 'B' && list.get(i).getSide() == 'S' && transaction.getQuantity() == list.get(i).getQuantity()){
closedTradecount++;
}
}
}
}
return tradeList;
}
I am very new to programming and handling data, and I want to do this right. Any help would be greatly appreciated because I can't wrap my head around matching transactions.
Thanks!
If I understand your logic correctly, you would need 2 data structures in your program:
A dynamic array (suggest using ArrayList) to hold all closed trades you collected.
A dictionary / map (suggest using HashMap) to hold all open trades and access them quickly by their symbol.
Your algorithm would look like this:
Iterate over all transactions.
For each transaction, check if its symbol is in the open trades map.
--> If it is, add the transaction to the exisitng trade. Check if it reduces the amount of symbol to 0.
----> If symobol == 0, close the trade, and move it from the map to the closed trades list.
----> if symbol > 0, continue to next transaction.
--> If it is not, create a new trade for the symbol and add it to the map.
Once all trades are processed, the map should be empty, and you can store the list in your DB.
The code would look something like this:
public class TransactionProcessor {
private ArrayList<Trade> mClosedTrades = new ArrayList<>();
private HashMap<String, Trade> mOpenTrades = new HashMap<>();
public void processTransaction(Transaction transaction) {
Trade curTrade; //for convinience
if (!mOpenTrades.containsKey(transaction.getSymbol())) {
curTrade = new Trade(transaction);
mOpenTrades.add(transaction.getSymbol(), curTrade);
} else {
curTrade = mOpenTrades.get(transaction.getSymbol());
//shortcut: this function returns true if current transaction closes the trade:
if (curTrade.addTransaction(transaction)) {
mClosedTrades.add(curTrade);
mOpenTrades.remove(curTrade.getSymbol());
}
}
}
}
For this code to work, you need to add two more functions to your Trade class.
First, add a constructor to your Trade class that initializes it directly from the first transaction, instead of passing each parameter individually.
public Trade(Transaction first) {
symbol = first.getSymbol();
// ... all other fields initialization ...
}
Second, move the logic of adding further transactions to the trade class:
public boolean addTransaction(Transaction newTrans) {
//optional: add code that makes sure this transaction belongs to this trade by checking the symbol
if (newTrans.getSide() == 'B') {
quantity += newTrans.getQuantity();
} else {
quantity -= newTrans.getQuantity();
}
return quantity == 0; //this is same as if q == 0 return true; else return false;
}
This code assumes that transactions in your CSV file are in order, so that you would never need to open a new trade while you still have quantity of any particular symbol.
Also, there is no error checking.
If there are errors in the CSV file, you could end up with negative quantity of some symbol.
If you are having trouble adding such code, you should open a separate question about it.
For your first problem,
Sometimes I scale out of positions meaning that I do not sell in 1 transactions (Multiple transactions to close trades), which means I would have to match multiple transactions.
Use groupingBy method :
Group your transactions by 'symbol' and collect as map.
Map<Symbol, List> postsPerType = transactions.stream()
.collect(groupingBy(Transactions::getSymbol));
This way you get all transactions grouped together.
There is the possibility of a trade being still partially opened in the list passed. I do not know how to handle that possibility.
Iterate above collected transactions and match the quantity by filtering out Buy and Sell transactions to ensure whether trade is completed.
I am supposed to let up to 16 guests order wine from a menu like this:
The program has to be modular. To place an order, the guest must be shown a list of product types and then variations based on that type. Once the orders are processed I have to show a final report with: total amount made by the winery, most ordered wine product type, and the wine product/variation combo ordered the most times.
I am not sure how to make a method that will search the counter array for the most ordered product type, and then another method that will search the counter array for the most ordered product/variation combo. That is what I need help with.
import javax.swing.JOptionPane;
public class Wine_Taste{
public static void main(String[] args){
String[]wines = {"Riesling", "Chardonnay", "Sauvignon Blanc", "Merlot"};
String[][]wineTypes=
{{"Dry- $4.50", "Off Dry-$4.00", "Sweet- $5.00",},
{"Apple- $6.00", "Lemon-$5.50","Vanilla- $6.00"},
{"Lime-$4.50", "Lemongrass- $6.50","Coconut- $7.00"},
{"Plum- $5.00", "Black Cherry- $7.50","Chocolate- $6.00"}};
}
double[][]prices= {{4.50, 4.00, 5.00},
{6.00, 5.50, 6.00},
{4.50, 6.50, 7.00},
{5.00, 7.50, 6.00}};
int[][]counter ={{0,0,0},
{0,0,0},
{0,0,0},
{0,0,0}};
counter = go(wines,wineTypes,counter,prices);
public static int[][] go(String[] wines, String[][] wineTypes, int[][] counter, double[][] prices){
go2(counter);
double totalCost = 0;
String user;
int x =0;
while (x<=16){
for(int i = 0;i<wines.length;i++){
JOptionPane.showMessageDialog(null,wines[i]);
}
user = JOptionPane.showInputDialog("choose wine 0-3");
int i = Integer.parseInt(user);
for(int j=0;j<wineTypes[i].length;j++){
JOptionPane.showMessageDialog(wineTypes[i][j]);
}
user = JOptionPane.showInputDialog("choose option 0-3");
int j = Integer.parseInt(user);
totalCost += prices[i][j];
counter[i][j]++;
user = JOptionPane.showInputDialog("Order more? y/n");
if (user.equals("y")){
x++;
else{
JOptionPane.showMessageDialog(totalCost);
}
}
}
return counter;
}
}
}
I wouldn't design the program like that. Following some basic object oriented dev principles you can have a wine class with a wine type, price etc, for example:
public class Wine {
String name;
String type;
double price;
public Wine(String name, String type, double price) {
super();
this.name = name;
this.type = type;
this.price = price;
}
//+getters setters
}
Then you can have an order class that keeps the order specific data, like which wine was ordered, the total price etc.
If for any reason you want to keep using the approach of multiple (not easy to manage) arrays then I guess you can create a hashmap where the keys are the wine names and the values the popularity. You can increment by one when a new wine is ordered. You can increment as here:
How to update a value, given a key in a java hashmap?
If for any reason you don't want or can't use this approach then you can create two functions: getPopularProductVarCombo() for the most ordered type per wine, and getMostPopular() for the most popular of all.
To implement getMostPopular you have to find the max value of the array. Here is a good example on how to do this
Print largest number in a 2d array - why do my code print three numbers
To implement getPopularProductVarCombo() then find the max value per line. Any other additional info you might need can be fetched in a similar way.
Task at hand:Consider a class ratingScore that represents a numeric rating for some thing such as a move. Attributes: A description of what is being rated, The maximum possible rating, rating.
It will have methods to: get rating from ta user, Return the maximum rating posisble, return the rating, return a string showing the rating in a format suitable for display.
a. write a method heading for each method
b. write pre and post conditions for each method
c. write some java statements to test the class
d. implement the class.
I think i did what i was supposed to do, but it is a method and i am not sure that i put enough room for it to be changed much, this is what i have so far.
import java.util.*;
public class MovieRating
{
// instance variables
private String description = " A movie that shows how racism affect our lives and choices";
private int maxRating = 10;
private int rating;
// methods
//precondition: Must have maxRating, rating and description before you post it back to the user.
//rating between 1 and 10, maxRating is set to 10, description of a movie
public void writeOutput()
{
System.out.println("The max rating is: " + maxRating );
System.out.println("Your rating is: " + rating );
System.out.println("The rating for" + description + " is " + rating);
System.out.println("while the max rating was " + maxRating);
}
// PostCondition: Will write maxRating, rating and description to the user.
//Precondition: description, enter the rating
public void readInput()
{
Scanner keyboard = new Scanner(System.in);
System.out.println("What would you rate the movie \"American History x\" out of ten");
System.out.println(description);
rating = keyboard.nextInt();
}
//postcondition: rating will be set to user's input for the movie American History x.
}
This is my Tester program.. not much so far
public class MovieRatingTester
{
public static void main(String[] args)
{
//object of the class MovieRating
MovieRating rating1 = new MovieRating();
rating1.readInput();
rating1.writeOutput();
}
}
SO did i cover what was told to cover? i think i did but i think i did it the wrong way, let me know please.
Ok, my point of view is:
Your class, MovieRating is missing some basic elements of OOP, and that is what I think you suppose to learn in this homework.
The first element missing is a constructor method, what you did is automatically assigning each new MovieRating the same description. The job of the constructor function is giving a unique values to the Object when it first built in the system.
The constructor method is special, it is public and has the exact same name is the class, as we said, in this method you suppose to assign values to your object variables.
the second thing will be to put getters/setters, these are methods who has access to your private values and will be used to assign/get the values from them. Note the use of them in the code:
import java.util.*;
public class MovieRating
{
// instance variables
private String description;
private int maxRating;
private int rating;
/*This is the constructor
Note the use of .this - the expression is used to call the class form withing
itself*/
public MovieRating(String description, int maxRating, int rating) {
this.setDescription(description);
this.setMaxRating(maxRating);
this.setRating(rating);
}
/*These are the getters and setters - get is used for getting the value
and set is used for assigning a value to it*/
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getMaxRating() {
return maxRating;
}
public void setMaxRating(int maxRating) {
this.maxRating = maxRating;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
//This is a method for the printing commands - notice the use of the get methods//
public void printRatings()
{
System.out.println("The max rating is: " + this.getMaxRating() );
System.out.println("Your rating is: " + this.getRating() );
System.out.println("The rating for" + this.getDescription() + " is " +
this.getRating());
System.out.println("while the max rating was " + this.getMaxRating();
}
// PostCondition: Will write maxRating, rating and description to the user.
/*Precondition: description, enter the rating
Note the use of this.setRating()*/
public void readInput()
{
Scanner keyboard = new Scanner(System.in);
System.out.println("What would you rate the movie \"American History x\" out of ten");
System.out.println(description);
this.setRating(keyboard.nextInt());
}
//postcondition: rating will be set to user's input for the movie American History x.
}
Using the constructor, you can create a different rating from your tester program
MovieRating rating1 = new MovieRating("description 1", 10, 5);
MovieRating rating2 = new MovieRating("description 2", 9, 7);
You should not ask / print the data from the Ratings class. These ratings can come from user input, but also from database, web, etc.
1 Add getters and setters for properties of MovieRating
2 Pass the read and write methods to the main. Something like
System.out.println("The rating for the movie |" + rating1.getTitle() + "| is " + rating1.getRating());
3 You are not aggregating ratings to a movie. You can't have two rating to the same movie (v.g., by different users) together. Convert the rating attribute into a Vector to solve it. Change setRating for addRating
There are many other things, but obviously this is a starters exercise and I do not want you to get confused. Work on these issues and check with your teacher.
Java (and OO in general) is all about abstractions. You want to keep your objects as general as possible so that you extend your programs functionality without modifying existing code. This may be beyond what your professor was looking for but here are my suggestions:
1) Rating - separate this into its own class
Again, the rating is totally separate from the movie - songs can have ratings, tv shows can have ratings. Today ratings can be 1-10, tomorrow ratings can up thumbs up or thumbs down, etc. A Movie "has a" rating. Let Rating decide how to prompt the user and how to display itself.
2) Now that you have a separate Movie class, I would take away the hard-coded title, description in my Movie class (this will let me create many movies and rate them).
Then I would eliminate System.out.println in writeOutput method (you can pass in the OutputStream to the function)
By hard-coding in System.in you are forcing implementation. What if tomorrow your professor says "now, instead of printing to the console, print to a file or a database"? You have to modify the code. Actually, instead of writeOutput, I would override the toString method that all Objects have and then just call System.in(movie.toString()) in main.
3) Your test method doesn't "test" anything - it is just executing a statement. Typically a test method will simulate input, execute the statements, and check for the proper state at the end. A good way to signal that the state is improper (if your test fails, like maybe your Movie Rating is -1), then you throw an exception.
4) This is un-OO related and just a preference, but I would put both Pre and Post conditions before the methods. This just makes it easier to find in my opinion.
The idea of OO is that you separate responsibilities/concerns into separate classes. Each class is responsible for itself. This helps to keep your code more flexible and maintainable. Good luck on the assignment!