new oder book and order execution system

This commit is contained in:
7u83 2017-01-10 19:27:11 +01:00
parent c556e5a970
commit 14061a2d21
10 changed files with 204 additions and 134 deletions

View File

@ -171,7 +171,7 @@ public class Chart extends javax.swing.JPanel implements QuoteReceiver {
@Override @Override
public void UpdateQuote(Quote q) { public void UpdateQuote(Quote q) {
// System.out.print("Quote Received\n"); // System.out.print("Quote Received\n");
this.realTimeAdd(q.time, (float) q.price, q.volume); this.realTimeAdd(q.time, (float) q.price, (float)q.volume);
// this.invalidate(); // this.invalidate();
this.repaint(); this.repaint();
} }

View File

@ -27,6 +27,7 @@ package gui;
import sesim.Order_old.*; import sesim.Order_old.*;
import java.util.ArrayList; import java.util.ArrayList;
import sesim.Exchange.*;
/** /**
* *
@ -36,7 +37,7 @@ public class AskBook extends OrderBook {
@Override @Override
ArrayList getOrderBook() { ArrayList getOrderBook() {
return MainWin.se.getOrderBook(OrderType_old.ask,40); return MainWin.se.getOrderBook(OrderType.ASK,40);
} }
@Override @Override
@ -48,7 +49,7 @@ public class AskBook extends OrderBook {
if (MainWin.se == null) { if (MainWin.se == null) {
return; return;
} }
MainWin.se.addBookReceiver(OrderType_old.ask, this); MainWin.se.addBookReceiver(OrderType.ASK, this);
} }

View File

@ -27,6 +27,7 @@ package gui;
import sesim.Order_old.*; import sesim.Order_old.*;
import java.util.ArrayList; import java.util.ArrayList;
import sesim.Exchange.*;
/** /**
* *
@ -36,13 +37,13 @@ public class BidBook extends OrderBook {
@Override @Override
ArrayList getOrderBook() { ArrayList getOrderBook() {
return MainWin.se.getOrderBook(OrderType_old.bid, 40); return MainWin.se.getOrderBook(OrderType.BID, 40);
} }
public BidBook() { public BidBook() {
if (MainWin.se == null) { if (MainWin.se == null) {
return; return;
} }
MainWin.se.addBookReceiver(OrderType_old.bid, this); MainWin.se.addBookReceiver(OrderType.BID, this);
} }
} }

View File

@ -33,6 +33,7 @@ import sesim.Exchange;
import sesim.BuyOrder; import sesim.BuyOrder;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.*; import javax.swing.*;
import sesim.AccountData;
/** /**
@ -52,6 +53,30 @@ public class MainWin extends javax.swing.JFrame {
initComponents(); initComponents();
double aid1 = se.createAccount(100, 100);
double aid2 = se.createAccount(100, 100);
AccountData a1 = se.getAccountData(aid1);
AccountData a2 = se.getAccountData(aid2);
se.createOrder(aid2, Exchange.OrderType.ASK, 20, 11);
se.createOrder(aid2, Exchange.OrderType.ASK, 10, 10);
se.createOrder(aid2, Exchange.OrderType.ASK, 10, 9);
se.createOrder(aid1, Exchange.OrderType.BID, 50, 7);
/*
System.out.print("Exec Orders\n");
se.executeOrders();
System.out.print("Executed Orders\n");
a1 = se.getAccountData(aid1);
a2 = se.getAccountData(aid2);
*/
/*
AutoTraderLIst at = new AutoTraderLIst(); AutoTraderLIst at = new AutoTraderLIst();
// RandomTraderConfig rcfg = new RandomTraderConfig(); // RandomTraderConfig rcfg = new RandomTraderConfig();
SwitchingTraderConfig rcfg = new SwitchingTraderConfig(); SwitchingTraderConfig rcfg = new SwitchingTraderConfig();
@ -61,6 +86,7 @@ public class MainWin extends javax.swing.JFrame {
SwitchingTraderConfig scfg = new SwitchingTraderConfig(); SwitchingTraderConfig scfg = new SwitchingTraderConfig();
at.add(1, scfg, se, 1000000, 0); at.add(1, scfg, se, 1000000, 0);
*/
} }

View File

