Libraryless. Click here for Pure Java version (9969L/55K).
sclass Corridor2 { settable double smallMove = 0.2; settable int capacity = 6; settable bool openTwoPositionsAtStart = true; record noeq Position(double openingPrice, double direction) { double closingPrice = Double.NaN; 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"); openPositionsMap(direction).remove(openingPrice); closingPrice = currentPrice(); closedPositions.add(this); realizedProfit += profit(); print(this); printPositions(); } toString { ret renderFunctionCall( spaceCombine( closed() ? "Closed" : null, type() ), openingPrice, "profit=" + profit()); } } gettable double currentPrice = 0; gettable double lastPrice = Double.NaN; gettable double startingPrice = Double.NaN; gettable double realizedProfit; gettable double maxDebtEncountered; gettable int stepCount; // open positions sorted by direction and price gettable new TreeMap<Double, Position> openLongs; gettable new TreeMap<Double, Position> openShorts; gettable new L<Position> closedPositions; gettable new DoubleBuffer priceHistory; TreeMap<Double, Position> openPositionsMap(double direction) { if (direction > 0) ret openLongs; if (direction < 0) ret openShorts; fail("direction 0"); } Position openPosition(double direction) { var p = new Position(currentPrice(), direction); openPositionsMap(direction).put(p.openingPrice, p); print("Opening " + p); printPositions(); ret p; } Position openShort() { ret openPosition(-1); } Position openLong() { ret openPosition(1); } L<Position> openPositions() { ret concatLists(values(openLongs), values(openShorts)); } void printPositions { var positions = openPositions(); print(colonCombine(n2(positions, "open position"), joinWithComma(positions))); } double unrealizedProfit() { ret doubleSum(map(openPositions(), ->.profit())); } 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()); } void prices(double... prices) { fOr (price : prices) price(price); } void currentPrice aka price(double price) { lastPrice = currentPrice; if (lastPrice == price) ret; currentPrice = price; priceHistory.add(price); ++stepCount; printWithPrecedingNL(commaCombine( "Step " + stepCount + ". Old price: " + lastPrice, "New price: " + price)); step(); maxDebtEncountered = max(maxDebtEncountered, debt()); print(this); } bool started() { ret !isNaN(startingPrice); } void start { if (started()) fail("Already started"); startingPrice = currentPrice(); print("Starting CORRIDOR at " + startingPrice + " +/- " + smallMove); if (openTwoPositionsAtStart) { openPosition(1); openPosition(-1); } } int currentDirection() { ret sign(currentPrice-lastPrice); } L<Position> positionsAtPriceOrWorse(double direction, double price) { var map = openPositionsMap(direction); ret direction < 0 ? valuesList(map.tailMap(price, true)) : valuesList(map.headMap(price, true)); } // Algorithm-specific logic follows swappable void step { // Close winning position(s) var positions = positionsAtPriceOrWorse(currentDirection(), currentPrice()-currentDirection()*smallMove); for (p : positions) p.close(); // If we closed anything, open a position in reverse direction if (nempty(positions)) { openPosition(-currentDirection()); } // TODO: "travelling" } }
Began life as a copy of #1036196
download show line numbers debug dex old transpilations
Travelled to 2 computer(s): elmgxqgtpvxh, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1036204 |
Snippet name: | Corridor2 - the "analog" version that doesn't digitize prices [dev., have to figure out first] |
Eternal ID of this version: | #1036204/11 |
Text MD5: | e1402bffeed571f1edb572b3837d6914 |
Transpilation MD5: | 09659741521ca370c190286f3300a77b |
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-17 23:26:03 |
Source code size: | 4701 bytes / 173 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 129 / 237 |
Version history: | 10 change(s) |
Referenced in: | #1003674 - Standard Classes + Interfaces (LIVE continued in #1034167) |