From 8f35e767bd0c623d0ba8d30f78ffb24562dde1ff Mon Sep 17 00:00:00 2001 From: 7u83 <7u83@maiil.ru> Date: Tue, 8 Jan 2019 09:24:08 +0100 Subject: [PATCH] Work on asset binding when creating orders --- nbproject/project.properties | 2 +- src/opensesim/gui/account/AccountPanel.java | 4 +- src/opensesim/world/Account.java | 87 +++++++++---- src/opensesim/world/SimpleTrader.java | 32 +---- src/opensesim/world/TradingEngine.java | 129 +++++++++----------- 5 files changed, 129 insertions(+), 125 deletions(-) diff --git a/nbproject/project.properties b/nbproject/project.properties index aaab35f..4d81600 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -1,4 +1,4 @@ -#Sat, 05 Jan 2019 10:43:36 +0100 +#Tue, 08 Jan 2019 09:22:34 +0100 annotation.processing.enabled=true annotation.processing.enabled.in.editor=false annotation.processing.processors.list= diff --git a/src/opensesim/gui/account/AccountPanel.java b/src/opensesim/gui/account/AccountPanel.java index 3d276d0..fdc7797 100644 --- a/src/opensesim/gui/account/AccountPanel.java +++ b/src/opensesim/gui/account/AccountPanel.java @@ -58,8 +58,8 @@ public class AccountPanel extends javax.swing.JPanel implements EventListener { int row = 0; model.setRowCount(am.size()); for (AbstractAsset a : am.keySet()) { - Double val = account.get(a); - Double avail = account.getAvail(a); + Double val = account.get(a,false); + Double avail = account.getBound(a); String astr = val.toString() + "/" + avail.toString(); Double mval = account.getMargin(a); diff --git a/src/opensesim/world/Account.java b/src/opensesim/world/Account.java index 034f15a..5be2fb7 100644 --- a/src/opensesim/world/Account.java +++ b/src/opensesim/world/Account.java @@ -112,12 +112,13 @@ public class Account { return this.getFinalBalance(currency) * getLeverage() + this.getFinalBalance(currency) - this.getAssetDebt(world.getDefaultExchange(), currency); + // + this.get(currency); } synchronized void add(AssetPack pack) { assets.put(pack.asset, get(pack.asset) + pack.volume); - assets_bound.put(pack.asset, getAvail(pack.asset) + pack.volume); + // assets_bound.put(pack.asset, getAvail(pack.asset) + pack.volume); } synchronized void sub(AssetPack pack) { @@ -125,11 +126,16 @@ public class Account { // assets_bound.put(pack.asset, getAvail(pack.asset) - pack.volume); } - public double get(AbstractAsset asset) { - return assets.getOrDefault(asset, 0.0); + public double get(AbstractAsset asset, boolean bound) { + return assets.getOrDefault(asset, 0.0) + + (bound ? this.getBound(asset) : 0.0); } - public double getAvail(AbstractAsset asset) { + public double get(AbstractAsset asset) { + return get(asset, true); + } + + /*public double getAvail(AbstractAsset asset) { if (this.getLeverage() > 0) { Double margin = this.getMargin(world.getDefaultCurrency()); @@ -142,12 +148,12 @@ public class Account { //return assets_bound.getOrDefault(asset, 0.0); } - - public void addAvail(AbstractAsset asset, double val) { + */ + /* public void addAvail(AbstractAsset asset, double val) { double avail = getAvail(asset); - assets_bound.put(asset, (avail + val)); + // assets_bound.put(asset, (avail + val)); } - + */ HashSet listeners = new HashSet<>(); public void addListener(EventListener l) { @@ -170,6 +176,8 @@ public class Account { public Double getAssetDebt(Exchange ex, AbstractAsset currency) { Double result = 0.0; + boolean bound = true; + for (AbstractAsset a : assets.keySet()) { if (a.equals(currency)) { continue; @@ -188,7 +196,9 @@ public class Account { } // System.out.printf("Asset: %s - %f %f %f\n", a.getSymbol(), n, v, sl * n); - result = result + (v - sl * n); + Double sld = v - sl * n; + + result = result + Math.abs(v); // - sl * n); // System.out.printf("Result is now %f\n", result); } @@ -205,21 +215,23 @@ public class Account { * @return final balance * */ - public Double getFinalBalance(Exchange ex, AbstractAsset currency, + public Double getFinalBalance(Exchange ex, AbstractAsset currency, boolean bound) { - Double result = get(currency); + Double result = 0.0; //get(currency); for (AbstractAsset a : assets.keySet()) { Double v; if (a.equals(currency)) { + v = get(a,bound); + result += v; continue; } AssetPair pair = world.getAssetPair(a, currency); if (pair == null) { continue; } - v = get(a) + (bound ? getBound(a) : 0.0); - + v = get(a,bound); + if (v == 0.0) { continue; } @@ -229,13 +241,20 @@ public class Account { } return result; } - - Double getBound(AbstractAsset asset){ + + /** + * Return the amount of bound assets + * + * @param asset Asset to check + * @return amount + */ + public Double getBound(AbstractAsset asset) { return assets_bound.getOrDefault(asset, 0.0); } - - void addBound(AbstractAsset asset, Double vol){ - assets_bound.put(asset, getBound(asset)+vol); + + void addBound(AbstractAsset asset, Double vol) { + assets.put(asset, get(asset,false)); + assets_bound.put(asset, getBound(asset) + vol); } /** @@ -247,7 +266,7 @@ public class Account { * @return final balance */ public Double getFinalBalance(AbstractAsset currency) { - return getFinalBalance(this.getExchange(), currency, false); + return getFinalBalance(this.getExchange(), currency, true); } /** @@ -299,7 +318,7 @@ public class Account { return getLeverage() > 0.0; } - boolean isCovered(AssetPair pair, double volume, double limit) { + boolean bind(AssetPair pair, double volume, double limit) { if (this.isUnlimied()) { return true; } @@ -314,18 +333,36 @@ public class Account { if (volume < 0) { // It's a limited sell order, we have just to check // if a sufficient amount of assets is available - return getAvail(pair.getAsset()) + volume > 0; + return get(pair.getAsset()) - volume >= 0; } // Check if enough money is available to cover the // entiere volume to by - return getAvail(pair.getCurrency()) >= limit * volume; + return get(pair.getCurrency()) >= limit * volume; } + + // we are dealing here with a leveraged account + + System.out.printf("Add %f %f\n",volume,-volume*limit); + + // bind asset and currecy + this.addBound(pair.getAsset(), volume); + this.addBound(pair.getCurrency(), -(volume * limit)); + + Double fb = this.getFinalBalance(); + + System.out.printf("FB: %f\n",fb); + + Double margin = this.getMargin(pair.getCurrency()); - System.out.printf("Margin: %f > %f\n", margin, Math.abs(volume * limit)); - - return margin > 0; //Math.abs(volume * limit); + if (margin >= 0) + return true; + + // Unbind asset and currency + this.addBound(pair.getAsset(), -volume); + this.addBound(pair.getCurrency(), (volume * limit)); + return false; } diff --git a/src/opensesim/world/SimpleTrader.java b/src/opensesim/world/SimpleTrader.java index b496b39..7397c5a 100644 --- a/src/opensesim/world/SimpleTrader.java +++ b/src/opensesim/world/SimpleTrader.java @@ -100,11 +100,11 @@ public class SimpleTrader extends AbstractTrader implements EventListener { account_1 = new Account(getWorld()); AssetPack pack; - pack = new AssetPack(p.getAsset(), 0); - account_b.add(pack); + // pack = new AssetPack(p.getAsset(), 0); + // account_b.add(pack); pack = new AssetPack(p.getCurrency(), 1000); - account_b.add(pack); + account_b.add(pack); account_b.setLeverage(9.0); pack = new AssetPack(p.getCurrency(), 1234567890); @@ -128,7 +128,7 @@ public class SimpleTrader extends AbstractTrader implements EventListener { @Override public long receive(Event task) { - // System.out.printf("Here we are !!! %f\n", getWorld().randNextFloat(12f, 27f)); + // System.out.printf("Here we are !!! %f\n", getWorld().randNextFloat(12f, 27f)); long diff = getWorld().currentTimeMillis() - last_time; last_time = getWorld().currentTimeMillis(); @@ -142,31 +142,11 @@ public class SimpleTrader extends AbstractTrader implements EventListener { getWorld().getAssetBySymbol("EUR")); TradingAPI mapi = ex.getAPI(msftp); - Order ob = api.createOrder(account_b, Order.Type.BUYLIMIT, 20, 100); + Order ob = mapi.createOrder(account_b, Order.Type.SELLLIMIT, 50, 100); + Order oba = api.createOrder(account_b, Order.Type.BUYLIMIT, 50, 100); - //Order mob = mapi.createOrder(account_b, Order.Type.SELLLIMIT, 80, 100); - Order oa = api.createOrder(account_1, Order.Type.SELLLIMIT, 100, 200); - //Order oaaa = mapi.createOrder(account_1, Order.Type.BUYLIMIT, 100, 100); -//Order oax = mapi.createOrder(account_1, Order.Type.BUYLIMIT, 100, 100); - // Order oa = api.createOrder(account_1, Order.Type.BUYLIMIT, 100, 10.0); - // Order ob = api.createOrder(account_1, Order.Type.BUYLIMIT, 100, 9.0); - // Order oc = api.createOrder(account_1, Order.Type.BUYLIMIT, 100, 8.0); - // Order o2 = api.createOrder(account_10, Order.Type.SELLLIMIT, 300, 1.0); - //Order ou = api.createOrder(account_1, Order.Type.BUYLIMIT, 30, 10.0); - // Order o1 = api.createOrder(account, Order.Type.SELLLIMIT, 250, 278); - /* - System.out.printf("Here we are: %d - [%d]\n", Thread.currentThread().getId(), diff); - getWorld().schedule(this, 1000); - - AssetPair p = getWorld().getDefaultAssetPair(); - - ex = getWorld().getDefaultExchange(); - api = ex.getAPI(p); - Order o = api.createOrder(account, Order.Type.BUY, 112.987123, limit); - limit += 12; - */ return -1; } diff --git a/src/opensesim/world/TradingEngine.java b/src/opensesim/world/TradingEngine.java index 1d87b76..1956b97 100644 --- a/src/opensesim/world/TradingEngine.java +++ b/src/opensesim/world/TradingEngine.java @@ -208,7 +208,7 @@ class TradingEngine implements TradingAPI { double volume = b.volume >= a.volume ? a.volume : b.volume; double avdiff = b.limit - price * volume; - b.account.addAvail(assetpair.getCurrency(), avdiff); +// b.account.addAvail(assetpair.getCurrency(), avdiff); finishTrade(b, a, price, volume); volume_total += volume; @@ -288,7 +288,7 @@ class TradingEngine implements TradingAPI { // Update available currency for the buyer. // For sellers there is no need to update. double avdiff = b.limit * volume - price * volume; - b.account.addAvail(assetpair.getCurrency(), avdiff); +// b.account.addAvail(assetpair.getCurrency(), avdiff); if (b.account.getLeverage() > 0.0) { //b.account.margin_bound-=avdiff; b.account.margin_bound -= b.limit * volume; @@ -432,77 +432,67 @@ class TradingEngine implements TradingAPI { double order_limit; - if (account.isUnlimied()) { - order_limit = l; - } else { - switch (type) { - case BUYLIMIT: { - - if (!account.isCovered(assetpair, volume, limit)){ - System.out.printf("Not enough funds\n"); - return null; - } - - // return if not enough funds are available + switch (type) { + case BUYLIMIT: { + + if (!account.bind(assetpair, volume, limit)) { + System.out.printf("Not enough funds\n"); + return null; + } + + // return if not enough funds are available // if (avail < v * l) { // o = new Order(this, account, type, v, l); // o.status = Order.Status.ERROR; - // System.out.printf("Error order no funds\n"); - // return o; - // } - - account.margin_bound += v * l; - // reduce the available money + // return o; + // } + // account.margin_bound += v * l; + // reduce the available money // account.assets_bound.put(currency, avail - v * l); - //account.addMarginAvail(currency, -((v * l)/account.getLeverage())); - 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_bound.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_bound.put(asset, avail - v); - order_limit = l; - break; - - } - - default: - return null; + 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); + Double avail = 1000.0; + // if (avail <= 0.0) { + // return null; + + + + // } + // All available monney is assigned to this unlimited order + account.assets_bound.put(currency, 0.0); + // we "mis"use order_limit to memorize occupied ammount \ + // of currency + order_limit = avail; + break; + + } + + case SELLLIMIT: + case SELL: { + if (!account.bind(assetpair, -volume, limit)) { + System.out.printf("Not enough funds\n"); + return null; + } + + + order_limit = l; + break; + + } + + default: + return null; + } o = new Order(this, account, type, v, order_limit); @@ -515,7 +505,7 @@ class TradingEngine implements TradingAPI { } executeOrders(); - last_quote.price = 150; //75-12.5; + //last_quote.price = 90; //75-12.5; for (FiringEvent e : book_listener) { e.fire(); } @@ -529,11 +519,8 @@ class TradingEngine implements TradingAPI { = new HashSet<>(); @Override - public void addOrderBookListener(EventListener listener - ) { - book_listener - .add(new FiringEvent(listener - )); + public void addOrderBookListener(EventListener listener) { + book_listener.add(new FiringEvent(listener)); }