2 registered members (Imhotep, opm),
785
guests, and 4
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
working with Futures
#486032
06/02/22 11:25
06/02/22 11:25
|
Joined: May 2022
Posts: 3 London
logomon
OP
Guest
|
OP
Guest
Joined: May 2022
Posts: 3
London
|
I am interested to try testing and trading Zorro on Futures (via Interactive Brokers). I have looked around the code examples, and the manual page for the contract functions, which give some nice examples of the functionality for options.
However, I can see that the way of working with futures must be slightly different - e.g. in the example AssetsIB.csv, it looks like each futures contract expiry must be specified as a separate asset (e.g. Jul wheat and Dec wheat). So this is different from the options case, where we specify an underlying and IB will return the full chain/surface in one shot. I.e. we cannot equivalently obtain the "chain" of e.g. wheat futures for all future months, and must query each contract individually?
Is there any canonical example of how to work with futures, in a strategy that may need to "roll" from one contract to the next as expiry approaches? Is it true that we must "manually" add into the AssetsIB the name of each specific contract that we need - so that to backtest a wheat strategy we add every monthly contract name for the backtest period?
Likewise, is there any example for parsing the historical Futures price data from csv (as obtained from e.g. barchart.com), into the .t8 format (this is recommended better than .t6 for Futures?). I can see the nice example for options but suspect the Futures case is not identical. If we already must treat each contract separately, is there any advantage to using .t8?
Massive thanks for the amazing tool that is Zorro - I'm sure there are very smart ways to do the above, so asking now before I try to reinvent the wheel!
|
|
|
Re: working with Futures
[Re: logomon]
#487328
03/18/23 23:21
03/18/23 23:21
|
Joined: May 2022
Posts: 3 London
logomon
OP
Guest
|
OP
Guest
Joined: May 2022
Posts: 3
London
|
I am revisiting my efforts to set up a futures trading script, and getting some unexpected behaviour - I wonder if anyone can give me a hint? :
When running a backtest I get a strange inconsistency between the entry/exit prices announced in the log at the point the trade is opened/closed, and the values that end up in the final results.
E.g. for first trade of the run, testtrades.csv shows: Name,Type,Asset,ID,Lots,Open,Close,Entry,Exit,Profit,Roll,ExitType MyStrategy,Short,LH-FUT-19980715-,38709,250,1998-07-09 16:30,1998-07-10 16:30,53.22,53.22,-0.63,0.00,Reverse
i.e. identical entry and exit prices!
However, the relevant log messages do show the trade was entered and exited at two different prices: [LH-FUT::SF38709] Short 1941@53.22 Bid 53.22 at 16:30:00 Thu Com 4.85 Mrg 41331301 Net 0 ... [LH-FUT::SF38709] Cover % 250@52.32: -0.63 at 23:00:00 Wed Opn 53.22 Cls 53.22 Spr 0.0 Slp -3272789.75 Rol 0.00 Com 4.23 Lif 1 Net -1941
So even though the log recognises entry @ 53.22 and exit @ 52.32, the "Opn" and "Cls" prices that ultimately get recorded are identical, and indeed the stats, chart etc all reflect this (i.e. the only pnl I see is cumulative commissions).
I am calling contractUpdate for every asset on each run(), is there something more I need to do to propagate the correct prices?
|
|
|
Re: working with Futures
[Re: logomon]
#487349
03/21/23 21:53
03/21/23 21:53
|
Joined: May 2022
Posts: 3 London
logomon
OP
Guest
|
OP
Guest
Joined: May 2022
Posts: 3
London
|
To make this more concrete, I have the following minimal example that reproduces the issue. Happy to provide the .t8 I am using on request (was blocked from attaching it to this post). I hesitate to say the issue is a bug but at least there seems to be something inconsistent in the handling of contracts/trades?
#include <contract.c>
#define HISTORY_DIR "History\\temp\\*_HistoricalFutures.t8"
#define ASSET_FILE "History\\temp\\AssetList.csv"
var equity;
int open_expiry;
int n_runs;
int j;
void run()
{
set(PLOTNOW|LOGFILE);
StartDate = ifelse(Live,NOW,19980715);
EndDate = 20010901;
BarPeriod = 1440;
LookBack = 0;
Verbose = 3;
set(PRELOAD);
History = HISTORY_DIR;
assetList(ASSET_FILE);
asset("W-FUT");
n_runs += 1;
Capital = 100000.00;
equity = Capital + ProfitTotal;
int thisdate = year(0)*10000 + month(0)*100 + day(0);
printf("\n--> %d, capital = %f", thisdate, equity);
// load futures
int nfound = contractUpdate(Asset,0,FUTURE);
// check contracts directly
var prce_curr;
for(j=1; j<= nfound; j++)
{
prce_curr = contractPrice(contract(j)); // access contract via index in chain
printf("\n--> contract expiry %i, strike %f, ask %f, bid %f, price %f", ContractExpiry, ContractStrike, ContractAsk, ContractBid, prce_curr); // --> all ok
}
// check explicitly for contract of open trade
CONTRACT* ctrptr;
if(open_expiry)
{
ctrptr = contract(FUTURE, open_expiry, 0); // access contract via specifying expiry and strike
if(ctrptr == 0)
printf("\n--> open expiry %i but no contract found", open_expiry); // --> gets hit
prce_curr = contractPrice(ctrptr);
printf("\n--> contract expiry %i, ask %f, bid %f, price %f", ContractExpiry, ContractAsk, ContractBid, prce_curr); // --> all zero
}
// check contracts via open trades
int pos_curr;
var dte_curr;
for(current_trades)
{
ctrptr = contract(ThisTrade); // access contract via trade object
if(ctrptr == 0)
printf("\n--> existing trade but no contract found"); // --> gets hit
pos_curr = contractPosition(ThisTrade);
prce_curr = contractPrice(ThisTrade);
dte_curr = contractDays(ThisTrade);
printf("\n--> existing pos %i, price %f, underlying %f, expiry %f", pos_curr, prce_curr, TradeUnderlying, dte_curr); // --> prce_curr is zero, but strangely, pos_curr, TradeUnderlying, dte_curr are all ok
}
// exit open trade
for(open_trades)
exitTrade(ThisTrade);
// enter new trade
int first_expiry;
j = 1;
while(!first_expiry && (j <= nfound))
{
contract(j);
if(ContractExpiry > thisdate)
first_expiry = ContractExpiry;
else
j += 1;
}
printf("\n--> %d, first non-expired contract is %i=%i", thisdate, j, first_expiry);
if(n_runs > 1)
{
contract(j);
enterLong(pow(-1,n_runs));
open_expiry = first_expiry;
}
if(n_runs >8) quit("Ok!");
}
any advice much appreciated!
|
|
|
|