Threaded order execution now

This commit is contained in:
7u83 2017-02-25 20:06:26 +01:00
parent 7c7479e2ac
commit 6a3b814aa6
15 changed files with 578 additions and 201 deletions

View File

@ -43,13 +43,6 @@
</Component> </Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Component class="gui.TraderListPanel" name="traderListPanel1">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="right"/>
</Constraint>
</Constraints>
</Component>
</SubComponents> </SubComponents>
</Container> </Container>
<Menu class="javax.swing.JMenuBar" name="menuBar"> <Menu class="javax.swing.JMenuBar" name="menuBar">
@ -242,6 +235,14 @@
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jCheckBoxMenuItem1ActionPerformed"/> <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jCheckBoxMenuItem1ActionPerformed"/>
</Events> </Events>
</MenuItem> </MenuItem>
<MenuItem class="javax.swing.JCheckBoxMenuItem" name="viewTraderListCheckBox">
<Properties>
<Property name="text" type="java.lang.String" value="Traders"/>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="viewTraderListCheckBoxActionPerformed"/>
</Events>
</MenuItem>
</SubComponents> </SubComponents>
</Menu> </Menu>
<Menu class="javax.swing.JMenu" name="helpMenu"> <Menu class="javax.swing.JMenu" name="helpMenu">

View File

