# Logistic Regression of tick data

I've been given some data (it's financial tick data) and I want to predict based on some observed variables whether the next move will be up, down or unchanged.

So I have been trying to use multinomial logistic regression, this is my first time doing logistic regression so I want to check that I have done this correctly and that my results look reasonable.

Right now I am doing 3 bi-variate logistic regressions.

So I code the data such that I have three new time series labelled up, down and unchanged. These are generated by testing whether the move n steps ahead was up, down or unchanged in the original series and adding a one to the appropriate array and making all other entries zero.

I then do a bi-variate logistic regression of these up, down and unchanged arrays against the regressors individually.

I can then calculate the probability of each using the transformation:

$$\textrm{prob} = 1/(1+\exp[-Bx])$$

where $\beta$ are the betas from the bi-variate logistic regressions. And $x$ is the value of the regressors.

This gives me the probability of up, down and unchanged.

I then simply compare if $\textrm{probability of UP} > \textrm{probability of Down}$ if so the model predicts up and vice versa.

Q.1) Is my methodology correct? Right now I am doing all calculations on the price series (not the returns series)?

Q.2) When I test this accuracy in sample I am getting 70% accuracy in sample (for both up and down moves)? Is that a reasonable test score in sample?

Q.3) The model probability for unchanged is very low typically around 14%. So unchanged is never selected (because the probabilities of up down moves are always much larger). However unchanged is the most commonly observed change with an unconditional probability of 91%. Is there a way I can correct the model so that unchanged is forecast accurately by the model.

Update: Here is the code unfortunately I am getting differences between 2 variable regression results and the 3 variable results!

Possible error between two: 2 variable regression run using mnrfit() and an equivalent 3 variable version on asset returns. The returns have been classified as positive, negative or flat. The logistic regression is then run on the rtns vs the classified returns (this is a simple test to check that the regression functions as intended). When I do this for the 2 variable version i.e. Up rtns v everything else, the regression gives an estimate of the probability that a 0 return is not an up return of 88%. As the return size is increased the probability that it is positive increases eventually converging to 1 (as you would expect). Also as increasingly negative rtns are put into the logistic regression model the probability that the rtn is positive goes to zero. The same is true for the 2 Variable estimate of Down returns v everything else. The figures are similar to those above but with the signs of the returns reversed.

Now when I run the 3 variable version. Things initially look OK: when given a return of zero it estimates the probability that it is zero to be 86% with a prob of a down move =6.4% and an up move =7.6% so very similar to the 2 variable case. Moreover when larger and larger returns are entered the probability that it is a positive return converges to 1 as you would expect but when you put in larger and larger negative returns the probability that the return is negative converges to zero while the probability it is equal to zero increases to 1!!! Which is clearly wrong.

Data1 = LoadMat_SHFE_Range(Contract1, StartDate, EndDate);

rtn=(Data1.Mid(2:end)-Data1.Mid(1:end-1))./(Data1.Mid(1:end-1));

NStep=0;

Up=nan(length(rtn),1);
Down=nan(length(rtn),1);
Flat=nan(length(rtn),1);
RtnClass=nan(length(rtn),1);

for i=1:length(rtn)-NStep

if(rtn(i+NStep)>0)
Up(i)=2;
Down(i)=1;
Flat(i)=1;
elseif(rtn(i+NStep)<0)
Up(i)=1;
Down(i)=2;
Flat(i)=1;
elseif(rtn(i+NStep)==0)
Up(i)=1;
Down(i)=1;
Flat(i)=2;
end

end

[BUp,dev,stats] = mnrfit(rtn,Up);
MatProbUp = mnrval(BUp,0.1);

[BDown,dev,stats] = mnrfit(rtn,Down);
MatProbDown = mnrval(BDown,0.1);

for i=1:length(rtn)

if(rtn(i)>0)
RtnClass(i)=3;
elseif(rtn(i)<0)
RtnClass(i)=2;
elseif(rtn(i)==0)
RtnClass(i)=1;
end

end

[BM,dev,stats] = mnrfit(rtn,RtnClass,'model','ordinal');
[pihat,dlow,hi] = mnrval(BM,0,stats,'model','ordinal');

• It's hard for me to understand what your methodology is exactly, can you share some code? Nov 22, 2015 at 22:19

I agree with Malick in the sense that an ARMA-GARCH is a better model but I would improve the model by doing a ARFIMA-FIGARCH, the FI stands for Fractional Integrated that are used to deal for long memory processes like HF data. When trying to fit the ARMA the normal approach would be to see the ACF and the PACF which will show a lot of dependency (almost all lags would be significant) and the same with the GARCH model, so a common way to deal with is with FI models.

On the other hand, don't discard the logistic regression. Sure you are going to have some problems with the Volatility clusters, but information is useful. I would suggest that instead a 1,0 model try to perform an order Probit or Logit so you can have a probability for the magnitude of the increase, (it is a great complement to the ARFIMA-FIGARH model). In this model the dependent variable is going to be an integer form 1 to 5 lets say and each number represents an interval of increase or decrease in the price. Lets say 1 if the price is going to be down between 0 and 5, 2 if the price is going up between 0 to 5 and so on.

The code you posted is wrong since you do not model the time series behavior of the up/down process (ie if you have 10 up move and consequently 10 down move it is not the same as the opposite ie 10 down and after 10 up..). I would recommend you to use standards Arma Garch models apply on returns instead of modeling the process of up/down. These are (at least) the main reasons:

1. if you use your binary process you'll have problems to take into account volatility clustering and so on (the conditional variance part.).

2. since you use tick data, you 'll have consistency problems since you may get 1 move in 5 seconds and after 100 moves in 5 seconds. If you use standards models such as Arma Garch models, you can deal with this fact by resampling the midquote every x seconds (or any other aggregation methods).

3. With standards models you 'll be able to achieve your aims by choosing a simple rule: let's say if the one step ahead forecasted conditional mean return is positive with 0.05 confidence level you could assume the next move will be up. Additionally you can add explanatory variables in both the conditional mean and variance processes.

4. it is likely that you are also interested in the magnitude of the move , and it is easier to obtain it via box-Jenkins class of models.

5. You also need to consider the move in the bid-ask spread ! if you use returns it is implicitly considered.
• Thanks Malick, I take your point about the time series and that will be the next step but right now I'm just trying to get a feel for the data. I am using the idea shown here: beyondmicrofoundations.blogspot.co.uk/2011/09/…. Are you saying this approach is completely flawed? Nov 23, 2015 at 17:53
• @Bazman Yes this approach is completely wrong because roughly speaking it does not consider the "t" (time) subscript. If you mix the data, (ex: move the first tick to the last position) you'll still obtain the same forecast. If you want to consider the time dimension and keep this kind of model then you should have a look to panel logistic model. Nov 23, 2015 at 20:51