Account improved
divided into interface and implementation
This commit is contained in:
parent
703fe209b2
commit
f5552c7b5b
@ -1,4 +1,4 @@
|
|||||||
#Tue, 08 Jan 2019 19:25:21 +0100
|
#Mon, 14 Jan 2019 08:39:39 +0100
|
||||||
annotation.processing.enabled=true
|
annotation.processing.enabled=true
|
||||||
annotation.processing.enabled.in.editor=false
|
annotation.processing.enabled.in.editor=false
|
||||||
annotation.processing.processors.list=
|
annotation.processing.processors.list=
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package opensesim.gui.account;
|
package opensesim.gui.account;
|
||||||
|
|
||||||
import opensesim.world.Account;
|
import opensesim.world.AccountImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -42,7 +42,7 @@ public class AccountDialog extends javax.swing.JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void runDialog(java.awt.Frame parent, Account account){
|
public static void runDialog(java.awt.Frame parent, AccountImpl account){
|
||||||
AccountDialog d;
|
AccountDialog d;
|
||||||
d=new AccountDialog(parent, false);
|
d=new AccountDialog(parent, false);
|
||||||
d.accountPanel1.account=account;
|
d.accountPanel1.account=account;
|
||||||
|
@ -30,7 +30,8 @@ import javax.swing.table.DefaultTableModel;
|
|||||||
import opensesim.util.scheduler.Event;
|
import opensesim.util.scheduler.Event;
|
||||||
import opensesim.util.scheduler.EventListener;
|
import opensesim.util.scheduler.EventListener;
|
||||||
import opensesim.world.AbstractAsset;
|
import opensesim.world.AbstractAsset;
|
||||||
import opensesim.world.Account;
|
import opensesim.world.AccountImpl;
|
||||||
|
import opensesim.world.Asset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -47,27 +48,27 @@ public class AccountPanel extends javax.swing.JPanel implements EventListener {
|
|||||||
assetTable.getTableHeader().setReorderingAllowed(false);
|
assetTable.getTableHeader().setReorderingAllowed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account account;
|
public AccountImpl account;
|
||||||
|
|
||||||
void update() {
|
void update() {
|
||||||
DefaultTableModel model;
|
DefaultTableModel model;
|
||||||
model = (DefaultTableModel) this.assetTable.getModel();
|
model = (DefaultTableModel) this.assetTable.getModel();
|
||||||
|
|
||||||
Map<AbstractAsset, Double> am = account.getAssets();
|
Map<Asset, Double> am = account.getAssets();
|
||||||
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
model.setRowCount(am.size());
|
model.setRowCount(am.size());
|
||||||
for (AbstractAsset a : am.keySet()) {
|
for (Asset a : am.keySet()) {
|
||||||
Double val = account.get(a,false);
|
Double val = account.get((AbstractAsset) a,false);
|
||||||
Double avail = account.getBound(a);
|
Double avail = account.getBound((AbstractAsset) a);
|
||||||
String astr = val.toString() + "/" + avail.toString();
|
String astr = val.toString() + "/" + avail.toString();
|
||||||
|
|
||||||
Double mval = account.getMargin(a);
|
Double mval = account.getMargin((AbstractAsset) a);
|
||||||
Double mavail = account.getMargin(a)-account.margin_bound;
|
// Double mavail = account.getMargin((AbstractAsset) a)-account.margin_bound;
|
||||||
String mastr = mval.toString()+ "/" + mavail.toString();
|
String mastr = "xxx" ; //Double(0.0(.toString()+ "/" + mavail.toString();
|
||||||
|
|
||||||
|
|
||||||
Double sl = account.calcStopLoss(a);
|
Double sl = account.calcStopLoss((AbstractAsset) a);
|
||||||
|
|
||||||
// model.setValueAt(ob1.getAccount().getOwner().getName(), row, 0);
|
// model.setValueAt(ob1.getAccount().getOwner().getName(), row, 0);
|
||||||
model.setValueAt(a.getSymbol(), row, 0);
|
model.setValueAt(a.getSymbol(), row, 0);
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package opensesim.gui.account;
|
package opensesim.gui.account;
|
||||||
|
|
||||||
import opensesim.world.Account;
|
import opensesim.world.AccountImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -40,14 +40,14 @@ public class StatusPanel extends javax.swing.JPanel {
|
|||||||
initComponents();
|
initComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatusPanel(Account account) {
|
public StatusPanel(AccountImpl account) {
|
||||||
this();
|
this();
|
||||||
setAccount(account);
|
setAccount(account);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Account account;
|
private AccountImpl account;
|
||||||
|
|
||||||
public void setAccount(Account account) {
|
public void setAccount(AccountImpl account) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ public abstract class AbstractTrader implements Trader {
|
|||||||
private String name = "Unnamed";
|
private String name = "Unnamed";
|
||||||
private String status;
|
private String status;
|
||||||
private World world;
|
private World world;
|
||||||
protected Account account;
|
protected AccountImpl account;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the world
|
* @return the world
|
||||||
@ -100,7 +100,7 @@ public abstract class AbstractTrader implements Trader {
|
|||||||
|
|
||||||
public AbstractTrader(World world, JSONObject cfg) {
|
public AbstractTrader(World world, JSONObject cfg) {
|
||||||
this.world=world;
|
this.world=world;
|
||||||
this.account = new Account(world);
|
this.account = new AccountImpl(world);
|
||||||
|
|
||||||
AssetPack pack;
|
AssetPack pack;
|
||||||
pack = new AssetPack(this.world.getDefaultAssetPair().getCurrency(),1000);
|
pack = new AssetPack(this.world.getDefaultAssetPair().getCurrency(),1000);
|
||||||
@ -118,7 +118,7 @@ public abstract class AbstractTrader implements Trader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Account getAccount(){
|
public AccountImpl getAccount(){
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, 7u83 <7u83@mail.ru>
|
* Copyright (c) 2019, 7u83 <7u83@mail.ru>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -25,373 +25,15 @@
|
|||||||
*/
|
*/
|
||||||
package opensesim.world;
|
package opensesim.world;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import opensesim.util.scheduler.Event;
|
|
||||||
import opensesim.util.scheduler.EventListener;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to hold account data of traders
|
|
||||||
*
|
*
|
||||||
* @author 7u83 <7u83@mail.ru>
|
* @author 7u83 <7u83@mail.ru>
|
||||||
*/
|
*/
|
||||||
public class Account {
|
public interface Account {
|
||||||
|
public Map<Asset, Double> getAssets();
|
||||||
HashMap<AbstractAsset, Double> assets = new HashMap<>();
|
public Exchange getExchange() ;
|
||||||
HashMap<AbstractAsset, Double> assets_bound = new HashMap<>();
|
|
||||||
HashMap<AbstractAsset, Double> stop_los = new HashMap<>();
|
|
||||||
|
|
||||||
public double margin_bound = 0.0;
|
|
||||||
|
|
||||||
Trader owner;
|
|
||||||
//public Exchange exchange = null;
|
|
||||||
|
|
||||||
private RealWorld world;
|
|
||||||
private Exchange exchange;
|
|
||||||
|
|
||||||
public Exchange getExchange() {
|
|
||||||
return exchange;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean unlimited = false;
|
|
||||||
|
|
||||||
public boolean isUnlimied() {
|
|
||||||
return unlimited;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setUnlimied(boolean unlimied) {
|
|
||||||
this.unlimited = unlimied;
|
|
||||||
}
|
|
||||||
|
|
||||||
private double leverage = 0.0;
|
|
||||||
|
|
||||||
public double getLeverage() {
|
|
||||||
return leverage;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setLeverage(double leverage) {
|
|
||||||
this.leverage = leverage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<AbstractAsset, Double> getAssets() {
|
|
||||||
return Collections.unmodifiableMap(assets);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<AbstractAsset, Double> getAssetsAavail() {
|
|
||||||
return Collections.unmodifiableMap(assets_bound);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Trader getOwner() {
|
|
||||||
return owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Account(World world) {
|
|
||||||
this(world, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Account(World world, Exchange exchange, JSONObject cfg) {
|
|
||||||
this.world = (RealWorld) world;
|
|
||||||
if (exchange == null) {
|
|
||||||
this.exchange = world.getDefaultExchange();
|
|
||||||
}
|
|
||||||
if (cfg == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Double getMargin(AbstractAsset currency) {
|
|
||||||
/* Double d = this.getAssetDebt(world.getDefaultExchange(), currency);
|
|
||||||
|
|
||||||
Double f = this.getFinalBalance(currency) * getLeverage() ;
|
|
||||||
System.out.printf("Debth %f - Final: %f Return margin %f\n", d,f, f-d);
|
|
||||||
|
|
||||||
return f-d;*/
|
|
||||||
if (!this.isLeveraged())
|
|
||||||
return 0.0;
|
|
||||||
|
|
||||||
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,false) + pack.volume);
|
|
||||||
// assets_bound.put(pack.asset, getAvail(pack.asset) + pack.volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized void sub(AssetPack pack) {
|
|
||||||
assets.put(pack.asset, get(pack.asset,false) - pack.volume);
|
|
||||||
// assets_bound.put(pack.asset, getAvail(pack.asset) - pack.volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double get(AbstractAsset asset, boolean bound) {
|
|
||||||
return assets.getOrDefault(asset, 0.0)
|
|
||||||
+ (bound ? this.getBound(asset) : 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double get(AbstractAsset asset) {
|
|
||||||
return get(asset, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*public double getAvail(AbstractAsset asset) {
|
|
||||||
if (this.getLeverage() > 0) {
|
|
||||||
Double margin = this.getMargin(world.getDefaultCurrency());
|
|
||||||
|
|
||||||
AssetPair ap = world.getAssetPair(asset, world.getDefaultCurrency());
|
|
||||||
|
|
||||||
return margin / world.getDefaultExchange().getAPI(ap).getLastQuote().price;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0.0;
|
|
||||||
|
|
||||||
//return assets_bound.getOrDefault(asset, 0.0);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/* public void addAvail(AbstractAsset asset, double val) {
|
|
||||||
double avail = getAvail(asset);
|
|
||||||
// assets_bound.put(asset, (avail + val));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
HashSet<EventListener> listeners = new HashSet<>();
|
|
||||||
|
|
||||||
public void addListener(EventListener l) {
|
|
||||||
listeners.add(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notfiyListeners() {
|
|
||||||
Event e = new Event() {
|
|
||||||
};
|
|
||||||
for (EventListener l : listeners) {
|
|
||||||
l.receive(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Double getFreeMargin(AbstractAsset asset) {
|
|
||||||
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Double getAssetDebt(Exchange ex, AbstractAsset currency) {
|
|
||||||
Double result = 0.0;
|
|
||||||
|
|
||||||
boolean bound = true;
|
|
||||||
|
|
||||||
for (AbstractAsset a : assets.keySet()) {
|
|
||||||
if (a.equals(currency)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
AssetPair pair = world.getAssetPair(a, currency);
|
|
||||||
if (pair == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TradingEngine api = (TradingEngine) ex.getAPI(pair);
|
|
||||||
Double v = get(a) * api.last_quote.price;
|
|
||||||
Double sl = this.calcStopLoss(a);
|
|
||||||
Double n = get(a);
|
|
||||||
if (n == 0.0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// System.out.printf("Asset: %s - %f %f %f\n", a.getSymbol(), n, v, sl * n);
|
|
||||||
Double sld = v - sl * n;
|
|
||||||
|
|
||||||
result = result + Math.abs(v); // - sl * n);
|
|
||||||
// System.out.printf("Result is now %f\n", result);
|
|
||||||
|
|
||||||
}
|
|
||||||
// System.out.printf("Return Dresult %f\n", result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine final balance of this account, as if all assets would be sold
|
|
||||||
* on exchange ex against given currency asset.
|
|
||||||
*
|
|
||||||
* @param ex Exchange to operate on
|
|
||||||
* @param currency Currency against the assets should be sold.
|
|
||||||
* @return final balance
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public Double getFinalBalance(Exchange ex, AbstractAsset currency,
|
|
||||||
boolean bound) {
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (v == 0.0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TradingEngine api = (TradingEngine) ex.getAPI(pair);
|
|
||||||
result = result + v * api.last_quote.price;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.put(asset, get(asset, false));
|
|
||||||
assets_bound.put(asset, getBound(asset) + vol);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the final balance as if all assets would be sold ob the default
|
|
||||||
* exchange against given currency.
|
|
||||||
* {@link #getFinalBalance(opensesim.world.Exchange, opensesim.world.AbstractAsset)}
|
|
||||||
*
|
|
||||||
* @param currency Currency for final balance
|
|
||||||
* @return final balance
|
|
||||||
*/
|
|
||||||
public Double getFinalBalance(AbstractAsset currency) {
|
|
||||||
return getFinalBalance(this.getExchange(), currency, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine final balance
|
|
||||||
* {@link #getFinalBalance(opensesim.world.Exchange, opensesim.world.AbstractAsset) }
|
|
||||||
*
|
|
||||||
* @see DoublegetFinalBalance( Exchange ex, AbstractAsset currency)
|
|
||||||
* @return Balance
|
|
||||||
*/
|
|
||||||
public Double getFinalBalance() {
|
|
||||||
return getFinalBalance(world.getDefaultCurrency());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param ex
|
|
||||||
* @param asset
|
|
||||||
* @param currency
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public Double calcStopLoss(Exchange ex, AbstractAsset asset, AbstractAsset currency) {
|
|
||||||
Double e = (get(currency,false));
|
|
||||||
for (AbstractAsset a : assets.keySet()) {
|
|
||||||
if (a.equals(asset)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
AssetPair pair = world.getAssetPair(a, currency);
|
|
||||||
if (pair == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TradingEngine api = (TradingEngine) ex.getAPI(pair);
|
|
||||||
Double v = get(a,false) * api.last_quote.price;
|
|
||||||
e = e + v;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return -(double) e / (double) get(asset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Double calcStopLoss(AbstractAsset asset) {
|
|
||||||
return calcStopLoss(world.getDefaultExchange(), asset, world.getDefaultAssetPair().getCurrency());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the world this account belongs to
|
|
||||||
*
|
|
||||||
* @return world
|
|
||||||
*/
|
|
||||||
public World getWorld() {
|
|
||||||
return world;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isLeveraged() {
|
|
||||||
return getLeverage() > 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bind asset which will be locked in an order.
|
|
||||||
*
|
|
||||||
* @param pair
|
|
||||||
* @param volume
|
|
||||||
* @param limit
|
|
||||||
* @return true if asset could be bound, false if assets couldn't be bound
|
|
||||||
*/
|
|
||||||
boolean bind(AssetPair pair, double volume, double limit) {
|
|
||||||
|
|
||||||
// Bind asset and currecy
|
|
||||||
this.addBound(pair.getAsset(), volume);
|
|
||||||
this.addBound(pair.getCurrency(), -(volume * limit));
|
|
||||||
|
|
||||||
if (this.isUnlimied()) {
|
|
||||||
// in case it is an unlimited account we can return
|
|
||||||
// true without further checks
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// checks for leveraged account
|
|
||||||
if (!this.isLeveraged()) {
|
|
||||||
if (limit == 0.0) {
|
|
||||||
// an unlimited order is always considered to be
|
|
||||||
// covereable. When the trade comes to execution,
|
|
||||||
// the limits will be checked.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (volume < 0) {
|
|
||||||
// It's a limited sell order, we have just to check
|
|
||||||
// if a sufficient amount of assets is available
|
|
||||||
|
|
||||||
if (get(pair.getAsset()) >= 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// unbind and return false
|
|
||||||
this.addBound(pair.getAsset(), -volume);
|
|
||||||
this.addBound(pair.getCurrency(), (volume * limit));
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
// Check if enough money is available to cover the
|
|
||||||
// entiere volume to by
|
|
||||||
if (get(pair.getCurrency()) >= 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// unbind and return false
|
|
||||||
this.addBound(pair.getAsset(), -volume);
|
|
||||||
this.addBound(pair.getCurrency(), (volume * limit));
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// we are dealing here with a leveraged account
|
|
||||||
Double margin = this.getMargin(pair.getCurrency());
|
|
||||||
if (margin >= 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unbind asset and currency
|
|
||||||
this.addBound(pair.getAsset(), -volume);
|
|
||||||
this.addBound(pair.getCurrency(), (volume * limit));
|
|
||||||
return false;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
52
src/opensesim/world/AccountBase.java
Normal file
52
src/opensesim/world/AccountBase.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019, 7u83 <7u83@mail.ru>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package opensesim.world;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author 7u83 <7u83@mail.ru>
|
||||||
|
*/
|
||||||
|
public abstract class AccountBase implements Account {
|
||||||
|
|
||||||
|
HashMap<Asset, Double> assets = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Asset, Double> getAssets() {
|
||||||
|
return Collections.unmodifiableMap(assets);
|
||||||
|
}
|
||||||
|
|
||||||
|
Exchange exchange;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Exchange getExchange() {
|
||||||
|
return exchange;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
425
src/opensesim/world/AccountImpl.java
Normal file
425
src/opensesim/world/AccountImpl.java
Normal file
@ -0,0 +1,425 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 7u83 <7u83@mail.ru>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package opensesim.world;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import opensesim.util.scheduler.Event;
|
||||||
|
import opensesim.util.scheduler.EventListener;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to hold account data of traders
|
||||||
|
*
|
||||||
|
* @author 7u83 <7u83@mail.ru>
|
||||||
|
*/
|
||||||
|
public class AccountImpl extends AccountBase {
|
||||||
|
|
||||||
|
|
||||||
|
HashMap<AbstractAsset, Double> assets_bound = new HashMap<>();
|
||||||
|
HashMap<AbstractAsset, Double> stop_loss = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
Trader owner;
|
||||||
|
//public Exchange exchange = null;
|
||||||
|
|
||||||
|
private RealWorld world;
|
||||||
|
|
||||||
|
private boolean unlimited = false;
|
||||||
|
|
||||||
|
public boolean isUnlimied() {
|
||||||
|
return unlimited;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUnlimied(boolean unlimied) {
|
||||||
|
this.unlimited = unlimied;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double leverage = 0.0;
|
||||||
|
|
||||||
|
public double getLeverage() {
|
||||||
|
return leverage;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setLeverage(double leverage) {
|
||||||
|
this.leverage = leverage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* public Map<AbstractAsset, Double> getAssetsAavail() {
|
||||||
|
return Collections.unmodifiableMap(assets_bound);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
public Trader getOwner() {
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AccountImpl(World world) {
|
||||||
|
this(world, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AccountImpl(World world, Exchange exchange, JSONObject cfg) {
|
||||||
|
this.world = (RealWorld) world;
|
||||||
|
if (exchange == null) {
|
||||||
|
this.exchange = world.getDefaultExchange();
|
||||||
|
}
|
||||||
|
if (cfg == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMargin(AbstractAsset currency) {
|
||||||
|
/* Double d = this.getAssetDebt(world.getDefaultExchange(), currency);
|
||||||
|
|
||||||
|
Double f = this.getFinalBalance(currency) * getLeverage() ;
|
||||||
|
System.out.printf("Debth %f - Final: %f Return margin %f\n", d,f, f-d);
|
||||||
|
|
||||||
|
return f-d;*/
|
||||||
|
if (!this.isLeveraged())
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
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,false) + pack.volume);
|
||||||
|
// assets_bound.put(pack.asset, getAvail(pack.asset) + pack.volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized void sub(AssetPack pack) {
|
||||||
|
assets.put(pack.asset, get(pack.asset,false) - pack.volume);
|
||||||
|
// assets_bound.put(pack.asset, getAvail(pack.asset) - pack.volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double get(AbstractAsset asset, boolean bound) {
|
||||||
|
return assets.getOrDefault(asset, 0.0)
|
||||||
|
+ (bound ? this.getBound(asset) : 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double get(AbstractAsset asset) {
|
||||||
|
return get(asset, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public double getAvail(AbstractAsset asset) {
|
||||||
|
if (this.getLeverage() > 0) {
|
||||||
|
Double margin = this.getMargin(world.getDefaultCurrency());
|
||||||
|
|
||||||
|
AssetPair ap = world.getAssetPair(asset, world.getDefaultCurrency());
|
||||||
|
|
||||||
|
return margin / world.getDefaultExchange().getAPI(ap).getLastQuote().price;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
//return assets_bound.getOrDefault(asset, 0.0);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/* public void addAvail(AbstractAsset asset, double val) {
|
||||||
|
double avail = getAvail(asset);
|
||||||
|
// assets_bound.put(asset, (avail + val));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
HashSet<EventListener> listeners = new HashSet<>();
|
||||||
|
|
||||||
|
public void addListener(EventListener l) {
|
||||||
|
listeners.add(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notfiyListeners() {
|
||||||
|
Event e = new Event() {
|
||||||
|
};
|
||||||
|
for (EventListener l : listeners) {
|
||||||
|
l.receive(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getFreeMargin(AbstractAsset asset) {
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getAssetDebt(Exchange ex, AbstractAsset currency) {
|
||||||
|
Double result = 0.0;
|
||||||
|
|
||||||
|
boolean bound = true;
|
||||||
|
|
||||||
|
for (Asset a : assets.keySet()) {
|
||||||
|
if (a.equals(currency)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AssetPair pair = world.getAssetPair((AbstractAsset) a, currency);
|
||||||
|
if (pair == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TradingEngine api = (TradingEngine) ex.getAPI(pair);
|
||||||
|
Double v = get((AbstractAsset) a) * api.last_quote.price;
|
||||||
|
// Double sl = this.calcStopLoss(a);
|
||||||
|
Double n = get((AbstractAsset) a);
|
||||||
|
if (n == 0.0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// System.out.printf("Asset: %s - %f %f %f\n", a.getSymbol(), n, v, sl * n);
|
||||||
|
// Double sld = v - sl * n;
|
||||||
|
|
||||||
|
result = result + Math.abs(v); // - sl * n);
|
||||||
|
// System.out.printf("Result is now %f\n", result);
|
||||||
|
|
||||||
|
}
|
||||||
|
// System.out.printf("Return Dresult %f\n", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine final balance of this account, as if all assets would be sold
|
||||||
|
* on exchange ex against given currency asset.
|
||||||
|
*
|
||||||
|
* @param ex Exchange to operate on
|
||||||
|
* @param currency Currency against the assets should be sold.
|
||||||
|
* @return final balance
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public Double getFinalBalance(Exchange ex, AbstractAsset currency,
|
||||||
|
boolean bound) {
|
||||||
|
|
||||||
|
Double result = 0.0; //get(currency);
|
||||||
|
for (Asset a : assets.keySet()) {
|
||||||
|
Double v;
|
||||||
|
if (a.equals(currency)) {
|
||||||
|
v = get((AbstractAsset) a, bound);
|
||||||
|
result += v;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
AssetPair pair = world.getAssetPair((AbstractAsset) a, currency);
|
||||||
|
if (pair == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
v = get((AbstractAsset) a, bound);
|
||||||
|
|
||||||
|
if (v == 0.0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TradingEngine api = (TradingEngine) ex.getAPI(pair);
|
||||||
|
result = result + v * api.last_quote.price;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.put(asset, get(asset, false));
|
||||||
|
assets_bound.put(asset, getBound(asset) + vol);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the final balance as if all assets would be sold ob the default
|
||||||
|
* exchange against given currency.
|
||||||
|
* {@link #getFinalBalance(opensesim.world.Exchange, opensesim.world.AbstractAsset)}
|
||||||
|
*
|
||||||
|
* @param currency Currency for final balance
|
||||||
|
* @return final balance
|
||||||
|
*/
|
||||||
|
public Double getFinalBalance(AbstractAsset currency) {
|
||||||
|
return getFinalBalance(this.getExchange(), currency, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine final balance
|
||||||
|
* {@link #getFinalBalance(opensesim.world.Exchange, opensesim.world.AbstractAsset) }
|
||||||
|
*
|
||||||
|
* @see DoublegetFinalBalance( Exchange ex, AbstractAsset currency)
|
||||||
|
* @return Balance
|
||||||
|
*/
|
||||||
|
public Double getFinalBalance() {
|
||||||
|
return getFinalBalance(world.getDefaultCurrency());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param ex
|
||||||
|
* @param asset
|
||||||
|
* @param currency
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Double calcStopLoss(Exchange ex, AbstractAsset asset, AbstractAsset currency) {
|
||||||
|
Double e = (get(currency,false));
|
||||||
|
for (Asset a : assets.keySet()) {
|
||||||
|
if (a.equals(asset)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetPair pair = world.getAssetPair((AbstractAsset) a, currency);
|
||||||
|
if (pair == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TradingEngine api = (TradingEngine) ex.getAPI(pair);
|
||||||
|
Double v = get((AbstractAsset) a,false) * api.last_quote.price;
|
||||||
|
e = e + v;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.calcMarginStopLosses(currency);
|
||||||
|
|
||||||
|
return -(double) e / (double) get(asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param currency
|
||||||
|
*/
|
||||||
|
public void calcMarginStopLosses(AbstractAsset currency){
|
||||||
|
Double e = (get(currency,false));
|
||||||
|
int n = 0;
|
||||||
|
for (Asset a : assets.keySet()){
|
||||||
|
AssetPair pair = world.getAssetPair(a, currency);
|
||||||
|
if (pair == null)
|
||||||
|
continue;
|
||||||
|
TradingEngine api = (TradingEngine) exchange.getAPI(pair);
|
||||||
|
Double v = get((AbstractAsset) a,false) * api.last_quote.price;
|
||||||
|
e = e + v;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Asset a : assets.keySet()){
|
||||||
|
AssetPair pair = world.getAssetPair(a, currency);
|
||||||
|
if (pair == null)
|
||||||
|
continue;
|
||||||
|
TradingEngine api = (TradingEngine) exchange.getAPI(pair);
|
||||||
|
Double v = get((AbstractAsset) a,false) * api.last_quote.price;
|
||||||
|
|
||||||
|
Double sl = -(double) (e-v) / (double) get((AbstractAsset) a);
|
||||||
|
|
||||||
|
sl = api.last_quote.price - (api.last_quote.price - sl)/(double)n;
|
||||||
|
|
||||||
|
System.out.printf("(%d)ASS SL for %s: %f\n",n, a.getSymbol(), sl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Double calcStopLoss(AbstractAsset asset) {
|
||||||
|
return calcStopLoss(world.getDefaultExchange(), asset, world.getDefaultAssetPair().getCurrency());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the world this account belongs to
|
||||||
|
*
|
||||||
|
* @return world
|
||||||
|
*/
|
||||||
|
public World getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isLeveraged() {
|
||||||
|
return getLeverage() > 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind asset which will be locked in an order.
|
||||||
|
*
|
||||||
|
* @param pair
|
||||||
|
* @param volume
|
||||||
|
* @param limit
|
||||||
|
* @return true if asset could be bound, false if assets couldn't be bound
|
||||||
|
*/
|
||||||
|
boolean bind(AssetPair pair, double volume, double limit) {
|
||||||
|
|
||||||
|
// Bind asset and currecy - optimistic
|
||||||
|
this.addBound(pair.getAsset(), volume);
|
||||||
|
this.addBound(pair.getCurrency(), -(volume * limit));
|
||||||
|
|
||||||
|
if (this.isUnlimied()) {
|
||||||
|
// in case it is an unlimited account we can return
|
||||||
|
// true without further checks
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks for leveraged account
|
||||||
|
if (!this.isLeveraged()) {
|
||||||
|
if (limit == 0.0) {
|
||||||
|
// an unlimited order is always considered to be
|
||||||
|
// covereable. When the trade comes to execution,
|
||||||
|
// the limits will be checked.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (volume < 0) {
|
||||||
|
// It's a limited sell order, we have just to check
|
||||||
|
// if a sufficient amount of assets is available
|
||||||
|
|
||||||
|
if (get(pair.getAsset()) >= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unbind and return false
|
||||||
|
this.addBound(pair.getAsset(), -volume);
|
||||||
|
this.addBound(pair.getCurrency(), (volume * limit));
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
// Check if enough money is available to cover the
|
||||||
|
// entiere volume to by
|
||||||
|
if (get(pair.getCurrency()) >= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// unbind and return false
|
||||||
|
this.addBound(pair.getAsset(), -volume);
|
||||||
|
this.addBound(pair.getCurrency(), (volume * limit));
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// we are dealing here with a leveraged account
|
||||||
|
Double margin = this.getMargin(pair.getCurrency());
|
||||||
|
if (margin >= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbind asset and currency
|
||||||
|
this.addBound(pair.getAsset(), -volume);
|
||||||
|
this.addBound(pair.getCurrency(), (volume * limit));
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -68,15 +68,15 @@ public class Exchange implements Configurable, GetJson {
|
|||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashSet<Account> accounts = new HashSet<>();
|
private HashSet<AccountImpl> accounts = new HashSet<>();
|
||||||
|
|
||||||
Account createAccount() {
|
AccountImpl createAccount() {
|
||||||
Account a = new Account(this.world);
|
AccountImpl a = new AccountImpl(this.world);
|
||||||
accounts.add(a);
|
accounts.add(a);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Order createOrder(Account account, AssetPair pair, Order.Type type, double volume, double limit) {
|
public Order createOrder(AccountImpl account, AssetPair pair, Order.Type type, double volume, double limit) {
|
||||||
|
|
||||||
// Order o = new Order(world,account,assetpair,type,volume,limit);
|
// Order o = new Order(world,account,assetpair,type,volume,limit);
|
||||||
return null;
|
return null;
|
||||||
|
@ -280,7 +280,7 @@ public class GodWorld implements GetJson, World {
|
|||||||
return default_asset_pair;
|
return default_asset_pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AssetPair getAssetPair(AbstractAsset asset, AbstractAsset currency){
|
public AssetPair getAssetPair(Asset asset, Asset currency){
|
||||||
String s = AssetPair.buildSymbol(asset.getSymbol(), currency.getSymbol());
|
String s = AssetPair.buildSymbol(asset.getSymbol(), currency.getSymbol());
|
||||||
return asset_pairs.getOrDefault(s, null);
|
return asset_pairs.getOrDefault(s, null);
|
||||||
}
|
}
|
||||||
|
@ -106,12 +106,12 @@ public class Order implements Comparable<Order> {
|
|||||||
protected final Id id;
|
protected final Id id;
|
||||||
protected final long created;
|
protected final long created;
|
||||||
|
|
||||||
protected final Account account;
|
protected final AccountImpl account;
|
||||||
|
|
||||||
double cost;
|
double cost;
|
||||||
GodWorld world;
|
GodWorld world;
|
||||||
|
|
||||||
Order(TradingEngine engine, Account account, Type type,
|
Order(TradingEngine engine, AccountImpl account, Type type,
|
||||||
double volume, double limit, Addition addition) {
|
double volume, double limit, Addition addition) {
|
||||||
|
|
||||||
// Assign volume and initial volume
|
// Assign volume and initial volume
|
||||||
@ -132,7 +132,7 @@ public class Order implements Comparable<Order> {
|
|||||||
this.addition = addition;
|
this.addition = addition;
|
||||||
}
|
}
|
||||||
|
|
||||||
Order(opensesim.world.TradingEngine engine, Account account, Type type,
|
Order(opensesim.world.TradingEngine engine, AccountImpl account, Type type,
|
||||||
double volume, double limit) {
|
double volume, double limit) {
|
||||||
this(engine, account, type, volume, limit, Addition.NONE);
|
this(engine, account, type, volume, limit, Addition.NONE);
|
||||||
}
|
}
|
||||||
@ -173,7 +173,7 @@ public class Order implements Comparable<Order> {
|
|||||||
return cost / e;
|
return cost / e;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account getAccount() {
|
public AccountImpl getAccount() {
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ public class RealWorld implements World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AssetPair getAssetPair(AbstractAsset asset, AbstractAsset currency) {
|
public AssetPair getAssetPair(Asset asset, Asset currency) {
|
||||||
return godworld.getAssetPair(asset, currency);
|
return godworld.getAssetPair(asset, currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ public class SimpleTrader extends AbstractTrader implements EventListener {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account account_b, account_1;
|
public AccountImpl account_b, account_1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
@ -96,8 +96,8 @@ public class SimpleTrader extends AbstractTrader implements EventListener {
|
|||||||
|
|
||||||
AssetPair p = getWorld().getDefaultAssetPair();
|
AssetPair p = getWorld().getDefaultAssetPair();
|
||||||
|
|
||||||
account_b = new Account(getWorld());
|
account_b = new AccountImpl(getWorld());
|
||||||
account_1 = new Account(getWorld());
|
account_1 = new AccountImpl(getWorld());
|
||||||
|
|
||||||
AssetPack pack;
|
AssetPack pack;
|
||||||
// pack = new AssetPack(p.getAsset(), 0);
|
// pack = new AssetPack(p.getAsset(), 0);
|
||||||
@ -146,7 +146,7 @@ public class SimpleTrader extends AbstractTrader implements EventListener {
|
|||||||
Order obm = mapi.createOrder(account_b, Order.Type.BUYLIMIT, 20, 100);
|
Order obm = mapi.createOrder(account_b, Order.Type.BUYLIMIT, 20, 100);
|
||||||
|
|
||||||
|
|
||||||
Order oba = api.createOrder(account_1, Order.Type.SELLLIMIT, 10, 100);
|
Order oba = api.createOrder(account_1, Order.Type.SELLLIMIT, 20, 100);
|
||||||
Order obam = mapi.createOrder(account_1, Order.Type.SELLLIMIT, 20, 100);
|
Order obam = mapi.createOrder(account_1, Order.Type.SELLLIMIT, 20, 100);
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,6 @@ public interface Trader {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Account getAccount();
|
public AccountImpl getAccount();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public interface TradingAPI {
|
|||||||
|
|
||||||
public void addOrderBookListener(EventListener listener);
|
public void addOrderBookListener(EventListener listener);
|
||||||
|
|
||||||
public Order createOrder(Account account, Order.Type type, double volume, double limit);
|
public Order createOrder(AccountImpl account, Order.Type type, double volume, double limit);
|
||||||
|
|
||||||
public Set getBidBook();
|
public Set getBidBook();
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ class TradingEngine implements TradingAPI {
|
|||||||
boolean compact_history = false;
|
boolean compact_history = false;
|
||||||
boolean compact_last = true;
|
boolean compact_last = true;
|
||||||
|
|
||||||
private void transferMoneyAndShares(Account src, Account dst, double money, double shares) {
|
private void transferMoneyAndShares(AccountImpl src, AccountImpl dst, double money, double shares) {
|
||||||
// src.money -= money;
|
// src.money -= money;
|
||||||
|
|
||||||
AssetPack pack;
|
AssetPack pack;
|
||||||
@ -421,7 +421,7 @@ class TradingEngine implements TradingAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Order createOrder(Account account, Order.Type type,
|
public Order createOrder(AccountImpl account, Order.Type type,
|
||||||
double volume, double limit) {
|
double volume, double limit) {
|
||||||
|
|
||||||
Order o;
|
Order o;
|
||||||
@ -513,7 +513,7 @@ class TradingEngine implements TradingAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
executeOrders();
|
executeOrders();
|
||||||
last_quote.price = 90; //75-12.5;
|
// last_quote.price = 90; //75-12.5;
|
||||||
for (FiringEvent e : book_listener) {
|
for (FiringEvent e : book_listener) {
|
||||||
e.fire();
|
e.fire();
|
||||||
}
|
}
|
||||||
|
@ -62,5 +62,5 @@ public interface World {
|
|||||||
|
|
||||||
public long currentTimeMillis();
|
public long currentTimeMillis();
|
||||||
|
|
||||||
public AssetPair getAssetPair(AbstractAsset asset, AbstractAsset currency);
|
public AssetPair getAssetPair(Asset asset, Asset currency);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ public class AccountTest {
|
|||||||
/* @Test
|
/* @Test
|
||||||
public void testGetAssets() {
|
public void testGetAssets() {
|
||||||
System.out.println("getAssets");
|
System.out.println("getAssets");
|
||||||
Account instance = new Account();
|
AccountImpl instance = new AccountImpl();
|
||||||
Map<AbstractAsset, Double> expResult = null;
|
Map<AbstractAsset, Double> expResult = null;
|
||||||
Map<AbstractAsset, Double> result = instance.getAssets();
|
Map<AbstractAsset, Double> result = instance.getAssets();
|
||||||
assertEquals(expResult, result);
|
assertEquals(expResult, result);
|
||||||
@ -75,12 +75,12 @@ public class AccountTest {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* Test of getOwner method, of class Account.
|
* Test of getOwner method, of class AccountImpl.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testGetOwner() {
|
public void testGetOwner() {
|
||||||
System.out.println("getOwner");
|
System.out.println("getOwner");
|
||||||
Account instance = new Account();
|
AccountImpl instance = new AccountImpl();
|
||||||
Trader expResult = null;
|
Trader expResult = null;
|
||||||
Trader result = instance.getOwner();
|
Trader result = instance.getOwner();
|
||||||
assertEquals(expResult, result);
|
assertEquals(expResult, result);
|
||||||
@ -89,7 +89,7 @@ public class AccountTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of add method, of class Account.
|
* Test of add method, of class AccountImpl.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAdd() {
|
public void testAdd() {
|
||||||
@ -100,7 +100,7 @@ public class AccountTest {
|
|||||||
|
|
||||||
Double expResult = 123.0;
|
Double expResult = 123.0;
|
||||||
AssetPack pack = new AssetPack(c, expResult);
|
AssetPack pack = new AssetPack(c, expResult);
|
||||||
Account account = new Account();
|
AccountImpl account = new AccountImpl();
|
||||||
|
|
||||||
account.add(pack);
|
account.add(pack);
|
||||||
Double result;
|
Double result;
|
||||||
|
@ -89,11 +89,11 @@ public class ExchangeTest {
|
|||||||
AssetPair ap = new AssetPair(world,"EUR","AAPL");
|
AssetPair ap = new AssetPair(world,"EUR","AAPL");
|
||||||
|
|
||||||
Exchange instance = new Exchange(null, (JSONObject) null);
|
Exchange instance = new Exchange(null, (JSONObject) null);
|
||||||
Account expResult = null;
|
AccountImpl expResult = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Account result = instance.createAccount();
|
AccountImpl result = instance.createAccount();
|
||||||
// assertEquals(expResult, result);
|
// assertEquals(expResult, result);
|
||||||
// TODO review the generated test code and remove the default call to fail.
|
// TODO review the generated test code and remove the default call to fail.
|
||||||
// fail("The test case is a prototype.");
|
// fail("The test case is a prototype.");
|
||||||
|
@ -78,7 +78,7 @@ public class TradingAPITest {
|
|||||||
@Test
|
@Test
|
||||||
public void testCreateOrder() {
|
public void testCreateOrder() {
|
||||||
System.out.println("createOrder");
|
System.out.println("createOrder");
|
||||||
Account account = null;
|
AccountImpl account = null;
|
||||||
Order.Type type = null;
|
Order.Type type = null;
|
||||||
double volume = 0.0;
|
double volume = 0.0;
|
||||||
double limit = 0.0;
|
double limit = 0.0;
|
||||||
@ -152,7 +152,7 @@ public class TradingAPITest {
|
|||||||
public void addOrderBookListener(EventListener listener) {
|
public void addOrderBookListener(EventListener listener) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Order createOrder(Account account, Order.Type type, double volume, double limit) {
|
public Order createOrder(AccountImpl account, Order.Type type, double volume, double limit) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ public class TradingEngineTest {
|
|||||||
|
|
||||||
// AbstractAsset currency = gdworld.createAsset(cfg);
|
// AbstractAsset currency = gdworld.createAsset(cfg);
|
||||||
|
|
||||||
Account account = new Account();
|
AccountImpl account = new AccountImpl();
|
||||||
|
|
||||||
|
|
||||||
Order.Type type = null;
|
Order.Type type = null;
|
||||||
|
Loading…
Reference in New Issue
Block a user