Rahul Savani

@Rahul Savani

Posts made by Rahul Savani

Adding a step to the broker's next method that will update each comminfo (possibly one for each data feed) with the new respective FX rate

Update the methods of a new commission class that extends CommissionInfo as per the original suggestion.

My first post was just confused. With the 2 changes here, the commission info objects have the current rate and apply it to the calculations, and only one minimal change is needed to the broker, and no changes to Trade or other classes are needed.

@backtrader I would like to do exactly per your suggestion, making the conversion to pnl in the broker's main currency using a changing FX rate from a field in datas. What in your opinion is the cleanest/best way to make the relevant field of datas`` available to the methods in the new subclass ofCommissionInfo```?

For the functions of the commission scheme called in this loop from the _get_value method of ```BackBroker``:

like getvalue and profitandloss, I can just pass in the FX rate here, as I have the data feed to hand. But I wonder if I only need to adapt those methods that are directly called from BackBroker?

Thanks for your guidance!

P.S. Looks like I would need to change Trade as well, as it uses methods like profitandloss. If the comminfo object had the data feed automatically available to it, the changes could be isolated to just the corresponding class, with no changes to BackBroker or Trade, but I am not sure if that's a feasible/sensible approach.

So managed to get an MWE. The problem relates to 0 prices. The problem goes away if those prices as empty in the csv and treated by NaNs by backtrader. This is really as simple as I can get it, hopefully you agree:

In case it wasn't clear, my claim is that there is a bug because in my original code I made no explicit use of the _name property; I only used this when investigating the problem. The problem is that self.getposition(d) returned the position for the wrong data feed. I will do my best to come up with an MWE for that.

In the meantime, on my question in the last post, essentially: "How do I even have names if, as you point out I have not assigned them, and they are not assigned automatically?", the following (shorter ;-) example shows that _name is set automatically:

Delving into the source by adding a print at the start of ```adddata`` as follows:

def adddata(self, data, name=None):
'''
Adds a ``Data Feed`` instance to the mix.
If ``name`` is not None it will be put into ``data._name`` which is
meant for decoration/plotting purposes.
'''
print(data._name)
if name is not None:
data._name = name

we see that data already has its name set when passed to adddata. Indeed the auto-naming happens here:

OK, thanks. That's easy to fix of course. But then what I don't understand:

In the code above we have not sett the name via adddata`` but he data feeds inself.datas**do** have names, and those names are used in the code above (e.g., withself.getpositionbyname(d._name)). The names returned byd._name``` correspond to the names of the csv files (without the ".csv" ending). I presumed that, having seen these names set automatically, everything was in order.

How are the names apparently set in the above code, but are somehow set differently (so as to not see the behaviour above) if I add the name as an explicit argument to adddata?

My very humble opinion: when one is creating a short snippet to test a bug/behavior, one creates something simple.

Yes, you are right of course. The reason for this not so simple code is that I started from something much much more complicated and chose to strip back to get something simpler (incrementally, while keeping the behaviour) rather than starting with something totally simple and trying to recreate the behaviour (since I didn't know exactly what was needed to create it).

If you really think there is a bug in backtrader it will take around 20 lines to proof it. If those 20 lines produce the expected (good) result, you will have proof that you have a bug.

OK, sure, I will try to create a MWE. Of course, it's far from inconceivable that I have inadvertently introduced a bug, but since I have extended backtrader.Strategy and not extended/changed any code that should affect self.datas (beyond populating them of course), I am at a loss as to how the code I have written could create this phenomenon. Will keep digging, but any suggestions would be great.

And thanks! Really great platform that I have found extremely useful. Your work is much appreciated.

I appreciate that a complete code example would be useful, but I am not sure I can extract one easily, though I will try to produce a MWE. Anyway, in the meantime, is there any obvious plausible explanation for the following (literally executed line after after in next()):

There are 3 data feeds in this example. We loop through them in next(). The first of them has a legitimate position. The second one no position. The third one, should have no position, but self.getposition(d) returns the position for the first one, as shown above. But then, when using self.getpositionbyname(d._name) returns a 0 position as expected.