@ -26,6 +26,7 @@
package gui; package gui;
import sesim.Exchange; import sesim.Exchange;
import sesim.Exchange.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Formatter; import java.util.Formatter;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
@ -96,7 +97,7 @@ public abstract class OrderBook extends javax.swing.JPanel implements Exchange.B
protected class OrderBookListModel extends AbstractTableModel { protected class OrderBookListModel extends AbstractTableModel {
private ArrayList list; private ArrayList <OrderBookItem> list;
//private final boolean desc = false; //private final boolean desc = false;
public OrderBookListModel() { public OrderBookListModel() {
@ -113,7 +114,7 @@ public abstract class OrderBook extends javax.swing.JPanel implements Exchange.B
this.fireTableDataChanged(); this.fireTableDataChanged();
this.update_calls++; this.update_calls++;
int hc = this.hashCode(); // int hc = this.hashCode();
//System.out.print("Update/ColCalls = " + update_calls + "/" + colcount_calls + " HC: " + hc + "\n"); //System.out.print("Update/ColCalls = " + update_calls + "/" + colcount_calls + " HC: " + hc + "\n");
} }
@ -145,15 +146,15 @@ public abstract class OrderBook extends javax.swing.JPanel implements Exchange.B
@Override @Override
public Object getValueAt(int r, int c) { public Object getValueAt(int r, int c) {
sesim.Order_old o; OrderBookItem o;
int s = list.size(); int s = list.size();
//System.out.print("Looking for Value at" + r + ":" + c + " w size:" + s + "\n"); //System.out.print("Looking for Value at" + r + ":" + c + " w size:" + s + "\n");
if (!getDesc()) { if (!getDesc()) {
o = (sesim.Order_old) list.get(r); o = list.get(r);
} else { } else {
o = (sesim.Order_old) list.get(list.size() - r - 1); o = list.get(list.size() - r - 1);
} }
Formatter f = new Formatter(); Formatter f = new Formatter();
switch (c) { switch (c) {

View File

@ -23,7 +23,8 @@ public class Exchange extends Thread {
protected double id; protected double id;
protected double shares; protected double shares;
protected double money; protected double money;
protected HashMap <Long,Order> orders;
protected HashMap<Long, Order> orders;
@Override @Override
public int compareTo(Object a) { public int compareTo(Object a) {
@ -34,6 +35,8 @@ public class Exchange extends Thread {
Account(double money, double shares) { Account(double money, double shares) {
id = (Math.random() + (account_id.getNext())); id = (Math.random() + (account_id.getNext()));
orders = new HashMap(); orders = new HashMap();
this.money = money;
this.shares = shares;
} }
} }
@ -93,9 +96,9 @@ public class Exchange extends Thread {
long created; long created;
Account account; Account account;
Order(Account account,OrderType type, double volume, double limit) { Order(Account account, OrderType type, double volume, double limit) {
id = order_id.getNext(); id = order_id.getNext();
this.account=account; this.account = account;
this.type = type; this.type = type;
this.limit = limit; this.limit = limit;
this.volume = volume; this.volume = volume;
@ -124,8 +127,6 @@ public class Exchange extends Thread {
} }
class BidBook extends TreeSet { class BidBook extends TreeSet {
TreeSet t = new TreeSet(); TreeSet t = new TreeSet();
@ -182,23 +183,23 @@ public class Exchange extends Thread {
final private ArrayList<BookReceiver> ask_bookreceivers = new ArrayList<>(); final private ArrayList<BookReceiver> ask_bookreceivers = new ArrayList<>();
final private ArrayList<BookReceiver> bid_bookreceivers = new ArrayList<>(); final private ArrayList<BookReceiver> bid_bookreceivers = new ArrayList<>();
private ArrayList<BookReceiver> selectBookReceiver(OrderType_old t) { private ArrayList<BookReceiver> selectBookReceiver(OrderType t) {
switch (t) { switch (t) {
case ask: case ASK:
return ask_bookreceivers; return ask_bookreceivers;
case bid: case BID:
return bid_bookreceivers; return bid_bookreceivers;
} }
return null; return null;
} }
public void addBookReceiver(OrderType_old t, BookReceiver br) { public void addBookReceiver(OrderType t, BookReceiver br) {
ArrayList<BookReceiver> bookreceivers; ArrayList<BookReceiver> bookreceivers;
bookreceivers = selectBookReceiver(t); bookreceivers = selectBookReceiver(t);
bookreceivers.add(br); bookreceivers.add(br);
} }
void updateBookReceivers(OrderType_old t) { void updateBookReceivers(OrderType t) {
ArrayList<BookReceiver> bookreceivers; ArrayList<BookReceiver> bookreceivers;
bookreceivers = selectBookReceiver(t); bookreceivers = selectBookReceiver(t);
@ -273,19 +274,32 @@ public class Exchange extends Thread {
} }
public ArrayList<Order_old> getOrderBook(OrderType_old t, int depth) { public class OrderBookItem {
public long id;
public double limit;
public double volume;
}
TreeSet<Order_old> book = selectOrderBook(t); public ArrayList<OrderBookItem> getOrderBook(OrderType type, int depth) {
TreeSet<Order> book = order_books.get(type);
if (book == null) { if (book == null) {
return null; return null;
} }
ArrayList<Order_old> ret = new ArrayList<>(); ArrayList<OrderBookItem> ret = new ArrayList<>();
Iterator<Order_old> it = book.iterator();
Iterator<Order> it = book.iterator();
for (int i = 0; i < depth && it.hasNext(); i++) { for (int i = 0; i < depth && it.hasNext(); i++) {
Order_old o;
o = it.next(); Order o = it.next();
ret.add(o); OrderBookItem n = new OrderBookItem();
n.id=o.id;
n.limit=o.limit;
n.volume=o.volume;
ret.add(n);
//System.out.print("Order_old" + o.limit); //System.out.print("Order_old" + o.limit);
//System.out.println(); //System.out.println();
} }
@ -345,15 +359,14 @@ public class Exchange extends Thread {
tradelock.lock(); tradelock.lock();
TreeSet<Order_old> book = this.selectOrderBook(o.type); TreeSet<Order_old> book = this.selectOrderBook(o.type);
book.remove(o); book.remove(o);
this.updateBookReceivers(o.type); /* this.updateBookReceivers(o.type);
o.account.pending.remove(o); o.account.pending.remove(o);
o.status = OrderStatus.canceled; o.status = OrderStatus.canceled;
tradelock.unlock(); tradelock.unlock();
*/
} }
/** /**
* Transfer shares from one account to another account * Transfer shares from one account to another account
* *
@ -371,13 +384,25 @@ public class Exchange extends Thread {
long nextQuoteId = 0; long nextQuoteId = 0;
private void removeOrderIfExecuted(Order o) {
if (o.volume != 0) {
return;
}
o.account.orders.remove(o.id);
order_books.get(o.type).pollFirst();
}
/** /**
* *
*/ */
public void executeOrders() { public void executeOrders() {
TreeSet <Order> bid=order_books.get(OrderType.BID); TreeSet<Order> bid = order_books.get(OrderType.BID);
TreeSet <Order> ask=order_books.get(OrderType.ASK); TreeSet<Order> ask = order_books.get(OrderType.ASK);
double volume_total=0;
double money_total=0;
while (!bid.isEmpty() && !ask.isEmpty()) { while (!bid.isEmpty() && !ask.isEmpty()) {
@ -394,82 +419,29 @@ public class Exchange extends Thread {
double price = b.id < a.id ? b.limit : a.limit; double price = b.id < a.id ? b.limit : a.limit;
double volume = b.volume >= a.volume ? a.volume : b.volume; double volume = b.volume >= a.volume ? a.volume : b.volume;
// Transfer money and shares
transferMoneyAndShares(b.account, a.account, volume * price, -volume); transferMoneyAndShares(b.account, a.account, volume * price, -volume);
System.out.print(price+","+volume); // Update volume
System.exit(0);
/* 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_old.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_old.bid);
continue;
}
*/
if (b.limit >= a.limit) {
price = b.id < a.id ? b.limit : a.limit;
/* if (b.id < a.id) {
price = b.limit;
} else {
price = a.limit;
}
*/
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; b.volume -= volume;
a.volume -= volume; a.volume -= volume;
lastprice = price; volume_total+=volume;
// lastsvolume = volume; money_total+=price*volume;
removeOrderIfExecuted(a);
removeOrderIfExecuted(b);
}
Quote q = new Quote(); Quote q = new Quote();
q.price=money_total/volume_total;
q.volume=volume_total;
q.time=System.currentTimeMillis();
// q.volume = volume; System.out.print("Price" + q.price + "," + q.volume + "\n");
q.price = price;
q.time = System.currentTimeMillis();
q.ask = a.limit;
q.bid = b.limit;
q.id = nextQuoteId++;
this.updateQuoteReceivers(q);
this.updateBookReceivers(OrderType_old.bid);
this.updateBookReceivers(OrderType_old.ask);
quoteHistory.add(q);
continue;
}
return;
}
} }
private void executeOrders_old() { private void executeOrders_old() {
@ -492,7 +464,7 @@ public class Exchange extends Thread {
a.account.pending.remove(a); a.account.pending.remove(a);
ask.pollFirst(); ask.pollFirst();
this.updateBookReceivers(OrderType_old.ask); // this.updateBookReceivers(OrderType_old.ask);
continue; continue;
} }
@ -502,7 +474,7 @@ public class Exchange extends Thread {
b.status = OrderStatus.executed; b.status = OrderStatus.executed;
b.account.pending.remove(b); b.account.pending.remove(b);
bid.pollFirst(); bid.pollFirst();
this.updateBookReceivers(OrderType_old.bid); // this.updateBookReceivers(OrderType_old.bid);
continue; continue;
} }
@ -545,8 +517,8 @@ public class Exchange extends Thread {
q.id = nextQuoteId++; q.id = nextQuoteId++;
this.updateQuoteReceivers(q); this.updateQuoteReceivers(q);
this.updateBookReceivers(OrderType_old.bid); // this.updateBookReceivers(OrderType_old.bid);
this.updateBookReceivers(OrderType_old.ask); // this.updateBookReceivers(OrderType_old.ask);
/* System.out.print( /* System.out.print(
"Executed: " "Executed: "
@ -592,7 +564,7 @@ public class Exchange extends Thread {
} }
if (ret) { if (ret) {
this.updateBookReceivers(o.type); // this.updateBookReceivers(o.type);
} }
return ret; return ret;
} }
@ -615,8 +587,7 @@ public class Exchange extends Thread {
return o; return o;
} }
private void addOrderToBook(Order o) {
private void addOrderToBook(Order o){
order_books.get(o.type).add(o); order_books.get(o.type).add(o);
} }
@ -636,14 +607,50 @@ public class Exchange extends Thread {
return -1; return -1;
} }
Order o = new Order(a,type, volume, limit); Order o = new Order(a, type, volume, limit);
addOrderToBook(o); addOrderToBook(o);
a.orders.put(o.id,o); a.orders.put(o.id, o);
this.executeOrders();
this.updateBookReceivers(type);
return o.id; return o.id;
} }
public AccountData getAccountData(double account_id) {
Account a = accounts.get(account_id);
if (a == null) {
return null;
}
AccountData ad = new AccountData();
ad.id = account_id;
ad.money = a.money;
ad.shares = a.shares;
return ad;
}
public ArrayList <OrderData> getOpenOrders(double account_id){
Account a = accounts.get(account_id);
if (a==null)
return null;
ArrayList <OrderData>al = new ArrayList();
Iterator it = a.orders.entrySet().iterator();
while (it.hasNext()){
Order o = (Order)it.next();
OrderData od = new OrderData();
od.limit=o.limit;
od.volume=o.initial_volume;
od.executed=o.initial_volume-o.volume;
od.id=o.id;
al.add(od);
}
return al;
}
/* /*

View File

@ -33,11 +33,15 @@ import java.util.concurrent.Semaphore;
*/ */
public class Locker { public class Locker {
private final Semaphore avail = new Semaphore(1, true); private final Semaphore AVAIL = new Semaphore(1, true);
/**
*
* @return
*/
public boolean lock() { public boolean lock() {
try { try {
avail.acquire(); AVAIL.acquire();
} catch (InterruptedException e) { } catch (InterruptedException e) {
return false; return false;
} }
@ -45,7 +49,7 @@ public class Locker {
} }
public void unlock() { public void unlock() {
avail.release(); AVAIL.release();
} }
} }

View File

@ -30,5 +30,9 @@ package sesim;
* @author 7u83 <7u83@mail.ru> * @author 7u83 <7u83@mail.ru>
*/ */
public class OrderData { public class OrderData {
long id;
double limit;
double volume;
double executed;
} }

View File

@ -37,7 +37,7 @@ public class Quote implements Comparable {
public double ask_volume; public double ask_volume;
public double price; public double price;
public long volume; public double volume;
public long time; public long time;
Locker lock = new Locker(); Locker lock = new Locker();

View File

@ -30,26 +30,52 @@ package sesim;
* @author tobias * @author tobias
*/ */
public class Test { public class Test {
static void print_account(AccountData ad) {
System.out.print(
"Account ID:"
+ ad.id
+ " Ballance:"
+ ad.money
+ " Shares:"
+ ad.shares
+ "\n"
);
}
/** /**
* @param args the command line arguments * @param args the command line arguments
*/ */
public static void main(String[] args) { public static void main(String[] args) {
Exchange se = new Exchange(); Exchange se = new Exchange();
double aid1 = se.createAccount(100, 110); double aid1 = se.createAccount(100, 100);
double aid2 = se.createAccount(100, 100);
AccountData a1 = se.getAccountData(aid1);
AccountData a2 = se.getAccountData(aid2);
Test.print_account(a1);
Test.print_account(a2);
double aid2 = se.createAccount(100, 110); se.createOrder(aid2, Exchange.OrderType.ASK, 20, 11);
se.createOrder(aid2, Exchange.OrderType.ASK, 50, 9); se.createOrder(aid2, Exchange.OrderType.ASK, 10, 10);
se.createOrder(aid2, Exchange.OrderType.ASK, 10, 9);
se.createOrder(aid1, Exchange.OrderType.BID, 50, 11); se.createOrder(aid1, Exchange.OrderType.BID, 50, 11);
System.out.print("Exec Orders\n");
se.executeOrders(); se.executeOrders();
System.out.print("Executed Orders\n");
a1 = se.getAccountData(aid1);
a2 = se.getAccountData(aid2);
Test.print_account(a1);
Test.print_account(a2);
//S/ystem.out.print(aid); //S/ystem.out.print(aid);
//System.out.print("\n"); //System.out.print("\n");
} }
} }