diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4e6d056 --- /dev/null +++ b/pom.xml @@ -0,0 +1,21 @@ + + + 4.0.0 + com.mycompany + MavenJava + 1.0-SNAPSHOT + jar + + + org.jfree + jfreechart + 1.0.19 + + + + UTF-8 + 1.8 + 1.8 + + SeSim + \ No newline at end of file diff --git a/src/main/java/gui/AskBook.java b/src/main/java/gui/AskBook.java new file mode 100644 index 0000000..c0b5fa2 --- /dev/null +++ b/src/main/java/gui/AskBook.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, 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 sesim.Exchange.*; +import sesim.Order.*; +import java.util.ArrayList; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class AskBook extends OrderBook { + + @Override + ArrayList getOrderBook() { + return MainWin.se.getOrderBook(OrderType.ask,40); + } + + @Override + boolean getDesc(){ + return true; + } + + public AskBook(){ + if (MainWin.se == null) { + return; + } + MainWin.se.addBookReceiver(OrderType.ask, this); + + } + +} diff --git a/src/main/java/gui/BidBook.java b/src/main/java/gui/BidBook.java new file mode 100644 index 0000000..c05b35c --- /dev/null +++ b/src/main/java/gui/BidBook.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, 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 sesim.Order.*; +import java.util.ArrayList; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class BidBook extends OrderBook { + + @Override + ArrayList getOrderBook() { + return MainWin.se.getOrderBook(OrderType.bid, 40); + } + + public BidBook() { + if (MainWin.se == null) { + return; + } + MainWin.se.addBookReceiver(OrderType.bid, this); + } +} diff --git a/src/main/java/gui/CandlestickDemo.java b/src/main/java/gui/CandlestickDemo.java new file mode 100644 index 0000000..17e59b7 --- /dev/null +++ b/src/main/java/gui/CandlestickDemo.java @@ -0,0 +1,99 @@ +package gui; + +import org.jfree.chart.*; +import org.jfree.chart.axis.*; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.CandlestickRenderer; +import org.jfree.data.xy.*; + +import javax.swing.*; +import java.awt.*; +import java.io.*; +import java.net.URL; +import java.text.*; +import java.util.*; +import java.util.List; + +public class CandlestickDemo extends JFrame { + public CandlestickDemo(String stockSymbol) { + super("CandlestickDemo"); + this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + DateAxis domainAxis = new DateAxis("Date"); + NumberAxis rangeAxis = new NumberAxis("Price"); + CandlestickRenderer renderer = new CandlestickRenderer(); + XYDataset dataset = getDataSet(stockSymbol); + + XYPlot mainPlot = new XYPlot(dataset, domainAxis, rangeAxis, renderer); + + //Do some setting up, see the API Doc + renderer.setSeriesPaint(0, Color.BLACK); + renderer.setDrawVolume(false); + rangeAxis.setAutoRangeIncludesZero(false); + domainAxis.setTimeline( SegmentedTimeline.newMondayThroughFridayTimeline() ); + + //Now create the chart and chart panel + JFreeChart chart = new JFreeChart(stockSymbol, null, mainPlot, false); + ChartPanel chartPanel = new ChartPanel(chart); + chartPanel.setPreferredSize(new Dimension(600, 300)); + + this.add(chartPanel); + this.pack(); + } + protected AbstractXYDataset getDataSet(String stockSymbol) { + //This is the dataset we are going to create + DefaultOHLCDataset result = null; + //This is the data needed for the dataset + OHLCDataItem[] data; + + //This is where we go get the data, replace with your own data source + data = getData(stockSymbol); + + //Create a dataset, an Open, High, Low, Close dataset + result = new DefaultOHLCDataset(stockSymbol, data); + + return result; + } + //This method uses yahoo finance to get the OHLC data + protected OHLCDataItem[] getData(String stockSymbol) { + List dataItems = new ArrayList(); + try { + String strUrl= "http://ichart.finance.yahoo.com/table.csv?s="+stockSymbol+"&a=0&b=1&c=2008&d=3&e=30&f=2008&ignore=.csv"; + URL url = new URL(strUrl); + BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); + DateFormat df = new SimpleDateFormat("y-M-d"); + + String inputLine; + in.readLine(); + while ((inputLine = in.readLine()) != null) { + StringTokenizer st = new StringTokenizer(inputLine, ","); + + Date date = df.parse( st.nextToken() ); + double open = Double.parseDouble( st.nextToken() ); + double high = Double.parseDouble( st.nextToken() ); + double low = Double.parseDouble( st.nextToken() ); + double close = Double.parseDouble( st.nextToken() ); + double volume = Double.parseDouble( st.nextToken() ); + double adjClose = Double.parseDouble( st.nextToken() ); + + OHLCDataItem item = new OHLCDataItem(date, open, high, low, close, volume); + dataItems.add(item); + } + in.close(); + } + catch (Exception e) { + e.printStackTrace(); + } + //Data from Yahoo is from newest to oldest. Reverse so it is oldest to newest + Collections.reverse(dataItems); + + //Convert the list into an array + OHLCDataItem[] data = dataItems.toArray(new OHLCDataItem[dataItems.size()]); + + return data; + } + + public static void main(String[] args) { + new CandlestickDemo("MSFT").setVisible(true); + } +} \ No newline at end of file diff --git a/src/main/java/gui/Chart.form b/src/main/java/gui/Chart.form new file mode 100644 index 0000000..c9a3f64 --- /dev/null +++ b/src/main/java/gui/Chart.form @@ -0,0 +1,30 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/gui/Chart.java b/src/main/java/gui/Chart.java new file mode 100644 index 0000000..f7d6f57 --- /dev/null +++ b/src/main/java/gui/Chart.java @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2016, 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 sesim.Exchange; +import sesim.Exchange.*; +import java.awt.Color; +import java.awt.Dimension; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.StringTokenizer; +import java.util.Iterator; + +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.DateAxis; +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.axis.SegmentedTimeline; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.CandlestickRenderer; +import org.jfree.data.xy.AbstractXYDataset; +import org.jfree.data.xy.DefaultOHLCDataset; +import org.jfree.data.xy.OHLCDataItem; +import org.jfree.data.xy.XYDataset; + +import sesim.Quote; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class Chart extends javax.swing.JPanel implements QuoteReceiver { + + /** + * Creates new form Chart + */ + public Chart() { + initComponents(); + + String stockSymbol = "Schliemanz Koch AG"; + //String stockSymbol = "MSFT"; + + DateAxis domainAxis = new DateAxis("Date"); + NumberAxis rangeAxis = new NumberAxis("Price"); + CandlestickRenderer renderer = new CandlestickRenderer(); + XYDataset dataset = getDataSet(stockSymbol); + + XYPlot mainPlot = new XYPlot(dataset, domainAxis, rangeAxis, renderer); + + //Do some setting up, see the API Doc + renderer.setSeriesPaint(0, Color.BLACK); + renderer.setDrawVolume(false); + rangeAxis.setAutoRangeIncludesZero(false); + domainAxis.setTimeline(SegmentedTimeline.newMondayThroughFridayTimeline()); + + //Now create the chart and chart panel + JFreeChart chart = new JFreeChart(stockSymbol, null, mainPlot, false); + ChartPanel chartPanel = new ChartPanel(chart); + + chartPanel.setPreferredSize(new Dimension(500, 270)); + + add(chartPanel); + System.out.print("Hallo Welt\n"); + + if (MainWin.se == null) { + return; + } + + MainWin.se.addQuoteReceiver(this); + + } + + protected AbstractXYDataset getDataSet(String stockSymbol) { + //This is the dataset we are going to create + DefaultOHLCDataset result = null; + //This is the data needed for the dataset + OHLCDataItem[] data; + + //This is where we go get the data, replace with your own data source + data = getData(); + + //Create a dataset, an Open, High, Low, Close dataset + result = new DefaultOHLCDataset(stockSymbol, data); + + return result; + } + + protected OHLCDataItem getOhlcData(long first, long last, SortedSet quotes) { + + Quote s = new Quote(); + + s.time = first; + + SortedSet l = quotes.tailSet(s); + + double open = 0; + double high = 0; + double low = 0; + double close = 0; + double volume=0; + + Iterator it = l.iterator(); + + Quote q; + + + if (it.hasNext()) { + q = it.next(); + open = q.price; + high = q.price; + low = q.price; + volume = q.volume; + } + else { + q = new Quote(); + } + + + while (it.hasNext() && q.time < last) { + q = it.next(); + + if (q.price > high) { + high = q.price; + } + if (q.price < low) { + low = q.price; + } + + volume += q.volume; + + } + close = q.price; + + Date date = new Date(first); + return new OHLCDataItem( + date, open, high, low, close, volume + ); + } + + protected OHLCDataItem[] getData() { + + List data = new ArrayList<>(); + + long ct; + ct = Exchange.getCurrentTimeSeconds(10); + + SortedSet h = MainWin.se.getQuoteHistory(ct - 60); + + for (long i = (ct - 60)*1000; i < (ct + 10)*1000; i += 10*1000) { + OHLCDataItem d = getOhlcData(i, i + 10*1000, h); + data.add(d); + } + + System.out.print(data.size() + "\n"); + // System.exit(0); + + return data.toArray(new OHLCDataItem[data.size()]); + + } + + //This method uses yahoo finance to get the OHLC data + protected OHLCDataItem[] getData_old() { + String stockSymbol = "MSFT"; + List dataItems = new ArrayList(); + try { + String strUrl = "http://ichart.finance.yahoo.com/table.csv?s=" + stockSymbol + "&a=0&b=1&c=2008&d=3&e=30&f=2008&ignore=.csv"; + URL url = new URL(strUrl); + BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); + DateFormat df = new SimpleDateFormat("y-M-d"); + + String inputLine; + in.readLine(); + while ((inputLine = in.readLine()) != null) { + StringTokenizer st = new StringTokenizer(inputLine, ","); + + Date date = df.parse(st.nextToken()); + double open = Double.parseDouble(st.nextToken()); + double high = Double.parseDouble(st.nextToken()); + double low = Double.parseDouble(st.nextToken()); + double close = Double.parseDouble(st.nextToken()); + double volume = Double.parseDouble(st.nextToken()); + double adjClose = Double.parseDouble(st.nextToken()); + + OHLCDataItem item = new OHLCDataItem(date, open, high, low, close, volume); + dataItems.add(item); + } + in.close(); + } catch (Exception e) { + e.printStackTrace(); + } + //Data from Yahoo is from newest to oldest. Reverse so it is oldest to newest + Collections.reverse(dataItems); + + //Convert the list into an array + OHLCDataItem[] data = dataItems.toArray(new OHLCDataItem[dataItems.size()]); + + System.out.print("Return oghls old data items\n"); + + return data; + } + + /** + * 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() { + + jToggleButton2 = new javax.swing.JToggleButton(); + + setLayout(new java.awt.BorderLayout()); + + jToggleButton2.setText("jToggleButton2"); + add(jToggleButton2, java.awt.BorderLayout.CENTER); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JToggleButton jToggleButton2; + // End of variables declaration//GEN-END:variables + + @Override + public void UpdateQuote(Quote q) { + return; + //q.print(); + /* SortedSet h = MainWin.se.getQuoteHistory(60); + System.out.print( + "SortedSet size:" + + h.size() + + "\n" + ); + */ + } +} diff --git a/src/main/java/gui/ControlPanel.form b/src/main/java/gui/ControlPanel.form new file mode 100644 index 0000000..057d9f3 --- /dev/null +++ b/src/main/java/gui/ControlPanel.form @@ -0,0 +1,76 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/gui/ControlPanel.java b/src/main/java/gui/ControlPanel.java new file mode 100644 index 0000000..e29de67 --- /dev/null +++ b/src/main/java/gui/ControlPanel.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2016, 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 ControlPanel extends javax.swing.JPanel { + + /** + * Creates new form ControlPanel + */ + public ControlPanel() { + 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() { + + SellButton = new javax.swing.JButton(); + jScrollPane1 = new javax.swing.JScrollPane(); + jTextArea1 = new javax.swing.JTextArea(); + BuyButton = new javax.swing.JButton(); + + setLayout(new java.awt.GridLayout(3, 0)); + + SellButton.setBackground(new java.awt.Color(181, 0, 12)); + SellButton.setFont(SellButton.getFont().deriveFont(SellButton.getFont().getStyle() | java.awt.Font.BOLD, SellButton.getFont().getSize()+12)); + SellButton.setForeground(new java.awt.Color(254, 254, 254)); + SellButton.setText("Sell"); + SellButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + SellButtonActionPerformed(evt); + } + }); + add(SellButton); + + jTextArea1.setColumns(20); + jTextArea1.setRows(5); + jScrollPane1.setViewportView(jTextArea1); + + add(jScrollPane1); + + BuyButton.setBackground(new java.awt.Color(5, 94, 1)); + BuyButton.setFont(BuyButton.getFont().deriveFont(BuyButton.getFont().getStyle() | java.awt.Font.BOLD, BuyButton.getFont().getSize()+12)); + BuyButton.setForeground(new java.awt.Color(254, 254, 254)); + BuyButton.setText("Buy"); + BuyButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + BuyButtonActionPerformed(evt); + } + }); + add(BuyButton); + }// //GEN-END:initComponents + + private void SellButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_SellButtonActionPerformed + MainWin.myAccount.sell(81, 55.0); + }//GEN-LAST:event_SellButtonActionPerformed + + private void BuyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_BuyButtonActionPerformed + MainWin.myAccount.buy(44, 66.0); + }//GEN-LAST:event_BuyButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton BuyButton; + private javax.swing.JButton SellButton; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextArea jTextArea1; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/gui/MainWin.form b/src/main/java/gui/MainWin.form new file mode 100644 index 0000000..5de2c7a --- /dev/null +++ b/src/main/java/gui/MainWin.form @@ -0,0 +1,105 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/gui/MainWin.java b/src/main/java/gui/MainWin.java new file mode 100644 index 0000000..8f56662 --- /dev/null +++ b/src/main/java/gui/MainWin.java @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2016, 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 traders.RandomTraderConfig; +import traders.SwitchingTraderConfig; +import sesim.Account; +import sesim.AutoTraderLIst; +import sesim.Exchange; +import sesim.BuyOrder; +import javax.swing.UIManager; +import javax.swing.*; + + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class MainWin extends javax.swing.JFrame { + + static sesim.Exchange se; + static sesim.Account myAccount; + static traders.ManTrader myTrader; + + /** + * Creates new form MainWin + */ + public MainWin() { + + 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() { + + jButton1 = new javax.swing.JButton(); + jMenuItem1 = new javax.swing.JMenuItem(); + controlPanel2 = new gui.ControlPanel(); + orderBookPanel1 = new gui.OrderBookPanel(); + zZChart1 = new gui.Chart(); + MainMenu = new javax.swing.JMenuBar(); + FileMenu = new javax.swing.JMenu(); + FileNew = new javax.swing.JMenuItem(); + FileRun = new javax.swing.JMenuItem(); + jMenu2 = new javax.swing.JMenu(); + + jButton1.setText("jButton1"); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + + jMenuItem1.setText("jMenuItem1"); + + setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); + setMinimumSize(new java.awt.Dimension(640, 480)); + getContentPane().add(controlPanel2, java.awt.BorderLayout.LINE_END); + getContentPane().add(orderBookPanel1, java.awt.BorderLayout.LINE_START); + getContentPane().add(zZChart1, java.awt.BorderLayout.CENTER); + + FileMenu.setBackground(new java.awt.Color(254, 203, 1)); + FileMenu.setText("File"); + + FileNew.setText("New"); + FileNew.setBorder(null); + FileNew.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + FileNewActionPerformed(evt); + } + }); + FileMenu.add(FileNew); + + FileRun.setText("Run"); + FileRun.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + FileRunActionPerformed(evt); + } + }); + FileMenu.add(FileRun); + + MainMenu.add(FileMenu); + + jMenu2.setText("Edit"); + MainMenu.add(jMenu2); + + setJMenuBar(MainMenu); + + pack(); + }// //GEN-END:initComponents + + private void FileNewActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileNewActionPerformed + + + }//GEN-LAST:event_FileNewActionPerformed + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + // TODO add your handling code here: + }//GEN-LAST:event_jButton1ActionPerformed + + private void FileRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_FileRunActionPerformed + se.start(); + }//GEN-LAST:event_FileRunActionPerformed + + /** + * @param args the command line arguments + */ + public static void main(String args[]) { + + se = new Exchange(); + myAccount = new Account(se,1000,100000000.0); + myTrader = new traders.ManTrader(myAccount,null); + +/* Account otherAccount = new Account(se,1000,1000); + Traders.ManTrader otherTrader = new Traders.ManTrader(otherAccount); + otherTrader.sell(80, 22.70); + +*/ + +/* + Account traccount = new Account(se,5500,1000000.0); + RandomTrader rt = new RandomTrader(traccount,null); + TraderRunner tr = new TraderRunner(rt); + tr.start(); +*/ + + AutoTraderLIst at = new AutoTraderLIst(); +// RandomTraderConfig rcfg = new RandomTraderConfig(); + SwitchingTraderConfig rcfg = new SwitchingTraderConfig(); + at.add(1000, rcfg, se, 100, 0); + at.add(1000, rcfg, se, 0, 10000); + + + SwitchingTraderConfig scfg = new SwitchingTraderConfig(); + at.add(1, scfg, se, 1000000, 0); + + + // at.add(10, rcfg, se, 1000000, 0); + + + 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. + * 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 ("Motif".equals(info.getName())) { + javax.swing.UIManager.setLookAndFeel(info.getClassName()); + break; + } + } + } catch (ClassNotFoundException ex) { + java.util.logging.Logger.getLogger(MainWin.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (InstantiationException ex) { + java.util.logging.Logger.getLogger(MainWin.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (IllegalAccessException ex) { + java.util.logging.Logger.getLogger(MainWin.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } catch (javax.swing.UnsupportedLookAndFeelException ex) { + java.util.logging.Logger.getLogger(MainWin.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + } + */ + // + + /* Create and display the form */ + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + new MainWin().setVisible(true); + } + }); + } + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JMenu FileMenu; + private javax.swing.JMenuItem FileNew; + private javax.swing.JMenuItem FileRun; + private javax.swing.JMenuBar MainMenu; + private gui.ControlPanel controlPanel2; + private javax.swing.JButton jButton1; + private javax.swing.JMenu jMenu2; + private javax.swing.JMenuItem jMenuItem1; + private gui.OrderBookPanel orderBookPanel1; + private gui.Chart zZChart1; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/gui/NewPanel.form b/src/main/java/gui/NewPanel.form new file mode 100644 index 0000000..a965931 --- /dev/null +++ b/src/main/java/gui/NewPanel.form @@ -0,0 +1,18 @@ + + +
+ + + + + + + + + + + + + + + diff --git a/src/main/java/gui/NewPanel.java b/src/main/java/gui/NewPanel.java new file mode 100644 index 0000000..2521ee4 --- /dev/null +++ b/src/main/java/gui/NewPanel.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016, 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 static Gui.SimpleJFreeDemo.createDemoPanel; +import javax.swing.JPanel; +import org.jfree.chart.ChartFactory; +import org.jfree.chart.ChartPanel; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.data.function.Function2D; +import org.jfree.data.general.DatasetUtilities; +import org.jfree.data.xy.XYDataset; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class NewPanel extends javax.swing.JPanel { + + /** + * Creates new form NewPanel + */ + public NewPanel() { + initComponents(); + + initComponents(); + JPanel chartPanel = createDemoPanel(); + chartPanel.setPreferredSize(new java.awt.Dimension(500, 270)); + add(chartPanel); + + + } + + private static JFreeChart createChart(XYDataset dataset) { + // create the chart... + JFreeChart chart = ChartFactory.createXYLineChart( + "Function2DDemo1 ", // chart title + "X", // x axis label + "Y", // y axis label + dataset, // data + PlotOrientation.VERTICAL, + true, // include legend + true, // tooltips + false // urls + ); + + XYPlot plot = (XYPlot) chart.getPlot(); + plot.getDomainAxis().setLowerMargin(0.0); + plot.getDomainAxis().setUpperMargin(0.0); + return chart; + } + + /** + * Creates a sample dataset. + * + * @return A sample dataset. + */ + public static XYDataset createDataset() { + XYDataset result = DatasetUtilities.sampleFunction2D(new X2(), + -4.0, 4.0, 40, "f(x)"); + return result; + } + + /** + * Creates a panel for the demo (used by SuperDemo.java). + * + * @return A panel. + */ + public static JPanel createDemoPanel() { + JFreeChart chart = createChart(createDataset()); + return new ChartPanel(chart); + } + + /** + * A simple function. + */ + static class X2 implements Function2D { + + /* (non-Javadoc) + * @see org.jfree.data.function.Function2D#getValue(double) + */ + public double getValue(double x) { + return x * x + 2; + } + + } + + + /** + * 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. + */ + // //GEN-BEGIN:initComponents + private void initComponents() { + + setLayout(new java.awt.BorderLayout()); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/gui/OrderBook.form b/src/main/java/gui/OrderBook.form new file mode 100644 index 0000000..040eed0 --- /dev/null +++ b/src/main/java/gui/OrderBook.form @@ -0,0 +1,83 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+
+
+
+
diff --git a/src/main/java/gui/OrderBook.java b/src/main/java/gui/OrderBook.java new file mode 100644 index 0000000..cf7e198 --- /dev/null +++ b/src/main/java/gui/OrderBook.java @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2016, 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 sesim.Exchange; +import java.util.ArrayList; +import java.util.Formatter; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.JTableHeader; +import javax.swing.SwingUtilities; +import java.awt.*; +import javax.swing.*; +import javax.swing.table.*; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +/** + * OderBook Class + */ +public abstract class OrderBook extends javax.swing.JPanel implements Exchange.BookReceiver { + + + OrderBookListModel model; + + abstract ArrayList getOrderBook(); + + private Color hdr_color = Color.LIGHT_GRAY; + + private class OrderBookCellRenderer extends DefaultTableCellRenderer { + + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, boolean isSelected, boolean hasFocus, + int row, int column) { + DefaultTableCellRenderer renderer + = (DefaultTableCellRenderer) super.getTableCellRendererComponent( + table, value, isSelected, hasFocus, row, column); + renderer.setBackground(hdr_color); + return renderer; + } + } + + @Override + public void UpdateOrderBook() { + + class Updater implements Runnable{ + OrderBookListModel model; + ArrayList newlist; + + @Override + public void run() { + model.update(this.newlist); + } + + Updater(OrderBookListModel model, ArrayList newlist){ + this.model = model; + this.newlist = newlist; + } + + } + ArrayList newlist = getOrderBook(); + SwingUtilities.invokeLater(new Updater(this.model,newlist)); + + } + + boolean getDesc() { + return false; + } + +// protected OrderBookListModel model; + + protected class OrderBookListModel extends AbstractTableModel { + + private ArrayList list; + private boolean desc = false; + + public OrderBookListModel() { + // System.out.print("CREATING A NEW MODEL\n"); +// update(); + list = getOrderBook(); + } + + int update_calls = 0; + int colcount_calls = 0; + + public void update(ArrayList newlist) { + list = newlist; //getOrderBook(); + this.fireTableDataChanged(); + + this.update_calls++; + int hc = this.hashCode(); + //System.out.print("Update/ColCalls = " + update_calls + "/" + colcount_calls + " HC: " + hc + "\n"); + } + + + @Override + public String getColumnName(int c) { + switch (c) { + case 0: + return "ID"; + case 1: + return "Price"; + case 2: + return "Vol."; + } + return ""; + } + + @Override + public int getRowCount() { + colcount_calls++; +// System.out.print("Update/ColCalls = " + update_calls + "/" + colcount_calls + "\n"); + return list.size(); + } + + @Override + public int getColumnCount() { + return 3; + } + + @Override + public Object getValueAt(int r, int c) { + sesim.Order o; + + int s = list.size(); + //System.out.print("Looking for Value at" + r + ":" + c + " w size:" + s + "\n"); + + if (!getDesc()) { + o = (sesim.Order) list.get(r); + } else { + o = (sesim.Order) list.get(list.size() - r - 1); + } + Formatter f = new Formatter(); + switch (c) { + case 0: + return f.format("#%06x", o.id); + + case 1: + return o.limit; + case 2: + return o.volume; + } + return ""; + } + } + + /** + * Creates new form OrderBook + */ + public OrderBook() { + //System.out.print("init Orderbook]\n"); + initComponents(); + + this.setBorder(BorderFactory.createEmptyBorder()); + this.orderBookScroller.setBorder(BorderFactory.createBevelBorder(0)); + + if (MainWin.se == null) { + return; + } + + this.model = new OrderBookListModel(); + this.orderBookList.setModel(model); + + orderBookList.setBorder(BorderFactory.createEmptyBorder()); + + JTableHeader h = this.orderBookList.getTableHeader(); + h.setBackground(hdr_color); + h.setForeground(Color.green); + h.setDefaultRenderer(new OrderBookCellRenderer()); + + } + + /** + * 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() { + + orderBookScroller = new javax.swing.JScrollPane(); + orderBookList = new javax.swing.JTable(); + + orderBookList.setModel(new javax.swing.table.DefaultTableModel( + new Object [][] { + {"1", null, null}, + {"2", null, null}, + {"3", null, null}, + {"4", null, null}, + {"5", null, null}, + {"7", null, null}, + {"4", null, null}, + {null, null, null}, + {"3", 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, 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}, + {null, null, null}, + {null, null, null}, + {null, null, null}, + {null, null, null}, + {null, null, null} + }, + new String [] { + "id", "Title 2pri", "Title 3" + } + ) { + boolean[] canEdit = new boolean [] { + false, false, false + }; + + public boolean isCellEditable(int rowIndex, int columnIndex) { + return canEdit [columnIndex]; + } + }); + orderBookList.setDoubleBuffered(true); + orderBookList.setFocusable(false); + orderBookScroller.setViewportView(orderBookList); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(orderBookScroller, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 162, Short.MAX_VALUE) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(orderBookScroller, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + ); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JTable orderBookList; + private javax.swing.JScrollPane orderBookScroller; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/gui/OrderBookPanel.form b/src/main/java/gui/OrderBookPanel.form new file mode 100644 index 0000000..e8f99f7 --- /dev/null +++ b/src/main/java/gui/OrderBookPanel.form @@ -0,0 +1,459 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/src/main/java/gui/OrderBookPanel.java b/src/main/java/gui/OrderBookPanel.java new file mode 100644 index 0000000..da9fe9f --- /dev/null +++ b/src/main/java/gui/OrderBookPanel.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016, 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 SeSim.*; +import static java.lang.Thread.sleep; +import javax.swing.AbstractListModel; +import javax.swing.table.AbstractTableModel; +import java.util.ArrayList; +import java.util.Formatter; +import static java.lang.Thread.sleep; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class OrderBookPanel extends javax.swing.JPanel { + + sesim.Exchange se; + + public OrderBookPanel() { + this.se = MainWin.se; + + initComponents(); + + if (this.se == null) { + return; + } + // System.out.print("Order boo init\n"); + + } + + /** + * 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() { + java.awt.GridBagConstraints gridBagConstraints; + + askBook1 = new gui.AskBook(); + bidBook1 = new gui.BidBook(); + quotePanel2 = new gui.QuotePanel(); + + setPreferredSize(new java.awt.Dimension(220, 262)); + java.awt.GridBagLayout layout = new java.awt.GridBagLayout(); + layout.columnWidths = new int[] {0}; + layout.rowHeights = new int[] {0, 5, 0, 5, 0}; + setLayout(layout); + + askBook1.setPreferredSize(new java.awt.Dimension(200, 200)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(askBook1, gridBagConstraints); + + bidBook1.setPreferredSize(new java.awt.Dimension(200, 200)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 4; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + add(bidBook1, gridBagConstraints); + + quotePanel2.setOpaque(false); + quotePanel2.setPreferredSize(new java.awt.Dimension(587, 200)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 2; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 0.5; + gridBagConstraints.weighty = 0.5; + add(quotePanel2, gridBagConstraints); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private gui.AskBook askBook1; + private gui.BidBook bidBook1; + private gui.QuotePanel quotePanel2; + // End of variables declaration//GEN-END:variables +} diff --git a/src/main/java/gui/QuotePanel.form b/src/main/java/gui/QuotePanel.form new file mode 100644 index 0000000..a017eba --- /dev/null +++ b/src/main/java/gui/QuotePanel.form @@ -0,0 +1,326 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/gui/QuotePanel.java b/src/main/java/gui/QuotePanel.java new file mode 100644 index 0000000..b49b3ab --- /dev/null +++ b/src/main/java/gui/QuotePanel.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2016, 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 sesim.Quote; +import java.awt.Color; +import javax.swing.SwingUtilities; +import java.util.*; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class QuotePanel extends javax.swing.JPanel implements sesim.Exchange.QuoteReceiver{ + + /** + * Creates new form QuotePanel + */ + public QuotePanel() { + initComponents(); + if (MainWin.se==null) + return; + MainWin.se.addQuoteReceiver(this); + } + + /** + * 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() { + java.awt.GridBagConstraints gridBagConstraints; + + jLabel2 = new javax.swing.JLabel(); + lastPrice = new javax.swing.JLabel(); + jLabel3 = new javax.swing.JLabel(); + + setBorder(null); + java.awt.GridBagLayout layout = new java.awt.GridBagLayout(); + layout.columnWidths = new int[] {0, 5, 0, 5, 0}; + layout.rowHeights = new int[] {0}; + setLayout(layout); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + add(jLabel2, gridBagConstraints); + + lastPrice.setFont(lastPrice.getFont().deriveFont(lastPrice.getFont().getStyle() | java.awt.Font.BOLD, lastPrice.getFont().getSize()+4)); + lastPrice.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); + lastPrice.setText("0.00"); + lastPrice.setOpaque(true); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.weightx = 0.9; + gridBagConstraints.weighty = 0.9; + add(lastPrice, gridBagConstraints); + + jLabel3.setPreferredSize(new java.awt.Dimension(30, 18)); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 4; + gridBagConstraints.gridy = 0; + add(jLabel3, gridBagConstraints); + }// //GEN-END:initComponents + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel2; + private javax.swing.JLabel jLabel3; + private javax.swing.JLabel lastPrice; + // End of variables declaration//GEN-END:variables + + @Override + public void UpdateQuote(Quote q) { + class Updater implements Runnable { + QuotePanel qp; + String text=""; + Color color = Color.BLUE; + + + @Override + public void run() { + qp.lastPrice.setText(text); + qp.lastPrice.setForeground(color); + } + + + } + Updater u= new Updater(); + u.qp=this; + + if (q.price==q.bid){ + u.color=new Color(172,0,0); + } + if (q.price==q.ask){ + u.color=new Color(0,120,0); //.; //new Color(30,0,0); + } + + + + + u.text = String.format("%.2f\n(%d)", q.price,q.volume); + + SwingUtilities.invokeLater(u); + +// SortedSet s = MainWin.se.getQuoteHistory(5); + + // System.out.print( + // "SortedSet size:" + // +s.size() + // +"\n" + // ); + + //this.lastPrice.setText(lp); + } +} diff --git a/src/main/java/gui/test.java b/src/main/java/gui/test.java new file mode 100644 index 0000000..4d604c4 --- /dev/null +++ b/src/main/java/gui/test.java @@ -0,0 +1,115 @@ +/* + * 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; + +import java.util.*; + +/** + * + * @author tobias + */ +public class test { + + static class Problem { + + class Elem implements Comparable { + + public int id; + + public Elem(int id) { + this.id = id; + + } + + @Override + public int compareTo(Object o) { + Elem e = (Elem) o; + return id - e.id; + + } + + } + + public void run() { + SortedSet s = new TreeSet<>(); + s.add(new Elem(1)); + s.add(new Elem(7)); + s.add(new Elem(12)); + Elem e = new Elem(5); + + SortedSet ts = exclusiveTailSet(s, e); + + Elem e2 = new Elem(0); + +// SortedSet ts2 = exclusiveTailSet(ts,e); + SortedSet ts2 = ts.tailSet(e2); + + e.id = 99; + + System.out.print(String.format("First: %s\n", ts.first().id)); + } + + } + + + static class NoProblem { + public void run(){ + SortedSet s=new TreeSet<>(); + + s.add(10); + s.add(20); + s.add(30); + s.add(40); + s.add(50); + s.add(60); + + int e1 = 15; + SortedSet l1 = s.tailSet(e1); + + int e2 = -1; + + SortedSet l2 = l1.tailSet(e2); + + System.out.print("First:"+l2.first()+"\n"); + + + + } + } + + public static SortedSet exclusiveTailSet(SortedSet ts, Ta elem) { + Iterator iter = ts.tailSet(elem).iterator(); + + return ts.tailSet(iter.next()); + } + + public static void main(String args[]) { + NoProblem p = new NoProblem(); + p.run(); + + + } +} diff --git a/src/main/java/sesim/Account.java b/src/main/java/sesim/Account.java new file mode 100644 index 0000000..332c2e7 --- /dev/null +++ b/src/main/java/sesim/Account.java @@ -0,0 +1,100 @@ +package sesim; + +import java.util.*; + + +final public class Account { + + /** + * Exchange this account belongs to + */ + public Exchange se; + + /** + * Number of shares in this account + */ + public long shares = 0; + + /** + * Ammount of money in this account + */ + public double money = 0; + + /** + * Name of this account + */ + public String name = ""; + + + public ArrayList pending; + + public boolean orderpending = false; + + + public Account(Exchange se, long shares, double money ) { + this.shares=shares; + this.money=money; + this.se=se; + pending = new ArrayList<>(); + } + + public Account(){ + //this(,0.0); + } + + // private double bound_money; + + + + public void print_current() { + System.out.printf("%s shares: %d credit: %.2f\n", + name, shares, money + ); + } + + + public boolean isRuined(){ + + +/* System.out.print( + "Account: " + +money + +" / " + +shares + +"\n" + ); + */ + return this.money<=se.lastprice && this.shares<=0; + } + + public Order sell(long volume, double limit) { + SellOrder o = new SellOrder(); + o.account = this; + o.limit = limit; + o.volume = volume; + orderpending = true; + return se.SendOrder(o); + } + + public Order buy(long volume, double limit) { + if (volume * limit > money) { + return null; + } + BuyOrder o = new BuyOrder(); + o.limit = limit; + o.volume = volume; + o.account = this; + orderpending = true; + return se.SendOrder(o); + } + + /* + public void Buy(Account a, long size, double price) { + shares += size; + money -= price * size; + a.shares -= size; + a.money += price * size; + } +*/ + +} diff --git a/src/main/java/sesim/AutoTrader.java b/src/main/java/sesim/AutoTrader.java new file mode 100644 index 0000000..d98e667 --- /dev/null +++ b/src/main/java/sesim/AutoTrader.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, 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 sesim; + +import static java.lang.Thread.sleep; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public abstract class AutoTrader extends Trader implements Runnable { + + public AutoTrader(Account account, TraderConfig config) { + super(account, config); + } + + protected void doSleep(int seconds) { + try { + sleep(seconds*1000); + } catch (InterruptedException e) { + } + } + + public void start(){ + System.out.print("Starting AutoTrader\n"); + class Runner extends Thread{ + AutoTrader trader; + @Override + public void run(){ + trader.run(); + } + } + Runner r = new Runner(); + r.trader=this; + r.start(); + + } + + +} diff --git a/src/main/java/sesim/AutoTraderLIst.java b/src/main/java/sesim/AutoTraderLIst.java new file mode 100644 index 0000000..9d8f0f4 --- /dev/null +++ b/src/main/java/sesim/AutoTraderLIst.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, 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 sesim; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class AutoTraderLIst { + + public void add(int n, TraderConfig config, Exchange se, long shares, double money) { + + for (int i = 0; i < n; i++) { + AutoTrader trader = config.createTrader(se, shares, money); + // TraderRunner tr = new TraderRunner(trader); + + trader.start(); + } + } + +} diff --git a/src/main/java/sesim/BuyOrder.java b/src/main/java/sesim/BuyOrder.java new file mode 100644 index 0000000..a706ccf --- /dev/null +++ b/src/main/java/sesim/BuyOrder.java @@ -0,0 +1,9 @@ +package sesim; + +public class BuyOrder extends Order implements Comparable { + + public BuyOrder(){ + type=OrderType.bid; + } + +} diff --git a/src/main/java/sesim/Exchange.java b/src/main/java/sesim/Exchange.java new file mode 100644 index 0000000..305d125 --- /dev/null +++ b/src/main/java/sesim/Exchange.java @@ -0,0 +1,457 @@ +package sesim; + +import java.util.*; +import java.util.concurrent.*; + +import sesim.Order.OrderStatus; +import sesim.Order.OrderType; + +/** + * + * @author tube + */ +public class Exchange extends Thread { + + /** + * Histrory of quotes + */ + public TreeSet quoteHistory = new TreeSet<>(); + + /** + * Constructor + */ + public Exchange() { + this.ask = new TreeSet<>(); + this.bid = new TreeSet<>(); + this.qrlist = new ArrayList<>(); + + } + + public static long getCurrentTimeSeconds(long div) { + long ct = System.currentTimeMillis() / 1000*div; + return ct * div; + } + + public static long getCurrentTimeSeconds(){ + return getCurrentTimeSeconds(1); + } + + public SortedSet getQuoteHistory(long start) { + + Quote s = new Quote(); + s.time = start; + s.time = 2; + s.id = 2; + + TreeSet result = new TreeSet<>(); + result.addAll(this.quoteHistory.tailSet(s)); + + return result; + + } + + /* public SortedSet getQuoteHistory(int seconds) { + Quote last = quoteHistory.last(); + return this.getQuoteHistory(seconds, last.time); + } + */ + + // Class to describe an executed order + // QuoteReceiver has to be implemented by objects that wants + // to receive quote updates + public interface QuoteReceiver { + + void UpdateQuote(Quote q); + } + + /** + * Bookreceiver Interface + */ + public interface BookReceiver { + + void UpdateOrderBook(); + } + + private ArrayList ask_bookreceivers = new ArrayList<>(); + private ArrayList bid_bookreceivers = new ArrayList<>(); + + private ArrayList selectBookReceiver(OrderType t) { + switch (t) { + case ask: + return ask_bookreceivers; + case bid: + return bid_bookreceivers; + } + return null; + } + + public void addBookReceiver(OrderType t, BookReceiver br) { + ArrayList bookreceivers; + bookreceivers = selectBookReceiver(t); + bookreceivers.add(br); + } + + void updateBookReceivers(OrderType t) { + ArrayList bookreceivers; + bookreceivers = selectBookReceiver(t); + + Iterator i = bookreceivers.iterator(); + while (i.hasNext()) { + i.next().UpdateOrderBook(); + } + try { + sleep(10); + } catch (InterruptedException e) { + System.out.println("I was Interrupted"); + } + + } + + // Here we store the list of quote receivers + private final ArrayList qrlist; + + /** + * + * @param qr + */ + public void addQuoteReceiver(QuoteReceiver qr) { + qrlist.add(qr); + } + + // send updated quotes to all quote receivers + private void updateQuoteReceivers(Quote q) { + Iterator i = qrlist.iterator(); + while (i.hasNext()) { + i.next().UpdateQuote(q); + } + } + + // long time = 0; + double theprice = 12.9; + long orderid = 1; + + double lastprice = 100.0; + long lastsvolume; + + public TreeSet bid; + public TreeSet ask; + + private Locker tradelock = new Locker(); + + /* + private final Semaphore available = new Semaphore(1, true); + + private void Lock() { + try { + available.acquire(); + } catch (InterruptedException s) { + System.out.println("Interrupted\n"); + } + + } + + private void Unlock() { + available.release(); + } + */ + private TreeSet selectOrderBook(OrderType t) { + + switch (t) { + case bid: + return this.bid; + case ask: + return this.ask; + } + return null; + + } + + public ArrayList getOrderBook(OrderType t, int depth) { + + TreeSet book = selectOrderBook(t); + if (book == null) { + return null; + } + + ArrayList ret = new ArrayList<>(); + Iterator it = book.iterator(); + for (int i = 0; i < depth && it.hasNext(); i++) { + Order o; + o = it.next(); + ret.add(o); + //System.out.print("Order" + o.limit); + //System.out.println(); + } + return ret; + + } + + public void print_current() { + + Order b; + Order a; + + //String bid; + if (bid.isEmpty()) { + b = new BuyOrder(); + b.limit = -1; + b.volume = 0; + } else { + b = bid.first(); + } + + if (ask.isEmpty()) { + a = new SellOrder(); + a.limit = -1; + a.volume = 0; + + } else { + a = ask.first(); + } + + Logger.info(String.format("BID: %s(%s) LAST: %.2f(%d) ASK: %s(%s)\n", + b.format_limit(), b.format_volume(), + lastprice, lastsvolume, + a.format_limit(), a.format_volume()) + ); + + } + + public void transferMoney(Account src, Account dst, double money) { + src.money -= money; + dst.money += money; + + } + + public void cancelOrder(Order o) { + tradelock.lock(); + TreeSet book = this.selectOrderBook(o.type); + book.remove(o); + this.updateBookReceivers(o.type); + o.account.pending.remove(o); + o.status = OrderStatus.canceled; + tradelock.unlock(); + + } + + /** + * Transfer shares from one account to another account + * + * @param src source account + * @param dst destination account + * @param volumen number of shares + * @param price price + */ + protected void transferShares(Account src, Account dst, long volume, double price) { + dst.shares += volume; + src.shares -= volume; + dst.money -= price * volume; + src.money += price * volume; + } + + long nextQuoteId = 0; + + public void OrderMatching() { + + while (true) { + + if (bid.isEmpty() || ask.isEmpty()) { + // nothing to do + return; + } + + Order b = bid.first(); + Order a = ask.first(); + + if (a.volume == 0) { + // This order is fully executed, remove + a.account.orderpending = false; + a.status = OrderStatus.executed; + + a.account.pending.remove(a); + + ask.pollFirst(); + this.updateBookReceivers(OrderType.ask); + continue; + } + + if (b.volume == 0) { + // This order is fully executed, remove + b.account.orderpending = false; + b.status = OrderStatus.executed; + b.account.pending.remove(b); + bid.pollFirst(); + this.updateBookReceivers(OrderType.bid); + continue; + } + + if (b.limit < a.limit) { + // no match, nothing to do + return; + } + + if (b.limit >= a.limit) { + double price; + + if (b.id < a.id) { + price = b.limit; + } else { + price = a.limit; + } + + long volume; + + if (b.volume >= a.volume) { + volume = a.volume; + } else { + volume = b.volume; + } + + transferShares(a.account, b.account, volume, price); + + // b.account.Buy(a.account, volume, price); + b.volume -= volume; + a.volume -= volume; + + lastprice = price; + lastsvolume = volume; + + Quote q = new Quote(); + + q.volume = volume; + q.price = price; + q.time = System.currentTimeMillis(); + + q.ask = a.limit; + q.bid = b.limit; + q.id = nextQuoteId++; + + this.updateQuoteReceivers(q); + this.updateBookReceivers(OrderType.bid); + this.updateBookReceivers(OrderType.ask); + + /* System.out.print( + "Executed: " + + q.price + + " / " + + q.volume + + "\n" + ); + */ + quoteHistory.add(q); + continue; + + } + + return; + } + } + + public void ExecuteOrder(BuyOrder o) { + // SellOrder op = ask.peek(); + + } + + private boolean InitOrder(Order o) { + double moneyNeeded = o.volume * o.limit; + return true; + } + + // Add an order to the orderbook + private boolean addOrder(Order o) { + boolean ret = false; + switch (o.type) { + case bid: + +// System.out.print("Exchange adding bid order \n"); + ret = bid.add(o); + break; + + case ask: +// System.out.print("Exchange adding ask order \n"); + ret = ask.add(o); + break; + } + + if (ret) { + this.updateBookReceivers(o.type); + } + return ret; + } + + public Order SendOrder(Order o) { + + boolean rc = InitOrder(o); + if (!rc) { + return null; + } + + tradelock.lock(); + o.timestamp = System.currentTimeMillis(); + o.id = orderid++; + addOrder(o); + o.account.pending.add(o); + OrderMatching(); + tradelock.unlock(); + + return o; + } + + /* + public void SendOrder(BuyOrder o) { + //System.out.println("EX Buyorder"); + Lock(); + o.timestamp = System.currentTimeMillis(); + o.id = orderid++; + bid.add(o); + + Unlock(); + Lock(); +// OrderMatching(); + Unlock(); + + } + */ + /* + * public void SendOrder(Order o){ + * + * + * if ( o.getClass() == BuyOrder.class){ bid.add((BuyOrder)o); } + * + * if ( o.getClass() == SellOrder.class){ ask.add((SellOrder)o); } + * + * } + */ + public double getlastprice() { + /* + * SellOrder so = new SellOrder(); so.limit=1000.0; so.volume=500; + * SendOrder(so); + * + * BuyOrder bo = new BuyOrder(); bo.limit=1001.0; bo.volume=300; + * SendOrder(bo); + */ + + return lastprice; + } + + /* public double sendOrder(Account o) { + return 0.7; + } + */ + /** + * + */ + @Override + public void run() { + while (true) { + try { + sleep(1500); + } catch (InterruptedException e) { + System.out.println("I was Interrupted"); + } + print_current(); + + } + } + +} diff --git a/src/main/java/sesim/Locker.java b/src/main/java/sesim/Locker.java new file mode 100644 index 0000000..6cd2a83 --- /dev/null +++ b/src/main/java/sesim/Locker.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016, 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 sesim; + +import java.util.concurrent.Semaphore; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class Locker { + + private final Semaphore avail = new Semaphore(1, true); + + public boolean lock() { + try { + avail.acquire(); + } catch (InterruptedException e) { + return false; + } + return true; + } + + public void unlock() { + avail.release(); + } + +} diff --git a/src/main/java/sesim/Logger.java b/src/main/java/sesim/Logger.java new file mode 100644 index 0000000..ad0beae --- /dev/null +++ b/src/main/java/sesim/Logger.java @@ -0,0 +1,23 @@ +package sesim; + +public class Logger { + + static boolean dbg = true; + static boolean info = true; + + static void dbg(String s) { + if (!dbg) { + return; + } + System.out.print("DBG: "); + System.out.println(s); + } + + static void info(String s) { + if (!info) { + return; + } + System.out.print("INFO: "); + System.out.println(s); + } +} diff --git a/src/main/java/sesim/Order.java b/src/main/java/sesim/Order.java new file mode 100644 index 0000000..ffed02a --- /dev/null +++ b/src/main/java/sesim/Order.java @@ -0,0 +1,110 @@ +package sesim; + +public abstract class Order implements Comparable { + + /** + * When the order was created + */ + public long timestamp = 0; + + /** + * Number of shares + */ + public long volume; + + /** + * Limit price + */ + public double limit; + + /** + * Order ID + */ + public long id = 0; + + /** + * Type of order + */ + public OrderType type; + + public Account account = null; + + + protected int compareLimit(Order o){ + int r=0; + if (o.limit < limit) { + r=-1; + } + if (o.limit > limit) { + r=1; + } + + if (type==OrderType.ask) + return -r; + + return r; + + }; + + @Override + public int compareTo(Order o) { + + if (o.type!=type){ + System.out.print("OrderType Missmatch\n"); + return -1; + } + + int r = compareLimit(o); + if (r!=0) + return r; + + /* if (o.timestamp> timestamp) + return -1; + + if (o.timestampid) + return -1; + + if (o.id + * 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 sesim; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class Quote implements Comparable { + + public double bid; + public double bid_volume; + public double ask; + public double ask_volume; + + public double price; + public long volume; + public long time; + + Locker lock = new Locker(); + + public void print() { + System.out.print("Quote (" + + time + + ") :" + + price + + " / " + + volume + + "\n" + ); + + } + + public long id; + + @Override + public int compareTo(Object o) { + int ret; + Quote q = (Quote)o; + + ret = (int)(this.time-q.time); + if (ret !=0) + return ret; + + return (int)(this.id-q.id); + } + + /* Quote (){ + lock.lock(); + id=nextid++; + lock.unlock(); + }*/ +} diff --git a/src/main/java/sesim/SellOrder.java b/src/main/java/sesim/SellOrder.java new file mode 100644 index 0000000..e6a9c29 --- /dev/null +++ b/src/main/java/sesim/SellOrder.java @@ -0,0 +1,8 @@ +package sesim; + +public class SellOrder extends Order { + + public SellOrder(){ + type=OrderType.ask; + } +} diff --git a/src/main/java/sesim/Trader.java b/src/main/java/sesim/Trader.java new file mode 100644 index 0000000..9816941 --- /dev/null +++ b/src/main/java/sesim/Trader.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016, 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 sesim; + +import static java.lang.Thread.sleep; + +public abstract class Trader { + + public String name = null; + + + public Account account; + public TraderConfig config; + + public void sell(long shares, double limit){ + account.sell(shares, limit); + } + + public void buy(long shares, double limit){ + account.buy(shares, limit); + } + + /** + * Construct a Trader object + * @param account Account for this trader + * @param config Configration for this trader + */ + public Trader(Account account, TraderConfig config){ + this.account=account; + this.config=config; + } + + /** + * Construct a Trader object w/o config + * The Trader object shoul initialize a default config + * @param account + */ + public Trader(Account account){ + this(account,null); + } + + + + + +}; diff --git a/src/main/java/sesim/TraderConfig.java b/src/main/java/sesim/TraderConfig.java new file mode 100644 index 0000000..a63aae9 --- /dev/null +++ b/src/main/java/sesim/TraderConfig.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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 sesim; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public abstract class TraderConfig{ + String name; + + public abstract AutoTrader createTrader(Exchange se, long shares, double money); +} diff --git a/src/main/java/traders/ManTrader.java b/src/main/java/traders/ManTrader.java new file mode 100644 index 0000000..3113e77 --- /dev/null +++ b/src/main/java/traders/ManTrader.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, 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 traders; + +import sesim.Account; +import sesim.Trader; +import sesim.TraderConfig; +import sesim.BuyOrder; + + + + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class ManTrader extends Trader{ + + public ManTrader(Account account,TraderConfig config) { + super(account,config); + } + + + + + public void trade(){ + + BuyOrder o = new BuyOrder(); + + } + +} diff --git a/src/main/java/traders/RandomTrader.java b/src/main/java/traders/RandomTrader.java new file mode 100644 index 0000000..7db13f8 --- /dev/null +++ b/src/main/java/traders/RandomTrader.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2016, 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 traders; + +import sesim.Account; +import sesim.Order; +import java.util.Random; +import sesim.AutoTrader; +import sesim.TraderConfig; + +public class RandomTrader extends AutoTrader { + + protected enum Action { + sell,buy + } + + // config for this trader + final private RandomTraderConfig myconfig; + + // object to generate random numbers + final private Random rand = new Random(); + + public RandomTrader(Account account, TraderConfig config) { + super(account, config); + if (config == null) { + config = new RandomTraderConfig(); + } + myconfig = (RandomTraderConfig) config; + } + + /** + * Get a (long) random number between min an max + * + * @param min minimum value + * @param max maximeum value + * @return the number + */ + protected double getRandom(double min, double max) { + double r = rand.nextDouble(); + return (max - min) * r + min; + } + + protected int getRandom(int[] minmax) { + return (int) Math.round(getRandom(minmax[0], minmax[1])); + } + + /** + * + * @param val + * @param minmax + * @return + */ + protected double getRandomAmmount(double val, float[] minmax) { + double min = val * minmax[0] / 100.0; + double max = val * minmax[1] / 100.0; + return getRandom(min, max); + } + + public boolean waitForOrder(long seconds) { + + for (int i = 0; (i < seconds) && (0 != account.pending.size()); i++) { + doSleep(1); + } + + if (account.pending.size() != 0) { + Order o = account.pending.get(0); + account.se.cancelOrder(o); + return false; + } + return true; + } + + public boolean doBuy() { + + double money = getRandomAmmount(account.money, myconfig.sell_volume); + + double lp = account.se.getlastprice(); + double limit; + limit = lp + getRandomAmmount(lp, myconfig.buy_limit); + + long volume = (int) (money / (limit * 1)); + if (volume <= 0) { + return false; + } + + buy(volume, limit); + return waitForOrder(getRandom(myconfig.buy_order_wait)); + + } + + public boolean doSell() { + + long volume; + volume = (long) Math.round(getRandomAmmount(account.shares, myconfig.sell_volume)); + + double lp = account.se.getlastprice(); + double limit; + limit = lp + getRandomAmmount(lp, myconfig.sell_limit); + + sell(volume, limit); + return waitForOrder(getRandom(myconfig.sell_order_wait)); + + } + + /* private boolean monitorTrades() { + + int numpending = account.pending.size(); + if (numpending == 0) { +// System.out.print("RT: pending = 0 - return false\n"); + return false; + } + + Order o = account.pending.get(0); + long age = o.getAge(); + + // System.out.print("RT: age is: "+age+"\n"); + if (age > myconfig.maxage) { + // System.out.print("MaxAge is"+myconfig.maxage+"\n"); + account.se.cancelOrder(o); +// System.out.print("Age reached - canel return false\n"); + return false; + } + + //System.out.print("RT: monitor return true\n"); + return true; + } + */ + public void trade() { + + float am[] = {-10, 200}; + + double x = Math.round(this.getRandomAmmount(1000, am)); + /* System.out.print( + "Random:" + + x + + "\n" + ); + + */ + /* + // System.out.print("RT: Now trading\n"); + if (monitorTrades()) { + return; + } + + // What next to do? + int action = rand.nextInt(5); + + if (account.money < 10 && account.shares < 5) { + System.out.print("I'm almost ruined\n"); + } + + if (action == 1) { + doBuy(); + return; + } + + if (action == 2) { + doSell(); + return; + } + */ + } + + protected Action getAction() { + if (rand.nextInt(2)==0){ + return Action.buy; + } + else{ + return Action.sell; + } + + + } + + @Override + public void run() { + System.out.print("Starting Random Trader\n"); + while (true) { + +// What next to do? + Action action = getAction(); + + if (account.isRuined()) { +// System.out.print("I'm ruined\n"); +// System.exit(0); + } + boolean rc; + // action=1; + switch (action) { + + case sell: + if (account.shares <= 0) { + // we have no shares + continue; + } +// System.out.print("Sell\n"); + rc = doSell(); + if (!rc) { + continue; + } +// System.out.print("Sold\n"); + doSleep(getRandom(myconfig.wait_after_sell)); +// System.out.print("Next\n"); + break; + case buy: + if (account.money <= 0) { + // we have no money + continue; + } +// System.out.print("Sell\n"); + rc = doBuy(); + if (!rc) { + continue; + } +// System.out.print("Bought\n"); + doSleep(getRandom(myconfig.wait_after_buy)); +// System.out.print("Next\n"); + break; + + } + // doSleep(1); + + } + + } + +} diff --git a/src/main/java/traders/RandomTraderConfig.java b/src/main/java/traders/RandomTraderConfig.java new file mode 100644 index 0000000..d582ecc --- /dev/null +++ b/src/main/java/traders/RandomTraderConfig.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016, 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 traders; + +import sesim.Account; +import sesim.TraderConfig; +import sesim.Exchange; +import sesim.AutoTrader; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class RandomTraderConfig extends TraderConfig { + + //public long maxage = 1000 * 10 * 1; + + + /*public long hold_shares_min = 10; + + public long hold_shares_max = 30; + + public float buy_volume_min = 10; + */ + + /** + * If shares are selled, this specifies + * the minimum and maximum volume to be selled + */ + public float[] sell_volume= {100,100}; + public float[] sell_limit = {-15,15}; + public int[] sell_order_wait = {15,33}; + public int[] wait_after_sell = {10,30}; + + + public float[] buy_volume={100,100}; + public float[] buy_limit = {-15,15}; + public int[] buy_order_wait = {15,33}; + public int[] wait_after_buy = {10,30}; + + + @Override + public AutoTrader createTrader(Exchange se, long shares, double money) { + Account a = new Account(se, shares, money); + return new RandomTrader(a, this); + } + + + +} diff --git a/src/main/java/traders/SwitchingTrader.java b/src/main/java/traders/SwitchingTrader.java new file mode 100644 index 0000000..2417734 --- /dev/null +++ b/src/main/java/traders/SwitchingTrader.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016, 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 traders; + +import sesim.Account; +import sesim.TraderConfig; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class SwitchingTrader extends RandomTrader{ + + + private Action mode; + + public SwitchingTrader(Account account, TraderConfig config) { + + super(account, config); + System.out.print("SWTrader Created\n"); + + if (account.shares>0) + mode=Action.sell; + else + mode=Action.buy; + printstartus(); + + } + + + private void printstartus(){ + + System.out.print("SWTrader:"); + switch (mode){ + case buy: + System.out.print("buy" + +account.shares + +" " + +account.money + ); + break; + case sell: + System.out.print("sell" + +account.shares + +" " + +account.money + ); + break; + + + } + System.out.print("\n"); + + } + + @Override + protected Action getAction(){ + + + + + if ( (account.shares>0) && (mode==Action.sell)){ + printstartus(); + return mode; + } + if ( (account.shares<=0 && mode==Action.sell)){ + mode=Action.buy; + printstartus(); + return mode; + } + if (account.money>100.0 && mode==Action.buy){ + printstartus(); + return mode; + } + if (account.money<=100.0 && mode==Action.buy){ + mode=Action.sell; + printstartus(); + return mode; + } + printstartus(); + return mode; + } + +} diff --git a/src/main/java/traders/SwitchingTraderConfig.java b/src/main/java/traders/SwitchingTraderConfig.java new file mode 100644 index 0000000..ac82ddc --- /dev/null +++ b/src/main/java/traders/SwitchingTraderConfig.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, 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 traders; + +import sesim.Account; +import sesim.AutoTrader; +import sesim.Exchange; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class SwitchingTraderConfig extends RandomTraderConfig { + + @Override + public AutoTrader createTrader(Exchange se, long shares, double money) { + Account a = new Account(se, shares, money); + System.out.print("Returning a new sw trader\n"); + return new SwitchingTrader(a, this); + } + + public SwitchingTraderConfig() { + + sell_volume = new float[]{100, 100}; + sell_limit = new float[]{-30, 1}; + sell_order_wait = new int[]{1, 5}; + wait_after_sell = new int[]{1, 5}; + + buy_volume = new float[]{100, 100}; + buy_limit = new float[]{-1, 30}; + buy_order_wait = new int[]{1, 5}; + wait_after_buy = new int[]{1, 5}; + } +}