In my previous article on Trading Forex: (1) Trend Identification I provided an introduction to the trading model invention and design. We made use of FX data of AUDUSD pair sampled hourly and splitting data into weekly time-series.
Today, we will work a bit harder over formulation of the very first rules for the model. This step will require an engagement of our creativity in understanding what data are like as well as how we can make a basic set of rules which would help us to perform an attractive time-series classification. Our objective is to invent a method which will be helpful in classification of last week FX pair’s time-series to be either in the downtrend or in the uptrend.
The most naive way of classification of directional information contained in any time-series is its slope: a straight line fit to the data. Let’s use it as our starting point. Instead of fitting all data points for a given week, we find median values for the first and the last 12 data points both in Time $(x1,x2)$ and Pair Ratio $(y1,y2)$ as specified in lines 92 to 94:
% FX time-series analysis % (c) Quant at Risk, 2012 % % Part 2: Classification of weekly time-series close all; scrsz = get(0,'ScreenSize'); h=figure('Position',[70 scrsz(4)/2 scrsz(3)/1.1 scrsz(4)/2],'Toolbar','none'); fprintf('\nuptrend/downtrend identification.. '); % for viewing use the loop hold off; set(0,'CurrentFigure',h); % pre-define variables trend=zeros(nw,1); slope=zeros(nw,1); midp={}; % middle points endp={}; % end points (median based on last 12 points) for i=1:nw %--- a loop over total number of weeks available % reading time-series for a current week w=week{i}; x=w(:,1); y=w(:,2); % plot the time-series hold on; plot(x,y,'k'); % linear trend estimation x1=median(x(1:12)); x2=median(x(end-11:end)); y1=median(y(1:12)); y2=median(y(end-11:end)); % define end-point of the time-series and mark it on the plot endp{i}=[x2 y2]; hold on; plot(endp{i}(1),endp{i}(2),'b*'); % find slope m=(y2-y1)/(x2-x1); slope(i)=m; xl=x1:dt:x2; yl=m*xl-m*x2+y2; % a line of representing the slope hold on; plot(xl,yl,'b:'); % find middle point of the line and mark it on the plot mx=mean(xl); my=mean(yl); midp{i}=[mx my]; hold on; plot(midp{i}(1),midp{i}(2),'bo');
As an example of the code execution, for the first two weeks we plot slopes, mid-points and end-points:
We assume that our classification procedure will be based solely on the information provided for end-points and slopes. The exception we make for the classification of the first two weeks. For the first week the distinction between uptrend and downtrend is made based on the position of the first and last point:
% Time-Series Classification if(i==1) ybeg=y(1); yend=y(end); if(ybeg<yend) trend(i)=+1; % uptrend hold on; plot(x,y,'k'); else trend(i)=-1; % downtrend hold on; plot(x,y,'r'); end end
where we mark the result of classification with a sign $+1$ or $-1$ in a vector element of $trend$, and plot it with black and red color denoting uptrend and downtrend, respectively.
For the second week, our rules of classification are enriched by additional information about the end-point of a current and a previous week:
if(i==2) % week(current-1) tmp=week{i-1}; x1=tmp(:,1); y1=tmp(:,2); y1b=y1(1); y1e=y1(end); % week(current) y0b=y(1); y0e=y(end); if(y0e>y1e) trend(i)=+1; % uptrend hold on; plot(x,y,'k'); else trend(i)=-1; % downtrend hold on; plot(x,y,'r'); end end
For weeks number 3 and higher we do our creative research over the data to define a specific set of rules. We allow to take into account the information from two weeks prior to the current one and combine them all together. The following code represents an attractive solution, subject to improvement:
if(i>2) % week(current-2) mid2=midp{i-2}(2); end2=endp{i-2}(2); slp2=slope(i-2); % week(current-1) mid1=midp{i-1}(2); end1=endp{i-1}(2); slp1=slope(i-1); % week(current) mid0=midp{i}(2); end0=endp{i}(2); slp0=slope(i); if((mid0>mid1)) % up-trend if((mid0>mid2)&&(end0>end1)) trend(i)=+1; hold on; plot(x,y,'k'); % strong up-trend elseif((mid0>mid2)&&(end0>end2)) trend(i)=+1; hold on; plot(x,y,'k'); % weak up-trend elseif((mid0<mid2)&&(end0<end2)&&(slp0<0)) trend(i)=-1; hold on; plot(x,y,'r'); % turns into possible down-trend elseif((mid0<mid2)&&(end0<end2)&&(slp0>0)) trend(i)=+1; hold on; plot(x,y,'k'); % turns into possible up-trend else trend(i)=+1; hold on; plot(x,y,'k'); % turns into possible up-trend end elseif(mid0<mid1) % down-trend if((mid0<mid2)&&(end0<end1)&&(end0<end2)) trend(i)=-1; hold on; plot(x,y,'r'); % weak down-trend elseif((mid0<mid2)&&(end0<end2)&&(end0>end1)) trend(i)=+1; hold on; plot(x,y,'k'); % possible up-trend elseif((mid0<mid2)&&(end0>end2)) trend(i)=+1; hold on; plot(x,y,'k'); % turns into possible up-trend elseif((mid0>mid2)&&(end0<end1)&&(end0<end2)) trend(i)=-1; hold on; plot(x,y,'r'); elseif((mid0>mid2)&&(end0>end2)) trend(i)=+1; hold on; plot(x,y,'k'); % turns into possible up-trend elseif((mid0>mid2)&&(end0>end1)) trend(i)=+1; hold on; plot(x,y,'k'); % turns into possible up-trend else trend(i)=-1; hold on; plot(x,y,'r'); end end end end
Since one picture is worth millions of lines of code, below we present three examples of our model in action. The last plot corresponds to the latest Global Financial Crisis and shows how weeks in uptrends of 2009 followed these in downtrend a year before.
It is straightforward to note that the performance of our rules works very intuitively and stays in general agreement with the market sentiments.
Explore Further
→ Trading Forex: (1) Trend Identification
→ Probability of a Limit Order Execution
→ Trading with the trend
3 comments
Hi Pawel,
I enjoyed your post so much that I challenged myself to find an alternative solution approach.
I attack it from the persepective of the most simple and pragmatic definition of trends:
>> uptrend: series of higher highs and higher lows
>> downtrend: series of lower highs and lower lows
>> neutral trend: none of the above
Hence I developed a MATLAB routine working on a self generated price chart St,
where I first identify the series of St local-max and St local-min as:
if (St(i) > St(i-1) && St(i+1) <local max at time= found>
if (St(i) St(i)) -> <local min at time= found>
This allows to compute two matrixes lmax[] and lmin[] defined as:
lmax = [time, St local max value]
lmin = [time, St local min value]
Then I plot both St and its local max and local min in figure #1.
Second step purpose is to identify trends, as classified within the {uptrend,downtrend,neutral} set.
That is based on their abovementioned definition, hence:
if (lmax(i,2) > lmax(i-1,2) && lmin(i,2) > lmin(i-1,2)) => uptrend
if (lmax(i,2) < lmax(i-1,2) && lmin(i,2) downtrend
else neutral trend
The computed trend is stored inside the matrix trend[] defined as:
trend = [trend starting time, trend value]
Then figure#2 shows the figure#1 St price chart with highlighted trends in blue/red/black colors.
I enclose herein below the MATLAB code. I would also have enclosed some results samples as jpg, however it appeared to me not possible as posted comment.
Very interesting post. I’m using MatLab for testing of strategies, and your blog is very useful for me.
I have noticed that the links for 2012 posts do not work.
Thank you for sharing your knowledge.
Felice, thank you for your warm words. I plan to drop more code in Matlab and programming some cool strategies. Stay tuned!