Fully automated futures trading

Discussion in 'Journals' started by globalarbtrader, Feb 11, 2015.

  1. wopr

    wopr

    I’d be interested in this as well @cholo if you get a chance.

    Regarding positions, I use Rob’s DO, and similar capital and risk target, and since launching it over a year ago, I’ve always had more positions on, both in terms of just number of positions as well as risk exposure. Also not sure what’s going on.
     
    #3881     Nov 24, 2023
  2. jiikoo

    jiikoo

    Hi Rob, I'm still experimenting with AFTS chapter 25 dynamic optimisation scripts and a question about negative covariance. Along with more instruments and carry & ewmac rule variations I'm getting more and more negative covariance errors, especially on capital levels over 100k. Am I doing something fundamentally wrong here? If you have written about this, can you share a link?


    tests.png
     
    #3882     Dec 5, 2023
  3. Not exactly what you mean by a negative covariance?

    Rob
     
    #3883     Dec 5, 2023
  4. jiikoo

    jiikoo

    So the problem is that optimisation runs are being interrupted by the following exception:

    File ~/pysystemtrade/AFTS/chapter25.py:223, in evaluate_tracking_error_for_weights(weights, other_weights, covariance)
    220 track_error_var = solution_gap.dot(covariance).dot(solution_gap)
    222 if track_error_var < 0:
    --> 223 raise Exception("Negative covariance when optimising!")
    225 track_error_std = track_error_var**0.5
    227 return track_error_std

    Exception: Negative covariance when optimising!
     
    #3884     Dec 5, 2023
  5. OK so you're using the provided AFTS code and not pysystemtrade. You have to shrink the correlation matrix (see https://qoppac.blogspot.com/2021/11/mr-greedy-and-tale-of-minimum-tracking.html)

    "
    Essentially, once I started examining the results of my optimisation more carefully, I realised that for large (100+ instrument) portfolios there were instances when my optimisation just broke as it couldn't evaluate the utility function. One cause was inputting costs of nan, and was easily fixed by making my cost deflation function more accurate. But I also got errors trying to find the standard deviation of the tracking error portfolio.

    So it turns out that pandas doesn't actually guarantee to produce positive semi-definite correlation matrices, which means that sometimes the tracking error of the portfolio can have a negative variance. I experimented with trying to find the nearest PSD matrix - it's very slow, too slow for backtesting though possibly worth a last line of defence. I tried tweaking the parameters of the exponential correlation; even tried going back to vanilla non exponential correlation estimates but still ended up with non PSD matrices.

    What eventually came to the rescue, just as I was about to give up, was shrinking the correlation matrix. For reasons that are too boring to go into here (but try here), shrinkage is a good way of fixing PSD issues. And shrinking the correlation matrix in this particular application isn't really a bad thing. It makes it less likely we'll put on weird positions, just because correlations are especially high or low."

    My shrinkage factor is 0.5 and I shrink to an indepedent matrix (off diagionals are zero)

    Rob
     
    #3885     Dec 5, 2023
    newbunch likes this.
  6. jiikoo

    jiikoo

    ...and it works! Thanks again, much appreciated!
     
    #3886     Dec 5, 2023
  7. Kernfusion

    Kernfusion

    I'm not using pandas, (just a matrix multiplication library for C#), but I have a check in my code before taking square root of portfolio variance - if the variance is negative -> make it zero. Not sure how safe\correct it is and how often it happens, probably need to add some logging around it at least..
     
    #3887     Dec 9, 2023
  8. Kernfusion

    Kernfusion

    So I added some logging and yeah, I do get quite a lot of these negative variances..
    I want to try to shrink my correlation matrix, but I don't quite understand what it means (sorry if it should be obvious :) ).
    So the paper defines shrinking as "αM1 + (1 − α)M0" where, as I understand, M1 is my actual correlation matrix that I want to 'fix', α should be 0.5 and M0 is some matrix that I will shrink towards (usually previous or average\default in some sense).
    That M0, as Rob wrote above is
    , so what values are on-diagonal, all '1'?, i.e. M0 is just an identity matrix same size as mine?
    Or we should have something else on the diagonal like average of all pairwise correlations?

    And the operation itself, do we just apply "αM1 + (1 − α)M0" element-by-element in matching positions (i.e. just like the normal operations of addition, subtraction and multiplication by a number are defined for matrixes)?

    i.e. so far, the way I understand this operation is this:
    M1(my initial correlation matrix):
    1 |0.35
    0.35 |1

    M0: (the matrix I shrink towards - identity matrix):
    1 |0
    0 |1

    the result, i.e. my 'fixed' correlation matrix:
    0.5*1+0.5*1 |0.5*0.35+0.5*0
    0.5*0.35+0.5*0 |0.5*1+0.5*1
    =
    1 |0.175
    0.175 |1

    which boils down to simply dividing by 2 each correlation value (except of on-diagonal) in my original correlation matrix
    Is that correct ?
     
    Last edited: Dec 9, 2023
    #3888     Dec 9, 2023
  9. Yes when I say 'independent' I mean all off diagonals are 0, so yes that would be the identity.

    I do sometimes use the average correlation when I'm trying to do a more robust optimisation, but for this use case we want something closer to 0.

    Yes addition for matricies is element by element

    Yes shrinkage by 0.5 to an identity matrix is the same as dividing everything by two.

    Rob
     
    #3889     Dec 10, 2023
    Kernfusion likes this.
  10. Kernfusion

    Kernfusion

    Thanks Rob, I already tried to run a backtest with this way of shrinking and the negative variances went away and the performance didn't suffer (in fact the Sharpe got ~10% higher, which is probably an accident). The number of trades went down a little, which can be corrected by the buffer value, or left as is..

    regarding this (not for the DO case, but in general):
    - you mean you would put average correlation to the off-diagonal positions (the same number everywhere instead of zeros), and leave 1s on-diagonal ?
     
    Last edited: Dec 10, 2023
    #3890     Dec 10, 2023