@ -76,8 +76,14 @@ public class NewMDIApplication extends javax.swing.JFrame {
return ac; return ac;
} }
public void startTraders() { public void startTraders() {
WaitBox wb = new WaitBox();
// Globals.se.setMoneyDecimals(8); // Globals.se.setMoneyDecimals(8);
// Globals.se.setSharesDecimals(0); // Globals.se.setSharesDecimals(0);
@ -108,20 +114,17 @@ public class NewMDIApplication extends javax.swing.JFrame {
for (int i1 = 0; i1 < count; i1++) { for (int i1 = 0; i1 < count; i1++) {
AutoTraderInterface trader; AutoTraderInterface trader;
// AutoTrader trader = ac.createTrader(Globals.se, strategy, id++, t.getString("Name") + i1, money, shares);
// if (trader == null) {
System.out.printf("shoudl create new\n"); System.out.printf("shoudl create new\n");
trader = this.createTraderNew(Globals.se, id, t.getString("Name") + i1, money, shares, strategy); trader = this.createTraderNew(Globals.se, id, t.getString("Name") + i1, money, shares, strategy);
// }
Globals.se.traders.add(trader); Globals.se.traders.add(trader);
// trader.setName(t.getString("Name")+i1);
moneyTotal += money; moneyTotal += money;
sharesTotal += shares; sharesTotal += shares;
// trader.start();
} }
} }
@ -150,7 +153,6 @@ public class NewMDIApplication extends javax.swing.JFrame {
jSplitPane1 = new javax.swing.JSplitPane(); jSplitPane1 = new javax.swing.JSplitPane();
jSplitPane2 = new javax.swing.JSplitPane(); jSplitPane2 = new javax.swing.JSplitPane();
orderBookNew1 = new gui.orderbook.OrderBook(); orderBookNew1 = new gui.orderbook.OrderBook();
traderListPanel1 = new gui.TraderListPanel();
jPanel2 = new javax.swing.JPanel(); jPanel2 = new javax.swing.JPanel();
stopButton = new javax.swing.JButton(); stopButton = new javax.swing.JButton();
runButton = new javax.swing.JButton(); runButton = new javax.swing.JButton();
@ -190,6 +192,7 @@ public class NewMDIApplication extends javax.swing.JFrame {
viewClock = new javax.swing.JMenuItem(); viewClock = new javax.swing.JMenuItem();
jMenuItem3 = new javax.swing.JMenuItem(); jMenuItem3 = new javax.swing.JMenuItem();
jCheckBoxMenuItem1 = new javax.swing.JCheckBoxMenuItem(); jCheckBoxMenuItem1 = new javax.swing.JCheckBoxMenuItem();
viewTraderListCheckBox = new javax.swing.JCheckBoxMenuItem();
helpMenu = new javax.swing.JMenu(); helpMenu = new javax.swing.JMenu();
contentMenuItem = new javax.swing.JMenuItem(); contentMenuItem = new javax.swing.JMenuItem();
aboutMenuItem = new javax.swing.JMenuItem(); aboutMenuItem = new javax.swing.JMenuItem();
@ -204,7 +207,6 @@ public class NewMDIApplication extends javax.swing.JFrame {
jSplitPane2.setLeftComponent(orderBookNew1); jSplitPane2.setLeftComponent(orderBookNew1);
jSplitPane1.setTopComponent(jSplitPane2); jSplitPane1.setTopComponent(jSplitPane2);
jSplitPane1.setRightComponent(traderListPanel1);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new java.awt.Dimension(640, 480)); setMinimumSize(new java.awt.Dimension(640, 480));
@ -487,6 +489,14 @@ public class NewMDIApplication extends javax.swing.JFrame {
}); });
viewMenu.add(jCheckBoxMenuItem1); viewMenu.add(jCheckBoxMenuItem1);
viewTraderListCheckBox.setText("Traders");
viewTraderListCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
viewTraderListCheckBoxActionPerformed(evt);
}
});
viewMenu.add(viewTraderListCheckBox);
menuBar.add(viewMenu); menuBar.add(viewMenu);
helpMenu.setMnemonic('h'); helpMenu.setMnemonic('h');
@ -562,7 +572,7 @@ public class NewMDIApplication extends javax.swing.JFrame {
} }
}; };
Globals.se.timer.startTimerEvent(tt, 0); // Globals.se.timer.startTimerTask(tt, 0);
} }
@ -591,6 +601,8 @@ public class NewMDIApplication extends javax.swing.JFrame {
d.setVisible(rootPaneCheckingEnabled); d.setVisible(rootPaneCheckingEnabled);
}//GEN-LAST:event_editPreferencesActionPerformed }//GEN-LAST:event_editPreferencesActionPerformed
private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
TraderListDialog d = new TraderListDialog(this, false); TraderListDialog d = new TraderListDialog(this, false);
d.setVisible(rootPaneCheckingEnabled); d.setVisible(rootPaneCheckingEnabled);
@ -706,6 +718,23 @@ public class NewMDIApplication extends javax.swing.JFrame {
Globals.se.pointZero(); Globals.se.pointZero();
}//GEN-LAST:event_jMenuItem4ActionPerformed }//GEN-LAST:event_jMenuItem4ActionPerformed
TraderListDialog tld=null;
private void viewTraderListCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_viewTraderListCheckBoxActionPerformed
if (this.viewTraderListCheckBox.getState()){
if (tld == null){
tld=new TraderListDialog(this,false);
}
tld.setVisible(true);
}
else {
if (tld!=null)
tld.setVisible(false);
}
}//GEN-LAST:event_viewTraderListCheckBoxActionPerformed
/** /**
* @param args the command line arguments * @param args the command line arguments
* @throws java.lang.IllegalAccessException * @throws java.lang.IllegalAccessException
@ -784,9 +813,9 @@ public class NewMDIApplication extends javax.swing.JFrame {
private javax.swing.JMenuItem simMenuStart; private javax.swing.JMenuItem simMenuStart;
private javax.swing.JMenuItem simMenuStop; private javax.swing.JMenuItem simMenuStop;
private javax.swing.JButton stopButton; private javax.swing.JButton stopButton;
private gui.TraderListPanel traderListPanel1;
private javax.swing.JMenuItem viewClock; private javax.swing.JMenuItem viewClock;
private javax.swing.JMenu viewMenu; private javax.swing.JMenu viewMenu;
private javax.swing.JCheckBoxMenuItem viewTraderListCheckBox;
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
} }

View File

@ -36,14 +36,8 @@
<Component class="javax.swing.JTable" name="list"> <Component class="javax.swing.JTable" name="list">
<Properties> <Properties>
<Property name="autoCreateRowSorter" type="boolean" value="true"/> <Property name="autoCreateRowSorter" type="boolean" value="true"/>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor"> <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Table columnCount="5" rowCount="5"> <Connection code="new MyModel(&#xa; new Object [][] {&#xa; {null, null, null, null, null},&#xa; {null, null, null, null, null},&#xa; {null, null, null, null, null},&#xa; {null, null, null, null, null},&#xa; {null, null, null, null, null}&#xa; },&#xa; new String [] {&#xa; &quot;ID&quot;, &quot;Name&quot;, &quot;Money&quot;, &quot;Shares&quot;, &quot;Wealth&quot;&#xa; }&#xa; ) {&#xa; Class[] types = new Class [] {&#xa; java.lang.Long.class, java.lang.String.class, java.lang.Double.class, java.lang.Double.class, java.lang.Double.class&#xa; };&#xa; boolean[] canEdit = new boolean [] {&#xa; false, false, false, false, false&#xa; };&#xa;&#xa; public Class getColumnClass(int columnIndex) {&#xa; return types [columnIndex];&#xa; }&#xa;&#xa; public boolean isCellEditable(int rowIndex, int columnIndex) {&#xa; return canEdit [columnIndex];&#xa; }&#xa; }" type="code"/>
<Column editable="false" title="ID" type="java.lang.Long"/>
<Column editable="false" title="Name" type="java.lang.String"/>
<Column editable="false" title="Money" type="java.lang.Double"/>
<Column editable="false" title="Shares" type="java.lang.Double"/>
<Column editable="false" title="Wealth" type="java.lang.Double"/>
</Table>
</Property> </Property>
<Property name="doubleBuffered" type="boolean" value="true"/> <Property name="doubleBuffered" type="boolean" value="true"/>
</Properties> </Properties>

View File

@ -32,7 +32,9 @@ import java.util.TimerTask;
import javax.swing.JDialog; import javax.swing.JDialog;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
import sesim.AutoTraderInterface; import sesim.AutoTraderInterface;
import sesim.Exchange; import sesim.Exchange;
@ -58,6 +60,7 @@ public class TraderListPanel extends javax.swing.JPanel {
sesim.Quote q = Globals.se.getLastQuoete(); sesim.Quote q = Globals.se.getLastQuoete();
double price = q == null ? 0 : q.price; double price = q == null ? 0 : q.price;
//DefaultTableModel newmodel = new DefaultTableModel();
int size = Globals.se.traders.size(); int size = Globals.se.traders.size();
model.setRowCount(size); model.setRowCount(size);
@ -72,6 +75,7 @@ public class TraderListPanel extends javax.swing.JPanel {
double wealth = a.getShares() * price + a.getMoney(); double wealth = a.getShares() * price + a.getMoney();
model.setValueAt(wealth, i, 4); model.setValueAt(wealth, i, 4);
} }
list.getRowSorter().allRowsChanged(); list.getRowSorter().allRowsChanged();
} }
@ -81,23 +85,99 @@ public class TraderListPanel extends javax.swing.JPanel {
* Creates new form TraderListPanel2 * Creates new form TraderListPanel2
*/ */
public TraderListPanel() { public TraderListPanel() {
initComponents(); initComponents();
model = (DefaultTableModel) list.getModel(); model = (DefaultTableModel) list.getModel();
updateModel(); // updateModel();
Timer timer = new Timer(); Timer timer = new Timer();
updater = new TimerTask() { updater = new TimerTask() {
@Override @Override
public void run() { public void run() {
//System.out.printf("Run traderlist\n");
// javax.swing.SwingUtilities.invokeLater(()->{updateModel();});
try{
updateModel(); updateModel();
}
catch (Exception e)
{
}
} }
}; };
//TableRowSorter sorter = (TableRowSorter) list.getRowSorter();
//sorter.setSortsOnUpdates(true);
timer.schedule(updater, 0, 1000); timer.schedule(updater, 0, 1000);
} }
class MyModel extends DefaultTableModel{
MyModel(Object arg0[][], Object arg1[]){
super(arg0,arg1);
}
@Override
public void fireTableDataChanged(){
}
@Override
public void fireTableStructureChanged() {
}
@Override
public void fireTableRowsUpdated(int firstRow, int lastRow) {
}
@Override
public void fireTableCellUpdated(int row, int column) {
}
}
void test(){
// new javax.swing.table.DefaultTableModel
MyModel m = new MyModel(
new Object [][] {
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null}
},
new String [] {
"ID", "Name", "Money", "Shares", "Wealth"
}
) {
Class[] types = new Class [] {
java.lang.Long.class, java.lang.String.class, java.lang.Double.class, java.lang.Double.class, java.lang.Double.class
};
boolean[] canEdit = new boolean [] {
false, false, false, false, false
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
};
}
/** /**
* This method is called from within the constructor to initialize the form. * 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 * WARNING: Do NOT modify this code. The content of this method is always
@ -111,7 +191,7 @@ public class TraderListPanel extends javax.swing.JPanel {
list = new javax.swing.JTable(); list = new javax.swing.JTable();
list.setAutoCreateRowSorter(true); list.setAutoCreateRowSorter(true);
list.setModel(new javax.swing.table.DefaultTableModel( list.setModel(new MyModel(
new Object [][] { new Object [][] {
{null, null, null, null, null}, {null, null, null, null, null},
{null, null, null, null, null}, {null, null, null, null, null},
@ -164,7 +244,7 @@ public class TraderListPanel extends javax.swing.JPanel {
index = list.getRowSorter().convertRowIndexToModel(index); index = list.getRowSorter().convertRowIndexToModel(index);
Integer tid = (Integer) model.getValueAt(index, 0); Integer tid = (Integer) model.getValueAt(index, 0);
System.out.printf("Trader ID %d\n", tid); // System.out.printf("Trader ID %d\n", tid);
JDialog console = Globals.se.traders.get(tid).getGuiConsole(); JDialog console = Globals.se.traders.get(tid).getGuiConsole();
if (console == null) { if (console == null) {

View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="progressBar" pref="388" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="progressBar" min="-2" pref="39" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JProgressBar" name="progressBar">
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,74 @@
/*
* 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;
/**
*
* @author 7u83 <7u83@mail.ru>
*/
public class WaitBox extends javax.swing.JPanel {
/**
* Creates new form WaitBox
*/
public WaitBox() {
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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
progressBar = new javax.swing.JProgressBar();
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JProgressBar progressBar;
// End of variables declaration//GEN-END:variables
}

View File

@ -27,8 +27,12 @@ package gui.orderbook;
import gui.Globals; import gui.Globals;
import gui.Globals.CfgListener; import gui.Globals.CfgListener;
import java.awt.Component;
import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import javax.swing.JTable;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn; import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel; import javax.swing.table.TableColumnModel;
@ -45,6 +49,29 @@ public class OrderBook extends javax.swing.JPanel implements Exchange.BookReceiv
DefaultTableModel model; DefaultTableModel model;
TableColumn trader_column = null; TableColumn trader_column = null;
class Renderer extends DefaultTableCellRenderer {
private final DecimalFormat formatter = new DecimalFormat("#.0000");
Renderer() {
super();
this.setHorizontalAlignment(RIGHT);
}
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
// First format the cell value as required
value = formatter.format((Number) value);
// And pass it on to parent class
return super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
}
}
OrderType type = OrderType.BUYLIMIT; OrderType type = OrderType.BUYLIMIT;
int depth = 40; int depth = 40;
@ -86,27 +113,22 @@ public class OrderBook extends javax.swing.JPanel implements Exchange.BookReceiv
*/ */
public OrderBook() { public OrderBook() {
initComponents(); initComponents();
if (Globals.se == null) { if (Globals.se == null) {
return; return;
} }
model = (DefaultTableModel) this.list.getModel(); model = (DefaultTableModel) this.list.getModel();
trader_column = list.getColumnModel().getColumn(0); trader_column = list.getColumnModel().getColumn(0);
list.getColumnModel().getColumn(1).setCellRenderer(new Renderer());
cfgChanged(); cfgChanged();
// Globals.se.addBookReceiver(Exchange.OrderType.BUYLIMIT, this); // Globals.se.addBookReceiver(Exchange.OrderType.BUYLIMIT, this);
Globals.addCfgListener(this); Globals.addCfgListener(this);
} }
boolean oupdate = false; boolean oupdate = false;
boolean new_oupdate = false;
@Override void oupdater() {
public synchronized void UpdateOrderBook() {
if (oupdate) {
return;
}
oupdate = true;
SwingUtilities.invokeLater(() -> {
ArrayList<Order> ob = Globals.se.getOrderBook(type, depth); ArrayList<Order> ob = Globals.se.getOrderBook(type, depth);
model.setRowCount(ob.size()); model.setRowCount(ob.size());
int row = 0; int row = 0;
@ -118,18 +140,24 @@ public class OrderBook extends javax.swing.JPanel implements Exchange.BookReceiv
} }
oupdate = false; oupdate = false;
}
@Override
public synchronized void UpdateOrderBook() {
if (oupdate) {
new_oupdate=true;
return;
}
oupdate = true;
SwingUtilities.invokeLater(() -> {
oupdater();
}); });
/* ArrayList<Order> ob = Globals.se.getOrderBook(type, depth);
model.setRowCount(ob.size());
int row = 0;
for (Order ob1 : ob) {
model.setValueAt(ob1.getAccount().getOwner().getName(), row, 0);
model.setValueAt(ob1.getLimit(), row, 1);
model.setValueAt(ob1.getVolume(), row, 2);
row++;
}
*/
} }
/** /**

View File

@ -115,6 +115,9 @@ public class QuoteVertical extends javax.swing.JPanel implements QuoteReceiver {
@Override @Override
public void UpdateQuote(Quote q) { public void UpdateQuote(Quote q) {
/*
javax.swing.SwingUtilities.invokeLater(() -> {
String text, vtext; String text, vtext;
text = dfm.format(q.price); text = dfm.format(q.price);
vtext = dfv.format(q.volume); vtext = dfv.format(q.volume);
@ -129,5 +132,10 @@ public class QuoteVertical extends javax.swing.JPanel implements QuoteReceiver {
last_price = q.price; last_price = q.price;
this.quoteLabel.setText(text); this.quoteLabel.setText(text);
this.volumeLabel.setText("(" + vtext + ")"); this.volumeLabel.setText("(" + vtext + ")");
});
*/
} }
} }

