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

195
LINES

< > BotCompany Repo | #1036207 // Corridor [backup 2]

JavaX fragment (include)

set flag Reparse.

sclass Corridor {
  settable double ladderStep = 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 isLong() { ret direction > 0; }
    bool isShort() { ret direction < 0; }
    
    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<Position> openPositions;
  gettable new L<Position> 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 {
    // Close forward position "behind us"
    closePosition(currentPrice()-ladderStep*lastDirection(), lastDirection());
    
    int p1 = oldPriceDigitized();
    int p2 = currentPriceDigitized();
    
    // Open backward position here (if not there yet)
    int direction = lastDirection();
    if (!hasPosition(currentPrice(), -direction))
      openPosition(-direction);
  }
  
  double unrealizedProfit() {
    ret doubleSum(map(openPositions, ->.profit()));
  }
  
  L<Position> shortPositionsAtOrBelowPrice(double openingPrice) {
    ret filter(openPositions, p -> p.isShort() && p.openingPrice <= openingPrice);
  }
  
  L<Position> longPositionsAtOrAbovePrice(double openingPrice) {
    ret filter(openPositions, p -> p.isLong() && p.openingPrice >= openingPrice);
  }
  
  L<Position> 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()); } 
}

Author comment

Began life as a copy of #1036196

download  show line numbers  debug dex  old transpilations   

Travelled to 2 computer(s): mqqgnosmbjvj, wnsclhtenguj

No comments. add comment

Snippet ID: #1036207
Snippet name: Corridor [backup 2]
Eternal ID of this version: #1036207/1
Text MD5: cff91d47fcef415ee640456ba21292f2
Author: stefan
Category: javax / gazelle 22
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-10-19 17:51:41
Source code size: 5452 bytes / 195 lines
Pitched / IR pitched: No / No
Views / Downloads: 124 / 138
Referenced in: [show references]