Order creation verifies available assets

This commit is contained in:
7u83 2018-12-28 11:37:52 +01:00
parent ab4a1035d2
commit 2eb3be4ce2
1 changed files with 90 additions and 22 deletions

View File

@ -40,13 +40,14 @@ import opensesim.world.scheduler.FiringEvent;
* @author tube
*/
class TradingEngine implements TradingAPI {
private final Exchange outer;
/**
* Construct a trading engine for an asset pair
*
* @param pair The AssetPair obect to create the tradinge engine for
* @param outer Outer class - points to an Exchange object thins trading
* @param outer Outer class - points to an Exchange object thins trading
* engine belongs to.
*/
TradingEngine(AssetPair pair, final Exchange outer) {
@ -86,8 +87,7 @@ class TradingEngine implements TradingAPI {
SortedSet<Order> ask = order_books.get(Order.Type.SELLLIMIT);
SortedSet<Order> ul_buy = order_books.get(Order.Type.BUY);
SortedSet<Order> ul_sell = order_books.get(Order.Type.SELL);
double volume_total = 0;
double money_total = 0;
while (true) {
@ -233,19 +233,91 @@ class TradingEngine implements TradingAPI {
@Override
public Order createOrder(Account account, Order.Type type, double volume, double limit) {
Order o = new opensesim.world.Order(this, account, type, volume, limit);
System.out.printf("The new Order has: volume: %f limit: %f\n", o.getVolume(), o.getLimit());
synchronized (this) {
order_books.get(o.type).add(o);
synchronized (account) {
// Round volume
double v = assetpair.getAsset().roundToDecimals(volume);
// Order volume must be grater than 0.0.
if (v <= 0.0) {
return null;
}
// Round currency (limit)
double l = assetpair.getCurrency().roundToDecimals(limit);
double order_limit;
switch (type) {
case BUYLIMIT: {
// verfify available currency for a buy limit order
AbstractAsset currency = this.assetpair.getCurrency();
Double avail = account.getAvail(currency);
// return if not enough money is available
if (avail < v * l) {
return null;
}
// reduce the available money
account.assets_avail.put(currency, avail - v * l);
order_limit = l;
break;
}
case BUY: {
// For an unlimited by order there is nothing to check
// other than currency is > 0.0
AbstractAsset currency = this.assetpair.getCurrency();
Double avail = account.getAvail(currency);
if(avail <=0.0){
return null;
}
// All available monney is assigned to this unlimited order
account.assets_avail.put(currency, 0.0);
// we "mis"use order_limit to memorize occupied ammount \
// of currency
order_limit = avail;
break;
}
case SELLLIMIT:
case SELL: {
// verfiy sell limit
AbstractAsset asset = this.assetpair.getAsset();
Double avail = account.getAvail(asset);
if (avail < v) {
// not enough items of asset (shares) available
return null;
}
account.assets_avail.put(asset, avail - v);
order_limit = l;
break;
}
default:
return null;
}
Order o = new opensesim.world.Order(this, account, type, v, order_limit);
System.out.printf("The new Order has: volume: %f limit: %f\n", o.getVolume(), o.getLimit());
synchronized (this) {
order_books.get(o.type).add(o);
}
for (FiringEvent e : book_listener) {
e.fire();
}
return o;
}
for (FiringEvent e : book_listener) {
e.fire();
}
return o;
}
HashSet<FiringEvent> book_listener = new HashSet<>();
@Override
@ -255,15 +327,14 @@ class TradingEngine implements TradingAPI {
@Override
public Set getOrderBook(Order.Type type) {
switch (type){
switch (type) {
case BUYLIMIT:
case BUY:
return Collections.unmodifiableSet(bidbook);
case SELLLIMIT:
case SELL:
return Collections.unmodifiableSet(askbook);
}
return null;
// return Collections.unmodifiableSet(order_books.get(type));
@ -279,7 +350,4 @@ class TradingEngine implements TradingAPI {
return getOrderBook(Order.Type.SELL);
}
}
}