NARXNET ONE STEP/MULTI STEP PREDICTIONS

8 views (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');
end
%% 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));
end
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);
view(netc)
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);
%sum(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)
plot(portValues)
Sig_Port = std(portReturns);
Mean_Port = mean(portReturns);
Sig_Stock = std(OutRet);
Mean_Stock = mean(OutRet);
portValues(end)
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)

Categories

Find more on Sequence and Numeric Feature Data Workflows in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!