diff --git a/src/main/java/chart/Chart.form b/src/main/java/chart/Chart.form index ba7e694..012b78c 100644 --- a/src/main/java/chart/Chart.form +++ b/src/main/java/chart/Chart.form @@ -1,6 +1,71 @@
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -14,6 +79,9 @@ + + + diff --git a/src/main/java/chart/Chart.java b/src/main/java/chart/Chart.java index 4adf9be..89750ed 100644 --- a/src/main/java/chart/Chart.java +++ b/src/main/java/chart/Chart.java @@ -38,11 +38,11 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollab protected Dimension gdim; private int first_bar, last_bar; - - - public final void initChart(){ + + public final void initChart() { // data = new OHLCData(60000*30); - data = new OHLCData(60000*15); + //data = new OHLCData(60000*30); + data = Globals.se.getOHLCdata(60000 * 30); } /** @@ -51,6 +51,7 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollab public Chart() { initComponents(); initChart(); + //setCompression(60000); if (Globals.se == null) { return; } @@ -59,16 +60,13 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollab } - OHLCData data; - OHLCDataItem current = null; //void drawCandle(Graphics2D g, OHLCData d, int x, int y) { // - // } - + // } @Override public Dimension getPreferredScrollableViewportSize() { return this.getPreferredSize(); @@ -105,7 +103,7 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollab } String getAt(int unit) { - Date date = new Date(/*sesim.Scheduler.timeStart*/ 0 + unit * 5000); + Date date = new Date(/*sesim.Scheduler.timeStart*/0 + unit * 5000); // DateFormat formatter = new SimpleDateFormat("HH:mm:ss:SSS"); DateFormat formatter = new SimpleDateFormat("HH:mm:ss"); String dateFormatted = formatter.format(date); @@ -188,25 +186,19 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollab float getY(float y) { if (logs) { - - float m = c_mm.max/c_mm.min; - + + float m = c_mm.max / c_mm.min; + //System.out.printf("Min: %f Max: %f M: %f\n",c_mm.min,c_mm.max,m); - - //float fac = (float) c_rect.height /(float) Math.log(c_mm.max * c_yscaling); - float fac = (float) c_rect.height /(float)Math.log(m); - + float fac = (float) c_rect.height / (float) Math.log(m); float fmin = c_rect.height - ((float) Math.log((y / c_mm.min)) * fac); - - + //System.out.printf("Fac: %f fmin: %f\n", fac, fmin); return fmin; //return c_rect.height - ((float) Math.log((y - c_mm.min) * c_yscaling) * fac); - - } return c_rect.height - ((y - c_mm.min) * c_yscaling); @@ -294,14 +286,12 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollab int yw = (int) (this.y_legend_width * this.em_size); // System.out.printf("MinMax: %f %f\n", c_mm.min, c_mm.max); - g.drawLine(dim.width + dim.x - yw, 0, dim.width + dim.x - yw, dim.height); // float yscale = gdim.height / c_mm.getDiff(); c_yscaling = c_rect.height / c_mm.getDiff(); // System.out.printf("yscale %f\n", c_yscaling); - for (float y = c_mm.min; y < c_mm.max; y += c_mm.getDiff() / 10.0) { int my = (int) getY(y); //c_rect.height - (int) ((y - c_mm.min) * c_yscaling); @@ -349,7 +339,7 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollab //this.getSize(); int pwidth = em_width * num_bars; int phight = 400; - // phight=this.getVisibleRect().height; + // phight=this.getVisibleRect().height; this.setPreferredSize(new Dimension(pwidth, gdim.height)); this.revalidate(); @@ -414,9 +404,7 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollab this.initEmSize(g); this.gdim = this.getParent().getSize(gdim); this.getParent().setPreferredSize(gdim); - - - + this.clip_bounds = g.getClipBounds(this.clip_bounds); // System.out.printf("X:%d %d\n",gdim.width,gdim.height); @@ -437,11 +425,77 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollab // //GEN-BEGIN:initComponents private void initComponents() { + ctxMenu = new javax.swing.JPopupMenu(); + jMenu1 = new javax.swing.JMenu(); + ctxMenuComp5s = new javax.swing.JMenuItem(); + ctxMenuComp1m = new javax.swing.JMenuItem(); + ctxMenuComp5min = new javax.swing.JMenuItem(); + ctxMenuComp1h = new javax.swing.JMenuItem(); + ctxMenuComp4h = new javax.swing.JMenuItem(); + ctxMenuComp1d = new javax.swing.JMenuItem(); + + jMenu1.setText("Compression"); + + ctxMenuComp5s.setText("5 s"); + ctxMenuComp5s.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + ctxMenuComp5sActionPerformed(evt); + } + }); + jMenu1.add(ctxMenuComp5s); + + ctxMenuComp1m.setText("1 min"); + ctxMenuComp1m.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + ctxMenuComp1mActionPerformed(evt); + } + }); + jMenu1.add(ctxMenuComp1m); + + ctxMenuComp5min.setText("5 min"); + ctxMenuComp5min.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + ctxMenuComp5minActionPerformed(evt); + } + }); + jMenu1.add(ctxMenuComp5min); + + ctxMenuComp1h.setText("1 h"); + ctxMenuComp1h.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + ctxMenuComp1hActionPerformed(evt); + } + }); + jMenu1.add(ctxMenuComp1h); + + ctxMenuComp4h.setText("4 h"); + ctxMenuComp4h.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + ctxMenuComp4hActionPerformed(evt); + } + }); + jMenu1.add(ctxMenuComp4h); + + ctxMenuComp1d.setText("1 d"); + ctxMenuComp1d.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + ctxMenuComp1dActionPerformed(evt); + } + }); + jMenu1.add(ctxMenuComp1d); + + ctxMenu.add(jMenu1); + setBackground(java.awt.Color.white); setBorder(null); setOpaque(false); setPreferredSize(new java.awt.Dimension(300, 300)); setRequestFocusEnabled(false); + addMouseListener(new java.awt.event.MouseAdapter() { + public void mousePressed(java.awt.event.MouseEvent evt) { + formMousePressed(evt); + } + }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -455,17 +509,65 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollab ); }// //GEN-END:initComponents + private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed + System.out.printf("Mouse ohlc was pressed\n"); + if (!evt.isPopupTrigger()) { + return; + }; + + this.ctxMenu.show(this, evt.getX(), evt.getY()); + + + }//GEN-LAST:event_formMousePressed + + void setCompression(int timeFrame) { + data = Globals.se.getOHLCdata(timeFrame); + repaint(); + } + + private void ctxMenuComp1mActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ctxMenuComp1mActionPerformed + this.setCompression(60000); + }//GEN-LAST:event_ctxMenuComp1mActionPerformed + + private void ctxMenuComp1hActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ctxMenuComp1hActionPerformed + this.setCompression(60000*60); + }//GEN-LAST:event_ctxMenuComp1hActionPerformed + + private void ctxMenuComp4hActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ctxMenuComp4hActionPerformed + this.setCompression(60000*60*4); + }//GEN-LAST:event_ctxMenuComp4hActionPerformed + + private void ctxMenuComp1dActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ctxMenuComp1dActionPerformed + this.setCompression(60000*60*24); + }//GEN-LAST:event_ctxMenuComp1dActionPerformed + + private void ctxMenuComp5sActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ctxMenuComp5sActionPerformed + this.setCompression(1000*5); + }//GEN-LAST:event_ctxMenuComp5sActionPerformed + + private void ctxMenuComp5minActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ctxMenuComp5minActionPerformed + this.setCompression(60*1000*5); + }//GEN-LAST:event_ctxMenuComp5minActionPerformed + @Override public void UpdateQuote(Quote q) { // System.out.print("Quote Received\n"); // this.realTimeAdd(q.time, (float) q.price, (float)q.volume); - data.realTimeAdd(q.time, (float) q.price, (float) q.volume); +// data.realTimeAdd(q.time, (float) q.price, (float) q.volume); // this.invalidate(); this.repaint(); } // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JPopupMenu ctxMenu; + private javax.swing.JMenuItem ctxMenuComp1d; + private javax.swing.JMenuItem ctxMenuComp1h; + private javax.swing.JMenuItem ctxMenuComp1m; + private javax.swing.JMenuItem ctxMenuComp4h; + private javax.swing.JMenuItem ctxMenuComp5min; + private javax.swing.JMenuItem ctxMenuComp5s; + private javax.swing.JMenu jMenu1; // End of variables declaration//GEN-END:variables } diff --git a/src/main/java/gui/EditExchangeDialog.java b/src/main/java/gui/EditExchangeDialog.java index aa6076f..3dbf45f 100644 --- a/src/main/java/gui/EditExchangeDialog.java +++ b/src/main/java/gui/EditExchangeDialog.java @@ -31,7 +31,7 @@ import org.json.JSONObject; * * @author 7u83 <7u83@mail.ru> */ -public class EditExchangeDialog extends javax.swing.JDialog { +public class EditExchangeDialog extends EscDialog /*javax.swing.JDialog*/ { /** * Creates new form EditExchnageDialog @@ -40,9 +40,11 @@ public class EditExchangeDialog extends javax.swing.JDialog { super(parent, modal); initComponents(); this.setLocationRelativeTo(parent); - JSONObject jo = new JSONObject(Globals.prefs.get("Exchange", "{}")); - this.moneyDecimalsSpinner.setValue(jo.getInt(Globals.se.CFG_MONEY_DECIMALS)); - this.sharesDecimalsSpinner.setValue(jo.getInt(Globals.se.CFG_SHARES_DECIMALS)); + JSONObject jo = new JSONObject(Globals.prefs.get("Exchange", Globals.DEFAULT_EXCHANGE_CFG)); + + this.moneyDecimalsSpinner.setValue(jo.getInt(Globals.se.CFG_MONEY_DECIMALS)); + this.sharesDecimalsSpinner.setValue(jo.getInt(Globals.se.CFG_SHARES_DECIMALS)); + this.setLocationRelativeTo(parent); } int showdialog() { diff --git a/src/main/java/gui/EscDialog.java b/src/main/java/gui/EscDialog.java index c358b6b..64ba93f 100644 --- a/src/main/java/gui/EscDialog.java +++ b/src/main/java/gui/EscDialog.java @@ -37,6 +37,13 @@ public class EscDialog extends javax.swing.JDialog { public EscDialog(java.awt.Frame parent, boolean modal) { super(parent, modal); initComponents(); + System.out.printf("Adding Key Listener\n", ""); + addKeyListener(new java.awt.event.KeyAdapter() { + public void keyReleased(java.awt.event.KeyEvent evt) { + formKeyReleased(evt); + } + }); + this.setLocationRelativeTo(parent); } /** diff --git a/src/main/java/gui/Globals.java b/src/main/java/gui/Globals.java index fcb746a..971b6c6 100644 --- a/src/main/java/gui/Globals.java +++ b/src/main/java/gui/Globals.java @@ -79,6 +79,13 @@ public class Globals { public static final String GODMODE = "godmode"; } + + public static String DEFAULT_EXCHANGE_CFG = + "{" + + " money_decimals: 2," + + " shares_decimals: 0" + + "}"; + //CfgStrings diff --git a/src/main/java/gui/OrdersList.java b/src/main/java/gui/OrdersList.java index d823e17..e6e4687 100644 --- a/src/main/java/gui/OrdersList.java +++ b/src/main/java/gui/OrdersList.java @@ -186,7 +186,7 @@ public class OrdersList extends javax.swing.JPanel { }// //GEN-END:initComponents private void tableMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableMousePressed - System.out.printf("The mouse is here\n"); + Point point = evt.getPoint(); int currentRow = table.rowAtPoint(point); diff --git a/src/main/java/gui/ZZZ.form b/src/main/java/gui/ZZZ.form new file mode 100644 index 0000000..05d9eba --- /dev/null +++ b/src/main/java/gui/ZZZ.form @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/gui/ZZZ.java b/src/main/java/gui/ZZZ.java new file mode 100644 index 0000000..3c0968f --- /dev/null +++ b/src/main/java/gui/ZZZ.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2017, tobias + * 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 tobias + */ +public class ZZZ extends EscDialog { + + /** + * Creates new form ZZZ + */ + public ZZZ(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() { + + 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) + .addGap(0, 400, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 300, Short.MAX_VALUE) + ); + + 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(ZZZ.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(ZZZ.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(ZZZ.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(ZZZ.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + // + + /* Create and display the dialog */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + ZZZ dialog = new ZZZ(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 + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/sesim/Exchange.java b/src/main/java/sesim/Exchange.java index 3620dfa..40cfde6 100644 --- a/src/main/java/sesim/Exchange.java +++ b/src/main/java/sesim/Exchange.java @@ -68,6 +68,55 @@ public class Exchange { public void accountUpdated(Account a, Order o); } + HashMap ohlc_data = new HashMap<>(); + + public OHLCData buildOHLCData(int timeFrame) { + OHLCData data = new OHLCData(timeFrame); + if (this.quoteHistory == null) { + return data; + } + + + Iterator it = quoteHistory.iterator(); + while (it.hasNext()) { + Quote q = it.next(); + data.realTimeAdd(q.time, (float) q.price, (float) q.volume); + + } + + return data; + } + + public OHLCData getOHLCdata(Integer timeFrame) { + OHLCData data; //=new OHLCData(timeFrame); + data = ohlc_data.get(timeFrame); + if (data == null){ + // data = new OHLCData(timeFrame); + data = this.buildOHLCData(timeFrame); + ohlc_data.put(timeFrame, data); + } + + return data; +/* try { + data = ohlc_data.get(timeFrame); + } catch (Exception e) { + data = null; + } + if (data == null) { + data = buildOHLCData(timeFrame); + } +*/ + + } + + void updateOHLCData(Quote q) { + Iterator it = ohlc_data.values().iterator(); + while (it.hasNext()) { + OHLCData data = it.next(); + data.realTimeAdd(q.time, (float) q.price, (float) q.volume); + } + } + /** * Implements a trading account */ @@ -279,6 +328,8 @@ public class Exchange { traders = new ArrayList(); num_trades = 0; + + this.ohlc_data = new HashMap(); // Create order books order_books = new HashMap(); @@ -385,6 +436,10 @@ public class Exchange { } tradelock.unlock(); + if (lq == null && b == null && a == null) { + return null; + } + if (a != null && b != null) { Quote q = new Quote(); if (lq == null) { @@ -399,11 +454,17 @@ public class Exchange { q.price = a.limit; return q; } + return lq; } if (a != null) { Quote q = new Quote(); if (lq == null) { + + q.price = a.limit; + return q; + } + if (lq.price > a.limit) { q.price = a.limit; return q; } @@ -416,10 +477,15 @@ public class Exchange { q.price = b.limit; return q; } + if (lq.price < b.limit) { + q.price = b.limit; + return q; + } + return lq; } - return null; + return lq; } // Class to describe an executed order @@ -710,6 +776,7 @@ public class Exchange { // System.out.print("There was a trade:"+q.price+"\n"); this.quoteHistory.add(q); + this.updateOHLCData(q); this.updateQuoteReceivers(q);