For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See:

Incorporating Convex Optimization

  • Hello backtrader community. After looking into many backtesting frameworks I have decided to move forward with backtrader.

    My issue is I am running a convex optimization to rebalance portfolio using cvxpy library. I do not want to any strategy, just want to rebalance daily according to the weight output from the cvxpy optimizer. Is this possible to do with backtrader?


  • I think this is doable by using order target inside a strategy class.

  • I've done some cvxpy, I'm doing some bt now. Stitching the two together should be possible. I am a bt newbie, but since I have now played in both sandboxes, I will reply, and likely be corrected by my betters here, but FWIW, my brief response is:

    "Likely yes. But what you actually want to do (but might not know it yet) is to let cvxpy make decisions within your strategy in bt."

    I think you might want to read some of the excellent documentation and blog posts @backtrader has already provided, I hope you already know where to look, goog is your friend, and I found "" helpful to stay "here".

    Here are some comments:

    • in order to get good help here you will have to ask specific questions that relate to the use of bt as it exists - it reminds me a bit of the insides of cvx;
    • I believe that within the framework of bt you will indeed need a "strategy" to accomplish your task, although you might bend bt to your will using an "indicator", it is so darn flexible...
    • if you are deeply into strategy-avoidance, you could try an "observer" but I think you will be one tick late-to-the-game. ;-)
    • you could either let bt track things and pull stuff out of the broker, or be broker-blind, track positions yourself either in your strategy or in your cvx code, and just fire orders at the broker. It's there, I'd say use it. Trust, but verify.
    • I think the only way to cleanly architect (@bt howls with laughter as the newbie tries to offer architectural advice...) would be to embed your calls to cvxpy in your strategy, kicked off whenever you want to rebalance (you could use a custom indicator, or embed a datetime compare right in the strategy next() function, this is a very flexible platform... and be careful about datetimes...all may not be as it first appears)

    Then the basic idea I have:

    • bt advances, your strategy next() gets called
    • if it is time to rebalance (time, mis-balance, gain/loss, build an indicator!) then figure out your new position params for cvx
    • make your call to solve()
    • get the cvxopt response stuff back
    • compute your orders if the cvx code hasn't already
    • place your orders with the broker.

    bt handles the rinse and repeat for you. by calling your strategy's next().
    You may have to init() some stuff.
    You should pay attention to various documentation about the differences in referencing lines variables in init versus next, and the use of bt-provided functions in init instead of being lazy and assuming cut+paste works. Read the bt code...

    If all that sounds like gobbledygook, you should probably just bear down, grit yer teeth, and start developing from some of the example code, and asking specific questions with code snippets in the code style ("</>" above the text box) of minimal-code examples of whatever specific problem you might have.

    Note that I have made an assumption. That you don't need to pass cvx all the historical data. Likely not an issue if you want to. Might have to do some data copying, maybe not. Be aware about the bt lines arrays: now = [0], last_tick = [-1], etc... having seen what I have, there is already likely a bt converter function sitting waiting for you, you just have to find it, and that's where all the docs and blog posts help. Or read the code.

    Trying it all out in my mind, I think it is possible, and if it is not possible in this framework, then...

    I must admit I am curious, in case you want to elaborate. I also had the notion of stuffing an optimizing engine in here somewhere... good luck.

  • ... you might need to init some cvxpy stuff that is invariant across cvxopt solve() runs. you could do it in the strategy init() or one of the pre-next() over-rideable bt function calls....

Log in to reply