11-08-2018, 06:54 PM
So I was recently doing some backtesting, and noticed that the single roundtrip profit report (gekko ui by the way) is a bit deceiving, at least to me.
It's not really that big of a problem but rases some questions.
At times it will show that during roundtrip I made a profit when in reality I made a loss.
Let me show you what I mean on a example:
My initial balance is 10000 currency no asset. fee is 0.1% (both maker and taker)
After the first roundtrip I get a report:
entry balance = 9990, exit balance = 9999, p&l = 9, profit = 0.09%
So report shows a profit of 9 currency, but when we look at the exit balance it's clearly a loss of 1 currency.
It calculates the profit based on "entry balance" which is the previous (in this case initial) balance after fee. this gives us 9990 currency.
Wouldn't it be better if it was based on previous roundtrip exit balance, so it would show a 1 currency loss instead of a profit?
Next I found the calculation in performance analyzer to be done like this:
I then determined how the entry balance is calculated:
Everything seems fine so far, but let's check out how trade.portfolio.asset is being calculated(assuming it's being fetched straight from paperTrader.js?):
where the extractFee() function does this:
}
I get 635.59726419 of asset so now paperTrader uses this number to calculate the balance we have and here is where it gets interesting:
When calculated returns : 0 + 15.7175 * 635.59726419 = 9989.999999906326 !?
Well that should be equal 9990 right?
Because the extractFee() function uses Math.floor() we lose that .59599 which changes the final result giving us a slightly incorrect balance.
I understand it's limiting the amount of numbers after the comma for the exchange.
So my question is how does this affect the whole bot? Does it have an effect at all?
How does it affect real trading?
It's a bit concerning that maybe this problem could compound on itself overtime affecting the final result of backtest/live trade.
It's not really that big of a problem but rases some questions.
At times it will show that during roundtrip I made a profit when in reality I made a loss.
Let me show you what I mean on a example:
My initial balance is 10000 currency no asset. fee is 0.1% (both maker and taker)
After the first roundtrip I get a report:
entry balance = 9990, exit balance = 9999, p&l = 9, profit = 0.09%
So report shows a profit of 9 currency, but when we look at the exit balance it's clearly a loss of 1 currency.
It calculates the profit based on "entry balance" which is the previous (in this case initial) balance after fee. this gives us 9990 currency.
Wouldn't it be better if it was based on previous roundtrip exit balance, so it would show a 1 currency loss instead of a profit?
Next I found the calculation in performance analyzer to be done like this:
Code:
roundtrip.pnl = roundtrip.exitBalance - roundtrip.entryBalance;
I then determined how the entry balance is calculated:
Code:
this.roundTrip.entry = {
date: trade.date,
price: trade.price,
total: trade.portfolio.currency + (trade.portfolio.asset * trade.price), // <--- here
}
Code:
PerformanceAnalyzer.prototype.handleCompletedRoundtrip = function() {
var roundtrip = {
id: this.roundTrip.id,
entryAt: this.roundTrip.entry.date,
entryPrice: this.roundTrip.entry.price,
entryBalance: this.roundTrip.entry.total,// <--- and further here
exitAt: this.roundTrip.exit.date,
exitPrice: this.roundTrip.exit.price,
exitBalance: this.roundTrip.exit.total,
duration: this.roundTrip.exit.date.diff(this.roundTrip.entry.date)
}
Everything seems fine so far, but let's check out how trade.portfolio.asset is being calculated(assuming it's being fetched straight from paperTrader.js?):
Code:
if(what === 'long') {
cost = (1 - this.fee) * this.portfolio.currency;
this.portfolio.asset += this.extractFee(this.portfolio.currency / this.price);// <------------------- here
amount = this.portfolio.asset;
this.portfolio.currency = 0;
this.exposed = true;
this.trades++;
}
where the extractFee() function does this:
Code:
PaperTrader.prototype.extractFee = function(amount) {
amount *= 1e8; // <------------------------------------- (10000 currency / price like 15.7175) 636.2334976936536 * 10^8 = 63623349769.36536
amount *= this.fee;//<----------------------------------- 63623349769.36536 * 0.999 = 63559726419.59599
amount = Math.floor(amount);//<--------------------------- Rounds down removing everything after the comma so we get 63559726419
amount /= 1e8; // <----------------------------------------63559726419 / 10^8 = 635.59726419
return amount;
}
I get 635.59726419 of asset so now paperTrader uses this number to calculate the balance we have and here is where it gets interesting:
Code:
PaperTrader.prototype.getBalance = function() {
return this.portfolio.currency + this.price * this.portfolio.asset;
}
When calculated returns : 0 + 15.7175 * 635.59726419 = 9989.999999906326 !?
Well that should be equal 9990 right?
Because the extractFee() function uses Math.floor() we lose that .59599 which changes the final result giving us a slightly incorrect balance.
I understand it's limiting the amount of numbers after the comma for the exchange.
So my question is how does this affect the whole bot? Does it have an effect at all?
How does it affect real trading?
It's a bit concerning that maybe this problem could compound on itself overtime affecting the final result of backtest/live trade.