Fee and roundtrip profit report calculations. Are they correct?
#1
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:

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.
  Reply
#2
Totally agree with you, i've noticed the same issues:
1) fee rounding, so we lose accuracy in the overall profit/loss calculation
2) fees not taken into account in the PnL% calculation (because they are not included in ExitBalance nor in EntryBalance)

These two issues always round up very much the final profit/loss calculation, that is never 100% true.

I've search on the internet for some solutions and also for some explanations (beacuse maybe we could be wrong!), but i didn't found anything.
Please anyone who noticed that, raise your hand so we can join our forces and figure it out.

Cheers!
  Reply
#3
anyone can help or is it not even a problem???
  Reply
#4
Someone help this thread please Smile
  Reply


Forum Jump:


Users browsing this thread: