Fully automated futures trading

How likely is it that you hit your volatility target in the long term?

On my single instrument model (Corn), no matter what I do, my annual returns volatility works out about 10%, when the target is 25%.

(Sharpe 0.27 without slippage, 0.08 with).

I'm wondering if this is a bug in my code.

Briefly (I can't tear myself away from this Brexit stuff; although I'm not trading I have a lot of price spikes to check and am just keeping a close eye on everything)

If you had a system with an average absolute forecast of zero you would never have a position on, and zero vol.

If you had a system which was always forecasting +20 maximum, then you would have (in expectation) twice the average vol.

So it depends on your average forecast (and also to an extent if there is a bias in your vol forecast, but this is very second order). Probably for Corn you don't have such a good system so the forecast isn't that great. Try plotting the combined forecast, see what comes out.

This works in your favour - systems with low profitability will have less risk.

GAT
 
I was wondering how this extreme event (Brexit) has affected your portfolio. I hope you have time to do a recap one of these days.

Great book BTW!
 
I'm just looking at combining instruments now.

If I've read the source code correctly, the forecasts in Pysystemtrade are calculated based on prices in the instrument currency (e.g. USD for Corn), with the fx just kicking in when calculating the overall position.

Is there a case for calculating forecasts/weights based on base currency? So translate Corn price series to GBP first, then do all the math/bootstrapping?
 
I'm just looking at combining instruments now.

If I've read the source code correctly, the forecasts in Pysystemtrade are calculated based on prices in the instrument currency (e.g. USD for Corn), with the fx just kicking in when calculating the overall position.

Is there a case for calculating forecasts/weights based on base currency? So translate Corn price series to GBP first, then do all the math/bootstrapping?

You'd get quite different results. So for example there would have been a sharp downtrend in all USD assets on Friday, regardless of what actually happened to the "native" price.

Given that most of the market looks at the native price, I think it usually makes more sense to do this.

Also in futures if the market drops in USD terms, but the USD appreciates against the GBP and exactly offsets that, you will be losing money (apart from a tiny gain on your margin cash). But your GBP price won't reflect that. So a trend following system won't be cutting it's losses.

GAT
 
A pretty dull month of more gradual losses quickly became quite exciting about a week and a half ago.

figure_2.png

figure_1.png



I bet you can't see when Brexit happened (clue: the futures hedge for my equity portfolio opens an hour earlier than the equities do). After it did I made profits every single day, and not small ones eithier, giving just some back yesterday. More analysis in the usual place.

P&L period: 10.7%
P&L to date: 95.6%
Drawdown: 6.0%


P&L:

Most money was made from the "risk off" nature of the portfolio plus the equity hedge which was effectively short £/euros.

Profits -
Stocks + futures hedge +32K (depreciation of the £)
OAT +8.8K
Soybean +6.8K
KR10 +6.5K
Eurodollar: +6K
US20 +3.8K
KR3 +2.6K

Losses:
GBP -6K
VIX -2.4K




Positions
Code:
       code contractid  positions   Lock WrongContract InFwdNotRoll
20     BOBL     201609          1  False         False        False
6       BTP     201609          1  False         False        False
4      BUND     201609          1  False         False        False
2   EDOLLAR     201906          2  False         False        False
3   EDOLLAR     201909          7  False         False        False
16      EUR     201609         -1  False         False        False
8   EUROSTX     201609         -9  False         False        False
11   GAS_US     201609          1  False         False        False
12     GOLD     201608          1  False         False        False
7      KR10     201609          2  False         False        False
13      KR3     201609          5  False         False        False
0   LEANHOG     201706          2  False         False        False
15      NZD     201609          1  False         False        False
1       OAT     201609          3  False         False        False
18  SOYBEAN     201611          1  False         False        False
19     US10     201609          1  False         False        False
9       US2     201609          2  False         False        False
17      US5     201609          1  False         False        False
14      V2X     201608         -1  False         False        False
10      VIX     201608         -1  False         False        False
5     WHEAT     201612         -2  False         False        False

Risk
Code:
       code  multisignal  expected_annual_risk  expected_annual_risk_per_contract  position  expected_annual_risk_rounded_pos
16      V2X         -2.1                  1587                               2485        -1                              2485
4     WHEAT        -13.9                 10496                               4749        -2                              9497
25      EUR         -8.6                  6506                              11729        -1                             11729
17      VIX        -14.5                 10893                              12862        -1                             12862

7      BOBL          4.6                  3432                               3018         1                              3018
15      US5          6.5                  4935                               3362         1                              3362
13      US2          4.9                  3678                               2216         2                              4432
6       KR3          6.7                  5044                                889         5                              4447
1   LEANHOG          6.6                  4964                               2952         2                              5903
12     US10          5.7                  4270                               5974         1                              5974
35   GAS_US          8.7                  6526                               6592         1                              6592
29      NZD          8.1                  6114                               7298         1                              7298
5      KR10         11.6                  8714                               3846         2                              7692
9      BUND         11.1                  8345                              10171         1                             10171
3   SOYBEAN         12.2                  9165                              10822         1                             10822
8       BTP          9.5                  7130                              12950         1                             12950
36  EDOLLAR         25.0                 18800                               1970         9                             17728
10      OAT         22.1                 16654                               6191         3                             18573
31     GOLD         15.8                 11940                              19982         1                             19982

I really have very small positions on, reflecting very high risk per contract, and a lack of clear forecasts except in Bond markets. My risk is running at 80% of the long run average.

Trades
Code:
          code contractid     filled_datetime  filledtrade  filledprice
