replace real with double. replace Real with Double. srecord noeq MPM2(real[] ticker) { // how much percentual slippage we have for each position on // average dependent on the market (trading site) we are using srecord Market(real adversity) {} srecord Juicer(real lossTolerance, real pullback) {} srecord Position(real openingTime, real direction) {} srecord noeq LiveTicker(real[] data, int time) { Real currently() { ret lookback(0); } Real lookback(real time) { int index = iceil(this.time-1-time); ret index >= 0 ? data[index] : null; } void add(real value) { if (time >= l(data)) { data = resizeArray(data, max(1, limitToSafeArraySize(l(data)*2L))); if (time >= l(data)) fail("Can't handle more than 2 billion ticker entries"); } data[time++] = value; } } srecord Eye(real time, real minMove) { real adviseDirection(LiveTicker ticker) { Real currently = ticker.currently(); if (currently == null) ret 0; Real before = ticker.lookback(time); if (before == null) ret 0; real move = currently-before; if (abs(move) >= minMove) ret (real) sign(move); ret 0; } } real ticker(real time) { ret ticker(iceil(time)); } real openingPrice(Position p) { ret ticker(p.openingTime); } // all "profit" functions return a positive or negative percent value real profit(Position p, real time, Market m) { ret (ticker(time)/openingPrice(p)*100-100)*p.direction - m.adversity; } Real closingTime(Position p, Juicer j, Market m) { int time = iceil(p.openingTime); real openingPrice = ticker(time); real crest = -infinity(); while (time < ticker.length-1) { real profit = profit(p, time, m); crest = max(crest, profit); if (profit < (profit < 0 ? -j.lossTolerance : crest-j.pullback)) break; ++time; } null; } Real profit(Position p, Juicer j, Market m) { Real closingTime = closingTime(p, j, m); ret closingTime == null ? null : profit(p, closingTime, m); } // How profitable is it to open a position of any direction // at a certain point in time? Real profitability(real time, Juicer j, Market m) { ret maxAllowingNull( profit(new Position(time, -1), j, m), profit(new Position(time, 1), j, m)); } abstract class Convergent extends ItIt<Real> { Real value; bool stepped, done; public bool hasNext() { if (done) false; if (!stepped) { stepped = true; step(); } ret !done; } public Real next() { assertTrue(hasNext()); stepped = false; ret value; } abstract void step(); } // eye can be null, then we just test the juicer record noeq Backtest(Eye eye, Juicer j, Market m) extends Convergent { Iterator<Int> openingTimes = new WeightlessShuffledIterator<Int>(intRangeList(ticker.length)); new Average profitPerPosition; new Average positionsOpenedPercentage; // percentage of positions closed before reaching the end of the ticker "tape" new Average positionsClosedInTimePercentage; void step { if (!openingTimes.hasNext()) ret with done = true; int openingTime = openingTimes.next(); Real profit; if (eye == null) profit = profitability(openingTime, j, m); else { real direction = eye.adviseDirection(new LiveTicker(ticker, openingTime)); positionsOpenedPercentage.addSample(direction != 0 ? 100 : 0); if (direction == 0) ret; Position position = new Position(openingTime, direction); profit = profit(position, j, m); } positionsClosedInTimePercentage.addSample(profit != null ? 100 : 0); if (profit != null) profitPerPosition.addSample(profit); value = profitPerPosition!; } } }
Began life as a copy of #1036148
download show line numbers debug dex old transpilations
Travelled to 2 computer(s): mqqgnosmbjvj, wnsclhtenguj
No comments. add comment
Snippet ID: | #1036152 |
Snippet name: | MPM2 backup untested |
Eternal ID of this version: | #1036152/2 |
Text MD5: | d9aa50c1837b83965f4784e733b73844 |
Author: | stefan |
Category: | javax / trading bot |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-10-01 06:21:14 |
Source code size: | 4081 bytes / 134 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 154 / 159 |
Version history: | 1 change(s) |
Referenced in: | [show references] |