Java 如何遍历列表并匹配事务

Java 如何遍历列表并匹配事务,java,trading,Java,Trading,我正在做一个项目,通过使用经纪人制作的CSV文件,将我的交易直接上传到我正在构建的应用程序中,而不必手动在日记账中输入交易或支付交易费用 我的问题是数据被表示为交易而不是交易,因此我必须匹配交易(买入/卖出),并从中创建另一个对象。我想要创建一个“Trade”对象的原因是将它们的列表存储在数据库中,并将这些对象传递给其他方法来计算内容 以下是我的经纪人提供的数据: 以下是CSV文件的标题: 账户、T/D、S/D、货币、类型、侧面、符号、数量、价格、执行时间、通信、SEC、TAF、NSCC、纳斯

我正在做一个项目,通过使用经纪人制作的CSV文件,将我的交易直接上传到我正在构建的应用程序中,而不必手动在日记账中输入交易或支付交易费用

我的问题是数据被表示为交易而不是交易,因此我必须匹配交易(买入/卖出),并从中创建另一个对象。我想要创建一个“Trade”对象的原因是将它们的列表存储在数据库中,并将这些对象传递给其他方法来计算内容

以下是我的经纪人提供的数据:

以下是CSV文件的标题:

账户、T/D、S/D、货币、类型、侧面、符号、数量、价格、执行时间、通信、SEC、TAF、NSCC、纳斯达克、ECN删除、ECN添加、总收益、净收益、Clr经纪人、Liq、注释

包含多个交易示例的CSV文件的示例数据:

伪造账户,2020年12月22日,2020年12月23日,美元,2,B,MSFT201224P00222500,1,0.77,09:50:45,0.59,0,0,0.033,0.09,0,0,0,-77,-77.713,LAMP,, 伪造账户,2020年12月23日,2020年12月24日,美元,2,S,MSFT201224P00222500,7,1.3,09:47:32,4.13,0.03,0.01,0.033,0.63,0,0910905.167,沃兰特,, 伪造账户,2020年12月24日,2020年12月29日,美元,2,B,COCP,450,1.7,07:31:58,2.25,0,0,0.033,0.007065,0,0,-765,-767.290065,LAMP,e, 伪造账户,2020年12月24日,2020年12月29日,美元,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, 伪造账户,2020年12月24日,2020年12月29日,美元,2,B,COCP,15,1.63,09:29:23,0.99,0,0,0,0.033,0.0002355,0,0,-24.45,-25.4732355,LAMP,, 伪造账户,2020年12月28日,2020年12月30日,美元,2,S,COCP,540,1.4709,10:30:36,2.7,0.02,0.07,0.033,0.008478,0,0794.286791.454522,MNGD,, 伪造账户,2020年12月29日,2020年12月30日,美元,2,B,PYPL210108P00235000,1,5.35,09:34:21,0.59,0,0,0.033,0.09,0,0,0,-535,-535.713,沃兰特,, 伪造账户,2020年12月29日,2020年12月30日,美元,2,S,PYPL210108P00235000,1,5.95,09:36:47,0.59,0.02,0.01,0.033,0.09,0,0595594.257,沃兰特,, 伪造账户,2020年12月29日,2020年12月30日,美元,2,B,NFLX201231P00535000,1,5.68,11:58:17,0.59,0,0,0.033,0.09,0,0,-568,-568.713,沃兰特,, 伪造账户,2020年12月29日,2020年12月30日,美元,2,B,SPY201230P00372000,1,0.91,12:01:26,0.59,0,0,0.033,0.09,0,0,0,-91,-91.713,沃兰特,, 伪造账户,2020年12月29日,2020年12月30日,美元,2,S,SPY201230P00372000,1,0.97,12:07:18,0.59,0.01,0.033,0.09,0,0,97,96.267,沃兰特,, 伪造账户,2020年12月29日,2020年12月30日,美元,2,S,NFLX201231P00535000,1,6.02,12:21:55,0.59,0.02,0.01,0.033,0.09,0,0602601.257,沃兰特

这里,我匹配了每种颜色的相同事务,以更好地解释这个概念。黄色表示构成一笔交易的两笔交易。期初交易为“买入”(B),因此要结束交易,匹配交易应为“卖出”(S)。

相同的概念,绿色稍微复杂一些。开盘交易是“买入”,数量为450。随后的交易也是带有相同符号的“买入”,因此增加了头寸(450+75+15=540数量)。完成交易的匹配交易应该是“卖出”,但也可以是增量交易。因此,我应该在交易初始化后跟踪数量。查看最后一笔绿色交易是如何用相同的符号卖出540个数量,使交易的总数量为零,这意味着交易已完成(结束)。

我创建了一个包含所有必需字段、构造函数、getter和setter以及交易类的事务类

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()
}
行业类别:

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);
}
}
我的问题:我一直在重复浏览事务列表并匹配它们,原因有两个:

  • 有时我会扩大仓位,这意味着我不会在1笔交易中卖出(多笔交易结束交易),这意味着我必须匹配多笔交易
  • 在通过的名单中,有可能有一笔交易仍然部分开放。我不知道如何处理这种可能性
  • 符号可以是“股票代码”符号或选项符号,不确定是否相关
我所尝试的

从已使用的文件中,我得到了一个事务对象列表,我想我应该按符号、边(买入/卖出)和数量匹配事务。这种方法的问题在于,它可能不是同一行业

 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; 
}
公共ObservableList从事务中解析交易(ObservableList列表){
用于(事务:列表){
int closedTradecount=0;
//遍历列表
String symbol=transaction.getSymbol();
LocalDate transactionDate=transaction.getTransactionDate();
int quantity=transaction.getQuantity();
char-side=transaction.getSide();
//遍历其余部分并进行匹配
对于(int i=0;i
我对编程和处理数据非常陌生,我想把这件事做好。任何帮助都将不胜感激,因为我无法对匹配的事务绞尽脑汁


谢谢

对于您的第一个问题

  • 有时我会扩大仓位,这意味着我不会在1笔交易中卖出(多笔交易结束交易),这意味着我必须匹配多笔交易
  • 使用分组方式:

    按“符号”对您的交易进行分组,并收集为地图

    Map postsPerType=transactions.stream() .collect(groupingBy(Transactions::getSymbol))

    这样,您可以将所有事务分组在一起

  • 在通过的名单中,有可能有一笔交易仍然部分开放。我不知道如何处理这种可能性
  • 迭代上述收集的交易,并通过过滤掉买入和卖出交易来匹配数量
    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());
                }
            }
        }
    }
    
    public Trade(Transaction first) {
        symbol = first.getSymbol();
        // ... all other fields initialization ...
    }
    
    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;
    }