Warning: session_start(): open(/var/lib/php/sessions/sess_md35sjm96hgal8imt5u7p82ptn, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import java.util.function.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.imageio.*;
import java.math.*;
import java.time.Duration;
import java.lang.invoke.VarHandle;
import java.lang.invoke.MethodHandles;
import java.text.*;
import java.text.NumberFormat;
import java.util.TimeZone;
import java.awt.geom.*;
import static x30_pkg.x30_util.DynamicObject;
import java.nio.file.Path;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
class main {
abstract static class G22TradingStrategy extends ConceptWithChangeListeners implements Comparable, Juiceable {
static final String _fieldOrder = "verbose globalID customName comment q market mergePositionsForMarket cryptoCoin marginCoin exchangeName tradingAccount priceDataFromExchange accountName primed usingLiveData doingRealTrades demoCoin active closedItself deactivated archived area adversity log timedLog epsilon cryptoStep minCrypto maxCrypto maxInvestment strategyCrest maxDrawdown cellSize leverage marginPerPosition riskPerTrade riskedEquity showClosedPositionsBackwards takeCoinProfit takeCoinProfitEnabled backDataHoursWanted backDataFed strategyJuicer logToPrint feedNote useDriftSystem driftSystem actualTicker cooldownMinutes image imageForWebServer compoundingBaseEquity tpSlOnPlatform listOrder digitizer direction maxDebt currentPrice oldPrice startingPrice startTime realizedProfit realizedCoinProfit realizedWins realizedCoinWins realizedLosses realizedCoinLosses stepCount stepSince openPositions closedPositions positionsThatFailedToOpen";
final String fieldsToReset_G22TradingStrategy(){ return fieldsToReset(); }
String fieldsToReset() {
return "\r\n globalID active\r\n q\r\n archived primed usingLiveData \r\n backDataFed startTime deactivated closedItself\r\n log timedLog currentTime currentPrice feedNote\r\n direction\r\n digitizer maxDebt direction oldPrice startingPrice\r\n strategyCrest\r\n maxInvestment maxDrawdown\r\n realizedProfit realizedCoinProfit\r\n realizedWins realizedCoinWins\r\n realizedLosses realizedCoinLosses\r\n stepCount stepSince\r\n openPositions closedPositions positionsThatFailedToOpen\r\n drift driftSystem\r\n ";
}
final public G22TradingStrategy setVerbose(boolean verbose){ return verbose(verbose); }
public G22TradingStrategy verbose(boolean verbose) { this.verbose = verbose; return this; } final public boolean getVerbose(){ return verbose(); }
public boolean verbose() { return verbose; }
boolean verbose = false;
final public String getGlobalID(){ return globalID(); }
public String globalID() { return globalID; }
String globalID = aGlobalID();
// user-given name, overriding the technical name
final public G22TradingStrategy setCustomName(String customName){ return customName(customName); }
public G22TradingStrategy customName(String customName) { this.customName = customName; return this; } final public String getCustomName(){ return customName(); }
public String customName() { return customName; }
String customName;
// user-given comment
final public G22TradingStrategy setComment(String comment){ return comment(comment); }
public G22TradingStrategy comment(String comment) { this.comment = comment; return this; } final public String getComment(){ return comment(); }
public String comment() { return comment; }
String comment;
final public Q getQ(){ return q(); }
public Q q() { return q; }
transient Q q = startQ();
// link to market (optional)
final public G22TradingStrategy setMarket(IFuturesMarket market){ return market(market); }
public G22TradingStrategy market(IFuturesMarket market) { this.market = market; return this; } final public IFuturesMarket getMarket(){ return market(); }
public IFuturesMarket market() { return market; }
transient IFuturesMarket market;
final public G22TradingStrategy setMergePositionsForMarket(boolean mergePositionsForMarket){ return mergePositionsForMarket(mergePositionsForMarket); }
public G22TradingStrategy mergePositionsForMarket(boolean mergePositionsForMarket) { this.mergePositionsForMarket = mergePositionsForMarket; return this; } final public boolean getMergePositionsForMarket(){ return mergePositionsForMarket(); }
public boolean mergePositionsForMarket() { return mergePositionsForMarket; }
boolean mergePositionsForMarket = false;
public transient FieldVar varCryptoCoin_cache;
public FieldVar varCryptoCoin() { if (varCryptoCoin_cache == null) varCryptoCoin_cache = varCryptoCoin_load(); return varCryptoCoin_cache;}
public FieldVar varCryptoCoin_load() {
return new FieldVar(this, "cryptoCoin", () -> cryptoCoin(), cryptoCoin -> cryptoCoin(cryptoCoin)); }
final public G22TradingStrategy setCryptoCoin(String cryptoCoin){ return cryptoCoin(cryptoCoin); }
public G22TradingStrategy cryptoCoin(String cryptoCoin) { if (!eq(this.cryptoCoin, cryptoCoin)) { this.cryptoCoin = cryptoCoin; change(); } return this; }
final public String getCryptoCoin(){ return cryptoCoin(); }
public String cryptoCoin() { return cryptoCoin; }
String cryptoCoin;
public transient FieldVar varMarginCoin_cache;
public FieldVar varMarginCoin() { if (varMarginCoin_cache == null) varMarginCoin_cache = varMarginCoin_load(); return varMarginCoin_cache;}
public FieldVar varMarginCoin_load() {
return new FieldVar(this, "marginCoin", () -> marginCoin(), marginCoin -> marginCoin(marginCoin)); }
final public G22TradingStrategy setMarginCoin(String marginCoin){ return marginCoin(marginCoin); }
public G22TradingStrategy marginCoin(String marginCoin) { if (!eq(this.marginCoin, marginCoin)) { this.marginCoin = marginCoin; change(); } return this; }
final public String getMarginCoin(){ return marginCoin(); }
public String marginCoin() { return marginCoin; }
String marginCoin = "USDT";
// Which exchange are we using ("Bitget", "ByBit" etc.)
public transient FieldVar varExchangeName_cache;
public FieldVar varExchangeName() { if (varExchangeName_cache == null) varExchangeName_cache = varExchangeName_load(); return varExchangeName_cache;}
public FieldVar varExchangeName_load() {
return new FieldVar(this, "exchangeName", () -> exchangeName(), exchangeName -> exchangeName(exchangeName)); }
final public G22TradingStrategy setExchangeName(String exchangeName){ return exchangeName(exchangeName); }
public G22TradingStrategy exchangeName(String exchangeName) { if (!eq(this.exchangeName, exchangeName)) { this.exchangeName = exchangeName; change(); } return this; }
final public String getExchangeName(){ return exchangeName(); }
public String exchangeName() { return exchangeName; }
String exchangeName;
Ref tradingAccount = new Ref();
// Optional: Exchange we get our price data from, if different from above
public transient FieldVar varPriceDataFromExchange_cache;
public FieldVar varPriceDataFromExchange() { if (varPriceDataFromExchange_cache == null) varPriceDataFromExchange_cache = varPriceDataFromExchange_load(); return varPriceDataFromExchange_cache;}
public FieldVar varPriceDataFromExchange_load() {
return new FieldVar(this, "priceDataFromExchange", () -> priceDataFromExchange(), priceDataFromExchange -> priceDataFromExchange(priceDataFromExchange)); }
final public G22TradingStrategy setPriceDataFromExchange(String priceDataFromExchange){ return priceDataFromExchange(priceDataFromExchange); }
public G22TradingStrategy priceDataFromExchange(String priceDataFromExchange) { if (!eq(this.priceDataFromExchange, priceDataFromExchange)) { this.priceDataFromExchange = priceDataFromExchange; change(); } return this; }
final public String getPriceDataFromExchange(){ return priceDataFromExchange(); }
public String priceDataFromExchange() { return priceDataFromExchange; }
String priceDataFromExchange;
// An identifier of the trading account (as of yet unused)
public transient FieldVar varAccountName_cache;
public FieldVar varAccountName() { if (varAccountName_cache == null) varAccountName_cache = varAccountName_load(); return varAccountName_cache;}
public FieldVar varAccountName_load() {
return new FieldVar(this, "accountName", () -> accountName(), accountName -> accountName(accountName)); }
final public G22TradingStrategy setAccountName(String accountName){ return accountName(accountName); }
public G22TradingStrategy accountName(String accountName) { if (!eq(this.accountName, accountName)) { this.accountName = accountName; change(); } return this; }
final public String getAccountName(){ return accountName(); }
public String accountName() { return accountName; }
String accountName;
// primed = started but waiting for first price
public transient FieldVar varPrimed_cache;
public FieldVar varPrimed() { if (varPrimed_cache == null) varPrimed_cache = varPrimed_load(); return varPrimed_cache;}
public FieldVar varPrimed_load() {
return new FieldVar(this, "primed", () -> primed(), primed -> primed(primed)); }
final public G22TradingStrategy setPrimed(boolean primed){ return primed(primed); }
public G22TradingStrategy primed(boolean primed) { if (!eq(this.primed, primed)) { this.primed = primed; change(); } return this; }
final public boolean getPrimed(){ return primed(); }
public boolean primed() { return primed; }
boolean primed = false;
public transient FieldVar varUsingLiveData_cache;
public FieldVar varUsingLiveData() { if (varUsingLiveData_cache == null) varUsingLiveData_cache = varUsingLiveData_load(); return varUsingLiveData_cache;}
public FieldVar varUsingLiveData_load() {
return new FieldVar(this, "usingLiveData", () -> usingLiveData(), usingLiveData -> usingLiveData(usingLiveData)); }
final public G22TradingStrategy setUsingLiveData(boolean usingLiveData){ return usingLiveData(usingLiveData); }
public G22TradingStrategy usingLiveData(boolean usingLiveData) { if (!eq(this.usingLiveData, usingLiveData)) { this.usingLiveData = usingLiveData; change(); } return this; }
final public boolean getUsingLiveData(){ return usingLiveData(); }
public boolean usingLiveData() { return usingLiveData; }
boolean usingLiveData = false;
public transient FieldVar varDoingRealTrades_cache;
public FieldVar varDoingRealTrades() { if (varDoingRealTrades_cache == null) varDoingRealTrades_cache = varDoingRealTrades_load(); return varDoingRealTrades_cache;}
public FieldVar varDoingRealTrades_load() {
return new FieldVar(this, "doingRealTrades", () -> doingRealTrades(), doingRealTrades -> doingRealTrades(doingRealTrades)); }
final public G22TradingStrategy setDoingRealTrades(boolean doingRealTrades){ return doingRealTrades(doingRealTrades); }
public G22TradingStrategy doingRealTrades(boolean doingRealTrades) { if (!eq(this.doingRealTrades, doingRealTrades)) { this.doingRealTrades = doingRealTrades; change(); } return this; }
final public boolean getDoingRealTrades(){ return doingRealTrades(); }
public boolean doingRealTrades() { return doingRealTrades; }
boolean doingRealTrades = false;
public transient FieldVar varDemoCoin_cache;
public FieldVar varDemoCoin() { if (varDemoCoin_cache == null) varDemoCoin_cache = varDemoCoin_load(); return varDemoCoin_cache;}
public FieldVar varDemoCoin_load() {
return new FieldVar(this, "demoCoin", () -> demoCoin(), demoCoin -> demoCoin(demoCoin)); }
final public G22TradingStrategy setDemoCoin(boolean demoCoin){ return demoCoin(demoCoin); }
public G22TradingStrategy demoCoin(boolean demoCoin) { if (!eq(this.demoCoin, demoCoin)) { this.demoCoin = demoCoin; change(); } return this; }
final public boolean getDemoCoin(){ return demoCoin(); }
public boolean demoCoin() { return demoCoin; }
boolean demoCoin = false;
public transient FieldVar varActive_cache;
public FieldVar varActive() { if (varActive_cache == null) varActive_cache = varActive_load(); return varActive_cache;}
public FieldVar varActive_load() {
return new FieldVar(this, "active", () -> active(), active -> active(active)); }
final public G22TradingStrategy setActive(boolean active){ return active(active); }
public G22TradingStrategy active(boolean active) { if (!eq(this.active, active)) { this.active = active; change(); } return this; }
final public boolean getActive(){ return active(); }
public boolean active() { return active; }
boolean active = false;
// set to date when strategy ended itself
public transient FieldVar varClosedItself_cache;
public FieldVar varClosedItself() { if (varClosedItself_cache == null) varClosedItself_cache = varClosedItself_load(); return varClosedItself_cache;}
public FieldVar varClosedItself_load() {
return new FieldVar(this, "closedItself", () -> closedItself(), closedItself -> closedItself(closedItself)); }
final public G22TradingStrategy setClosedItself(long closedItself){ return closedItself(closedItself); }
public G22TradingStrategy closedItself(long closedItself) { if (!eq(this.closedItself, closedItself)) { this.closedItself = closedItself; change(); } return this; }
final public long getClosedItself(){ return closedItself(); }
public long closedItself() { return closedItself; }
long closedItself;
// set to date when strategy was deactivated (by itself or by the user)
public transient FieldVar varDeactivated_cache;
public FieldVar varDeactivated() { if (varDeactivated_cache == null) varDeactivated_cache = varDeactivated_load(); return varDeactivated_cache;}
public FieldVar varDeactivated_load() {
return new FieldVar(this, "deactivated", () -> deactivated(), deactivated -> deactivated(deactivated)); }
final public G22TradingStrategy setDeactivated(long deactivated){ return deactivated(deactivated); }
public G22TradingStrategy deactivated(long deactivated) { if (!eq(this.deactivated, deactivated)) { this.deactivated = deactivated; change(); } return this; }
final public long getDeactivated(){ return deactivated(); }
public long deactivated() { return deactivated; }
long deactivated;
// moved to archive (out of main list)
public transient FieldVar varArchived_cache;
public FieldVar varArchived() { if (varArchived_cache == null) varArchived_cache = varArchived_load(); return varArchived_cache;}
public FieldVar varArchived_load() {
return new FieldVar(this, "archived", () -> archived(), archived -> archived(archived)); }
final public G22TradingStrategy setArchived(boolean archived){ return archived(archived); }
public G22TradingStrategy archived(boolean archived) { if (!eq(this.archived, archived)) { this.archived = archived; change(); } return this; }
final public boolean getArchived(){ return archived(); }
public boolean archived() { return archived; }
boolean archived = false;
// area where this strategy is held, e.g. "Candidates"
public transient FieldVar varArea_cache;
public FieldVar varArea() { if (varArea_cache == null) varArea_cache = varArea_load(); return varArea_cache;}
public FieldVar varArea_load() {
return new FieldVar(this, "area", () -> area(), area -> area(area)); }
final public G22TradingStrategy setArea(String area){ return area(area); }
public G22TradingStrategy area(String area) { if (!eq(this.area, area)) { this.area = area; change(); } return this; }
final public String getArea(){ return area(); }
public String area() { return area; }
String area;
public transient FieldVar varAdversity_cache;
public FieldVar varAdversity() { if (varAdversity_cache == null) varAdversity_cache = varAdversity_load(); return varAdversity_cache;}
public FieldVar varAdversity_load() {
return new FieldVar(this, "adversity", () -> adversity(), adversity -> adversity(adversity)); }
final public G22TradingStrategy setAdversity(double adversity){ return adversity(adversity); }
public G22TradingStrategy adversity(double adversity) { if (!eq(this.adversity, adversity)) { this.adversity = adversity; change(); } return this; }
final public double getAdversity(){ return adversity(); }
public double adversity() { return adversity; }
double adversity = 0.2;
// should migrate to the timedLog completely
public transient FieldVar> varLog_cache;
public FieldVar> varLog() { if (varLog_cache == null) varLog_cache = varLog_load(); return varLog_cache;}
public FieldVar> varLog_load() {
return new FieldVar>(this, "log", () -> log(), log -> log(log)); }
final public G22TradingStrategy setLog(List log){ return log(log); }
public G22TradingStrategy log(List log) { if (!eq(this.log, log)) { this.log = log; change(); } return this; }
final public List getLog(){ return log(); }
public List log() { return log; }
List log = new ArrayList();
// O is always a string for now
public transient FieldVar>> varTimedLog_cache;
public FieldVar>> varTimedLog() { if (varTimedLog_cache == null) varTimedLog_cache = varTimedLog_load(); return varTimedLog_cache;}
public FieldVar>> varTimedLog_load() {
return new FieldVar>>(this, "timedLog", () -> timedLog(), timedLog -> timedLog(timedLog)); }
final public G22TradingStrategy setTimedLog(List> timedLog){ return timedLog(timedLog); }
public G22TradingStrategy timedLog(List> timedLog) { if (!eq(this.timedLog, timedLog)) { this.timedLog = timedLog; change(); } return this; }
final public List> getTimedLog(){ return timedLog(); }
public List> timedLog() { return timedLog; }
List> timedLog = new ArrayList();
public transient FieldVar varEpsilon_cache;
public FieldVar varEpsilon() { if (varEpsilon_cache == null) varEpsilon_cache = varEpsilon_load(); return varEpsilon_cache;}
public FieldVar varEpsilon_load() {
return new FieldVar(this, "epsilon", () -> epsilon(), epsilon -> epsilon(epsilon)); }
final public G22TradingStrategy setEpsilon(double epsilon){ return epsilon(epsilon); }
public G22TradingStrategy epsilon(double epsilon) { if (!eq(this.epsilon, epsilon)) { this.epsilon = epsilon; change(); } return this; }
final public double getEpsilon(){ return epsilon(); }
public double epsilon() { return epsilon; }
double epsilon = 1e-6;
// increment of crypto we can bet on
public transient FieldVar varCryptoStep_cache;
public FieldVar varCryptoStep() { if (varCryptoStep_cache == null) varCryptoStep_cache = varCryptoStep_load(); return varCryptoStep_cache;}
public FieldVar varCryptoStep_load() {
return new FieldVar(this, "cryptoStep", () -> cryptoStep(), cryptoStep -> cryptoStep(cryptoStep)); }
final public G22TradingStrategy setCryptoStep(double cryptoStep){ return cryptoStep(cryptoStep); }
public G22TradingStrategy cryptoStep(double cryptoStep) { if (!eq(this.cryptoStep, cryptoStep)) { this.cryptoStep = cryptoStep; change(); } return this; }
final public double getCryptoStep(){ return cryptoStep(); }
public double cryptoStep() { return cryptoStep; }
double cryptoStep = 0.0001;
// minimum crypto we need to bet on
public transient FieldVar varMinCrypto_cache;
public FieldVar varMinCrypto() { if (varMinCrypto_cache == null) varMinCrypto_cache = varMinCrypto_load(); return varMinCrypto_cache;}
public FieldVar varMinCrypto_load() {
return new FieldVar(this, "minCrypto", () -> minCrypto(), minCrypto -> minCrypto(minCrypto)); }
final public G22TradingStrategy setMinCrypto(double minCrypto){ return minCrypto(minCrypto); }
public G22TradingStrategy minCrypto(double minCrypto) { if (!eq(this.minCrypto, minCrypto)) { this.minCrypto = minCrypto; change(); } return this; }
final public double getMinCrypto(){ return minCrypto(); }
public double minCrypto() { return minCrypto; }
double minCrypto = 0.0001;
// maximum crypto we can bet on
public transient FieldVar varMaxCrypto_cache;
public FieldVar varMaxCrypto() { if (varMaxCrypto_cache == null) varMaxCrypto_cache = varMaxCrypto_load(); return varMaxCrypto_cache;}
public FieldVar varMaxCrypto_load() {
return new FieldVar(this, "maxCrypto", () -> maxCrypto(), maxCrypto -> maxCrypto(maxCrypto)); }
final public G22TradingStrategy setMaxCrypto(double maxCrypto){ return maxCrypto(maxCrypto); }
public G22TradingStrategy maxCrypto(double maxCrypto) { if (!eq(this.maxCrypto, maxCrypto)) { this.maxCrypto = maxCrypto; change(); } return this; }
final public double getMaxCrypto(){ return maxCrypto(); }
public double maxCrypto() { return maxCrypto; }
double maxCrypto = infinity();
public transient FieldVar varMaxInvestment_cache;
public FieldVar varMaxInvestment() { if (varMaxInvestment_cache == null) varMaxInvestment_cache = varMaxInvestment_load(); return varMaxInvestment_cache;}
public FieldVar varMaxInvestment_load() {
return new FieldVar(this, "maxInvestment", () -> maxInvestment(), maxInvestment -> maxInvestment(maxInvestment)); }
final public G22TradingStrategy setMaxInvestment(double maxInvestment){ return maxInvestment(maxInvestment); }
public G22TradingStrategy maxInvestment(double maxInvestment) { if (!eq(this.maxInvestment, maxInvestment)) { this.maxInvestment = maxInvestment; change(); } return this; }
final public double getMaxInvestment(){ return maxInvestment(); }
public double maxInvestment() { return maxInvestment; }
double maxInvestment;
// highest value of coinProfit
public transient FieldVar varStrategyCrest_cache;
public FieldVar varStrategyCrest() { if (varStrategyCrest_cache == null) varStrategyCrest_cache = varStrategyCrest_load(); return varStrategyCrest_cache;}
public FieldVar varStrategyCrest_load() {
return new FieldVar(this, "strategyCrest", () -> strategyCrest(), strategyCrest -> strategyCrest(strategyCrest)); }
final public G22TradingStrategy setStrategyCrest(double strategyCrest){ return strategyCrest(strategyCrest); }
public G22TradingStrategy strategyCrest(double strategyCrest) { if (!eq(this.strategyCrest, strategyCrest)) { this.strategyCrest = strategyCrest; change(); } return this; }
final public double getStrategyCrest(){ return strategyCrest(); }
public double strategyCrest() { return strategyCrest; }
double strategyCrest;
// Maximum drawdown seen on account (realized+unrealized)
public transient FieldVar varMaxDrawdown_cache;
public FieldVar varMaxDrawdown() { if (varMaxDrawdown_cache == null) varMaxDrawdown_cache = varMaxDrawdown_load(); return varMaxDrawdown_cache;}
public FieldVar varMaxDrawdown_load() {
return new FieldVar(this, "maxDrawdown", () -> maxDrawdown(), maxDrawdown -> maxDrawdown(maxDrawdown)); }
final public G22TradingStrategy setMaxDrawdown(double maxDrawdown){ return maxDrawdown(maxDrawdown); }
public G22TradingStrategy maxDrawdown(double maxDrawdown) { if (!eq(this.maxDrawdown, maxDrawdown)) { this.maxDrawdown = maxDrawdown; change(); } return this; }
final public double getMaxDrawdown(){ return maxDrawdown(); }
public double maxDrawdown() { return maxDrawdown; }
double maxDrawdown;
public transient FieldVar varCellSize_cache;
public FieldVar varCellSize() { if (varCellSize_cache == null) varCellSize_cache = varCellSize_load(); return varCellSize_cache;}
public FieldVar varCellSize_load() {
return new FieldVar(this, "cellSize", () -> cellSize(), cellSize -> cellSize(cellSize)); }
final public G22TradingStrategy setCellSize(double cellSize){ return cellSize(cellSize); }
public G22TradingStrategy cellSize(double cellSize) { if (!eq(this.cellSize, cellSize)) { this.cellSize = cellSize; change(); } return this; }
final public double getCellSize(){ return cellSize(); }
public double cellSize() { return cellSize; }
double cellSize = 1;
// position options
public transient FieldVar varLeverage_cache;
public FieldVar varLeverage() { if (varLeverage_cache == null) varLeverage_cache = varLeverage_load(); return varLeverage_cache;}
public FieldVar varLeverage_load() {
return new FieldVar(this, "leverage", () -> leverage(), leverage -> leverage(leverage)); }
final public G22TradingStrategy setLeverage(double leverage){ return leverage(leverage); }
public G22TradingStrategy leverage(double leverage) { if (!eq(this.leverage, leverage)) { this.leverage = leverage; change(); } return this; }
final public double getLeverage(){ return leverage(); }
public double leverage() { return leverage; }
double leverage = 1;
public transient FieldVar varMarginPerPosition_cache;
public FieldVar varMarginPerPosition() { if (varMarginPerPosition_cache == null) varMarginPerPosition_cache = varMarginPerPosition_load(); return varMarginPerPosition_cache;}
public FieldVar varMarginPerPosition_load() {
return new FieldVar(this, "marginPerPosition", () -> marginPerPosition(), marginPerPosition -> marginPerPosition(marginPerPosition)); }
final public G22TradingStrategy setMarginPerPosition(double marginPerPosition){ return marginPerPosition(marginPerPosition); }
public G22TradingStrategy marginPerPosition(double marginPerPosition) { if (!eq(this.marginPerPosition, marginPerPosition)) { this.marginPerPosition = marginPerPosition; change(); } return this; }
final public double getMarginPerPosition(){ return marginPerPosition(); }
public double marginPerPosition() { return marginPerPosition; }
double marginPerPosition = 1; // in USDT
// optional (for compounding): how much of the account's equity to risk per position
public transient FieldVar varRiskPerTrade_cache;
public FieldVar varRiskPerTrade() { if (varRiskPerTrade_cache == null) varRiskPerTrade_cache = varRiskPerTrade_load(); return varRiskPerTrade_cache;}
public FieldVar varRiskPerTrade_load() {
return new FieldVar(this, "riskPerTrade", () -> riskPerTrade(), riskPerTrade -> riskPerTrade(riskPerTrade)); }
final public G22TradingStrategy setRiskPerTrade(double riskPerTrade){ return riskPerTrade(riskPerTrade); }
public G22TradingStrategy riskPerTrade(double riskPerTrade) { if (!eq(this.riskPerTrade, riskPerTrade)) { this.riskPerTrade = riskPerTrade; change(); } return this; }
final public double getRiskPerTrade(){ return riskPerTrade(); }
public double riskPerTrade() { return riskPerTrade; }
double riskPerTrade; // in percent
// Equity risked in last trade
public transient FieldVar varRiskedEquity_cache;
public FieldVar varRiskedEquity() { if (varRiskedEquity_cache == null) varRiskedEquity_cache = varRiskedEquity_load(); return varRiskedEquity_cache;}
public FieldVar varRiskedEquity_load() {
return new FieldVar(this, "riskedEquity", () -> riskedEquity(), riskedEquity -> riskedEquity(riskedEquity)); }
final public G22TradingStrategy setRiskedEquity(double riskedEquity){ return riskedEquity(riskedEquity); }
public G22TradingStrategy riskedEquity(double riskedEquity) { if (!eq(this.riskedEquity, riskedEquity)) { this.riskedEquity = riskedEquity; change(); } return this; }
final public double getRiskedEquity(){ return riskedEquity(); }
public double riskedEquity() { return riskedEquity; }
double riskedEquity;
public transient FieldVar varShowClosedPositionsBackwards_cache;
public FieldVar varShowClosedPositionsBackwards() { if (varShowClosedPositionsBackwards_cache == null) varShowClosedPositionsBackwards_cache = varShowClosedPositionsBackwards_load(); return varShowClosedPositionsBackwards_cache;}
public FieldVar varShowClosedPositionsBackwards_load() {
return new FieldVar(this, "showClosedPositionsBackwards", () -> showClosedPositionsBackwards(), showClosedPositionsBackwards -> showClosedPositionsBackwards(showClosedPositionsBackwards)); }
final public G22TradingStrategy setShowClosedPositionsBackwards(boolean showClosedPositionsBackwards){ return showClosedPositionsBackwards(showClosedPositionsBackwards); }
public G22TradingStrategy showClosedPositionsBackwards(boolean showClosedPositionsBackwards) { if (!eq(this.showClosedPositionsBackwards, showClosedPositionsBackwards)) { this.showClosedPositionsBackwards = showClosedPositionsBackwards; change(); } return this; }
final public boolean getShowClosedPositionsBackwards(){ return showClosedPositionsBackwards(); }
public boolean showClosedPositionsBackwards() { return showClosedPositionsBackwards; }
boolean showClosedPositionsBackwards = true;
// End strategy when this margin coin profit is reached.
public transient FieldVar varTakeCoinProfit_cache;
public FieldVar varTakeCoinProfit() { if (varTakeCoinProfit_cache == null) varTakeCoinProfit_cache = varTakeCoinProfit_load(); return varTakeCoinProfit_cache;}
public FieldVar varTakeCoinProfit_load() {
return new FieldVar(this, "takeCoinProfit", () -> takeCoinProfit(), takeCoinProfit -> takeCoinProfit(takeCoinProfit)); }
final public G22TradingStrategy setTakeCoinProfit(double takeCoinProfit){ return takeCoinProfit(takeCoinProfit); }
public G22TradingStrategy takeCoinProfit(double takeCoinProfit) { if (!eq(this.takeCoinProfit, takeCoinProfit)) { this.takeCoinProfit = takeCoinProfit; change(); } return this; }
final public double getTakeCoinProfit(){ return takeCoinProfit(); }
public double takeCoinProfit() { return takeCoinProfit; }
double takeCoinProfit = infinity();
public transient FieldVar varTakeCoinProfitEnabled_cache;
public FieldVar varTakeCoinProfitEnabled() { if (varTakeCoinProfitEnabled_cache == null) varTakeCoinProfitEnabled_cache = varTakeCoinProfitEnabled_load(); return varTakeCoinProfitEnabled_cache;}
public FieldVar varTakeCoinProfitEnabled_load() {
return new FieldVar(this, "takeCoinProfitEnabled", () -> takeCoinProfitEnabled(), takeCoinProfitEnabled -> takeCoinProfitEnabled(takeCoinProfitEnabled)); }
final public G22TradingStrategy setTakeCoinProfitEnabled(boolean takeCoinProfitEnabled){ return takeCoinProfitEnabled(takeCoinProfitEnabled); }
public G22TradingStrategy takeCoinProfitEnabled(boolean takeCoinProfitEnabled) { if (!eq(this.takeCoinProfitEnabled, takeCoinProfitEnabled)) { this.takeCoinProfitEnabled = takeCoinProfitEnabled; change(); } return this; }
final public boolean getTakeCoinProfitEnabled(){ return takeCoinProfitEnabled(); }
public boolean takeCoinProfitEnabled() { return takeCoinProfitEnabled; }
boolean takeCoinProfitEnabled = false;
// How many hours of recent back data this algorithm likes
// to be fed with prior to running live.
public transient FieldVar varBackDataHoursWanted_cache;
public FieldVar varBackDataHoursWanted() { if (varBackDataHoursWanted_cache == null) varBackDataHoursWanted_cache = varBackDataHoursWanted_load(); return varBackDataHoursWanted_cache;}
public FieldVar varBackDataHoursWanted_load() {
return new FieldVar(this, "backDataHoursWanted", () -> backDataHoursWanted(), backDataHoursWanted -> backDataHoursWanted(backDataHoursWanted)); }
final public G22TradingStrategy setBackDataHoursWanted(double backDataHoursWanted){ return backDataHoursWanted(backDataHoursWanted); }
public G22TradingStrategy backDataHoursWanted(double backDataHoursWanted) { if (!eq(this.backDataHoursWanted, backDataHoursWanted)) { this.backDataHoursWanted = backDataHoursWanted; change(); } return this; }
final public double getBackDataHoursWanted(){ return backDataHoursWanted(); }
public double backDataHoursWanted() { return backDataHoursWanted; }
double backDataHoursWanted;
// Did we feed the back data?
public transient FieldVar varBackDataFed_cache;
public FieldVar varBackDataFed() { if (varBackDataFed_cache == null) varBackDataFed_cache = varBackDataFed_load(); return varBackDataFed_cache;}
public FieldVar varBackDataFed_load() {
return new FieldVar(this, "backDataFed", () -> backDataFed(), backDataFed -> backDataFed(backDataFed)); }
final public G22TradingStrategy setBackDataFed(boolean backDataFed){ return backDataFed(backDataFed); }
public G22TradingStrategy backDataFed(boolean backDataFed) { if (!eq(this.backDataFed, backDataFed)) { this.backDataFed = backDataFed; change(); } return this; }
final public boolean getBackDataFed(){ return backDataFed(); }
public boolean backDataFed() { return backDataFed; }
boolean backDataFed = false;
// Juicer that is used to stop the whole strategy depending
// on its profit (optional)
public transient FieldVar varStrategyJuicer_cache;
public FieldVar varStrategyJuicer() { if (varStrategyJuicer_cache == null) varStrategyJuicer_cache = varStrategyJuicer_load(); return varStrategyJuicer_cache;}
public FieldVar varStrategyJuicer_load() {
return new FieldVar(this, "strategyJuicer", () -> strategyJuicer(), strategyJuicer -> strategyJuicer(strategyJuicer)); }
final public G22TradingStrategy setStrategyJuicer(AbstractJuicer strategyJuicer){ return strategyJuicer(strategyJuicer); }
public G22TradingStrategy strategyJuicer(AbstractJuicer strategyJuicer) { if (!eq(this.strategyJuicer, strategyJuicer)) { this.strategyJuicer = strategyJuicer; change(); } return this; }
final public AbstractJuicer getStrategyJuicer(){ return strategyJuicer(); }
public AbstractJuicer strategyJuicer() { return strategyJuicer; }
AbstractJuicer strategyJuicer;
transient IF0 currentTime;
long currentTime() { return currentTime != null ? currentTime.get() : currentTime_base(); }
final long currentTime_fallback(IF0 _f) { return _f != null ? _f.get() : currentTime_base(); }
long currentTime_base() { return now(); }
final public G22TradingStrategy setLogToPrint(boolean logToPrint){ return logToPrint(logToPrint); }
public G22TradingStrategy logToPrint(boolean logToPrint) { this.logToPrint = logToPrint; return this; } final public boolean getLogToPrint(){ return logToPrint(); }
public boolean logToPrint() { return logToPrint; }
transient boolean logToPrint = true;
// Note from price feeder
public transient FieldVar varFeedNote_cache;
public FieldVar varFeedNote() { if (varFeedNote_cache == null) varFeedNote_cache = varFeedNote_load(); return varFeedNote_cache;}
public FieldVar varFeedNote_load() {
return new FieldVar(this, "feedNote", () -> feedNote(), feedNote -> feedNote(feedNote)); }
final public G22TradingStrategy setFeedNote(String feedNote){ return feedNote(feedNote); }
public G22TradingStrategy feedNote(String feedNote) { if (!eq(this.feedNote, feedNote)) { this.feedNote = feedNote; change(); } return this; }
final public String getFeedNote(){ return feedNote(); }
public String feedNote() { return feedNote; }
String feedNote;
// optimization to save fees
public transient FieldVar varUseDriftSystem_cache;
public FieldVar varUseDriftSystem() { if (varUseDriftSystem_cache == null) varUseDriftSystem_cache = varUseDriftSystem_load(); return varUseDriftSystem_cache;}
public FieldVar varUseDriftSystem_load() {
return new FieldVar(this, "useDriftSystem", () -> useDriftSystem(), useDriftSystem -> useDriftSystem(useDriftSystem)); }
final public G22TradingStrategy setUseDriftSystem(boolean useDriftSystem){ return useDriftSystem(useDriftSystem); }
public G22TradingStrategy useDriftSystem(boolean useDriftSystem) { if (!eq(this.useDriftSystem, useDriftSystem)) { this.useDriftSystem = useDriftSystem; change(); } return this; }
final public boolean getUseDriftSystem(){ return useDriftSystem(); }
public boolean useDriftSystem() { return useDriftSystem; }
boolean useDriftSystem = false;
// The drift system we are connected to
public transient FieldVar varDriftSystem_cache;
public FieldVar varDriftSystem() { if (varDriftSystem_cache == null) varDriftSystem_cache = varDriftSystem_load(); return varDriftSystem_cache;}
public FieldVar varDriftSystem_load() {
return new FieldVar(this, "driftSystem", () -> driftSystem(), driftSystem -> driftSystem(driftSystem)); }
final public G22TradingStrategy setDriftSystem(G22DriftSystem driftSystem){ return driftSystem(driftSystem); }
public G22TradingStrategy driftSystem(G22DriftSystem driftSystem) { if (!eq(this.driftSystem, driftSystem)) { this.driftSystem = driftSystem; change(); } return this; }
final public G22DriftSystem getDriftSystem(){ return driftSystem(); }
public G22DriftSystem driftSystem() { return driftSystem; }
G22DriftSystem driftSystem;
// Set to the actual ticker used by the system
public transient FieldVar varActualTicker_cache;
public FieldVar varActualTicker() { if (varActualTicker_cache == null) varActualTicker_cache = varActualTicker_load(); return varActualTicker_cache;}
public FieldVar varActualTicker_load() {
return new FieldVar(this, "actualTicker", () -> actualTicker(), actualTicker -> actualTicker(actualTicker)); }
final public G22TradingStrategy setActualTicker(TickerSequence actualTicker){ return actualTicker(actualTicker); }
public G22TradingStrategy actualTicker(TickerSequence actualTicker) { if (!eq(this.actualTicker, actualTicker)) { this.actualTicker = actualTicker; change(); } return this; }
final public TickerSequence getActualTicker(){ return actualTicker(); }
public TickerSequence actualTicker() { return actualTicker; }
transient TickerSequence actualTicker;
// How many minutes to wait after closing a position
// before a new one can be opened (0 for no cooldown)
public transient FieldVar varCooldownMinutes_cache;
public FieldVar varCooldownMinutes() { if (varCooldownMinutes_cache == null) varCooldownMinutes_cache = varCooldownMinutes_load(); return varCooldownMinutes_cache;}
public FieldVar varCooldownMinutes_load() {
return new FieldVar(this, "cooldownMinutes", () -> cooldownMinutes(), cooldownMinutes -> cooldownMinutes(cooldownMinutes)); }
final public G22TradingStrategy setCooldownMinutes(double cooldownMinutes){ return cooldownMinutes(cooldownMinutes); }
public G22TradingStrategy cooldownMinutes(double cooldownMinutes) { if (!eq(this.cooldownMinutes, cooldownMinutes)) { this.cooldownMinutes = cooldownMinutes; change(); } return this; }
final public double getCooldownMinutes(){ return cooldownMinutes(); }
public double cooldownMinutes() { return cooldownMinutes; }
double cooldownMinutes;
// An image showing this strategy's current state
final public G22TradingStrategy setImage(BufferedImage image){ return image(image); }
public G22TradingStrategy image(BufferedImage image) { this.image = image; return this; } final public BufferedImage getImage(){ return image(); }
public BufferedImage image() { return image; }
transient BufferedImage image;
final public G22TradingStrategy setImageForWebServer(byte[] imageForWebServer){ return imageForWebServer(imageForWebServer); }
public G22TradingStrategy imageForWebServer(byte[] imageForWebServer) { this.imageForWebServer = imageForWebServer; return this; } final public byte[] getImageForWebServer(){ return imageForWebServer(); }
public byte[] imageForWebServer() { return imageForWebServer; }
transient byte[] imageForWebServer;
// Initial assumed equity for backtest.
// If not zero, marginPerPosition will be scaled up and down
// relative to compoundingBaseEquity+realizedCoinProfit()
public transient FieldVar varCompoundingBaseEquity_cache;
public FieldVar varCompoundingBaseEquity() { if (varCompoundingBaseEquity_cache == null) varCompoundingBaseEquity_cache = varCompoundingBaseEquity_load(); return varCompoundingBaseEquity_cache;}
public FieldVar varCompoundingBaseEquity_load() {
return new FieldVar(this, "compoundingBaseEquity", () -> compoundingBaseEquity(), compoundingBaseEquity -> compoundingBaseEquity(compoundingBaseEquity)); }
final public G22TradingStrategy setCompoundingBaseEquity(double compoundingBaseEquity){ return compoundingBaseEquity(compoundingBaseEquity); }
public G22TradingStrategy compoundingBaseEquity(double compoundingBaseEquity) { if (!eq(this.compoundingBaseEquity, compoundingBaseEquity)) { this.compoundingBaseEquity = compoundingBaseEquity; change(); } return this; }
final public double getCompoundingBaseEquity(){ return compoundingBaseEquity(); }
public double compoundingBaseEquity() { return compoundingBaseEquity; }
double compoundingBaseEquity;
// Use the exchange's TP & SL features
public transient FieldVar varTpSlOnPlatform_cache;
public FieldVar varTpSlOnPlatform() { if (varTpSlOnPlatform_cache == null) varTpSlOnPlatform_cache = varTpSlOnPlatform_load(); return varTpSlOnPlatform_cache;}
public FieldVar varTpSlOnPlatform_load() {
return new FieldVar(this, "tpSlOnPlatform", () -> tpSlOnPlatform(), tpSlOnPlatform -> tpSlOnPlatform(tpSlOnPlatform)); }
final public G22TradingStrategy setTpSlOnPlatform(boolean tpSlOnPlatform){ return tpSlOnPlatform(tpSlOnPlatform); }
public G22TradingStrategy tpSlOnPlatform(boolean tpSlOnPlatform) { if (!eq(this.tpSlOnPlatform, tpSlOnPlatform)) { this.tpSlOnPlatform = tpSlOnPlatform; change(); } return this; }
final public boolean getTpSlOnPlatform(){ return tpSlOnPlatform(); }
public boolean tpSlOnPlatform() { return tpSlOnPlatform; }
boolean tpSlOnPlatform = false;
// Strategies are listed according to this key field (alphanum-IC)
public transient FieldVar varListOrder_cache;
public FieldVar varListOrder() { if (varListOrder_cache == null) varListOrder_cache = varListOrder_load(); return varListOrder_cache;}
public FieldVar varListOrder_load() {
return new FieldVar(this, "listOrder", () -> listOrder(), listOrder -> listOrder(listOrder)); }
final public G22TradingStrategy setListOrder(String listOrder){ return listOrder(listOrder); }
public G22TradingStrategy listOrder(String listOrder) { if (!eq(this.listOrder, listOrder)) { this.listOrder = listOrder; change(); } return this; }
final public String getListOrder(){ return listOrder(); }
public String listOrder() { return listOrder; }
String listOrder;
// add fields here
A log(A o) {
if (o != null) {
String s = str(o);
long time = currentTime();
log.add(printIf(logToPrint, "[" + formatLocalDateWithSeconds(time) + "] " + s));
timedLog.add(withTimestamp(time, s));
change();
}
return o;
}
void logVars(Object... o) {
log(renderVars(o));
}
List activationStatus() {
return llNempties(
active ? "Active" : "Inactive",
exchangeName,
empty(cryptoCoin) ? null
: "coin: " + cryptoCoin + " over " + marginCoin
+ stringIf(demoCoin, " (demo coin)"),
stringIf(market != null, "connected to market"),
stringIf(usingLiveData, "using live data"),
stringIf(doingRealTrades, "real trades")
);
}
double unrealizedProfit() {
double sum = 0;
for (var p : openPositions())
sum += p.profit();
return sum;
}
double openMargins() {
double sum = 0;
for (var p : openPositions())
sum += p.margin();
return sum;
}
double unrealizedCoinProfit() {
return unrealizedCoinProfitAtPrice(currentPrice);
}
double unrealizedCoinProfitAtPrice(double price) {
double sum = 0;
for (var p : openPositions)
sum += p.coinProfitAtPrice(price);
return sum;
}
List positionsInDirection(int direction) {
return filter(openPositions, p -> sign(p.direction) == sign(direction));
}
List longPositions() { return positionsInDirection(1); }
List shortPositions() { return positionsInDirection(-1); }
List shortPositionsAtOrBelowPrice(double openingPrice) {
return filter(openPositions, p -> p.isShort() && p.openingPrice <= openingPrice);
}
List longPositionsAtOrAbovePrice(double openingPrice) {
return filter(openPositions, p -> p.isLong() && p.openingPrice >= openingPrice);
}
List negativePositions() {
return filter(openPositions, p -> p.profit() < 0);
}
double debt() {
return max(0, -unrealizedCoinProfit());
}
// TODO: remove
double profit() {
return realizedProfit+unrealizedProfit();
}
double coinProfit() {
return realizedCoinProfit+unrealizedCoinProfit();
}
double coinProfitAtPrice(double price) {
return realizedCoinProfit+unrealizedCoinProfitAtPrice(price);
}
String formatProfit(double x) {
return plusMinusFix(formatDouble1(x));
}
public transient FieldVar varDigitizer_cache;
public FieldVar varDigitizer() { if (varDigitizer_cache == null) varDigitizer_cache = varDigitizer_load(); return varDigitizer_cache;}
public FieldVar varDigitizer_load() {
return new FieldVar(this, "digitizer", () -> digitizer(), digitizer -> digitizer(digitizer)); }
final public G22TradingStrategy setDigitizer(PriceDigitizer2 digitizer){ return digitizer(digitizer); }
public G22TradingStrategy digitizer(PriceDigitizer2 digitizer) { if (!eq(this.digitizer, digitizer)) { this.digitizer = digitizer; change(); } return this; }
final public PriceDigitizer2 getDigitizer(){ return digitizer(); }
public PriceDigitizer2 digitizer() { return digitizer; }
PriceDigitizer2 digitizer;
// TODO: This doesn't belong here
public transient FieldVar varDirection_cache;
public FieldVar varDirection() { if (varDirection_cache == null) varDirection_cache = varDirection_load(); return varDirection_cache;}
public FieldVar varDirection_load() {
return new FieldVar(this, "direction", () -> direction(), direction -> direction(direction)); }
final public G22TradingStrategy setDirection(int direction){ return direction(direction); }
public G22TradingStrategy direction(int direction) { if (!eq(this.direction, direction)) { this.direction = direction; change(); } return this; }
final public int getDirection(){ return direction(); }
public int direction() { return direction; }
int direction;
// maximum debt seen
public transient FieldVar varMaxDebt_cache;
public FieldVar varMaxDebt() { if (varMaxDebt_cache == null) varMaxDebt_cache = varMaxDebt_load(); return varMaxDebt_cache;}
public FieldVar varMaxDebt_load() {
return new FieldVar(this, "maxDebt", () -> maxDebt(), maxDebt -> maxDebt(maxDebt)); }
final public G22TradingStrategy setMaxDebt(double maxDebt){ return maxDebt(maxDebt); }
public G22TradingStrategy maxDebt(double maxDebt) { if (!eq(this.maxDebt, maxDebt)) { this.maxDebt = maxDebt; change(); } return this; }
final public double getMaxDebt(){ return maxDebt(); }
public double maxDebt() { return maxDebt; }
double maxDebt;
//settableWithVar double minCoinProfit;
//settableWithVar double maxBoundCoin;
class Position {
final public String getPositionID(){ return positionID(); }
public String positionID() { return positionID; }
String positionID = aGlobalID();
final public Position setMarginToUse(double marginToUse){ return marginToUse(marginToUse); }
public Position marginToUse(double marginToUse) { this.marginToUse = marginToUse; return this; } final public double getMarginToUse(){ return marginToUse(); }
public double marginToUse() { return marginToUse; }
double marginToUse;
final public Position setOpeningPrice(double openingPrice){ return openingPrice(openingPrice); }
public Position openingPrice(double openingPrice) { this.openingPrice = openingPrice; return this; } final public double getOpeningPrice(){ return openingPrice(); }
public double openingPrice() { return openingPrice; }
double openingPrice;
final public Position setDirection(double direction){ return direction(direction); }
public Position direction(double direction) { this.direction = direction; return this; } final public double getDirection(){ return direction(); }
public double direction() { return direction; }
double direction;
final public Position setDigitizedOpeningPrice(double digitizedOpeningPrice){ return digitizedOpeningPrice(digitizedOpeningPrice); }
public Position digitizedOpeningPrice(double digitizedOpeningPrice) { this.digitizedOpeningPrice = digitizedOpeningPrice; return this; } final public double getDigitizedOpeningPrice(){ return digitizedOpeningPrice(); }
public double digitizedOpeningPrice() { return digitizedOpeningPrice; }
double digitizedOpeningPrice;
final public double getClosingPrice(){ return closingPrice(); }
public double closingPrice() { return closingPrice; }
double closingPrice = Double.NaN;
long openingStep, closingStep;
final public long getOpeningTime(){ return openingTime(); }
public long openingTime() { return openingTime; }
long openingTime;
final public long getClosingTime(){ return closingTime(); }
public long closingTime() { return closingTime; }
long closingTime;
double leverage;
final public Position setCryptoAmount(double cryptoAmount){ return cryptoAmount(cryptoAmount); }
public Position cryptoAmount(double cryptoAmount) { this.cryptoAmount = cryptoAmount; return this; } final public double getCryptoAmount(){ return cryptoAmount(); }
public double cryptoAmount() { return cryptoAmount; }
double cryptoAmount;
final public Position setOpenReason(Object openReason){ return openReason(openReason); }
public Position openReason(Object openReason) { this.openReason = openReason; return this; } final public Object getOpenReason(){ return openReason(); }
public Object openReason() { return openReason; }
Object openReason;
final public Position setOpenError(Object openError){ return openError(openError); }
public Position openError(Object openError) { this.openError = openError; return this; } final public Object getOpenError(){ return openError(); }
public Object openError() { return openError; }
Object openError;
final public Position setCloseReason(Object closeReason){ return closeReason(closeReason); }
public Position closeReason(Object closeReason) { this.closeReason = closeReason; return this; } final public Object getCloseReason(){ return closeReason(); }
public Object closeReason() { return closeReason; }
Object closeReason;
final public Position setCloseError(Object closeError){ return closeError(closeError); }
public Position closeError(Object closeError) { this.closeError = closeError; return this; } final public Object getCloseError(){ return closeError(); }
public Object closeError() { return closeError; }
Object closeError;
final public double getMargin(){ return margin(); }
public double margin() { return margin; }
double margin;
final public Position setOpenedOnMarket(boolean openedOnMarket){ return openedOnMarket(openedOnMarket); }
public Position openedOnMarket(boolean openedOnMarket) { this.openedOnMarket = openedOnMarket; return this; } final public boolean getOpenedOnMarket(){ return openedOnMarket(); }
public boolean openedOnMarket() { return openedOnMarket; }
boolean openedOnMarket = false;
final public Position setOpenOrderID(String openOrderID){ return openOrderID(openOrderID); }
public Position openOrderID(String openOrderID) { this.openOrderID = openOrderID; return this; } final public String getOpenOrderID(){ return openOrderID(); }
public String openOrderID() { return openOrderID; }
String openOrderID; // open order ID returned from platform
final public Position setClosedOnMarket(boolean closedOnMarket){ return closedOnMarket(closedOnMarket); }
public Position closedOnMarket(boolean closedOnMarket) { this.closedOnMarket = closedOnMarket; return this; } final public boolean getClosedOnMarket(){ return closedOnMarket(); }
public boolean closedOnMarket() { return closedOnMarket; }
boolean closedOnMarket = false;
final public Position setDontCloseOnMarket(boolean dontCloseOnMarket){ return dontCloseOnMarket(dontCloseOnMarket); }
public Position dontCloseOnMarket(boolean dontCloseOnMarket) { this.dontCloseOnMarket = dontCloseOnMarket; return this; } final public boolean getDontCloseOnMarket(){ return dontCloseOnMarket(); }
public boolean dontCloseOnMarket() { return dontCloseOnMarket; }
boolean dontCloseOnMarket = false;
final public Position setComment(String comment){ return comment(comment); }
public Position comment(String comment) { this.comment = comment; return this; } final public String getComment(){ return comment(); }
public String comment() { return comment; }
String comment;
final public Position setJuicers(List juicers){ return juicers(juicers); }
public Position juicers(List juicers) { this.juicers = juicers; return this; } final public List getJuicers(){ return juicers(); }
public List juicers() { return juicers; }
List juicers;
final public Position setTpPrice(Double tpPrice){ return tpPrice(tpPrice); }
public Position tpPrice(Double tpPrice) { this.tpPrice = tpPrice; return this; } final public Double getTpPrice(){ return tpPrice(); }
public Double tpPrice() { return tpPrice; }
Double tpPrice;
final public Position setSlPrice(Double slPrice){ return slPrice(slPrice); }
public Position slPrice(Double slPrice) { this.slPrice = slPrice; return this; } final public Double getSlPrice(){ return slPrice(); }
public Double slPrice() { return slPrice; }
Double slPrice;
// highest and lowest unrealized P&L seen (after leverage)
final public Position setCrest(double crest){ return crest(crest); }
public Position crest(double crest) { this.crest = crest; return this; } final public double getCrest(){ return crest(); }
public double crest() { return crest; }
double crest = negativeInfinity();
final public Position setAntiCrest(double antiCrest){ return antiCrest(antiCrest); }
public Position antiCrest(double antiCrest) { this.antiCrest = antiCrest; return this; } final public double getAntiCrest(){ return antiCrest(); }
public double antiCrest() { return antiCrest; }
double antiCrest = infinity();
G22TradingStrategy strategy() { return G22TradingStrategy.this; }
{
if (!dynamicObjectIsLoading()) {
marginToUse = marginToUseForNewPosition();
openingStep = stepCount;
leverage = G22TradingStrategy.this.leverage;
}
}
boolean isLong() { return direction > 0; }
boolean isShort() { return direction < 0; }
boolean closed() { return !isNaN(closingPrice); }
String type() { return trading_directionToPositionType(direction); }
long closingOrCurrentTime() { return closed() ? closingTime() : currentTime(); }
long duration() { return closingOrCurrentTime()-openingTime(); }
double profitAtPrice(double price) {
return profitAtPriceBeforeLeverage(price)*leverage;
}
double profitAtPriceBeforeLeverage(double price) {
return ((price-openingPrice)/openingPrice*direction*100-adversity);
}
double workingPrice() {
return closed() ? closingPrice : currentPrice();
}
double profit() {
return profitAtPrice(workingPrice());
}
double profitBeforeLeverage() {
return profitAtPriceBeforeLeverage(workingPrice());
}
final public Position setImaginaryProfit(Double imaginaryProfit){ return imaginaryProfit(imaginaryProfit); }
public Position imaginaryProfit(Double imaginaryProfit) { this.imaginaryProfit = imaginaryProfit; return this; } final public Double getImaginaryProfit(){ return imaginaryProfit(); }
public Double imaginaryProfit() { return imaginaryProfit; }
Double imaginaryProfit;
double coinProfit() {
{ var __2= imaginaryProfit; if (__2 != null) return __2; }
return coinProfitAtPrice(workingPrice());
}
boolean isOpenError() { return openError != null; }
double coinProfitAtPrice(double price) {
return isOpenError() ? 0 : profitAtPrice(price)/100*margin();
}
void close(Object closeReason) {
if (closed()) throw fail("Can't close again");
if (closeReason != null) closeReason(closeReason);
openPositions.remove(this);
closingPrice = currentPrice();
closingTime = currentTime();
closingStep = stepCount;
if (!isOpenError())
closedPositions.add(this);
addToRealizedStats();
closeOnMarket();
log(this);
//print(this);
//printPositions();
}
Position partialClose(double amount, Object closeReason) {
Position p = new Position();
p.cryptoAmount = cryptoAmount-amount;
log("Partial close (" + amount + ") of " + this + ", creating remainder position with amount " + p.cryptoAmount + ". Reason: " + closeReason);
cryptoAmount = amount;
return openPosition(p, (int) direction, closeReason);
}
void makeFake(double coinProfit) {
closeReason("Fake");
imaginaryProfit(coinProfit);
closedPositions.add(this);
addToRealizedStats();
log(this);
}
void addToRealizedStats() {
double cp = coinProfit();
realizedProfit += profit();
realizedCoinProfit += cp;
if (cp > 0) {
realizedWins++;
realizedCoinWins += cp;
} else {
realizedLosses++;
realizedCoinLosses += cp;
}
change();
}
String winnerOrLoser() {
var profit = coinProfit();
if (profit == 0) return "NEUTRAL";
if (profit > 0) return "WIN";
return "LOSS";
}
// Position.toString
public String toString() {
return commaCombine(
spaceCombine(
!closed() ? null :
winnerOrLoser()
+ appendBracketed(strOrNull(closeReason))
+ appendBracketed(comment)
+ " " + formatLocalDateWithSeconds(closingTime())
+ " " + formatProfit(profit()) + "% (" + marginCoin + " " + formatMarginProfit(coinProfit()) + ")"
+ " (min " + formatProfit(antiCrest())
+ ", max " + formatProfit(crest()) + ")"
+ ", " + formatDouble1(leverage) + "X " + upper(type())
+ " held " + formatHoursMinutesColonSeconds(duration())),
openingTime() == 0 == null ? null : "opened " + formatLocalDateWithSeconds(openingTime())
+ (openReason == null ? "" : " " + roundBracket(str(openReason))),
"before leverage: " + formatProfit(profitBeforeLeverage()) + "%",
"margin: " + marginCoin + " " + formatMarginPrice(margin()),
"crypto: " + formatPrice(cryptoAmount),
"opening price: " + formatPriceX(openingPrice)
+ (isNaN(digitizedOpeningPrice()) ? "" : " (digitized: " + formatPrice(digitizedOpeningPrice())
+ ")") + (openingStep == 0 ? "" : " @ step " + openingStep),
!closed() ? null : "closing price: " + formatPriceX(closingPrice)
+ (closingStep == 0 ? "" : " @ step " + closingStep));
}
void closeOnMarket() {
if (dontCloseOnMarket) return;
if (isOpenError()) { log("Not closing because open error: " + this); return; }
try {
if (market != null) {
log("Closing on market: " + this);
market.closePosition(new IFuturesMarket.CloseOrder()
.holdSide(HoldSide.fromInt(direction))
.cryptoAmount(cryptoAmount));
closedOnMarket(true);
change();
}
} catch (Throwable e) {
closeError = toPersistableThrowable(e);
}
}
void open() {
margin = cryptoAmount*openingPrice/leverage;
log("Opening: " + this);
openingTime = currentTime();
openPositions.add(this);
change();
}
void openOnMarket() {
try {
if (market != null) {
log("Opening on market: " + this);
var order = new IFuturesMarket.OpenOrder()
.clientOrderID(positionID())
.holdSide(HoldSide.fromInt(direction))
.cryptoAmount(cryptoAmount)
.leverage(leverage)
.isCross(true);
if (tpSlOnPlatform) {
if (tpPrice != null)
order.takeProfitPrice(tpPrice);
if (slPrice != null)
order.stopLossPrice(slPrice);
}
market.openPosition(order);
openOrderID(order.orderID());
openedOnMarket(true);
change();
}
} catch (Throwable e) {
openError(toPersistableThrowable(e));
log("Open error: " + getStackTrace(e));
positionsThatFailedToOpen.add(this);
close("Open error");
}
}
void updateStats() {
double profit = profit();
crest(max(crest, profit));
antiCrest(min(antiCrest, profit));
}
void addJuicer(AbstractJuicer juicer) {
juicers(listCreateAndAdd(juicers, juicer));
}
void removeJuicer(AbstractJuicer juicer) {
juicers(removeDyn(juicers, juicer));
}
// Call this when position was closed manually on the platform
void notification_closedOutsideOfStrategy() {
closedOnMarket(true);
close("Closed outside of strategy");
}
} // end of Position
final public double getCurrentPrice(){ return currentPrice(); }
public double currentPrice() { return currentPrice; }
double currentPrice = 0;
final public double getOldPrice(){ return oldPrice(); }
public double oldPrice() { return oldPrice; }
double oldPrice = Double.NaN;
final public double getStartingPrice(){ return startingPrice(); }
public double startingPrice() { return startingPrice; }
double startingPrice = Double.NaN;
final public G22TradingStrategy setStartTime(long startTime){ return startTime(startTime); }
public G22TradingStrategy startTime(long startTime) { this.startTime = startTime; return this; } final public long getStartTime(){ return startTime(); }
public long startTime() { return startTime; }
long startTime;
public transient FieldVar varRealizedProfit_cache;
public FieldVar varRealizedProfit() { if (varRealizedProfit_cache == null) varRealizedProfit_cache = varRealizedProfit_load(); return varRealizedProfit_cache;}
public FieldVar varRealizedProfit_load() {
return new FieldVar(this, "realizedProfit", () -> realizedProfit(), realizedProfit -> realizedProfit(realizedProfit)); }
final public G22TradingStrategy setRealizedProfit(double realizedProfit){ return realizedProfit(realizedProfit); }
public G22TradingStrategy realizedProfit(double realizedProfit) { if (!eq(this.realizedProfit, realizedProfit)) { this.realizedProfit = realizedProfit; change(); } return this; }
final public double getRealizedProfit(){ return realizedProfit(); }
public double realizedProfit() { return realizedProfit; }
double realizedProfit;
public transient FieldVar varRealizedCoinProfit_cache;
public FieldVar varRealizedCoinProfit() { if (varRealizedCoinProfit_cache == null) varRealizedCoinProfit_cache = varRealizedCoinProfit_load(); return varRealizedCoinProfit_cache;}
public FieldVar varRealizedCoinProfit_load() {
return new FieldVar(this, "realizedCoinProfit", () -> realizedCoinProfit(), realizedCoinProfit -> realizedCoinProfit(realizedCoinProfit)); }
final public G22TradingStrategy setRealizedCoinProfit(double realizedCoinProfit){ return realizedCoinProfit(realizedCoinProfit); }
public G22TradingStrategy realizedCoinProfit(double realizedCoinProfit) { if (!eq(this.realizedCoinProfit, realizedCoinProfit)) { this.realizedCoinProfit = realizedCoinProfit; change(); } return this; }
final public double getRealizedCoinProfit(){ return realizedCoinProfit(); }
public double realizedCoinProfit() { return realizedCoinProfit; }
double realizedCoinProfit;
public transient FieldVar varRealizedWins_cache;
public FieldVar varRealizedWins() { if (varRealizedWins_cache == null) varRealizedWins_cache = varRealizedWins_load(); return varRealizedWins_cache;}
public FieldVar varRealizedWins_load() {
return new FieldVar(this, "realizedWins", () -> realizedWins(), realizedWins -> realizedWins(realizedWins)); }
final public G22TradingStrategy setRealizedWins(int realizedWins){ return realizedWins(realizedWins); }
public G22TradingStrategy realizedWins(int realizedWins) { if (!eq(this.realizedWins, realizedWins)) { this.realizedWins = realizedWins; change(); } return this; }
final public int getRealizedWins(){ return realizedWins(); }
public int realizedWins() { return realizedWins; }
int realizedWins;
public transient FieldVar varRealizedCoinWins_cache;
public FieldVar varRealizedCoinWins() { if (varRealizedCoinWins_cache == null) varRealizedCoinWins_cache = varRealizedCoinWins_load(); return varRealizedCoinWins_cache;}
public FieldVar varRealizedCoinWins_load() {
return new FieldVar(this, "realizedCoinWins", () -> realizedCoinWins(), realizedCoinWins -> realizedCoinWins(realizedCoinWins)); }
final public G22TradingStrategy setRealizedCoinWins(double realizedCoinWins){ return realizedCoinWins(realizedCoinWins); }
public G22TradingStrategy realizedCoinWins(double realizedCoinWins) { if (!eq(this.realizedCoinWins, realizedCoinWins)) { this.realizedCoinWins = realizedCoinWins; change(); } return this; }
final public double getRealizedCoinWins(){ return realizedCoinWins(); }
public double realizedCoinWins() { return realizedCoinWins; }
double realizedCoinWins;
public transient FieldVar varRealizedLosses_cache;
public FieldVar varRealizedLosses() { if (varRealizedLosses_cache == null) varRealizedLosses_cache = varRealizedLosses_load(); return varRealizedLosses_cache;}
public FieldVar varRealizedLosses_load() {
return new FieldVar(this, "realizedLosses", () -> realizedLosses(), realizedLosses -> realizedLosses(realizedLosses)); }
final public G22TradingStrategy setRealizedLosses(int realizedLosses){ return realizedLosses(realizedLosses); }
public G22TradingStrategy realizedLosses(int realizedLosses) { if (!eq(this.realizedLosses, realizedLosses)) { this.realizedLosses = realizedLosses; change(); } return this; }
final public int getRealizedLosses(){ return realizedLosses(); }
public int realizedLosses() { return realizedLosses; }
int realizedLosses;
public transient FieldVar varRealizedCoinLosses_cache;
public FieldVar varRealizedCoinLosses() { if (varRealizedCoinLosses_cache == null) varRealizedCoinLosses_cache = varRealizedCoinLosses_load(); return varRealizedCoinLosses_cache;}
public FieldVar varRealizedCoinLosses_load() {
return new FieldVar(this, "realizedCoinLosses", () -> realizedCoinLosses(), realizedCoinLosses -> realizedCoinLosses(realizedCoinLosses)); }
final public G22TradingStrategy setRealizedCoinLosses(double realizedCoinLosses){ return realizedCoinLosses(realizedCoinLosses); }
public G22TradingStrategy realizedCoinLosses(double realizedCoinLosses) { if (!eq(this.realizedCoinLosses, realizedCoinLosses)) { this.realizedCoinLosses = realizedCoinLosses; change(); } return this; }
final public double getRealizedCoinLosses(){ return realizedCoinLosses(); }
public double realizedCoinLosses() { return realizedCoinLosses; }
double realizedCoinLosses;
public transient FieldVar varStepCount_cache;
public FieldVar varStepCount() { if (varStepCount_cache == null) varStepCount_cache = varStepCount_load(); return varStepCount_cache;}
public FieldVar varStepCount_load() {
return new FieldVar(this, "stepCount", () -> stepCount(), stepCount -> stepCount(stepCount)); }
final public G22TradingStrategy setStepCount(long stepCount){ return stepCount(stepCount); }
public G22TradingStrategy stepCount(long stepCount) { if (!eq(this.stepCount, stepCount)) { this.stepCount = stepCount; change(); } return this; }
final public long getStepCount(){ return stepCount(); }
public long stepCount() { return stepCount; }
long stepCount;
public transient FieldVar varStepSince_cache;
public FieldVar varStepSince() { if (varStepSince_cache == null) varStepSince_cache = varStepSince_load(); return varStepSince_cache;}
public FieldVar varStepSince_load() {
return new FieldVar(this, "stepSince", () -> stepSince(), stepSince -> stepSince(stepSince)); }
final public G22TradingStrategy setStepSince(long stepSince){ return stepSince(stepSince); }
public G22TradingStrategy stepSince(long stepSince) { if (!eq(this.stepSince, stepSince)) { this.stepSince = stepSince; change(); } return this; }
final public long getStepSince(){ return stepSince(); }
public long stepSince() { return stepSince; }
long stepSince;
LinkedHashSet openPositions = new LinkedHashSet();
final public List getClosedPositions(){ return closedPositions(); }
public List closedPositions() { return closedPositions; }
List closedPositions = new ArrayList();
final public List getPositionsThatFailedToOpen(){ return positionsThatFailedToOpen(); }
public List positionsThatFailedToOpen() { return positionsThatFailedToOpen; }
List positionsThatFailedToOpen = new ArrayList();
void closeOnMarketMerged(Collection extends Position> positions) {
if (market == null) return;
closeOnMarketMerged_oneDirection(filter(positions, __3 -> __3.isShort()));
closeOnMarketMerged_oneDirection(filter(positions, __4 -> __4.isLong()));
}
// all positions must have the same direction
void closeOnMarketMerged_oneDirection(List extends Position> positions) {
if (empty(positions)) return;
double direction = first(positions).direction;
double cryptoAmount = doubleSum(positions, __5 -> __5.cryptoAmount);
log("Closing on market: " + positions);
try {
market.closePosition(new IFuturesMarket.CloseOrder()
.holdSide(HoldSide.fromInt(direction))
.cryptoAmount(cryptoAmount));
for (var p : positions)
p.closedOnMarket(true);
change();
} catch (Throwable e) {
var e2 = toPersistableThrowable(e);
for (var p : positions)
p.closeError(e2);
}
}
boolean hasPosition(double price, double direction) {
return findPosition(price, direction) != null;
}
Position closePosition(double price, double direction, Object closeReason) {
var p = findPosition(price, direction);
{ if (p != null) p.close(closeReason); }
return p;
}
void closePositions(Collection extends Position> positions) { closePositions(positions, null); }
void closePositions(Collection extends Position> positions, Object closeReason) {
if (mergePositionsForMarket) {
for (var p : positions)
p.dontCloseOnMarket(true).close(closeReason);
closeOnMarketMerged(positions);
} else
forEach(positions, __6 -> __6.close(closeReason));
}
Position findPosition(double digitizedPrice, double direction) {
return firstThat(openPositions(), p ->
diffRatio(p.digitizedOpeningPrice(), digitizedPrice) <= epsilon() && sign(p.direction) == sign(direction));
}
void printPositions() {
print(colonCombine(n2(openPositions, "open position"),
joinWithComma(openPositions)));
}
boolean started() { return !isNaN(startingPrice); }
void prices(double... prices) {
for (var price : unnullForIteration(prices)) {
if (!active()) return;
price(price);
}
}
transient IF1 makePriceCells;
PriceCells makePriceCells(double basePrice) { return makePriceCells != null ? makePriceCells.get(basePrice) : makePriceCells_base(basePrice); }
final PriceCells makePriceCells_fallback(IF1 _f, double basePrice) { return _f != null ? _f.get(basePrice) : makePriceCells_base(basePrice); }
PriceCells makePriceCells_base(double basePrice) {
return new GeometricPriceCells(basePrice, cellSize);
}
double digitizedPrice() { return digitizer == null ? Double.NaN : digitizer.digitizedPrice(); }
double lastDigitizedPrice() { return digitizer == null ? Double.NaN : digitizer.lastDigitizedPrice(); }
int digitizedCellNumber() { return digitizer == null ? 0 : digitizer.cellNumber(); }
void handleNewPriceInQ(double price) {
q.add(() -> price(price));
}
void nextStep() {
++stepCount;
stepSince(currentTime());
}
void afterStep() {
double coinProfit = coinProfit();
maxDebt(max(maxDebt, debt()));
//minCoinProfit = min(minCoinProfit, coinProfit);
//maxBoundCoin = max(maxBoundCoin, boundCoin());
maxInvestment(max(maxInvestment, investment()));
strategyCrest(max(strategyCrest, coinProfit));
maxDrawdown(max(maxDrawdown, strategyCrest-coinProfit));
if (takeCoinProfitEnabled() && coinProfit >= takeCoinProfit) {
log("Taking coin profit.");
closeMyself();
}
for (var p : openPositions) p.updateStats();
}
double investment() {
return boundCoin()-realizedCoinProfit;
}
double boundCoin() {
return max(openMargins(), max(0, -coinProfit()));
}
double fromCellNumber(double cellNumber) { return cells().fromCellNumber(cellNumber); }
double toCellNumber(double price) { return cells().toCellNumber(price); }
List shortPositionsAtOrBelowDigitizedPrice(double openingPrice) {
return filter(openPositions, p -> p.isShort() && p.digitizedOpeningPrice() <= openingPrice);
}
List shortPositionsAtOrAboveDigitizedPrice(double openingPrice) {
return filter(openPositions, p -> p.isShort() && p.digitizedOpeningPrice() >= openingPrice);
}
List