Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

122
LINES

< > BotCompany Repo | #1036143 // TradingCandleMaker - puts ticker values into candles of fixed length

JavaX fragment (include) [tags: use-pretranspiled]

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: 229 / 421
Version history: 29 change(s)
Referenced in: #1003674 - Standard Classes + Interfaces (LIVE continued in #1034167)