Libraryless. Click here for Pure Java version (10137L/58K).
sclass MPM { gettable new PositionSet imaginaryPositions; gettable new PositionSet realPositions; settable double cryptoPrice; new DoubleBuffer cryptoPriceLog; // -1, 0 [initial value only] or 1 settable int cryptoDirection; event cryptoDirectionChanged; settable double currentTime; settable double maxAllowedLoss = 1; // in percent Position newShort() { ret new Position().direction(-1); } Position newLong() { ret new Position().direction(1); } abstract class CloseReason {} class LossClose > CloseReason {} class HappyClose > CloseReason {} class RegularClose > CloseReason {} // pullback close class KillClose > CloseReason {} // hard-closed for any reason settable double fees = 0.12; settable double expectedSlippage = .1; // in percent before leverage class Position { settable bool real; // -1 (short) or 1 (long) settable int direction; settable double openingTime; settable double openingPrice; settable double lastPrice; settable double closingTime; settable double closingPrice; simplyCached double openingPriceWithFeesAndSlippage() { ret openingPrice*(1+(fees+expectedSlippage)/100*direction); } settable double relativeValue; settable double maxRelativeValue = negativeInfinity(); settable double minRelativeValue = infinity(); settable double pullbackThreshold; // null when position is open, not null when position was closed settable CloseReason closeReason; PositionSet motherList() { ret real ? realPositions : imaginaryPositions; } void close(CloseReason reason) { closingTime(time()); closingPrice(cryptoPrice); closeReason(reason); motherList().wasClosed(this); } void imagine { real(false); launch(); } void launch { update(cryptoPrice); motherList().add(this); } void update(double cryptoPrice) { lastPrice(cryptoPrice); relativeValue((cryptoPrice/openingPriceWithFeesAndSlippage()-1)*direction*100); maxRelativeValue(max(maxRelativeValue, relativeValue)); minRelativeValue(min(minRelativeValue, relativeValue)); pullbackThreshold(maxRelativeValue-pullback(this)); } toString { ret renderVars(+direction, +openingPrice, +openingPriceWithFeesAndSlippage(), +lastPrice, +relativeValue, +maxRelativeValue); } void autoClose { if (relativeValue < -maxAllowedLoss) ret with close(new LossClose); if (relativeValue >= 0 && relativeValue < pullbackThreshold) ret with close(new RegularClose); } bool isOpen() { ret closeReason == null; } } // end of Position class PositionSet { new LinkedHashSet<Position> positionsByDate; new LinkedHashSet<Position> openPositions; new LinkedHashSet<Position> closedPositions; void add(Position p) { positionsByDate.add(p); (p.isOpen() ? openPositions : closedPositions).add(p); } void remove(Position p) { positionsByDate.remove(p); openPositions.remove(p); closedPositions.remove(p); } void wasClosed(Position p) { openPositions.remove(p); closedPositions.add(p); } } swappable double pullback(Position p) { ret 0.5; } double time() { ret currentTime; } void addTickerSequence(TickerSequence ts) { int n = l(ts); for i to n: newCryptoPrice(ts.prices.get(i), ts.timestamps.get(i)); } void newCryptoPrice(double price) { newCryptoPrice(price, currentTime+1); } void newCryptoPrice(double price, double time) { currentTime(time); // don't store non-changes if (price == cryptoPrice) ret; int direction = sign(cryptoPrice-price); cryptoPriceLog.add(price); cryptoPrice(price); for (p : allOpenPositions()) { p.update(cryptoPrice); p.autoClose(); } if (direction != cryptoDirection) { cryptoDirection(direction); cryptoDirectionChanged(); } } L<Position> allPositions() { ret concatLists(realPositions().positionsByDate, imaginaryPositions().positionsByDate); } L<Position> allOpenPositions() { ret concatLists(realPositions().openPositions, imaginaryPositions().openPositions); } { init(); } void init { onCryptoDirectionChanged(-> { for (p : ll(newLong(), newShort())) p.openingTime(time()).openingPrice(cryptoPrice).imagine(); }); } void printStatus { print(toString()); } toString { ret combineWithSeparator(" + ", n2(realPositions.positionsByDate, "real position"), n2(imaginaryPositions.positionsByDate, "imaginary position")); } }
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): elmgxqgtpvxh, mqqgnosmbjvj, wnsclhtenguj
No comments. add comment
Snippet ID: | #1036123 |
Snippet name: | MPM Trading Bot [dev.] |
Eternal ID of this version: | #1036123/39 |
Text MD5: | 76ccefe7624497e3bf9f72d558a4fcee |
Transpilation MD5: | a9bef09bf56e2533816ae9d5d838221d |
Author: | someone |
Category: | |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-09-28 22:36:32 |
Source code size: | 4976 bytes / 181 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 216 / 463 |
Version history: | 38 change(s) |
Referenced in: | #1003674 - Standard Classes + Interfaces (LIVE continued in #1034167) |