Classifying Tick Returns with Logistic and Time-Series Models
Summary
The document examines a proposed approach to forecasting whether a future tick return will be positive, negative, or unchanged. It describes converting outcomes into class labels, fitting separate binary logistic regressions, and comparing predicted probabilities. The questioner reports strong in-sample directional accuracy but says the model badly underpredicts the unchanged class, which is common in the data. A later code example compares binary fits with an ordinal model and raises concerns about classification and model specification.
The replies recommend modeling returns and their time dependence rather than treating each up or down label as an isolated event. They point to volatility clustering, irregular tick arrival, and bid-ask spread changes as practical complications, suggesting time aggregation and conditional mean and variance models as alternatives. An ordinal logit or probit is also proposed when the target is a range of return magnitudes. The answers are suggestions rather than empirical validation: the reported in-sample score does not establish out-of-sample performance, and the exchange does not fully resolve the coding issue or provide a tested forecasting procedure.
Key ideas
- Separate binary classifiers can produce probabilities that do not form a coherent three-class probability model.
- A dominant unchanged class can be poorly forecast when class frequencies and model structure are not handled appropriately.
- Tick data can exhibit volatility clustering and irregular event timing, complicating simple up-or-down classification.
- Return time-series models can represent conditional mean and volatility and may also estimate move magnitude.
- In-sample directional accuracy alone does not establish reliable out-of-sample performance.
Tags
Full text
# Logistic Regression of tick data
# 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');
```
## Answer by Alejandro Andrade (score 1, accepted)
https://quant.stackexchange.com/a/22137
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.
## Answer by Malick (score 2)
https://quant.stackexchange.com/a/21891
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:
- if you use your binary process you'll have problems to take into account volatility clustering and so on (the conditional variance part.).
- 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).
- 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.
- 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.
- You also need to consider the move in the bid-ask spread ! if you use returns it is implicitly considered.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.