Warning: session_start(): open(/var/lib/php/sessions/sess_olbkcmp2l6rl3u1ps2d305qq0q, 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 sclass TradingCandleMaker {
settable double candleLength = 1; // in minutes
settable int maxCandles = Int.MAX_VALUE;
settable double alignment; // shift in seconds
*(double *candleLength) {}
L candles = syncL();
TradingCandle currentCandle() { ret last(candles); }
bool isEmpty() { ret main isEmpty(candles); }
Timestamp endTime() {
var candle = last(candles);
ret candle?.endTime();
}
double lastPrice() { ret currentCandle().end(); }
void add(double price, long timestamp) {
var ts = new Timestamp(timestamp);
int safety = 0;
while (currentCandle() != null) {
if (safety++ >= 1000) {
warn("TradingCandleMaker safety warning");
break;
}
Timestamp maxEnd = maxEndOfCurrentCandle();
if (!greaterOrEq(ts, maxEnd)) break;
currentCandle().endTime(maxEnd);
double lastPrice = lastPrice();
newCandle();
currentCandle().addValue(lastPrice, maxEnd);
}
if (empty(candles)) newCandle();
currentCandle().addValue(price, ts);
}
void newCandle {
candles.add(new TradingCandle);
dropOldCandles();
}
// returns number of entries processed
int addTickerSequence aka feed(TickerSequence ts) {
int entriesProcessed = 0;
Timestamp endTime = endTime();
// TODO: Cut off beginning of ticker according to maxCandles
if (endTime != null)
ts = ts.subSequenceFromTimestamp(endTime().unixDate()+1);
int n = l(ts);
for i to n: {
add(ts.prices.get(i), ts.timestamps.get(i));
++entriesProcessed;
}
if (!isEmpty() && ts.lastTickerEvent > currentCandle().endTime().toLong()) {
add(ts.lastPrice(), ts.lastTickerEvent);
++entriesProcessed;
}
ret entriesProcessed;
}
Timestamp maxEndOfCurrentCandle() {
long time = currentCandle().startTime.toLong();
long align = secondsToMS(alignment);
time = roundUpTo(secondsToMS(candleLength*60), time+align+1)-align;
ret new Timestamp(time);
}
/*bool needNewCandle(long timestamp) {
ret empty(candles)
|| timestamp >= maxEndOfCurrentCandle().unixDate();
}*/
void dropOldCandles {
if (l(candles) > maxCandles)
removeSubList(candles, 0, l(candles)-maxCandles);
}
L candles() {
ret cloneList(candles);
}
toString { ret "Candle maker " + formatDouble(candleLength) + "m, " + nCandles(candles); }
}