11140      AEX     201606 2016-06-10 08:28:01           -1   441.250000
11458      AUD     201609 2016-06-22 09:08:53            1     0.746000
11512      AUD     201609 2016-06-27 00:55:49           -1     0.740400
11293     BOBL     201609 2016-06-17 08:09:39            1   133.140000
11515     BOBL     201609 2016-06-27 07:31:28           -2   133.440000
11863      BTP     201609 2016-06-30 13:13:35            1   142.220000
11137     BUND     201609 2016-06-10 08:21:15            1   164.780000
11488     BUND     201609 2016-06-23 11:17:44           -1   163.800000
11212      CAC     201606 2016-06-10 16:00:53           -1  4301.000000
11503   COPPER     201609 2016-06-23 13:50:03            1     2.159000
11251     CORN     201612 2016-06-15 14:30:00            1   448.000000
11329     CORN     201612 2016-06-20 16:33:13           -1   436.750000
11581     CORN     201612 2016-06-27 14:30:00           -1   398.750000
11209  EDOLLAR     201909 2016-06-10 14:44:50            1    98.645000
11254  EDOLLAR     201909 2016-06-15 14:31:17            1    98.690000
11572  EDOLLAR     201906 2016-06-27 13:16:39           -2    98.900000
11755  EDOLLAR     201906 2016-06-28 12:38:59           -1    98.890000
11875  EDOLLAR     201909 2016-07-01 13:30:04            1    98.850000
11740      EUR     201609 2016-06-28 02:14:05           -1     1.105250
11224  EUROSTX     201606 2016-06-14 07:56:21            9  2823.000000
11227  EUROSTX     201609 2016-06-14 07:56:21           -9  2811.000000
11866   GAS_US     201609 2016-06-30 13:57:34            1     2.866000
11242      GBP     201609 2016-06-15 02:38:16           -1     1.412600
11296      GBP     201609 2016-06-17 18:54:08            1     1.434800
11461      GBP     201609 2016-06-23 02:51:41            1     1.483000
11509      GBP     201609 2016-06-24 03:54:26           -1     1.366400
11881     GOLD     201608 2016-07-04 17:29:05            1  1354.100000
11290      JPY     201609 2016-06-17 04:54:49            1     0.009609
11506      JPY     201609 2016-06-24 03:04:46           -1     0.009586
11302     KR10     201606 2016-06-20 01:02:55           -3   131.130000
11413     KR10     201609 2016-06-21 02:12:52            3   130.970000
11752     KR10     201609 2016-06-28 02:25:37           -1   132.780000
11287      KR3     201606 2016-06-17 04:44:35           -1   110.650000
11299      KR3     201609 2016-06-20 01:06:02            8   110.690000
11305      KR3     201609 2016-06-20 01:14:36            8   110.680000
11308      KR3     201609 2016-06-20 01:17:34            8   110.670000
11311      KR3     201609 2016-06-20 01:45:07            8   110.670000
11314      KR3     201606 2016-06-20 01:47:29           -8   110.590000
11326      KR3     201609 2016-06-20 06:20:00          -25   110.670000
11746      KR3     201609 2016-06-28 02:17:24           -2   111.090000
11215  LEANHOG     201606 2016-06-10 16:33:18           -1    82.225000
11218  LEANHOG     201706 2016-06-10 16:33:18            1    79.950000
11455  LEANHOG     201706 2016-06-21 16:11:31            1    78.750000
11116      MXP     201606 2016-06-09 08:06:17            1     0.055230
11119      MXP     201609 2016-06-09 08:06:17           -1     0.054700
11869      MXP     201609 2016-07-01 02:45:00            1     0.054100
11221   NASDAQ     201606 2016-06-13 14:04:36           -1  4441.250000
11317      NZD     201609 2016-06-20 02:29:42            1     0.705700
11143      SMI     201606 2016-06-10 08:31:34           -1  8012.000000
11257  SOYBEAN     201611 2016-06-16 15:27:42           -1  1116.250000
11491  SOYBEAN     201611 2016-06-23 11:56:53           -1  1113.000000
11233    SP500     201606 2016-06-14 13:58:32           -1  2078.700000
11236    SP500     201609 2016-06-14 13:58:32            1  2069.550000
11248    SP500     201609 2016-06-15 13:58:23           -1  2070.250000
11125     US10     201609 2016-06-09 14:20:00            1   131.203125
11575      US2     201609 2016-06-27 14:02:12           -1   109.687500
11878      US2     201609 2016-07-01 15:16:56            1   109.679688
11128     US20     201609 2016-06-09 14:22:42            1   167.781250
11584     US20     201609 2016-06-27 14:08:27           -1   172.718750
11239      US5     201609 2016-06-14 14:08:13            1   121.570312
11578      US5     201609 2016-06-27 14:01:09           -1   122.250000
11131      V2X     201607 2016-06-10 08:04:54            1    25.750000
11134      V2X     201608 2016-06-10 08:04:54           -1    25.400000
11146      V2X     201607 2016-06-10 08:37:19            4    26.400000
11149      V2X     201608 2016-06-10 08:37:19           -4    26.050000
11158      V2X     201608 2016-06-10 10:35:36            1    26.200000
11179      V2X     201608 2016-06-10 13:54:16            1    26.800000
11245      V2X     201608 2016-06-15 08:12:00            1    28.050000
11527      V2X     201608 2016-06-27 08:19:51            1    28.100000
11152      VIX     201607 2016-06-10 09:57:03            2    17.560000
11155      VIX     201608 2016-06-10 09:57:03           -2    18.740000
11230      VIX     201608 2016-06-14 09:59:23            1    21.800000
11122    WHEAT     201612 2016-06-09 13:21:09            1   543.750000
11500    WHEAT     201612 2016-06-23 12:43:32           -1   494.250000
11860    WHEAT     201612 2016-06-29 13:16:50           -1   477.750000

Expected trading costs £545.77 actual £230
 
