Some testing...
This commit is contained in:
61
src/SeSim/Account.java
Normal file
61
src/SeSim/Account.java
Normal file
@ -0,0 +1,61 @@
|
||||
package SeSim;
|
||||
|
||||
public class Account {
|
||||
|
||||
/**
|
||||
* Number of shares in this account
|
||||
*/
|
||||
public long shares = 0;
|
||||
|
||||
/**
|
||||
* Ammount of money in this account
|
||||
*/
|
||||
public double money = 0;
|
||||
|
||||
public String name = "";
|
||||
|
||||
public boolean orderpending = false;
|
||||
|
||||
private double bound_money;
|
||||
|
||||
public void print_current() {
|
||||
System.out.printf("%s shares: %d credit: %.2f\n",
|
||||
name, shares, money
|
||||
);
|
||||
}
|
||||
|
||||
public SellOrder Sell(long size, double limit, Exchange ex) {
|
||||
SellOrder o = new SellOrder();
|
||||
o.account = this;
|
||||
o.limit = limit;
|
||||
o.size = size;
|
||||
|
||||
orderpending = true;
|
||||
ex.SendOrder(o);
|
||||
return o;
|
||||
|
||||
}
|
||||
|
||||
public BuyOrder Buy(long size, double limit, Exchange ex) {
|
||||
if (size * limit > money) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BuyOrder o = new BuyOrder();
|
||||
o.limit = limit;
|
||||
o.size = size;
|
||||
o.account = this;
|
||||
orderpending = true;
|
||||
ex.SendOrder(o);
|
||||
return o;
|
||||
|
||||
}
|
||||
|
||||
public void Buy(Account a, long size, double price) {
|
||||
shares += size;
|
||||
money -= price * size;
|
||||
a.shares -= size;
|
||||
a.money += price * size;
|
||||
}
|
||||
|
||||
}
|
19
src/SeSim/BuyOrder.java
Normal file
19
src/SeSim/BuyOrder.java
Normal file
@ -0,0 +1,19 @@
|
||||
package SeSim;
|
||||
|
||||
public class BuyOrder extends Order implements Comparable<Order> {
|
||||
|
||||
@Override
|
||||
public int compareTo(Order o) {
|
||||
|
||||
if (o.limit < limit) {
|
||||
//System.out.println("return 1");
|
||||
return -1;
|
||||
}
|
||||
if (o.limit > limit) {
|
||||
//System.out.println("return -1");
|
||||
return +1;
|
||||
}
|
||||
// System.out.println("0000000000000000000000");
|
||||
return 0;
|
||||
}
|
||||
}
|
262
src/SeSim/Exchange.java
Normal file
262
src/SeSim/Exchange.java
Normal file
@ -0,0 +1,262 @@
|
||||
package SeSim;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import SeSim.Order.OrderStatus;
|
||||
|
||||
public class Exchange extends Thread {
|
||||
|
||||
// Class to describe an executed order
|
||||
public class Quote {
|
||||
|
||||
double bid;
|
||||
double bid_size;
|
||||
double ask;
|
||||
double ask_size;
|
||||
|
||||
public double price;
|
||||
public long size;
|
||||
public long time;
|
||||
}
|
||||
|
||||
// QuoteReceiver has to be implemented by objects that wants
|
||||
// to receive quote updates
|
||||
public interface QuoteReceiver {
|
||||
|
||||
void UpdateQuote(Quote q);
|
||||
}
|
||||
|
||||
// Here we store the list of quote receivers
|
||||
TreeSet<QuoteReceiver> qrlist = new TreeSet();
|
||||
|
||||
public void AddQuoteReceiver(QuoteReceiver qr) {
|
||||
qrlist.add(qr);
|
||||
}
|
||||
|
||||
// send updated quotes to all quote receivers
|
||||
void UpdateQuoteReceivers(Quote q) {
|
||||
Iterator<QuoteReceiver> i = qrlist.iterator();
|
||||
while (i.hasNext()) {
|
||||
i.next().UpdateQuote(q);
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Quote> quoteHistory = new ArrayList();
|
||||
|
||||
// long time = 0;
|
||||
double price = 12.9;
|
||||
long orderid = 1;
|
||||
|
||||
double lastprice = 300.0;
|
||||
long lastsize;
|
||||
|
||||
// Order orderlist[];
|
||||
TreeSet<BuyOrder> bid = new TreeSet();
|
||||
TreeSet<SellOrder> ask = new TreeSet<SellOrder>();
|
||||
|
||||
private final Semaphore available = new Semaphore(1, true);
|
||||
|
||||
private void Lock() {
|
||||
try {
|
||||
available.acquire();
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Interrupted");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void Unlock() {
|
||||
available.release();
|
||||
}
|
||||
|
||||
public void print_current() {
|
||||
|
||||
BuyOrder b;
|
||||
SellOrder a;
|
||||
|
||||
//String bid;
|
||||
if (bid.isEmpty()) {
|
||||
b = new BuyOrder();
|
||||
b.limit = -1;
|
||||
b.size = 0;
|
||||
} else {
|
||||
b = bid.first();
|
||||
}
|
||||
|
||||
if (ask.isEmpty()) {
|
||||
a = new SellOrder();
|
||||
a.limit = -1;
|
||||
a.size = 0;
|
||||
|
||||
} else {
|
||||
a = ask.first();
|
||||
}
|
||||
|
||||
Logger.info(
|
||||
String.format("BID: %s(%s) LAST: %.2f(%d) ASK: %s(%s)\n",
|
||||
b.format_limit(), b.format_size(),
|
||||
lastprice, lastsize,
|
||||
a.format_limit(), a.format_size())
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public void TransferMoney(Account src, Account dst, double money) {
|
||||
src.money -= money;
|
||||
dst.money += money;
|
||||
}
|
||||
|
||||
public void CancelOrder(Order o) {
|
||||
Lock();
|
||||
// System.out.println("Cancel BuyOrder");
|
||||
bid.remove(o);
|
||||
ask.remove(o);
|
||||
o.status = OrderStatus.canceled;
|
||||
Unlock();
|
||||
|
||||
}
|
||||
|
||||
public void OrderMatching() {
|
||||
|
||||
while (true) {
|
||||
if (bid.isEmpty() || ask.isEmpty()) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
BuyOrder b = bid.first();
|
||||
SellOrder a = ask.first();
|
||||
|
||||
if (a.size == 0) {
|
||||
// This order is fully executed, remove
|
||||
a.account.orderpending = false;
|
||||
a.status = OrderStatus.executed;
|
||||
ask.pollFirst();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (b.size == 0) {
|
||||
//
|
||||
b.account.orderpending = false;
|
||||
b.status = OrderStatus.executed;
|
||||
bid.pollFirst();
|
||||
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 size = 0;
|
||||
|
||||
if (b.size >= a.size) {
|
||||
size = a.size;
|
||||
} else {
|
||||
size = b.size;
|
||||
}
|
||||
|
||||
b.account.Buy(a.account, size, price);
|
||||
b.size -= size;
|
||||
a.size -= size;
|
||||
|
||||
lastprice = price;
|
||||
lastsize = size;
|
||||
|
||||
Quote q = new Quote();
|
||||
|
||||
q.size = size;
|
||||
q.price = price;
|
||||
q.time = System.currentTimeMillis();
|
||||
|
||||
this.UpdateQuoteReceivers(q);
|
||||
|
||||
//quoteHistory.add(q);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteOrder(BuyOrder o) {
|
||||
// SellOrder op = ask.peek();
|
||||
|
||||
}
|
||||
|
||||
public void SendOrder(SellOrder o) {
|
||||
// System.out.println("EX Sellorder");
|
||||
Lock();
|
||||
o.timestamp = System.currentTimeMillis();
|
||||
o.id = orderid++;
|
||||
ask.add(o);
|
||||
Unlock();
|
||||
Lock();
|
||||
OrderMatching();
|
||||
Unlock();
|
||||
|
||||
}
|
||||
|
||||
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.size=500;
|
||||
* SendOrder(so);
|
||||
*
|
||||
* BuyOrder bo = new BuyOrder(); bo.limit=1001.0; bo.size=300;
|
||||
* SendOrder(bo);
|
||||
*/
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
public double sendOrder(Account o) {
|
||||
return 0.7;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
sleep(1500);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Interrupted");
|
||||
}
|
||||
print_current();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
23
src/SeSim/Logger.java
Normal file
23
src/SeSim/Logger.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
88
src/SeSim/MTrader.java
Normal file
88
src/SeSim/MTrader.java
Normal file
@ -0,0 +1,88 @@
|
||||
package SeSim;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class MTrader implements Trader {
|
||||
Exchange ex;
|
||||
Random rand;
|
||||
|
||||
public MTrader (Exchange ex1, long shares, double money){
|
||||
account.money=money;
|
||||
account.shares=shares;
|
||||
this.ex=ex;
|
||||
rand = new Random();
|
||||
}
|
||||
|
||||
public void DoBuy()
|
||||
{
|
||||
// System.out.println("AAA");
|
||||
|
||||
if (account.orderpending)
|
||||
return;
|
||||
|
||||
if (account.money <= 0)
|
||||
return;
|
||||
|
||||
double perc = rand.nextDouble() * 1.0;
|
||||
double lp = ex.lastprice;
|
||||
double limit = lp/100 * perc + lp;
|
||||
|
||||
// System.out.println("HW");
|
||||
long size = (int)(account.money/limit);
|
||||
|
||||
|
||||
account.Buy(size, limit, ex);
|
||||
return;
|
||||
}
|
||||
|
||||
public void DoSell()
|
||||
{
|
||||
// System.out.println("SoSell");
|
||||
|
||||
if (account.orderpending)
|
||||
return;
|
||||
|
||||
if (account.shares<=0)
|
||||
return;
|
||||
|
||||
double perc = rand.nextDouble() * 1.0;
|
||||
double lp = ex.lastprice;
|
||||
double limit = lp - lp/100 * perc;
|
||||
|
||||
long size = (int)(account.shares);
|
||||
|
||||
|
||||
account.Sell(size, limit, ex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void trade(){
|
||||
|
||||
|
||||
// What to do?
|
||||
int action = rand.nextInt(3);
|
||||
// System.out.print("Action");
|
||||
// System.out.println(action);
|
||||
if (action==0)
|
||||
return;
|
||||
|
||||
if (action == 1)
|
||||
{
|
||||
DoBuy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (action == 2)
|
||||
{
|
||||
DoSell();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//System.out.printf("MyPrice: %.2f\n",price);
|
||||
|
||||
}
|
||||
|
||||
}
|
52
src/SeSim/Order.java
Normal file
52
src/SeSim/Order.java
Normal file
@ -0,0 +1,52 @@
|
||||
package SeSim;
|
||||
|
||||
public abstract class Order implements Comparable<Order> {
|
||||
|
||||
/**
|
||||
* When the order was created
|
||||
*/
|
||||
public long timestamp = 0;
|
||||
|
||||
/**
|
||||
* Number of shares
|
||||
*/
|
||||
public long size;
|
||||
|
||||
/**
|
||||
* Limit price
|
||||
*/
|
||||
public double limit;
|
||||
|
||||
// double money = 0;
|
||||
|
||||
public long id = 0;
|
||||
public Account account = null;
|
||||
|
||||
enum OrderStatus {
|
||||
open, executed, canceled
|
||||
}
|
||||
|
||||
OrderStatus status = OrderStatus.open;
|
||||
|
||||
public long getAge() {
|
||||
if (timestamp == 0) {
|
||||
return 0;
|
||||
}
|
||||
return System.currentTimeMillis() - timestamp;
|
||||
}
|
||||
|
||||
String format_limit() {
|
||||
if (limit < 0.0) {
|
||||
return "n.a.";
|
||||
}
|
||||
return String.format("%.2f", limit);
|
||||
}
|
||||
|
||||
String format_size() {
|
||||
return String.format("%d", size);
|
||||
}
|
||||
|
||||
Order() {
|
||||
|
||||
}
|
||||
}
|
128
src/SeSim/RandomTrader.java
Normal file
128
src/SeSim/RandomTrader.java
Normal file
@ -0,0 +1,128 @@
|
||||
package SeSim;
|
||||
|
||||
import java.util.Random;
|
||||
import SeSim.Order.OrderStatus;
|
||||
|
||||
public class RandomTrader extends ThreadedTrader {
|
||||
|
||||
// public Account account=new Account();
|
||||
Exchange ex = null;
|
||||
Random rand = new Random();
|
||||
|
||||
public String name;
|
||||
|
||||
// my current order
|
||||
private Order myorder = null;
|
||||
|
||||
public RandomTrader(Exchange ex, long shares, double money) {
|
||||
account.money = money;
|
||||
account.shares = shares;
|
||||
this.ex = ex;
|
||||
}
|
||||
|
||||
public void DoBuy() {
|
||||
|
||||
if (myorder != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (account.money <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
double perc = rand.nextDouble() * 1.0;
|
||||
double lp = ex.lastprice;
|
||||
double limit = lp / 100 * perc + lp;
|
||||
|
||||
long size = (int) (account.money / (limit * 1));
|
||||
|
||||
myorder = account.Buy(size, limit, ex);
|
||||
return;
|
||||
}
|
||||
|
||||
public void DoSell() {
|
||||
if (myorder != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (account.shares <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
double perc = rand.nextDouble() * 1.0;
|
||||
double lp = ex.lastprice;
|
||||
double limit = lp - lp / 100 * perc;
|
||||
|
||||
long size = (int) (account.shares);
|
||||
|
||||
myorder = account.Sell(size, limit, ex);
|
||||
}
|
||||
|
||||
public void trade() {
|
||||
|
||||
if (myorder != null) {
|
||||
long age = myorder.getAge();
|
||||
if (myorder.status == OrderStatus.executed) {
|
||||
myorder = null;
|
||||
// System.out.println(name);
|
||||
// System.out.println("----------------------");
|
||||
// account.print_current();
|
||||
return;
|
||||
}
|
||||
|
||||
if (myorder.getAge() > 10) {
|
||||
//System.out.println("Shall cancel now");
|
||||
//System.out.println(myorder.status);
|
||||
ex.CancelOrder(myorder);
|
||||
myorder = null;
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// What to do?
|
||||
int action = rand.nextInt(3);
|
||||
/* System.out.print(name);
|
||||
System.out.println("---------------------------");
|
||||
System.out.print("Action:");
|
||||
System.out.println(action);
|
||||
*/
|
||||
/* if (action==0)
|
||||
{
|
||||
DoSell();
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
if (action == 1) {
|
||||
DoBuy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (action == 2) {
|
||||
DoSell();
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* public void run(){
|
||||
while (true)
|
||||
{
|
||||
try{
|
||||
sleep(200);
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
System.out.println("Interrupted");
|
||||
}
|
||||
// System.out.println("Trader has slept");
|
||||
trade();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
16
src/SeSim/SellOrder.java
Normal file
16
src/SeSim/SellOrder.java
Normal file
@ -0,0 +1,16 @@
|
||||
package SeSim;
|
||||
|
||||
public class SellOrder extends Order {
|
||||
|
||||
@Override
|
||||
public int compareTo(Order o) {
|
||||
|
||||
if (o.limit < limit) {
|
||||
return 1;
|
||||
}
|
||||
if (o.limit > limit) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
23
src/SeSim/ThreadedTrader.java
Normal file
23
src/SeSim/ThreadedTrader.java
Normal file
@ -0,0 +1,23 @@
|
||||
package SeSim;
|
||||
|
||||
public abstract class ThreadedTrader extends Thread implements Trader {
|
||||
|
||||
protected long sleeptime = 100;
|
||||
|
||||
public void RandomTrader(Exchange ex, long shares, double money) {
|
||||
// this.ex=ex;
|
||||
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
sleep(sleeptime);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Interrupted");
|
||||
}
|
||||
trade();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
11
src/SeSim/Trader.java
Normal file
11
src/SeSim/Trader.java
Normal file
@ -0,0 +1,11 @@
|
||||
package SeSim;
|
||||
|
||||
public interface Trader {
|
||||
|
||||
String name = null;
|
||||
|
||||
public void trade();
|
||||
public Account account = new Account();
|
||||
// public Exchange ex=null;
|
||||
|
||||
};
|
36
src/SeSim/TraderRun.java
Normal file
36
src/SeSim/TraderRun.java
Normal file
@ -0,0 +1,36 @@
|
||||
package SeSim;
|
||||
|
||||
public class TraderRun extends Thread {
|
||||
|
||||
public String tname = "";
|
||||
public Exchange ex;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
System.out.println("Interrupted");
|
||||
}
|
||||
|
||||
/*
|
||||
System.out.printf("%s locking\n", tname);
|
||||
ex.Lock();
|
||||
System.out.printf("%s locked\n", tname);
|
||||
|
||||
try{
|
||||
sleep(1000);
|
||||
}
|
||||
catch(InterruptedException e) {
|
||||
System.out.println("Interrupted");
|
||||
}
|
||||
|
||||
System.out.printf("%s unlocking\n", tname);
|
||||
// ex.Free();
|
||||
System.out.printf("%s unlocked\n", tname);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user