Libraryless. Click here for Pure Java version (17529L/101K).
persistable sclass TradingCandleMaker { settable double candleLength = 1; // in minutes settable int maxCandles = Int.MAX_VALUE; settable double alignment; // shift in seconds // candleLength = granularity in minutes *(double *candleLength) {} L<TradingCandle> candles = syncL(); TradingCandle currentCandle() { ret last(candles); } TradingCandle completedCandle() { ret nextToLast(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(); var cc = currentCandle(); cc.addValue(lastPrice, maxEnd); if (cc.projectedEndTime() == 0) cc.projectedEndTime(maxEndOfCurrentCandle().unixDate()); } if (empty(candles)) newCandle(); currentCandle().addValue(price, ts); } void newCandle { var c = currentCandle(); c?.ongoing(false).projectedEndTime(0); candles.add(new TradingCandle().ongoing(true)); dropOldCandles(); } // returns number of entries processed int addTickerSequence aka add 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<TradingCandle> candles aka get() { ret cloneList(candles); } L<TradingCandle> liveCandles() { ret candles; } // only complete candles (cut off last candle and also first candle if incomplete) L<TradingCandle> completeCandles() { synchronized(mutex()) { int startIdx = isComplete(first(candles)) ? 0 : 1; ret cloneSubList(candles, startIdx, l(candles)-1); } } // We just synchronize on the candles list O mutex() { ret candles; } bool isComplete(TradingCandle candle) { ret candle != null && candle.durationInSeconds() == candleLength*60; } toString { ret "Candle maker " + formatDouble(candleLength) + "m, " + nCandles(candles); } L<TradingCandle> get(TickerSequence ticker) { feed(ticker); ret candles(); } selfType granularity(double minutes) { ret candleLength(minutes); } }
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): elmgxqgtpvxh, mqqgnosmbjvj, wnsclhtenguj
No comments. add comment
Snippet ID: | #1036143 |
Snippet name: | TradingCandleMaker - puts ticker values into candles of fixed length |
Eternal ID of this version: | #1036143/30 |
Text MD5: | 3e74364ba4cb81b4ce5bfafbdb8cc229 |
Transpilation MD5: | f15b774f3e9ca9e6547586990f6b703f |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2023-03-20 21:40:43 |
Source code size: | 3632 bytes / 122 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 227 / 419 |
Version history: | 29 change(s) |
Referenced in: | [show references] |