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 {
settable double ladderStep = 1;
settable double patience = 1; // This probably should always be 1
settable int capacity = 6;
settable bool openTwoPositionsAtStart = true;
record noeq Position(double openingPrice, double direction) {
double closingPrice = Double.NaN;
int digitizedOpeningPrice() { ret 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());
}
}
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 stepCount;
gettable new LinkedHashSet openPositions;
gettable new L closedPositions;
gettable new DoubleBuffer priceHistory;
Position openPosition(double direction) {
var p = new Position(currentPrice(), direction);
openPositions.add(p);
print("Opening " + p);
printPositions();
ret p;
}
bool hasPosition(double price, double direction) {
ret findPosition(price, direction) != null;
}
Position closePosition(double price, double direction) {
var p = findPosition(price, direction);
p?.close();
ret p;
}
Position findPosition(double price, double direction) {
ret firstThat(openPositions(), p ->
p.digitizedOpeningPrice() == digitizedPrice(price) && p.direction == direction);
}
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);
if (openTwoPositionsAtStart) {
openPosition(1);
openPosition(-1);
}
}
int digitizePrice aka digitizedPrice(double price) {
ret iround((price-digitizationBase)/ladderStep);
}
int oldPriceDigitized() {
ret digitizePrice(oldPrice);
}
int currentPriceDigitized() {
ret digitizePrice(currentPrice());
}
void prices(double... prices) {
fOr (price : prices)
price(price);
}
void currentPrice aka price(double price) {
oldPrice = currentPrice;
if (oldPrice == price) ret;
currentPrice = price;
int direction = sign(price-oldPrice);
lastDirection = direction;
if (oldPriceDigitized() == currentPriceDigitized()) ret;
bool first = empty(priceHistory);
priceHistory.add(price);
++stepCount;
if (first)
printWithPrecedingNL("Starting price: " + price);
else
printWithPrecedingNL(commaCombine(
"Step " + stepCount + ". Old price: " + oldPrice,
"New price: " + price));
if (started)
step();
print(this);
}
swappable void step {
closePosition(currentPrice()-ladderStep*lastDirection()*patience(), lastDirection());
int p1 = oldPriceDigitized();
int p2 = currentPriceDigitized();
int direction = lastDirection();
if (!hasPosition(currentPrice(), -direction))
openPosition(-direction);
//profitHistory.add(iround(profit()));
}
double unrealizedProfit() {
ret doubleSum(map(openPositions, ->.profit()));
}
L negativePositions() {
ret filter(openPositions, p -> p.profit() < 0);
}
double debt() {
ret doubleSum(map(negativePositions(), ->.profit()));
}
double profit() {
ret realizedProfit+unrealizedProfit();
}
LS status() {
ret ll(
"Step " + n2(stepCount),
"Profit: " + profit(),
"Realized profit: " + realizedProfit + " from " + n2(closedPositions, "closed position"),
"Unrealized profit: " + unrealizedProfit() + " in " + n2(openPositions, "open position"),
"Debt: " + debt(),
);
}
toString { ret commaCombine(status()); }
}