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};
+ }
+}