I wanted to explore this question of FX volatility and impact on base returns a little further, so I tried to set up a test. (Spoiler: your method wins- but I'm not sure why). What I'm really looking for here is a critique of my approach (which I think is wrong).

Test parameters:
Corn data (1991-Present), Bootstrapped (n=100), Carry & EWMAC, Base currency GBP, Transactions costs/slippage included

To be clear, I've calculated instrument value volatility as:
Code:
instrument_value_volatility = (prices * fx_rate).diff().ewm(span=36, min_periods=36).std()
where fx_rate is a series.

Important note:
Sharpe Ratios are calculated in the base currency.
Bootstrapping minimises the sharpe in the currency as well.

The bootstrap is performed on the whole period 1991-2016. I don't use rolling weights to calculate my historical Sharpe, so there is some implicit overfitting here.

Results:

Pysystemtrade method-
Just use the fx_rate for position sizing, forecasts are on USD futures prices
Result: Sharpe 0.18

Proposed method- Convert original price series to base currency, then bootstrap. Forecasts will be on GDP.
Result: Sharpe 0.18

Conclusion? Doesn't seem to make much difference. Not entirely sure what I've learned here.

Next, I tried to break it up, and created a new indicator, ewmacfx, which operates on fx series rather than the corn series. The hypothesis is that we can capture the trend on both the corn and the fx.

I fed this into the bootstrap and got a weight distribution that looks like this:

download (4).png


(Just a reminder- this is optimising a Sharpe based on returns in the base currency GBP.)

Seems sensible enough to me.

The Catch: Running this produces a Sharpe of 0.10 (when using instrument value volatility to scale position sizes like you do) - lower than before.

For reference, the Sharpe's for the individual account curves are here:
download (5).png

My Dilemmas:
  1. I had hoped that adding FX tracking rules to my bootstrap would have given me a better Sharpe, but it seems to make it worse. Is there any practical rationale for the approach of tracking them separately, as I have tried?
  2. I would have thought the bootstrap process would have increased Sharpe with the more rules you add (due to overfitting); I'm surprised that the opposite happened here. Is that what I should expect?
  3. Am I really wasting my time, and should crack on with the less interesting task of adding more instruments?
Thank you!
 
I wanted to explore this question of FX volatility and impact on base returns a little further, so I tried to set up a test. (Spoiler: your method wins- but I'm not sure why). What I'm really looking for here is a critique of my approach (which I think is wrong).

Test parameters:
Corn data (1991-Present), Bootstrapped (n=100), Carry & EWMAC, Base currency GBP, Transactions costs/slippage included

To be clear, I've calculated instrument value volatility as:
Code:
instrument_value_volatility = (prices * fx_rate).diff().ewm(span=36, min_periods=36).std()
where fx_rate is a series.

Important note:
Sharpe Ratios are calculated in the base currency.
Bootstrapping minimises the sharpe in the currency as well.

The bootstrap is performed on the whole period 1991-2016. I don't use rolling weights to calculate my historical Sharpe, so there is some implicit overfitting here.

Results:

Pysystemtrade method-
Just use the fx_rate for position sizing, forecasts are on USD futures prices
Result: Sharpe 0.18

Proposed method- Convert original price series to base currency, then bootstrap. Forecasts will be on GDP.
Result: Sharpe 0.18

Conclusion? Doesn't seem to make much difference. Not entirely sure what I've learned here.

Next, I tried to break it up, and created a new indicator, ewmacfx, which operates on fx series rather than the corn series. The hypothesis is that we can capture the trend on both the corn and the fx.

I fed this into the bootstrap and got a weight distribution that looks like this:

View attachment 165135

(Just a reminder- this is optimising a Sharpe based on returns in the base currency GBP.)

Seems sensible enough to me.

The Catch: Running this produces a Sharpe of 0.10 (when using instrument value volatility to scale position sizes like you do) - lower than before.

For reference, the Sharpe's for the individual account curves are here:
View attachment 165136

My Dilemmas:
  1. I had hoped that adding FX tracking rules to my bootstrap would have given me a better Sharpe, but it seems to make it worse. Is there any practical rationale for the approach of tracking them separately, as I have tried?
  2. I would have thought the bootstrap process would have increased Sharpe with the more rules you add (due to overfitting); I'm surprised that the opposite happened here. Is that what I should expect?
  3. Am I really wasting my time, and should crack on with the less interesting task of adding more instruments?
Thank you!

3. Yes you are wasting your time. The difference in SR of your results is not statistically different. Doing the boring thing will make you more money.

GAT
 
Back
Top