Warning: session_start(): open(/var/lib/php/sessions/sess_n1d8ocivi8hmqjpkvh8ehb8eqm, 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
persistable class Position extends G22TradingStrategy.Position {
settable AbstractJuicer juicer;
toString {
ret super.toString()
+ (juicer == null ? "" : ". " + commaCombine(juicer.currentSignals()));
}
}
srecord ProfitBeforeLeverageJuiceable(Position p) is Juiceable {
public double juiceValue() { ret p.profitBeforeLeverage(); }
}
void juiceStrategy_price(double price) {
if (currentPrice == price) ret;
currentPrice = price;
afterwards { afterStep(); change(); }
juiceStrategy_newPrice(price);
}
void juiceStrategy_newPrice(double price) {
for (p : openPositions()) {
cast p to Position;
if (p.juicer != null) {
var signals = p.juicer.calculateCloseSignals();
var strongest = highestBy(signals, s -> s.strength());
if (strongest != null && strongest.isTrigger()) {
p.close(strongest);
}
}
}
}
Position openShort() { ret openPosition(-1); }
Position openLong() { ret openPosition(1); }
Position openPosition(int direction, O openReason default null) {
new Position p;
p.marginToUse = marginToUseForNewPosition();
addJuicer(p);
ret openPosition(p, direction, openReason);
}
void addJuicer(Position p) {
var j = makeJuicer();
if (j == null) ret;
j.copyTransientValuesFrom(p.juicer);
j.juiceable(new ProfitBeforeLeverageJuiceable(p));
p.juicer(j);
}
void recreateJuicersForExistingPositions aka updateJuicers() {
for (p : openPositions()) {
cast p to Position;
addJuicer(p);
}
}
L extends Position> openPositions() { ret (L) super.openPositions(); }
L allJuicers aka juicers() {
ret map(openPositions(), -> .juicer());
}