Compare commits
34 Commits
b5cf77abbd
...
7359e15a54
Author | SHA1 | Date | |
---|---|---|---|
7359e15a54 | |||
8ab7c51101 | |||
9a4548ab35 | |||
9e1f1b8580 | |||
54ec792c13 | |||
97366b8335 | |||
9a88f42b7e | |||
|
f5552c7b5b | ||
|
703fe209b2 | ||
|
236138a822 | ||
|
8f35e767bd | ||
|
2d7feed929 | ||
a2e5143c64 | |||
|
b5c6d45f66 | ||
b193d69f52 | |||
fcdae01a8b | |||
|
0cedbbc3d4 | ||
|
3f43ff6f29 | ||
|
a1c1196ba1 | ||
|
0b62def911 | ||
|
0177510961 | ||
|
641285fafb | ||
|
215fb5e074 | ||
|
22e77665ee | ||
|
f7c2b6266e | ||
|
3a01f672eb | ||
|
3853beac19 | ||
|
d661de2892 | ||
|
6eb9ab8ff9 | ||
|
a9ad772112 | ||
|
e99aa62c59 | ||
|
401b6ce2f9 | ||
|
904b4a1016 | ||
|
844a57df27 |
11
ivy.xml
11
ivy.xml
@ -11,18 +11,7 @@
|
||||
<!-- https://mvnrepository.com/artifact/javax.help/javahelp -->
|
||||
<dependency org="javax.help" name="javahelp" rev="2.0.05"/>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
|
||||
<dependency org="com.fasterxml.jackson.core" name="jackson-core" rev="2.9.7"/>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
|
||||
<dependency org="com.fasterxml.jackson.core" name="jackson-databind" rev="2.9.7"/>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
|
||||
<!--<dependency org="com.fasterxml.jackson.core" name="jackson-annotations" rev="2.9.7"/>-->
|
||||
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
|
||||
<dependency org="com.google.code.gson" name="gson" rev="2.8.5"/>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
@ -155,18 +155,6 @@ is divided into following sections:
|
||||
<istrue value="${not.archive.disabled}"/>
|
||||
</or>
|
||||
</condition>
|
||||
<condition property="do.mkdist">
|
||||
<and>
|
||||
<isset property="do.archive"/>
|
||||
<isset property="libs.CopyLibs.classpath"/>
|
||||
<not>
|
||||
<istrue value="${mkdist.disabled}"/>
|
||||
</not>
|
||||
<not>
|
||||
<istrue value="${modules.supported.internal}"/>
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
<condition property="do.archive+manifest.available">
|
||||
<and>
|
||||
<isset property="manifest.available"/>
|
||||
@ -1194,13 +1182,27 @@ is divided into following sections:
|
||||
<attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
|
||||
</manifest>
|
||||
</target>
|
||||
<target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs">
|
||||
<target depends="init,compile" name="-check-do-mkdist">
|
||||
<condition property="do.mkdist">
|
||||
<and>
|
||||
<isset property="do.archive"/>
|
||||
<isset property="libs.CopyLibs.classpath"/>
|
||||
<not>
|
||||
<istrue value="${mkdist.disabled}"/>
|
||||
</not>
|
||||
<not>
|
||||
<available file="${build.classes.dir}/module-info.class"/>
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
</target>
|
||||
<target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-check-do-mkdist" if="do.mkdist" name="-do-jar-copylibs">
|
||||
<j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
|
||||
<echo level="info">To run this application from the command line without Ant, try:</echo>
|
||||
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
||||
<echo level="info">java -jar "${dist.jar.resolved}"</echo>
|
||||
</target>
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
|
||||
<target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-check-do-mkdist" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
|
||||
<j2seproject1:jar manifest="${tmp.manifest.file}"/>
|
||||
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
||||
|
@ -4,5 +4,5 @@ build.xml.stylesheet.CRC32=8064a381@1.79.1.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=65c6cbee
|
||||
nbproject/build-impl.xml.script.CRC32=ae093a94
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=3a2fa800@1.89.1.48
|
||||
nbproject/build-impl.xml.script.CRC32=afd0a16a
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=f89f7d21@1.95.0.48
|
||||
|
@ -1,4 +1,4 @@
|
||||
#Sat, 29 Dec 2018 21:04:02 +0100
|
||||
#Sat, 25 Jul 2020 00:02:41 +0200
|
||||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processors.list=
|
||||
@ -114,4 +114,4 @@ source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
ivy.home=/usr/share/java
|
||||
ivy.classpath=lib/commons-cli-1.0-javadoc.jar\:lib/commons-cli-1.0-sources.jar\:lib/commons-cli-1.0.jar\:lib/commons-lang-2.0-javadoc.jar\:lib/commons-lang-2.0-sources.jar\:lib/commons-lang-2.0.jar\:lib/commons-logging-1.0.jar\:lib/gson-2.8.5-javadoc.jar\:lib/gson-2.8.5-sources.jar\:lib/gson-2.8.5.jar\:lib/jackson-annotations-2.9.0.jar\:lib/jackson-core-2.9.7-javadoc.jar\:lib/jackson-core-2.9.7-sources.jar\:lib/jackson-core-2.9.7.jar\:lib/jackson-databind-2.9.7-javadoc.jar\:lib/jackson-databind-2.9.7-sources.jar\:lib/jackson-databind-2.9.7.jar\:lib/javahelp-2.0.05-javadoc.jar\:lib/javahelp-2.0.05-sources.jar\:lib/javahelp-2.0.05.jar\:lib/json-20160810-javadoc.jar\:lib/json-20160810-sources.jar\:lib/json-20160810.jar
|
||||
ivy.classpath=lib/accessors-smart-1.1.jar\:lib/asm-5.0.3.jar\:lib/hamcrest-core-1.3.jar\:lib/javahelp-2.0.05-javadoc.jar\:lib/javahelp-2.0.05-sources.jar\:lib/javahelp-2.0.05.jar\:lib/json-20160810-javadoc.jar\:lib/json-20160810-sources.jar\:lib/json-20160810.jar\:lib/json-path-2.1.0.jar\:lib/json-smart-2.2.jar\:lib/junit-4.12.jar\:lib/mockito-core-1.9.5.jar\:lib/objenesis-1.0.jar\:lib/slf4j-api-1.7.13.jar
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
package opensesim.gui;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Frame;
|
||||
import java.awt.GraphicsDevice;
|
||||
@ -94,6 +94,7 @@ public class SeSimApplication extends javax.swing.JFrame {
|
||||
cfg = new JSONObject(Globals.prefs.get("world", "{}"));
|
||||
godworld = new GodWorld(cfg);
|
||||
godworld.addAssetPair("AAPL", "EUR");
|
||||
godworld.addAssetPair("MSFT", "EUR");
|
||||
|
||||
// Get default screen and place our window
|
||||
// to the center of this screen
|
||||
@ -606,11 +607,12 @@ public class SeSimApplication extends javax.swing.JFrame {
|
||||
+ "strategy: opensesim.world.SimpleTrader"
|
||||
+ "}");
|
||||
Trader t = godworld.createTrader(cfg);
|
||||
t.start();
|
||||
|
||||
AccountDialog.runDialog(this, ((SimpleTrader)t).account_b);
|
||||
AccountDialog.runDialog(this, ((SimpleTrader)t).account_s);
|
||||
|
||||
t.start();
|
||||
AccountDialog.runDialog(this, ((SimpleTrader)t).account_1);
|
||||
AccountDialog.runDialog(this, ((SimpleTrader)t).account_b);
|
||||
|
||||
|
||||
updateGodWorld(godworld);
|
||||
|
||||
AssetPair p = godworld.getDefaultAssetPair();
|
||||
@ -929,7 +931,10 @@ public class SeSimApplication extends javax.swing.JFrame {
|
||||
AssetPair ap = godworld.getDefaultAssetPair();
|
||||
opensesim.world.Exchange ex = godworld.getDefaultExchange();
|
||||
opensesim.gui.orderbook.OrderBookDialog.runDialog(this, godworld, ex, ap);
|
||||
|
||||
|
||||
AbstractAsset eu = godworld.getAssetBySymbol("EUR");
|
||||
AssetPair ap2 = godworld.getAssetPair(godworld.getAssetBySymbol("MSFT"), eu);
|
||||
opensesim.gui.orderbook.OrderBookDialog.runDialog(this, godworld, ex, ap2);
|
||||
|
||||
}//GEN-LAST:event_jCheckBoxMenuItem1ActionPerformed
|
||||
|
||||
@ -1048,10 +1053,10 @@ public class SeSimApplication extends javax.swing.JFrame {
|
||||
// testing
|
||||
Pojo p = new Pojo();
|
||||
|
||||
Gson g = new Gson();
|
||||
String r = g.toJson(p);
|
||||
// Gson g = new Gson();
|
||||
// String r = g.toJson(p);
|
||||
|
||||
System.out.printf("GSON: %s\n", r);
|
||||
// System.out.printf("GSON: %s\n", r);
|
||||
|
||||
JSONObject o = new JSONObject(p, new String[]{"name", "symbol"});
|
||||
System.out.printf("OJSON: %s\n", o.toString(8));
|
||||
|
@ -23,18 +23,12 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="1" attributes="0">
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
<Component id="accountPanel1" min="-2" pref="400" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="accountPanel1" alignment="1" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="accountPanel1" min="-2" pref="228" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="72" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="accountPanel1" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
package opensesim.gui.account;
|
||||
|
||||
import opensesim.world.Account;
|
||||
import opensesim.world.AccountImpl;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -42,11 +42,12 @@ 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;
|
||||
d=new AccountDialog(parent, false);
|
||||
d.accountPanel1.account=account;
|
||||
d.accountPanel1.update();
|
||||
account.addListener(d.accountPanel1);
|
||||
d.setVisible(true);
|
||||
}
|
||||
|
||||
@ -67,15 +68,11 @@ public class AccountDialog extends javax.swing.JDialog {
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
|
||||
.addGap(0, 0, Short.MAX_VALUE)
|
||||
.addComponent(accountPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 400, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addComponent(accountPanel1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(accountPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 228, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(0, 72, Short.MAX_VALUE))
|
||||
.addComponent(accountPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
pack();
|
||||
|
@ -17,11 +17,26 @@
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" pref="400" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace type="unrelated" max="-2" attributes="0"/>
|
||||
<Component id="finalbalance" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="jScrollPane1" min="-2" pref="214" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" pref="32" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="finalbalance" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace min="0" pref="32" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
@ -36,9 +51,11 @@
|
||||
<Component class="javax.swing.JTable" name="assetTable">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
|
||||
<Table columnCount="2" rowCount="2">
|
||||
<Table columnCount="4" rowCount="2">
|
||||
<Column editable="false" title="Asset" type="java.lang.String"/>
|
||||
<Column editable="false" title="Ammount" type="java.lang.String"/>
|
||||
<Column editable="false" title="Margin" type="java.lang.String"/>
|
||||
<Column editable="false" title="SL" type="java.lang.String"/>
|
||||
</Table>
|
||||
</Property>
|
||||
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
|
||||
@ -62,5 +79,15 @@
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="jLabel1">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="Final:"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="finalbalance">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" value="jLabel2"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -30,44 +30,61 @@ import javax.swing.table.DefaultTableModel;
|
||||
import opensesim.util.scheduler.Event;
|
||||
import opensesim.util.scheduler.EventListener;
|
||||
import opensesim.world.AbstractAsset;
|
||||
import opensesim.world.Account;
|
||||
import opensesim.world.AccountImpl;
|
||||
import opensesim.world.Asset;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author tube
|
||||
*/
|
||||
public class AccountPanel extends javax.swing.JPanel implements EventListener{
|
||||
public class AccountPanel extends javax.swing.JPanel implements EventListener {
|
||||
|
||||
/**
|
||||
* Creates new form AccountPanel
|
||||
*/
|
||||
public AccountPanel() {
|
||||
initComponents();
|
||||
assetTable.setAutoCreateRowSorter(true);
|
||||
assetTable.setAutoCreateRowSorter(true);
|
||||
assetTable.getTableHeader().setReorderingAllowed(false);
|
||||
}
|
||||
|
||||
public Account account;
|
||||
public AccountImpl account;
|
||||
|
||||
void update() {
|
||||
DefaultTableModel model;
|
||||
model = (DefaultTableModel) this.assetTable.getModel();
|
||||
|
||||
Map<AbstractAsset, Double> am = account.getAssets();
|
||||
|
||||
Map<Asset, Double> am = account.getAssets();
|
||||
|
||||
int row = 0;
|
||||
model.setRowCount(am.size());
|
||||
for (AbstractAsset a : am.keySet()) {
|
||||
Double val = account.get(a);
|
||||
Double avail = account.getAvail(a);
|
||||
String astr = val.toString()+"/"+avail.toString();
|
||||
for (Asset a : am.keySet()) {
|
||||
Double val = account.get((AbstractAsset) a,false);
|
||||
Double avail = account.getBound((AbstractAsset) a);
|
||||
String astr = val.toString() + "/" + avail.toString();
|
||||
|
||||
Double mval = account.getMargin((AbstractAsset) a);
|
||||
// Double mavail = account.getMargin((AbstractAsset) a)-account.margin_bound;
|
||||
String mastr = "xxx" ; //Double(0.0(.toString()+ "/" + mavail.toString();
|
||||
|
||||
|
||||
Double sl = account.calcStopLoss((AbstractAsset) a);
|
||||
|
||||
// model.setValueAt(ob1.getAccount().getOwner().getName(), row, 0);
|
||||
model.setValueAt(a.getSymbol(), row, 0);
|
||||
model.setValueAt(astr, row, 1);
|
||||
// model.setValueAt(mastr, row, 2);
|
||||
model.setValueAt(sl.toString(), row, 3);
|
||||
row++;
|
||||
}
|
||||
|
||||
String fb;
|
||||
Double margin = account.getMargin(account.getWorld().getDefaultCurrency());
|
||||
fb = account.getFinalBalance().toString() + " Margin: " +
|
||||
margin.toString();
|
||||
|
||||
this.finalbalance.setText(fb);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,21 +98,23 @@ public class AccountPanel extends javax.swing.JPanel implements EventListener{
|
||||
|
||||
jScrollPane1 = new javax.swing.JScrollPane();
|
||||
assetTable = new javax.swing.JTable();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
finalbalance = new javax.swing.JLabel();
|
||||
|
||||
assetTable.setModel(new javax.swing.table.DefaultTableModel(
|
||||
new Object [][] {
|
||||
{null, null},
|
||||
{null, null}
|
||||
{null, null, null, null},
|
||||
{null, null, null, null}
|
||||
},
|
||||
new String [] {
|
||||
"Asset", "Ammount"
|
||||
"Asset", "Ammount", "Margin", "SL"
|
||||
}
|
||||
) {
|
||||
Class[] types = new Class [] {
|
||||
java.lang.String.class, java.lang.String.class
|
||||
java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
|
||||
};
|
||||
boolean[] canEdit = new boolean [] {
|
||||
false, false
|
||||
false, false, false, false
|
||||
};
|
||||
|
||||
public Class getColumnClass(int columnIndex) {
|
||||
@ -108,21 +127,39 @@ public class AccountPanel extends javax.swing.JPanel implements EventListener{
|
||||
});
|
||||
jScrollPane1.setViewportView(assetTable);
|
||||
|
||||
jLabel1.setText("Final:");
|
||||
|
||||
finalbalance.setText("jLabel2");
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(jLabel1)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
|
||||
.addComponent(finalbalance)
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 214, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addGap(32, 32, 32)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(jLabel1)
|
||||
.addComponent(finalbalance))
|
||||
.addGap(0, 32, Short.MAX_VALUE))
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JTable assetTable;
|
||||
private javax.swing.JLabel finalbalance;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
|
28
src/opensesim/gui/account/StatusPanel.form
Normal file
28
src/opensesim/gui/account/StatusPanel.form
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="400" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<EmptySpace min="0" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
</Form>
|
78
src/opensesim/gui/account/StatusPanel.java
Normal file
78
src/opensesim/gui/account/StatusPanel.java
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.gui.account;
|
||||
|
||||
import opensesim.world.AccountImpl;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author 7u83 <7u83@mail.ru>
|
||||
*/
|
||||
public class StatusPanel extends javax.swing.JPanel {
|
||||
|
||||
/**
|
||||
* Creates new form StatusPanel
|
||||
*/
|
||||
public StatusPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
public StatusPanel(AccountImpl account) {
|
||||
this();
|
||||
setAccount(account);
|
||||
}
|
||||
|
||||
private AccountImpl account;
|
||||
|
||||
public void setAccount(AccountImpl account) {
|
||||
this.account = account;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 400, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGap(0, 300, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
@ -37,7 +37,7 @@ public abstract class AbstractTrader implements Trader {
|
||||
private String name = "Unnamed";
|
||||
private String status;
|
||||
private World world;
|
||||
protected Account account;
|
||||
protected AccountImpl account;
|
||||
|
||||
/**
|
||||
* @return the world
|
||||
@ -100,7 +100,7 @@ public abstract class AbstractTrader implements Trader {
|
||||
|
||||
public AbstractTrader(World world, JSONObject cfg) {
|
||||
this.world=world;
|
||||
this.account = new Account();
|
||||
this.account = new AccountImpl(world);
|
||||
|
||||
AssetPack pack;
|
||||
pack = new AssetPack(this.world.getDefaultAssetPair().getCurrency(),1000);
|
||||
@ -118,7 +118,7 @@ public abstract class AbstractTrader implements Trader {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account getAccount(){
|
||||
public AccountImpl getAccount(){
|
||||
return account;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 7u83 <7u83@mail.ru>
|
||||
* Copyright (c) 2019, 7u83 <7u83@mail.ru>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -25,86 +25,24 @@
|
||||
*/
|
||||
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 Account {
|
||||
|
||||
HashMap<AbstractAsset, Double> assets = new HashMap<>();
|
||||
HashMap<AbstractAsset, Double> assets_avail = new HashMap<>();
|
||||
|
||||
Trader owner;
|
||||
Exchange exchange = null;
|
||||
|
||||
public Map<AbstractAsset, Double> getAssets() {
|
||||
return Collections.unmodifiableMap(assets);
|
||||
}
|
||||
|
||||
public Map<AbstractAsset, Double> getAssetsAavail() {
|
||||
return Collections.unmodifiableMap(assets_avail);
|
||||
}
|
||||
|
||||
public Trader getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
protected Account(Exchange exchange) {
|
||||
this.exchange = exchange;
|
||||
}
|
||||
|
||||
protected Account(Exchange exchange, JSONObject cfg) {
|
||||
this.exchange = exchange;
|
||||
}
|
||||
|
||||
Account() {
|
||||
|
||||
}
|
||||
|
||||
synchronized void add(AssetPack pack) {
|
||||
assets.put(pack.asset, get(pack.asset) + pack.volume);
|
||||
assets_avail.put(pack.asset, getAvail(pack.asset) + pack.volume);
|
||||
}
|
||||
|
||||
synchronized void sub(AssetPack pack) {
|
||||
assets.put(pack.asset, get(pack.asset) - pack.volume);
|
||||
// assets_avail.put(pack.asset, getAvail(pack.asset) - pack.volume);
|
||||
}
|
||||
|
||||
public interface Account {
|
||||
/**
|
||||
* Get a list of assets accumulated in this account
|
||||
* @return Map of assets
|
||||
*/
|
||||
public Map<Asset, Double> getAssets();
|
||||
|
||||
/**
|
||||
* Get the exchange this accounts belongs to
|
||||
* @return Exchange
|
||||
*/
|
||||
public Exchange getExchange() ;
|
||||
|
||||
|
||||
public double get(AbstractAsset asset) {
|
||||
return assets.getOrDefault(asset, 0.0);
|
||||
}
|
||||
|
||||
public double getAvail(AbstractAsset asset) {
|
||||
return assets_avail.getOrDefault(asset, 0.0);
|
||||
}
|
||||
|
||||
public void addAvail(AbstractAsset asset, double val) {
|
||||
double avail = getAvail(asset);
|
||||
assets_avail.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
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, Order> 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -50,7 +50,7 @@ public interface Asset {
|
||||
public String getSymbol();
|
||||
|
||||
/**
|
||||
* Determine if this asset can be used as currency
|
||||
* Determine if this asset can be used as currency.
|
||||
* @return true if asset can act as currency, false if not.
|
||||
*/
|
||||
public boolean isCurrency();
|
||||
|
@ -51,12 +51,12 @@ public class AssetPair {
|
||||
return buildSymbol(asset.getSymbol(),currency.getSymbol());
|
||||
}
|
||||
|
||||
public AssetPair(AbstractAsset asset, AbstractAsset currency) {
|
||||
AssetPair(AbstractAsset asset, AbstractAsset currency) {
|
||||
this.asset = asset;
|
||||
this.currency = currency;
|
||||
}
|
||||
|
||||
public AssetPair(World world, String asset, String currency){
|
||||
AssetPair(World world, String asset, String currency){
|
||||
this.asset = world.getAssetBySymbol(asset);
|
||||
this.currency = world.getAssetBySymbol(currency);
|
||||
}
|
||||
|
@ -41,10 +41,10 @@ public class Exchange implements Configurable, GetJson {
|
||||
private String name;
|
||||
private String symbol;
|
||||
|
||||
public void setName(String name) {
|
||||
/* public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
*/
|
||||
private final HashMap<AssetPair, TradingAPI> asset_pairs = new HashMap<>();
|
||||
|
||||
Exchange(GodWorld world, String symbol) {
|
||||
@ -68,15 +68,15 @@ public class Exchange implements Configurable, GetJson {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
private HashSet<Account> accounts = new HashSet<>();
|
||||
private HashSet<AccountImpl> accounts = new HashSet<>();
|
||||
|
||||
Account createAccount() {
|
||||
Account a = new Account(this);
|
||||
AccountImpl createAccount() {
|
||||
AccountImpl a = new AccountImpl(this.world);
|
||||
accounts.add(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);
|
||||
return null;
|
||||
|
@ -62,6 +62,11 @@ public class GodWorld implements GetJson, World {
|
||||
return scheduler.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractAsset getDefaultCurrency() {
|
||||
return getDefaultAssetPair().getCurrency();
|
||||
}
|
||||
|
||||
public static final class JKEYS {
|
||||
|
||||
public static final String ASSETS = "assets";
|
||||
@ -256,6 +261,9 @@ public class GodWorld implements GetJson, World {
|
||||
}
|
||||
|
||||
public void add(AssetPair pair) {
|
||||
if (pair.getAsset()==null || pair.getCurrency()==null){
|
||||
return;
|
||||
}
|
||||
asset_pairs.put(pair.getSymbol(), pair);
|
||||
if (default_asset_pair == null) {
|
||||
default_asset_pair = pair;
|
||||
@ -271,6 +279,11 @@ public class GodWorld implements GetJson, World {
|
||||
public AssetPair getDefaultAssetPair() {
|
||||
return default_asset_pair;
|
||||
}
|
||||
|
||||
public AssetPair getAssetPair(Asset asset, Asset currency){
|
||||
String s = AssetPair.buildSymbol(asset.getSymbol(), currency.getSymbol());
|
||||
return asset_pairs.getOrDefault(s, null);
|
||||
}
|
||||
|
||||
|
||||
/* public AbstractAsset createAsset(long key, JSONObject cfg) throws SeSimException{
|
||||
|
@ -69,9 +69,21 @@ public class Order implements Comparable<Order> {
|
||||
* Definition of order status
|
||||
*/
|
||||
public static enum Status {
|
||||
OPEN, PARTIALLY_EXECUTED, CLOSED, CANCELED
|
||||
OPEN, PARTIALLY_EXECUTED, CLOSED, CANCELED, ERROR
|
||||
}
|
||||
|
||||
String message="";
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
private void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Definition of order types
|
||||
*/
|
||||
@ -94,12 +106,12 @@ public class Order implements Comparable<Order> {
|
||||
protected final Id id;
|
||||
protected final long created;
|
||||
|
||||
protected final Account account;
|
||||
protected final AccountImpl account;
|
||||
|
||||
double cost;
|
||||
GodWorld world;
|
||||
|
||||
Order(TradingEngine engine, Account account, Type type,
|
||||
Order(TradingEngine engine, AccountImpl account, Type type,
|
||||
double volume, double limit, Addition addition) {
|
||||
|
||||
// Assign volume and initial volume
|
||||
@ -120,7 +132,7 @@ public class Order implements Comparable<Order> {
|
||||
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) {
|
||||
this(engine, account, type, volume, limit, Addition.NONE);
|
||||
}
|
||||
@ -161,7 +173,7 @@ public class Order implements Comparable<Order> {
|
||||
return cost / e;
|
||||
}
|
||||
|
||||
public Account getAccount() {
|
||||
public AccountImpl getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
|
@ -85,4 +85,14 @@ public class RealWorld implements World {
|
||||
return godworld.getDefaultAssetPair();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssetPair getAssetPair(Asset asset, Asset currency) {
|
||||
return godworld.getAssetPair(asset, currency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractAsset getDefaultCurrency() {
|
||||
return godworld.getDefaultCurrency();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public class SimpleTrader extends AbstractTrader implements EventListener {
|
||||
if (cfg == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public SimpleTrader() {
|
||||
@ -74,8 +74,8 @@ public class SimpleTrader extends AbstractTrader implements EventListener {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Account account_s, account_b;
|
||||
|
||||
public AccountImpl account_b, account_1;
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
setVerbose(true);
|
||||
@ -92,47 +92,30 @@ public class SimpleTrader extends AbstractTrader implements EventListener {
|
||||
setStatus("Stopped.");
|
||||
return;
|
||||
}
|
||||
AbstractAsset c,a;
|
||||
AbstractAsset c, a;
|
||||
|
||||
AssetPair p = getWorld().getDefaultAssetPair();
|
||||
|
||||
account_s = new Account();
|
||||
account_b = new Account();
|
||||
|
||||
|
||||
account_b = new AccountImpl(getWorld());
|
||||
account_1 = new AccountImpl(getWorld());
|
||||
|
||||
AssetPack pack;
|
||||
pack = new AssetPack(p.getAsset(),200);
|
||||
account_s.add(pack);
|
||||
|
||||
pack = new AssetPack(p.getCurrency(),10000);
|
||||
// pack = new AssetPack(p.getAsset(), 0);
|
||||
// account_b.add(pack);
|
||||
|
||||
pack = new AssetPack(p.getCurrency(), 1000);
|
||||
account_b.add(pack);
|
||||
|
||||
ex = getWorld().getDefaultExchange();
|
||||
api = ex.getAPI(p);
|
||||
|
||||
account_b.setLeverage(9);
|
||||
|
||||
Order oa = api.createOrder(account_b, Order.Type.BUYLIMIT, 200, 100);
|
||||
Order ob = api.createOrder(account_s, Order.Type.SELLLIMIT, 200,200);
|
||||
pack = new AssetPack(p.getCurrency(), 10000);
|
||||
account_1.add(pack);
|
||||
account_1.setLeverage(0.0);
|
||||
account_1.setUnlimied(true);
|
||||
|
||||
|
||||
// Order oa = api.createOrder(account_b, Order.Type.BUYLIMIT, 100, 10.0);
|
||||
// Order ob = api.createOrder(account_b, Order.Type.BUYLIMIT, 100, 9.0);
|
||||
// Order oc = api.createOrder(account_b, Order.Type.BUYLIMIT, 100, 8.0);
|
||||
|
||||
// Order o2 = api.createOrder(account_s, Order.Type.SELLLIMIT, 300, 1.0);
|
||||
|
||||
|
||||
//Order ou = api.createOrder(account_b, Order.Type.BUYLIMIT, 30, 10.0);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Order o1 = api.createOrder(account, Order.Type.SELLLIMIT, 250, 278);
|
||||
|
||||
|
||||
long delay = (long) (1000.0f * getWorld().randNextFloat(3.0f, 12.7f));
|
||||
long delay = (long) (1000.0f * getWorld().randNextFloat(5.0f, 5.7f));
|
||||
setStatus(String.format("Initial delay: Sleeping for %d seconds.", delay));
|
||||
// getWorld().schedule(this, delay);
|
||||
|
||||
getWorld().schedule(this, delay);
|
||||
|
||||
// long delay = (long) (getRandom(initial_delay[0], initial_delay[1]) * 1000);
|
||||
// setStatus("Inital delay: %d", delay);
|
||||
@ -143,9 +126,6 @@ public class SimpleTrader extends AbstractTrader implements EventListener {
|
||||
|
||||
double limit = 253.871239;
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public long receive(Event task) {
|
||||
// System.out.printf("Here we are !!! %f\n", getWorld().randNextFloat(12f, 27f));
|
||||
@ -153,16 +133,23 @@ public class SimpleTrader extends AbstractTrader implements EventListener {
|
||||
long diff = getWorld().currentTimeMillis() - last_time;
|
||||
last_time = getWorld().currentTimeMillis();
|
||||
|
||||
System.out.printf("Here we are: %d - [%d]\n", Thread.currentThread().getId(), diff);
|
||||
getWorld().schedule(this, 1000);
|
||||
|
||||
AssetPair p = getWorld().getDefaultAssetPair();
|
||||
|
||||
AssetPair p = getWorld().getDefaultAssetPair();
|
||||
|
||||
ex = getWorld().getDefaultExchange();
|
||||
api = ex.getAPI(p);
|
||||
Order o = api.createOrder(account, Order.Type.BUY, 112.987123, limit);
|
||||
limit += 12;
|
||||
|
||||
api = ex.getAPI(p);
|
||||
|
||||
AssetPair msftp = getWorld().getAssetPair(
|
||||
getWorld().getAssetBySymbol("MSFT"),
|
||||
getWorld().getAssetBySymbol("EUR"));
|
||||
|
||||
TradingAPI mapi = ex.getAPI(msftp);
|
||||
|
||||
Order ob = api.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, 20, 100);
|
||||
Order obam = mapi.createOrder(account_1, Order.Type.SELLLIMIT, 20, 100);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,6 @@ public interface Trader {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Account getAccount();
|
||||
public AccountImpl getAccount();
|
||||
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public interface TradingAPI {
|
||||
|
||||
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();
|
||||
|
||||
@ -51,5 +51,7 @@ public interface TradingAPI {
|
||||
public AssetPair getAssetPair();
|
||||
|
||||
public Set<Quote> getQuoteHistory();
|
||||
|
||||
|
||||
public Quote getLastQuote();
|
||||
|
||||
}
|
||||
|
@ -42,17 +42,17 @@ import opensesim.util.scheduler.FiringEvent;
|
||||
*/
|
||||
class TradingEngine implements TradingAPI {
|
||||
|
||||
private final Exchange outer;
|
||||
private final Exchange exchange;
|
||||
|
||||
/**
|
||||
* Construct a trading engine for an asset pair
|
||||
*
|
||||
* @param pair The AssetPair object to create the trading engine for
|
||||
* @param outer Outer class - points to an Exchange object thins trading
|
||||
* @param exchange Outer class - points to an Exchange object this trading
|
||||
* engine belongs to.
|
||||
*/
|
||||
TradingEngine(AssetPair pair, final Exchange outer) {
|
||||
this.outer = outer;
|
||||
TradingEngine(AssetPair pair, final Exchange exchange) {
|
||||
this.exchange = exchange;
|
||||
assetpair = pair;
|
||||
reset();
|
||||
}
|
||||
@ -117,7 +117,7 @@ class TradingEngine implements TradingAPI {
|
||||
boolean compact_history = false;
|
||||
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;
|
||||
|
||||
AssetPack pack;
|
||||
@ -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;
|
||||
@ -219,8 +219,8 @@ class TradingEngine implements TradingAPI {
|
||||
q = new Quote(quote_id_generator.getNext());
|
||||
q.price = price;
|
||||
q.volume = volume;
|
||||
q.time = outer.world.currentTimeMillis();
|
||||
q.type = type;
|
||||
q.time = exchange.world.currentTimeMillis();
|
||||
q.type = type;
|
||||
addQuoteToHistory(q);
|
||||
}
|
||||
|
||||
@ -250,7 +250,6 @@ class TradingEngine implements TradingAPI {
|
||||
this.checkSLOrders(price);
|
||||
}
|
||||
*/
|
||||
|
||||
//
|
||||
// Match limited orders against limited orders
|
||||
//
|
||||
@ -288,16 +287,30 @@ 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);
|
||||
double avdiff;
|
||||
// b.account.addAvail(assetpair.getCurrency(), avdiff);
|
||||
avdiff = b.limit * volume - price * volume;
|
||||
|
||||
// Unbind
|
||||
|
||||
double bound = b.account.getBound(assetpair.getCurrency());
|
||||
double addbound = volume*b.limit;
|
||||
|
||||
b.account.addBound(assetpair.getCurrency(), volume*b.limit);
|
||||
b.account.addBound(assetpair.getAsset(), -volume);
|
||||
|
||||
a.account.addBound(assetpair.getCurrency(), -volume*b.limit);
|
||||
a.account.addBound(assetpair.getAsset(), volume);
|
||||
|
||||
|
||||
// b.account.addMarginAvail(assetpair.getCurrency(), avdiff/b.account.getLeverage());
|
||||
finishTrade(b, a, price, volume);
|
||||
|
||||
if (!compact_history) {
|
||||
q = new Quote(quote_id_generator.getNext());
|
||||
q.price = price;
|
||||
q.volume = volume;
|
||||
q.time = outer.world.currentTimeMillis();
|
||||
q.time = exchange.world.currentTimeMillis();
|
||||
q.type = type;
|
||||
addQuoteToHistory(q);
|
||||
}
|
||||
@ -317,7 +330,7 @@ class TradingEngine implements TradingAPI {
|
||||
qc = new Quote(quote_id_generator.getNext());
|
||||
qc.price = money_total / volume_total;
|
||||
qc.volume = volume_total;
|
||||
qc.time = outer.world.currentTimeMillis();
|
||||
qc.time = exchange.world.currentTimeMillis();
|
||||
|
||||
if (compact_history) {
|
||||
addQuoteToHistory(qc);
|
||||
@ -362,7 +375,7 @@ class TradingEngine implements TradingAPI {
|
||||
return b.limit;
|
||||
}
|
||||
|
||||
// Last price is grater ask, so return the current ask
|
||||
// Last price is greater than ask, so return the current ask
|
||||
if (last_quote.price > a.limit) {
|
||||
return a.limit;
|
||||
}
|
||||
@ -409,7 +422,7 @@ class TradingEngine implements TradingAPI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Order createOrder(Account account, Order.Type type,
|
||||
public Order createOrder(AccountImpl account, Order.Type type,
|
||||
double volume, double limit) {
|
||||
|
||||
Order o;
|
||||
@ -430,17 +443,23 @@ class TradingEngine implements TradingAPI {
|
||||
|
||||
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) {
|
||||
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
|
||||
account.assets_avail.put(currency, avail - v * l);
|
||||
// account.assets_bound.put(currency, avail - v * l);
|
||||
//account.addMarginAvail(currency, -((v * l)/account.getLeverage()));
|
||||
order_limit = l;
|
||||
break;
|
||||
|
||||
@ -450,15 +469,16 @@ class TradingEngine implements TradingAPI {
|
||||
// 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;
|
||||
|
||||
}
|
||||
// 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_avail.put(currency, 0.0);
|
||||
account.assets_bound.put(currency, 0.0);
|
||||
// we "mis"use order_limit to memorize occupied ammount \
|
||||
// of currency
|
||||
order_limit = avail;
|
||||
@ -468,17 +488,12 @@ class TradingEngine implements TradingAPI {
|
||||
|
||||
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
|
||||
if (!account.bind(assetpair, -volume, limit)) {
|
||||
System.out.printf("Not enough funds\n");
|
||||
return null;
|
||||
}
|
||||
account.assets_avail
|
||||
.put(asset, avail - v);
|
||||
}
|
||||
|
||||
|
||||
order_limit = l;
|
||||
break;
|
||||
|
||||
@ -497,16 +512,20 @@ class TradingEngine implements TradingAPI {
|
||||
|
||||
}
|
||||
}
|
||||
executeOrders();
|
||||
|
||||
executeOrders();
|
||||
// last_quote.price = 90; //75-12.5;
|
||||
for (FiringEvent e : book_listener) {
|
||||
e.fire();
|
||||
}
|
||||
|
||||
account.notfiyListeners();
|
||||
return o;
|
||||
|
||||
}
|
||||
|
||||
HashSet<FiringEvent> book_listener = new HashSet<>();
|
||||
HashSet<FiringEvent> book_listener
|
||||
= new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void addOrderBookListener(EventListener listener) {
|
||||
@ -515,18 +534,25 @@ class TradingEngine implements TradingAPI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set getOrderBook(Order.Type type) {
|
||||
public Set
|
||||
getOrderBook(Order.Type type
|
||||
) {
|
||||
switch (type) {
|
||||
case BUYLIMIT:
|
||||
case BUY:
|
||||
return Collections.unmodifiableSet(bidbook);
|
||||
return Collections
|
||||
.unmodifiableSet(bidbook
|
||||
);
|
||||
|
||||
case SELLLIMIT:
|
||||
case SELL:
|
||||
return Collections.unmodifiableSet(askbook);
|
||||
return Collections
|
||||
.unmodifiableSet(askbook
|
||||
);
|
||||
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -547,9 +573,12 @@ class TradingEngine implements TradingAPI {
|
||||
|
||||
@Override
|
||||
public Set<Quote> getQuoteHistory() {
|
||||
return Collections
|
||||
.unmodifiableSet(quote_history
|
||||
);
|
||||
return Collections.unmodifiableSet(quote_history);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Quote getLastQuote() {
|
||||
return this.last_quote;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,19 +30,29 @@ import java.util.Collection;
|
||||
import opensesim.util.scheduler.EventListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* The interface to the world. Used by traders. And others.
|
||||
* @author 7u83 <7u83@mail.ru>
|
||||
*/
|
||||
public interface World {
|
||||
|
||||
/**
|
||||
* Get available assets in this world.
|
||||
* @return Collection of {@link opensesim.world.Asset}s
|
||||
*/
|
||||
public Collection<AbstractAsset> getAssetCollection();
|
||||
|
||||
/**
|
||||
* Return asset by symbol
|
||||
* @param symbol symbol to find
|
||||
* @return asset
|
||||
*/
|
||||
public AbstractAsset getAssetBySymbol(String symbol);
|
||||
|
||||
Collection<Exchange> getExchangeCollection();
|
||||
|
||||
public Exchange getDefaultExchange();
|
||||
public AssetPair getDefaultAssetPair();
|
||||
public AbstractAsset getDefaultCurrency();
|
||||
|
||||
Collection<Trader> getTradersCollection();
|
||||
|
||||
@ -51,4 +61,6 @@ public interface World {
|
||||
public float randNextFloat(float min, float max);
|
||||
|
||||
public long currentTimeMillis();
|
||||
|
||||
public AssetPair getAssetPair(Asset asset, Asset currency);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public class AccountTest {
|
||||
/* @Test
|
||||
public void testGetAssets() {
|
||||
System.out.println("getAssets");
|
||||
Account instance = new Account();
|
||||
AccountImpl instance = new AccountImpl();
|
||||
Map<AbstractAsset, Double> expResult = null;
|
||||
Map<AbstractAsset, Double> result = instance.getAssets();
|
||||
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
|
||||
public void testGetOwner() {
|
||||
System.out.println("getOwner");
|
||||
Account instance = new Account();
|
||||
AccountImpl instance = new AccountImpl();
|
||||
Trader expResult = null;
|
||||
Trader result = instance.getOwner();
|
||||
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
|
||||
public void testAdd() {
|
||||
@ -100,7 +100,7 @@ public class AccountTest {
|
||||
|
||||
Double expResult = 123.0;
|
||||
AssetPack pack = new AssetPack(c, expResult);
|
||||
Account account = new Account();
|
||||
AccountImpl account = new AccountImpl();
|
||||
|
||||
account.add(pack);
|
||||
Double result;
|
||||
|
@ -89,11 +89,11 @@ public class ExchangeTest {
|
||||
AssetPair ap = new AssetPair(world,"EUR","AAPL");
|
||||
|
||||
Exchange instance = new Exchange(null, (JSONObject) null);
|
||||
Account expResult = null;
|
||||
AccountImpl expResult = null;
|
||||
|
||||
|
||||
|
||||
Account result = instance.createAccount();
|
||||
AccountImpl result = instance.createAccount();
|
||||
// assertEquals(expResult, result);
|
||||
// TODO review the generated test code and remove the default call to fail.
|
||||
// fail("The test case is a prototype.");
|
||||
|
@ -78,7 +78,7 @@ public class TradingAPITest {
|
||||
@Test
|
||||
public void testCreateOrder() {
|
||||
System.out.println("createOrder");
|
||||
Account account = null;
|
||||
AccountImpl account = null;
|
||||
Order.Type type = null;
|
||||
double volume = 0.0;
|
||||
double limit = 0.0;
|
||||
@ -152,7 +152,7 @@ public class TradingAPITest {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ public class TradingEngineTest {
|
||||
|
||||
// AbstractAsset currency = gdworld.createAsset(cfg);
|
||||
|
||||
Account account = new Account();
|
||||
AccountImpl account = new AccountImpl();
|
||||
|
||||
|
||||
Order.Type type = null;
|
||||
|
Loading…
Reference in New Issue
Block a user