View File

@ -4,6 +4,8 @@ import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
@ -69,6 +71,11 @@ public class Exchange {
public void accountUpdated(Account a, Order o); public void accountUpdated(Account a, Order o);
} }
public interface OrderListener {
public void orderUpdated(Order o);
}
HashMap<Integer, OHLCData> ohlc_data = new HashMap<>(); HashMap<Integer, OHLCData> ohlc_data = new HashMap<>();
public OHLCData buildOHLCData(int timeFrame) { public OHLCData buildOHLCData(int timeFrame) {
@ -119,10 +126,10 @@ public class Exchange {
data = ohlc_data.get(timeFrame); data = ohlc_data.get(timeFrame);
if (data == null) { if (data == null) {
this.tradelock.lock(); synchronized (executor) {
data = this.buildOHLCData(timeFrame); data = this.buildOHLCData(timeFrame);
ohlc_data.put(timeFrame, data); ohlc_data.put(timeFrame, data);
this.tradelock.unlock(); }
} }
return data; return data;
@ -375,6 +382,7 @@ public class Exchange {
qrlist = (new CopyOnWriteArrayList<>()); qrlist = (new CopyOnWriteArrayList<>());
initExchange(); initExchange();
executor.start();
} }
@ -397,11 +405,39 @@ public class Exchange {
} }
class Executor extends Thread {
@Override
public void run() {
synchronized (this) {
try {
while (true) {
System.out.printf("Executor waits -0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0--0-0-00--0-0\n");
this.wait();
System.out.printf("Executor runs\n");
executeOrders();
updateBookReceivers(OrderType.SELLLIMIT);
updateBookReceivers(OrderType.BUYLIMIT);
}
} catch (InterruptedException ex) {
Logger.getLogger(Exchange.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
final Executor executor = new Executor();
/** /**
* Start the exchange * Start the exchange
*/ */
public void start() { public void start() {
timer.start(); timer.start();
} }
public void reset() { public void reset() {
@ -678,16 +714,17 @@ public class Exchange {
double lastprice = 100.0; double lastprice = 100.0;
long lastsvolume; long lastsvolume;
private final Locker tradelock = new Locker(); // private final Locker tradelock = new Locker();
public ArrayList<Order> getOrderBook(OrderType type, int depth) { public ArrayList<Order> getOrderBook(OrderType type, int depth) {
SortedSet<Order> book = order_books.get(type); SortedSet<Order> book = order_books.get(type);
if (book == null) { if (book == null) {
return null; return null;
} }
tradelock.lock(); ArrayList<Order> ret;
ArrayList<Order> ret = new ArrayList<>(); synchronized (executor) {
ret = new ArrayList<>();
Iterator<Order> it = book.iterator(); Iterator<Order> it = book.iterator();
@ -695,12 +732,13 @@ public class Exchange {
Order o = it.next(); Order o = it.next();
// System.out.print(o.volume); // System.out.print(o.volume);
if (o.volume <= 0) { if (o.volume <= 0) {
System.out.printf("Volume < 0\n");
System.exit(0); System.exit(0);
} }
ret.add(o); ret.add(o);
} }
// System.out.println(); // System.out.println();
tradelock.unlock(); }
return ret; return ret;
} }
@ -728,8 +766,9 @@ public class Exchange {
boolean ret = false; boolean ret = false;
tradelock.lock(); Order o;
Order o = a.orders.get(order_id); synchronized (executor) {
o = a.orders.get(order_id);
// System.out.print("The Order:"+o.limit+"\n"); // System.out.print("The Order:"+o.limit+"\n");
if (o != null) { if (o != null) {
@ -742,8 +781,10 @@ public class Exchange {
ret = true; ret = true;
} }
tradelock.unlock(); }
this.updateBookReceivers(OrderType.BUYLIMIT); if (ret) {
this.updateBookReceivers(o.type);
}
return ret; return ret;
} }
@ -845,6 +886,7 @@ public class Exchange {
*/ */
public void executeOrders() { public void executeOrders() {
System.out.printf("Exec Orders\n");
SortedSet<Order> bid = order_books.get(OrderType.BUYLIMIT); SortedSet<Order> bid = order_books.get(OrderType.BUYLIMIT);
SortedSet<Order> ask = order_books.get(OrderType.SELLLIMIT); SortedSet<Order> ask = order_books.get(OrderType.SELLLIMIT);
@ -874,7 +916,6 @@ public class Exchange {
//System.out.printf("Cannot match two unlimited orders!\n"); //System.out.printf("Cannot match two unlimited orders!\n");
//System.exit(0); //System.exit(0);
} }
while (!ul_buy.isEmpty() && !ask.isEmpty()) { while (!ul_buy.isEmpty() && !ask.isEmpty()) {
@ -964,23 +1005,17 @@ public class Exchange {
Order o = new Order(a, type, volume, limit); Order o = new Order(a, type, volume, limit);
if (o.volume <= 0 || o.limit <= 0) { if (o.volume <= 0 || o.limit <= 0) {
//System.out.print("binweg\n");
return -1; return -1;
} }
//System.out.printf("Creating Order width Volume %f %f \n",o.volume,o.limit); synchronized (executor) {
tradelock.lock();
num_orders++; num_orders++;
addOrderToBook(o); addOrderToBook(o);
a.orders.put(o.id, o); a.orders.put(o.id, o);
a.update(o); a.update(o);
executor.notify();
this.executeOrders(); }
tradelock.unlock();
this.updateBookReceivers(OrderType.SELLLIMIT);
this.updateBookReceivers(OrderType.BUYLIMIT);
return o.id; return o.id;
} }

View File

@ -30,6 +30,7 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.SortedSet; import java.util.SortedSet;
@ -94,8 +95,8 @@ public class Scheduler extends Thread {
@Override @Override
public int compare(Object o1, Object o2) { public int compare(Object o1, Object o2) {
return (((TimerTask) o1).getID() - ((TimerTask) o2).getID()) < 0 ? -1 : 1; //return (((TimerTask) o1).getID() - ((TimerTask) o2).getID()) < 0 ? -1 : 1;
//return System.identityHashCode(o1) - System.identityHashCode(o2); return System.identityHashCode(o1) - System.identityHashCode(o2);
} }
} }
@ -110,8 +111,9 @@ public class Scheduler extends Thread {
long diff = System.currentTimeMillis() - last_time_millis; long diff = System.currentTimeMillis() - last_time_millis;
last_time_millis += diff; last_time_millis += diff;
if (diff==0) if (diff == 0) {
diff++; diff++;
}
if (pause) { if (pause) {
return (long) this.current_time_millis; return (long) this.current_time_millis;
} }
@ -140,10 +142,10 @@ public class Scheduler extends Thread {
* @param e * @param e
* @param time * @param time
*/ */
public void startTimerEvent(TimerTask e, long time) { public void startTimerTask(TimerTask e, long time) {
long evtime = time + currentTimeMillis(); long evtime = time + currentTimeMillis();
synchronized (event_queue) { synchronized (event_queue) {
this.addEvent(e, evtime); this.addTimerTask(e, evtime);
} }
synchronized (this) { synchronized (this) {
notify(); notify();
@ -173,7 +175,9 @@ public class Scheduler extends Thread {
return e.timerTask(); return e.timerTask();
} }
private boolean addEvent(TimerTask e, long evtime) { HashMap<TimerTask, Long> tasks = new HashMap<>();
private boolean addTimerTask(TimerTask e, long evtime) {
// long evtime = time + currentTimeMillis(); // long evtime = time + currentTimeMillis();
SortedSet<TimerTask> s = event_queue.get(evtime); SortedSet<TimerTask> s = event_queue.get(evtime);
@ -181,9 +185,45 @@ public class Scheduler extends Thread {
s = new TreeSet<>(new ObjectComparator()); s = new TreeSet<>(new ObjectComparator());
event_queue.put(evtime, s); event_queue.put(evtime, s);
} }
System.out.printf("Put timer task for %d %d\n",System.identityHashCode(e),evtime);
tasks.put(e, evtime);
return s.add(e); return s.add(e);
} }
public void cancelTimerTask(TimerTask e) {
synchronized (event_queue) {
Long evtime = tasks.get(e);
if (evtime == null) {
System.out.printf("Cancel evtime is null\n","");
return;
}
System.out.printf("Cancel evtime is %d\n",evtime);
SortedSet<TimerTask> s = event_queue.get(evtime);
if (s == null) {
System.out.printf("Task was null\n", "");
return;
}
System.out.printf("Remove now\n", "");
Boolean rc = s.remove(e);
System.out.printf("Remove RC %s",rc.toString());
if (s.isEmpty()) {
System.out.printf("Complete removed\n");
event_queue.remove(evtime);
}
}
}
public long runEvents() { public long runEvents() {
synchronized (event_queue) { synchronized (event_queue) {
if (event_queue.isEmpty()) { if (event_queue.isEmpty()) {
@ -205,7 +245,7 @@ public class Scheduler extends Thread {
next_t++; next_t++;
} }
this.addEvent(e, next_t + t); this.addTimerTask(e, next_t + t);
} }
return 0; return 0;

View File

@ -84,7 +84,6 @@ public class CreateOrderDialog extends javax.swing.JDialog {
this.volumeSpinner.setValue(Globals.se.roundShares(account.getShares())); this.volumeSpinner.setValue(Globals.se.roundShares(account.getShares()));
} }
} }
/** /**
@ -180,6 +179,7 @@ public class CreateOrderDialog extends javax.swing.JDialog {
dispose(); dispose();
}//GEN-LAST:event_jButton2ActionPerformed }//GEN-LAST:event_jButton2ActionPerformed
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
double volume = (double) volumeSpinner.getValue(); double volume = (double) volumeSpinner.getValue();
double limit = (double) limitSpinner.getValue(); double limit = (double) limitSpinner.getValue();
@ -188,8 +188,16 @@ public class CreateOrderDialog extends javax.swing.JDialog {
System.out.printf("Account is null\n"); System.out.printf("Account is null\n");
} }
OrderType type = this.getOrderType(); OrderType type = this.getOrderType();
new Thread() {
@Override
public void run() {
Globals.se.createOrder(account.getID(), type, volume, limit); Globals.se.createOrder(account.getID(), type, volume, limit);
}
}.start();
dispose(); dispose();
}//GEN-LAST:event_jButton1ActionPerformed }//GEN-LAST:event_jButton1ActionPerformed
/** /**

View File

@ -62,7 +62,7 @@ public class ManTrader extends AutoTraderBase implements AccountListener {
@Override @Override
public void start() { public void start() {
se.timer.startTimerEvent(this, 0); se.timer.startTimerTask(this, 0);
consoleDialog = new ManTraderConsoleDialog(Globals.frame, false, this.getAccount()); consoleDialog = new ManTraderConsoleDialog(Globals.frame, false, this.getAccount());
this.consoleDialog.getBalancePanel().updateBalance(this.getAccount()); this.consoleDialog.getBalancePanel().updateBalance(this.getAccount());
// consoleDialog. rdersList1.account=trader.getAccount(); // consoleDialog. rdersList1.account=trader.getAccount();

View File

@ -26,30 +26,24 @@
package traders; package traders;
import gui.Globals; import gui.Globals;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedMap;
import javax.swing.JDialog; import javax.swing.JDialog;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
//import sesim.AccountData;
import sesim.AutoTraderBase; import sesim.AutoTraderBase;
import sesim.AutoTraderConfig;
import sesim.AutoTraderGui; import sesim.AutoTraderGui;
import sesim.Exchange; import sesim.Exchange;
import sesim.Exchange.Account; import sesim.Exchange.Account;
import sesim.Exchange.Order; import sesim.Exchange.AccountListener;
import sesim.OrderData; import sesim.Exchange.OrderStatus;
import sesim.Quote; import sesim.Quote;
/** /**
* *
* @author 7u83 <7u83@mail.ru> * @author 7u83 <7u83@mail.ru>
*/ */
public class RandomTraderA extends AutoTraderBase { public class RandomTraderA extends AutoTraderBase implements AccountListener {
public Float[] initial_delay = {0f, 5.0f}; public Float[] initial_delay = {0f, 5.0f};
@ -75,14 +69,19 @@ public class RandomTraderA extends AutoTraderBase {
@Override @Override
public void start() { public void start() {
Account a = se.getAccount(account_id);
a.setListener(this);
long delay = (long) (getRandom(initial_delay[0], initial_delay[1]) * 1000); long delay = (long) (getRandom(initial_delay[0], initial_delay[1]) * 1000);
se.timer.startTimerEvent(this, delay); se.timer.startTimerTask(this, delay);
} }
@Override @Override
public long timerTask() { public long timerTask() {
System.out.printf("Enter TimerTask for %d\n", System.identityHashCode(this));
sesim.Exchange.Account a = se.getAccount(account_id); sesim.Exchange.Account a = se.getAccount(account_id);
long rc = this.doTrade(); long rc = this.doTrade();
System.out.printf("Exit TimerTask for %d\n", System.identityHashCode(this));
return rc; return rc;
} }
@ -166,7 +165,6 @@ public class RandomTraderA extends AutoTraderBase {
if (n > 0) { if (n > 0) {
Account ad = se.getAccount(account_id); Account ad = se.getAccount(account_id);
Set<Long> keys = ad.getOrders().keySet(); Set<Long> keys = ad.getOrders().keySet();
Iterator<Long> it = keys.iterator(); Iterator<Long> it = keys.iterator();
@ -184,6 +182,25 @@ public class RandomTraderA extends AutoTraderBase {
return null; return null;
} }
@Override
public void accountUpdated(Account a, Exchange.Order o) {
System.out.printf("Order waht %s\n", o.getOrderStatus().toString());
if (o.getOrderStatus() == OrderStatus.CLOSED && false) {
System.out.printf("Enteter canel timer\n");
se.timer.cancelTimerTask(this);
System.out.printf("back from canel timer %d\n", System.identityHashCode(this));
System.exit(0);
Long w = doTrade();
System.out.printf("We have no to wait for %d\n", w);
se.timer.startTimerTask(this, w);
}
// System.out.printf("Updatetd Account\n", "");
}
protected enum Action { protected enum Action {
BUY, SELL, RANDOM BUY, SELL, RANDOM
} }
@ -199,9 +216,8 @@ public class RandomTraderA extends AutoTraderBase {
Action mode = Action.RANDOM; Action mode = Action.RANDOM;
long doTrade() { Integer doTrade1(Action a) {
cancelOrders();
Action a = getAction();
switch (a) { switch (a) {
case BUY: { case BUY: {
boolean rc = doBuy(); boolean rc = doBuy();
@ -209,22 +225,59 @@ public class RandomTraderA extends AutoTraderBase {
mode = Action.BUY; mode = Action.BUY;
return getRandom(buy_wait); return getRandom(buy_wait);
} }
return 5000; return null;
} }
case SELL: case SELL: {
{
boolean rc = doSell(); boolean rc = doSell();
if (rc) { if (rc) {
mode = Action.SELL; mode = Action.SELL;
return getRandom(sell_wait); return getRandom(sell_wait);
} }
return null;
}
}
return 0;
}
long doTrade() {
cancelOrders();
Action a = getAction();
if (mode == Action.RANDOM) {
System.out.printf("Action: %s\n", a.toString());
Integer rc = doTrade1(a);
if (rc != null) {
return rc;
}
rc = doTrade1(Action.BUY);
if (rc != null) {
return rc;
}
rc = doTrade1(Action.SELL);
if (rc != null) {
return rc;
}
System.out.printf("All ha s failed\n");
return 5000; return 5000;
} }
if (mode == Action.BUY) {
mode = Action.RANDOM;
return getRandom(wait_after_buy);
} }
if (mode == Action.SELL) {
mode = Action.RANDOM;
return getRandom(wait_after_sell);
}
return 0; return 0;
} }
@ -271,7 +324,6 @@ public class RandomTraderA extends AutoTraderBase {
public boolean doBuy() { public boolean doBuy() {
// AccountData ad = this.se.getAccountData(account_id); // AccountData ad = this.se.getAccountData(account_id);
Account ad = se.getAccount(account_id); Account ad = se.getAccount(account_id);
Exchange.OrderType type = Exchange.OrderType.BUYLIMIT; Exchange.OrderType type = Exchange.OrderType.BUYLIMIT;
@ -290,15 +342,14 @@ public class RandomTraderA extends AutoTraderBase {
double limit; double limit;
limit = lp + getRandomAmmount(lp, buy_limit); limit = lp + getRandomAmmount(lp, buy_limit);
double volume = money / limit; double volume = money / limit;
// System.out.printf("Volume : %f", volume); // System.out.printf("Volume : %f", volume);
limit = se.roundMoney(limit); limit = se.roundMoney(limit);
volume = se.roundShares(volume); volume = se.roundShares(volume);
if (volume <= 0 || money <= 0) { if (volume <= 0 || money <= 0) {
System.out.printf("Buy Order wont work\n");
return false; return false;
} }
@ -316,36 +367,28 @@ public class RandomTraderA extends AutoTraderBase {
Exchange.OrderType type = Exchange.OrderType.SELLLIMIT; Exchange.OrderType type = Exchange.OrderType.SELLLIMIT;
// how much shares we ant to sell? // how much shares we ant to sell?
double volume = getRandomAmmount(ad.getShares(), sell_volume); double volume = getRandomAmmount(ad.getShares(), sell_volume);
volume = se.roundShares(volume); volume = se.roundShares(volume);
// double lp = 100.0; //se.getBestLimit(type); // double lp = 100.0; //se.getBestLimit(type);
Quote q = se.getBestPrice_0(); Quote q = se.getBestPrice_0();
// q=se.getLastQuoete(); // q=se.getLastQuoete();
double lp = q == null ? getStart() : q.price; double lp = q == null ? getStart() : q.price;
double limit; double limit;
limit = lp + getRandomAmmount(lp, sell_limit); limit = lp + getRandomAmmount(lp, sell_limit);
se.roundMoney(limit); se.roundMoney(limit);
if (volume <= 0 || limit <= 0) { if (volume <= 0 || limit <= 0) {
System.out.printf("Sell wont work\n");
return false; return false;
} }
System.out.printf("Create a Sell Order %f %f!!!!\n", volume, limit);
se.createOrder(account_id, type, volume, limit); se.createOrder(account_id, type, volume, limit);
return true; return true;
} }
} }

View File

@ -76,7 +76,7 @@ public class RandomTraderB extends AutoTraderBase {
@Override @Override
public void start() { public void start() {
long delay = (long) (getRandom(initial_delay[0], initial_delay[1]) * 1000); long delay = (long) (getRandom(initial_delay[0], initial_delay[1]) * 1000);
se.timer.startTimerEvent(this, delay); se.timer.startTimerTask(this, delay);
} }
@Override @Override

View File

@ -57,7 +57,6 @@ public class Test {
System.out.print("haha\n"); System.out.print("haha\n");
} }
static public String getFullClassName(String classFileName) throws IOException { static public String getFullClassName(String classFileName) throws IOException {
File file = new File(classFileName); File file = new File(classFileName);
@ -82,25 +81,23 @@ public class Test {
} }
*/ */
static class Z{
Double x;
}
/** /**
* @param args the command line arguments * @param args the command line arguments
*/ */
public static void main(String[] args) throws InterruptedException, MalformedURLException, InstantiationException, IllegalAccessException, IOException { public static void main(String[] args) throws InterruptedException, MalformedURLException, InstantiationException, IllegalAccessException, IOException {
Double x = 3.1415926; Z z = new Z();
Double r = Math.floor(x*100.0)/100.0; z.x = 3.1415926;
System.out.print(r);
System.out.println();
Double p = Math.pow(10, 5);
System.out.print(p);
System.out.printf("ID: %d\n", System.identityHashCode(z));
z.x = 90.0;
System.out.printf("ID: %d\n", System.identityHashCode(z));
} }