1 view (last 30 days)
Mario Viola
Mario Viola on 27 Feb 2021
Commented: Mario Viola on 1 Mar 2021
Hi All!
I'm trying to implement a narxnet to prediction next day market return direction (1=up, 0 = down). I have some questions regarding the FeedaBack Delays and Input Delays, as well as for the output. Here's the Code :
StockData = readtable('MSFT.csv');
Close = StockData.Close;
Date = StockData.Date;
Open = StockData.Open;
Price = Close;
T = timetable(Date,Price);
if any(any(ismissing(T.Price)))== 1
T = fillmissing(T,'linear');
%% Calulate (1-day) Returns and Indicators
r = NaN(size(Close,1),1);
r(2:end) = Close(2:end) ./ Close(1:end-1) - 1;
nDay2 = [7, 14, 21];
for i = 1:numel(nDay2);
factorName = ['rsi' num2str(nDay2(i))];
T.(factorName) = rsindex(T.Price,nDay2(i));
T.MACD = macd(T.Price);
T.Ma20 = movavg(T.Price,'simple',20);
T.Ma50 = movavg(T.Price,'simple',50);
T.EMa9 = movavg(T.Price,'exponential',9);
T.EMa27 = movavg(T.Price,'exponential',27);
Lag = T.Ma20 > T.Ma50;
T.Lag = double(Lag);
clear Lag
Lead = T.EMa9 > T.EMa27;
T.Lead = double(Lead);
clear Lead
nextDayReturn = double(r(2:end) > 0);
T.r = r;
T.nextDayReturn = [missing; nextDayReturn];
T = rmmissing(T);%Remove missing values (rows)
T = timetable2table(T); %Convert to Table
r = T.r;
nextDayReturn = T.nextDayReturn;
x = T{:,2:end-1};%Define predictor table as a double array
y = T{:,end}';
nextDayReturn is my target variable, the one i want to predict with the net, and has the form as a vector of 1 & 0 according to the direction of the return for that day.
%% Partitioning data
nOut = 252*2; %2 years of data for Out of Sample
N = height(T);
nIn = N - nOut;
idxIn = [1:nIn]';
idxOut = [nIn + 1:N]';
Xin = x(idxIn,:);
Xout = x(idxOut,:);
yIn = y(:,idxIn);
yOut = y(:,idxOut);
%% Normalize input variables
Xin = mapminmax(Xin);
Xout = mapminmax(Xout);
I know that this is a default processing function, but it runs much better and gives more accurate results by normalizing the data before the training process.
%% Define Network Architecture
Xin = tonndata(Xin,false,false);
yin = tonndata(yIn,true,false);
trainFcn = 'trainlm';
hiddenLayerSize = [25 20];
FD = 1:9; %autocorr(r) significant up to lag 9
ID = 0:20; %crosscorr significant up to lag 20 (even more)
net = narxnet(ID,FD,hiddenLayerSize,'open',trainFcn);
net.divideFcn = 'divideblock';
net.layers{1}.transferFcn = 'tansig';
net.layers{2}.transferFcn = 'tansig';
net.layers{3}.transferFcn = 'tansig';
net.trainParam.max_fail =10;
%% Train and evaluate Network Performance
[Xs,Xi,Ai,Ts] = preparets(net,Xin,{},yin);
[net tr] = train(net,Xs,Ts,Xi,Ai);
[P Xf Af] = net(Xs,Xi,Ai);
e = gsubtract(Ts,P);
performance = perform(net,Ts,P);
P= cell2mat(P);
P = P>0.5;
P = double(P);
H = cell2mat(Ts);
hh = P==H;
hh = double(hh);
sum(hh)/numel(hh) %percentage of correct guesses in In-Sample
%% Closed Loop - Multi Step ahead prediction
[netc,Xic,Aic] = closeloop(net,Xf,Af);
Xout = tonndata(Xout,false,false);
y_c = netc(Xout,Xic,Aic);
y_c = cell2mat(y_c);
y_c = y_c>0.65; %Try 0.65
y_c = double(y_c);
b = y_c==yOut;
b = double(b);
sum(b)/numel(b) % percentage of correct guesses in Out Sample
Mi questions regards first the Delays : I would like to have, when training, that y(t) should be a function of X(t), X(t-1),....,X(t-20), so ID = 0:20 is the correct implementation ? On the other hand, for the FD i have to start at 1 lag at least,and to get it up to lag 9 should translate in FD=1:9, as i wrote. In case it's wrong, i hope someone will point it out.
After that, when going to the Out-Sample Prediction, whith the closed net (netc), the FD disappears, but the ID should remain the same (up to lag 20). The prediction here is done on multi-step ahead, but what if i have just one (new) input at a time (imagining a real-time implementation, where each day i get a new input), and want to predict the output based on that new factor (and of coursed the lagged versions that i still have), how to implement that ?
One Last thing : I am trying to predict the signal (1 or 0) for the next traiding day, but i suppose that the outputs i get from the model refer to the same day as the input one (y(t) based on X(t),..X(t-20)), how can i get the y(t+1), based only on the Inputs (and its delays) up to time t, but no current target variable ?
I will upload also the trading simulation code, for completition :
%% Simulation of the trading strategy
OutRet = r(idxOut);
DayRet = StockData.Close./StockData.Open -1 ;
DayRetOut = DayRet(idxOut);
portReturns = y_c(1:end-1).*DayRetOut(2:end)';
sharpeRatioPort = sharpe(portReturns,0)*sqrt(252)
SharpeRatioStock = sharpe(OutRet,0)*sqrt(252)
portValues = ret2tick(portReturns');
maxdd = maxdrawdown(portValues)
Sig_Port = std(portReturns);
Mean_Port = mean(portReturns);
Sig_Stock = std(OutRet);
Mean_Stock = mean(OutRet);
Max = max(portValues)
Min = min(portValues)
portReturns = y_c(1:end-1).*DayRetOut(2:end)'; This is what i was referring before, when getting the signal in y_c, y(5) for example is based on inputs up to x(5), but refers to day 5, am i right? But since the input is the closing prices, i can exploit that prediction only in the next trading day. Or the prediction is already referring to the next trading day.
I am actually a bit confused about timing in this type of netwroks, i hope that i was clear enough in pointing out my doubts. Hope someone could help me, any kind of suggestions would be really appreciated.
Thank you all, and Good Coding to everyone!
  1 Comment
Mario Viola
Mario Viola on 1 Mar 2021
Another approach that i was thinking about would be to present delayed inputs and outputs. For example, i can feed the Netwroks with inputs up to time t (and all its delays), but giving as target variables the returns from t+1 up to the last one, dropping of course the last vaue of the inputs for size matching purposes.
Could this approach be, at least theoretically, valid ?

Sign in to comment.

Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!