Warning: session_start(): open(/var/lib/php/sessions/sess_uokdk2r5juingt4affr48oq8tm, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
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 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 openingTimes = new WeightlessShuffledIterator(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!;
}
}
}