From 563e902613077c8cc6df87f82e8fe21b91ba639f Mon Sep 17 00:00:00 2001 From: 7u83 <7u83@maiol.ru> Date: Tue, 17 Jan 2017 01:23:59 +0100 Subject: [PATCH] TraderList implemented --- src/main/java/gui/MainWin.form | 13 + src/main/java/gui/MainWin.java | 36 ++- src/main/java/gui/OrderBook.java | 6 +- src/main/java/gui/TraderListDialog.form | 47 ++++ src/main/java/gui/TraderListDialog.java | 124 +++++++++ src/main/java/gui/TraderListPanel.form | 51 ++++ src/main/java/gui/TraderListPanel.java | 255 ++++++++++++++++++ src/main/java/sesim/AutoTrader.java | 4 + src/main/java/sesim/Exchange.java | 4 +- src/main/java/traders/RandomTrader.java | 28 +- src/main/java/traders/RandomTraderConfig.java | 4 +- 11 files changed, 547 insertions(+), 25 deletions(-) create mode 100644 src/main/java/gui/TraderListDialog.form create mode 100644 src/main/java/gui/TraderListDialog.java create mode 100644 src/main/java/gui/TraderListPanel.form create mode 100644 src/main/java/gui/TraderListPanel.java diff --git a/src/main/java/gui/MainWin.form b/src/main/java/gui/MainWin.form index 4e0547a..02e9131 100644 --- a/src/main/java/gui/MainWin.form +++ b/src/main/java/gui/MainWin.form @@ -55,6 +55,18 @@ + + + + + + + + + + + + @@ -63,6 +75,7 @@ + diff --git a/src/main/java/gui/MainWin.java b/src/main/java/gui/MainWin.java index 0be9a22..8b117eb 100644 --- a/src/main/java/gui/MainWin.java +++ b/src/main/java/gui/MainWin.java @@ -25,6 +25,8 @@ */ package gui; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; import sesim.AutoTrader; import sesim.Exchange; import traders.*; @@ -106,6 +108,7 @@ public class MainWin extends javax.swing.JFrame { FileRun = new javax.swing.JMenuItem(); jMenu2 = new javax.swing.JMenu(); viewMenu = new javax.swing.JMenu(); + traderList = new javax.swing.JMenuItem(); helpMenu = new javax.swing.JMenu(); helpAbout = new javax.swing.JMenuItem(); @@ -150,10 +153,22 @@ public class MainWin extends javax.swing.JFrame { MainMenu.add(jMenu2); viewMenu.setText("View"); + + traderList.setMnemonic('t'); + traderList.setText("Traders"); + traderList.setToolTipText(""); + traderList.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + traderListActionPerformed(evt); + } + }); + viewMenu.add(traderList); + MainMenu.add(viewMenu); helpMenu.setText("Help"); + helpAbout.setMnemonic('a'); helpAbout.setText("About"); helpAbout.setToolTipText("About this Software"); helpAbout.addActionListener(new java.awt.event.ActionListener() { @@ -188,6 +203,11 @@ public class MainWin extends javax.swing.JFrame { d.show(); }//GEN-LAST:event_helpAboutActionPerformed + private void traderListActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_traderListActionPerformed + TraderListDialog tl = new TraderListDialog(this,false); + tl.setVisible(true); + }//GEN-LAST:event_traderListActionPerformed + /** * @param args the command line arguments */ @@ -204,10 +224,12 @@ public class MainWin extends javax.swing.JFrame { // SwitchingTraderConfig rcfg1 = new SwitchingTraderConfig(); // SwitchingTraderConfig rcfg1 = new SwitchingTraderConfig(); RandomTraderConfig rcfg1 = new RandomTraderConfig(); - AutoTrader rt1 = rcfg1.createTrader(se, 0, 1000000); - + AutoTrader rt1 = rcfg1.createTrader(se, 1000, 1000); + se.traders.add(rt1); rt1.setName("Bob"); rt1.start(); + + //AutoTrader rt2 = rcfg1.createTrader(se, 1, 100); //rt2.start(); @@ -215,9 +237,10 @@ public class MainWin extends javax.swing.JFrame { // SwitchingTraderConfig cfg = new SwitchingTraderConfig(); RandomTraderConfig cfg= new RandomTraderConfig(); - for (int i=0; i<1; i++){ - AutoTrader randt = cfg.createTrader(se, 100000, 0); + for (int i=0; i<530; i++){ + AutoTrader randt = cfg.createTrader(se, 100, 100); + se.traders.add(randt); randt.setName("Alice"); randt.start(); } @@ -230,13 +253,13 @@ public class MainWin extends javax.swing.JFrame { // at.add(10, rcfg, se, 1000000, 0); - /* try { +/* try { // Set cross-platform Java L&F (also called "Metal") UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel"); } catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { } -*/ + */ /* Set the Nimbus look and feel */ // /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. @@ -280,6 +303,7 @@ public class MainWin extends javax.swing.JFrame { private javax.swing.JMenu jMenu2; private javax.swing.JMenuItem jMenuItem1; private gui.OrderBookPanel orderBookPanel1; + private javax.swing.JMenuItem traderList; private javax.swing.JMenu viewMenu; // End of variables declaration//GEN-END:variables } diff --git a/src/main/java/gui/OrderBook.java b/src/main/java/gui/OrderBook.java index da46078..2bb97b5 100644 --- a/src/main/java/gui/OrderBook.java +++ b/src/main/java/gui/OrderBook.java @@ -106,14 +106,14 @@ public abstract class OrderBook extends javax.swing.JPanel implements Exchange.B list = getOrderBook(); } - int update_calls = 0; + // int update_calls = 0; int colcount_calls = 0; public void update(ArrayList newlist) { list = newlist; //getOrderBook(); this.fireTableDataChanged(); - this.update_calls++; + // this.update_calls++; // int hc = this.hashCode(); //System.out.print("Update/ColCalls = " + update_calls + "/" + colcount_calls + " HC: " + hc + "\n"); } @@ -156,7 +156,7 @@ public abstract class OrderBook extends javax.swing.JPanel implements Exchange.B } else { o = list.get(list.size() - r - 1); } - Formatter f = new Formatter(); + // Formatter f = new Formatter(); switch (c) { case 0: return String.format("#%06x", o.getID()); diff --git a/src/main/java/gui/TraderListDialog.form b/src/main/java/gui/TraderListDialog.form new file mode 100644 index 0000000..64e2236 --- /dev/null +++ b/src/main/java/gui/TraderListDialog.form @@ -0,0 +1,47 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/gui/TraderListDialog.java b/src/main/java/gui/TraderListDialog.java new file mode 100644 index 0000000..f74390a --- /dev/null +++ b/src/main/java/gui/TraderListDialog.java @@ -0,0 +1,124 @@ +package gui; + +/* + * Copyright (c) 2017, 7u83 <7u83@mail.ru> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class TraderListDialog extends javax.swing.JDialog { + + /** + * Creates new form TraderList + * @param parent + * @param modal + */ + public TraderListDialog(java.awt.Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + traderListPanel1 = new gui.TraderListPanel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(traderListPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(traderListPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 294, Short.MAX_VALUE) + .addContainerGap()) + ); + + pack(); + }// //GEN-END:initComponents + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + /* Set the Nimbus look and feel */ + // + /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. + * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html + */ + try { + for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { + if ("Nimbus".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(TraderListDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(TraderListDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(TraderListDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(TraderListDialog.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + //
+ + /* Create and display the dialog */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + TraderListDialog dialog = new TraderListDialog(new javax.swing.JFrame(), true); + dialog.addWindowListener(new java.awt.event.WindowAdapter() { + @Override + public void windowClosing(java.awt.event.WindowEvent e) { + System.exit(0); + } + }); + dialog.setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private gui.TraderListPanel traderListPanel1; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/gui/TraderListPanel.form b/src/main/java/gui/TraderListPanel.form new file mode 100644 index 0000000..4b5398c --- /dev/null +++ b/src/main/java/gui/TraderListPanel.form @@ -0,0 +1,51 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
diff --git a/src/main/java/gui/TraderListPanel.java b/src/main/java/gui/TraderListPanel.java new file mode 100644 index 0000000..8063485 --- /dev/null +++ b/src/main/java/gui/TraderListPanel.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2017, 7u83 <7u83@mail.ru> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package gui; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Formatter; +import java.util.Iterator; +import javax.swing.BorderFactory; +import javax.swing.ListModel; +import javax.swing.SwingUtilities; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.JTableHeader; +import sesim.AutoTrader; +import sesim.Exchange; +import sesim.Scheduler; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class TraderListPanel extends javax.swing.JPanel + implements Scheduler.TimerTask { + + Exchange se; + TraderListModel model; + + /** + * Creates new form TraderListPanel + */ + public TraderListPanel() { + initComponents(); + + this.setBorder(BorderFactory.createEmptyBorder()); +// this.orderBookScroller.setBorder(BorderFactory.createBevelBorder(0)); + + if (MainWin.se == null) { + return; + } + + this.model = new TraderListModel(); + this.traderList.setModel(this.model); + + traderList.setBorder(BorderFactory.createEmptyBorder()); + + JTableHeader h = this.traderList.getTableHeader(); +// h.setBackground(Color.BLUE); +// h.setForeground(Color.green); + + if (MainWin.se != null) { + this.se = MainWin.se; + this.list = this.getTraderList(); + se.timer.startTimerEvent(this, 1000); + } + + } + + final ArrayList getTraderList() { + + sesim.Quote q = se.getLastQuoete(); + double price = q == null ? 0 : q.price; + Iterator it = se.traders.iterator(); + ArrayList tlist = new ArrayList<>(); + while (it.hasNext()) { + AutoTrader at = it.next(); + Exchange.Account a = at.getAccount(); + + TraderListItem ti = new TraderListItem(); + ti.name = at.getName(); + ti.shares = a.getShares(); + ti.money = a.getMoney(); + ti.welth = price==0 ? 0 : ti.shares * price + ti.money; + tlist.add(ti); + + } + return tlist; + } + + @Override + public long timerTask() { + class Updater implements Runnable { + + TraderListModel model; + ArrayList newlist; + + @Override + public void run() { + System.out.print("TTrunner\n"); + model.update(this.newlist); + } + + Updater(TraderListModel model, ArrayList newlist) { + this.model = model; + this.newlist = newlist; + } + + } + + System.out.print("TimerTaskUpdater\n"); + + ArrayList newlist = getTraderList(); + SwingUtilities.invokeLater(new Updater(this.model, newlist)); + + return 2000; +// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. + } + + class TraderListItem { + + public String name; + public double shares; + public double money; + public double welth; + } + + private ArrayList list = new ArrayList<>(); + + protected class TraderListModel extends AbstractTableModel { + + //private final boolean desc = false; + public TraderListModel() { + + } + + public void update(ArrayList newlist) { + + + list = newlist; //getOrderBook(); + this.fireTableDataChanged(); + } + + @Override + public String getColumnName(int c) { + switch (c) { + case 0: + return "ID"; + case 1: + return "Name"; + case 2: + return "Money"; + case 3: + return "Shares"; + case 4: + return "Welth"; + } + return ""; + } + + @Override + public int getRowCount() { + int rc = list.size(); + //System.out.print("Size" + rc + "\n"); + return list.size(); + } + + @Override + public int getColumnCount() { + return 5; + } + + + + + @Override + public Object getValueAt(int r, int c) { + TraderListItem ti; + ti = list.get(r); + + int s = list.size(); + Formatter f = new Formatter(); + switch (c) { + case 0: + return String.format("#%06x", 0); + + case 1: + return String.format("%s", ti.name); + case 2: + return String.format("%.2f", ti.money); + case 3: + return String.format("%.2f", ti.shares); + case 4: + return String.format("%.2f", ti.welth); + } + + return "x"; + } + + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + + traderListScroller = new javax.swing.JScrollPane(); + traderList = new javax.swing.JTable(); + + traderList.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null}, + {null, null, null, null} + }, + new String [] { + "Title 1", "Title 2", "Title 3", "Title 4" + } + )); + traderListScroller.setViewportView(traderList); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(traderListScroller, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(traderListScroller, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JTable traderList; + private javax.swing.JScrollPane traderListScroller; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/sesim/AutoTrader.java b/src/main/java/sesim/AutoTrader.java index a6200f1..45e3310 100644 --- a/src/main/java/sesim/AutoTrader.java +++ b/src/main/java/sesim/AutoTrader.java @@ -52,6 +52,10 @@ public abstract class AutoTrader implements Scheduler.TimerTask { public String getName() { return name; } + + public Exchange.Account getAccount(){ + return se.getAccount(account_id); + } public abstract void start(); diff --git a/src/main/java/sesim/Exchange.java b/src/main/java/sesim/Exchange.java index f73ecca..6c120cb 100644 --- a/src/main/java/sesim/Exchange.java +++ b/src/main/java/sesim/Exchange.java @@ -19,6 +19,8 @@ public class Exchange { //extends Thread { //public static Timer timer = new Timer(); public Scheduler timer = new Scheduler(); + //public AutoTraderList traders = new AutoTraderList(); + public ArrayList traders = new ArrayList(); /** * @@ -353,7 +355,7 @@ public class Exchange { //extends Thread { } public Quote getLastQuoete() { - return this.quoteHistory.first(); + return this.quoteHistory.last(); } diff --git a/src/main/java/traders/RandomTrader.java b/src/main/java/traders/RandomTrader.java index 8595734..71bec30 100644 --- a/src/main/java/traders/RandomTrader.java +++ b/src/main/java/traders/RandomTrader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, tobias + * Copyright (c) 2017, 7u83 * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,16 +38,15 @@ import sesim.*; /** * - * @author tobias + * @author 7u83 */ public class RandomTrader extends AutoTrader { - long event() { sesim.Exchange.Account a = se.getAccount(account_id); long rc = this.doTrade(); - return rc/3; + return rc / 3; } @@ -59,12 +58,16 @@ public class RandomTrader extends AutoTrader { } + /** + * + * @return + */ @Override public long timerTask() { - sesim.Exchange.Account a = se.getAccount(account_id); + sesim.Exchange.Account a = se.getAccount(account_id); long rc = this.doTrade(); - return rc/33; - + return rc / 33; + // return this.event(); } @@ -81,13 +84,13 @@ public class RandomTrader extends AutoTrader { } - double start = 0.1; + double start = 1.1; //Timer timer = new Timer(); @Override public void start() { - // timer.schedule(new TimerTaskImpl(this, timer), 0); + // timer.schedule(new TimerTaskImpl(this, timer), 0); se.timer.startTimerEvent(this, 0); // timer.schedule(new TimerTaskImpl, date); @@ -152,7 +155,7 @@ public class RandomTrader extends AutoTrader { OrderType type = OrderType.BID; if (ad == null || myconfig == null) { - System.out.print(ad + "\n"); +// System.out.print(ad + "\n"); return 0; } @@ -194,7 +197,7 @@ public class RandomTrader extends AutoTrader { // long volume = (long) (money / (limit * 1)); if (volume <= 0) { - System.out.print("SellVolume 0\n"); +// System.out.print("SellVolume 0\n"); return 0; } @@ -243,6 +246,5 @@ public class RandomTrader extends AutoTrader { } } -*/ - + */ } diff --git a/src/main/java/traders/RandomTraderConfig.java b/src/main/java/traders/RandomTraderConfig.java index f19bc28..45e5620 100644 --- a/src/main/java/traders/RandomTraderConfig.java +++ b/src/main/java/traders/RandomTraderConfig.java @@ -36,12 +36,12 @@ import sesim.Exchange; public class RandomTraderConfig extends AutoTraderConfig { public float[] sell_volume = {100, 100}; - public float[] sell_limit = {-10f, 10f}; + public float[] sell_limit = {-1f, 1f}; public int[] sell_order_wait = {1000, 5000}; public int[] wait_after_sell = {10, 30}; public float[] buy_volume = {100, 100}; - public float[] buy_limit = {-10, 10f}; + public float[] buy_limit = {-1, 1f}; public int[] buy_order_wait = {1000, 5000}; public int[] wait_after_buy = {10, 30};