diff --git a/src/opensesim/world/TradingEngine.java b/src/opensesim/world/TradingEngine.java index 89a4cc8..0851644 100644 --- a/src/opensesim/world/TradingEngine.java +++ b/src/opensesim/world/TradingEngine.java @@ -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 ask = order_books.get(Order.Type.SELLLIMIT); SortedSet ul_buy = order_books.get(Order.Type.BUY); SortedSet 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 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); } - - - -} \ No newline at end of file +}