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
sclass Corridor {
record noeq Position(/*settable*/ double openingPrice, /*settable*/ double direction) {
/*settable*/ double closingPrice = Double.NaN;
void close {
openPositions.remove(this);
closingPrice = currentPrice();
closedPositions.add(this);
}
}
record noeq Threshold(/*settable*/ double price, /*settable*/ double direction, Runnable action) {
}
settable double ladderStep = 1;
gettable double currentPrice = 0;
new L loops;
new TreeMultiMap thresholds;
new LinkedHashSet openPositions;
new L closedPositions;
record noeq Loop(/*settable*/ double startingPrice, /*settable*/ double direction) {
Position position;
Loop successor;
selfType init() {
loops.add(this);
addThreshold(startingPrice+ladderStep, direction, -> {
position = openPosition(direction);
if (successor == null)
successor = new Loop(startingPrice+ladderStep, direction).init();
});
addThreshold(startingPrice-ladderStep, -direction, -> {
position.close();
});
this;
}
}
Position openPosition(double direction) {
ret addAndReturn(openPositions, new Position(currentPrice(), direction));
}
Threshold addThreshold(double price, double direction, Runnable action) {
var t = new Threshold(price, direction, action);
thresholds.put(t.price, t);
ret t;
}
void start {
double price = currentPrice();
new Loop(price-ladderStep, 1).init();
new Loop(price+ladderStep, -1).init();
}
selfType currentPrice(double price) {
double oldPrice = currentPrice;
currentPrice = price;
int direction = sign(price-oldPrice);
if (direction != 0) {
NagivableMap map = thresholds.innerMap();
map = direction > 0
? map.subMap(oldPrice, false, price, true)
: map.subMap(price, true, oldPrice, false);
for (Threshold t : cloneValues(map))
if (t.direction == direction)
callF(t.action);
}
this;
}
}