Warning: session_start(): open(/var/lib/php/sessions/sess_6rsg9v9e39lak2irfr2mq452tc, 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
set flag Reparse.
sclass Corridor {
record noeq Position(double openingPrice, double direction) {
double closingPrice = Double.NaN;
gettable int digitizedOpeningPrice = digitizePrice(openingPrice);
bool closed() { ret !isNaN(closingPrice); }
S type() { ret trading_directionToPositionType(direction); }
double profitAtPrice(double price) {
ret (price-openingPrice)*direction;
}
double profit() {
ret profitAtPrice(closed() ? closingPrice : currentPrice());
}
void close {
if (closed()) fail("Can't close again");
openPositions.remove(this);
closingPrice = currentPrice();
closedPositions.add(this);
realizedProfit += profit();
print(this);
printPositions();
}
toString {
ret renderFunctionCall(
spaceCombine(
closed() ? "Closed" : null,
type()
),
openingPrice + " [" + digitizedOpeningPrice() + "]",
"profit=" + profit());
}
}
settable double ladderStep = 1;
gettable double currentPrice = 0;
gettable double oldPrice = Double.NaN;
gettable double startingPrice = Double.NaN;
gettable double digitizationBase;
gettable int lastDirection;
gettable double realizedProfit;
gettable int step;
new LinkedHashSet openPositions;
new L closedPositions;
Position openPosition(double direction) {
var p = new Position(currentPrice(), direction);
openPositions.add(p);
print("Opening " + p);
printPositions();
ret p;
}
Position openShort() { ret openPosition(-1); }
Position openLong() { ret openPosition(1); }
void printPositions {
print(colonCombine(n2(openPositions, "open position"),
joinWithComma(openPositions)));
}
bool started() { ret !isNaN(startingPrice); }
void start {
if (started()) fail("Already started");
startingPrice = currentPrice();
digitizationBase = frac(startingPrice/ladderStep);
print("Starting CORRIDOR at " + startingPrice + " +/- " + ladderStep);
openPosition(1);
openPosition(-1);
}
int digitizePrice(double price) {
ret iround((price-digitizationBase)/ladderStep);
}
int oldPriceDigitized() {
ret digitizePrice(oldPrice);
}
int currentPriceDigitized() {
ret digitizePrice(currentPrice());
}
selfType currentPrice aka price(double price) {
oldPrice = currentPrice;
if (oldPrice == price) this;
currentPrice = price;
int direction = sign(price-oldPrice);
lastDirection = direction;
if (oldPriceDigitized() == currentPriceDigitized()) this;
++step;
printWithPrecedingNL(commaCombine(
"Step " + step + ." Old price: " + oldPrice,
"New price: " + price));
step();
this;
}
swappable void step {
for (p : cloneList(openPositions)) {
if (digitizePrice(p.openingPrice) < currentPriceDigitized()
&& p.direction == lastDirection)
p.close();
}
}
double unrealizedProfit() {
ret doubleSum(map(openPositions, ->.profit()));
}
L negativePositions() {
ret filter(openPositions, p -> p.profit() < 0);
}
double negativePositionSum() {
ret doubleSum(map(negativePositions(), ->.profit()));
}
double profit() {
ret realizedProfit+unrealizedProfit();
}
LS status() {
ret ll(
"Profit: " + profit(),
"Realized profit: " + realizedProfit + " from " + n2(closedPositions, "closed position"),
"Unrealized profit: " + unrealizedProfit() + " in " + n2(openPositions, "open position"),
"Negative positions: " + negativePositionSum(),
);
}
toString { ret commaCombine(status()); }
}