Linear regression for non-overlapping segments of a wave
Eduard Kas
What I would like to do is calculate the regression line first of all for a segment with the first 32 points, then for the subsequent 32 points, next for the third segment of 32 points, and so on, up to the 30th segment.
Per segment I would also like to calculate the Fluctuation magnitude (see variable Fluctuationmagn) and write the outcomes (a single real number for each of the 30 segments) to a wave, so that another curve fit can be performed. This time with the Fluctuation magnitude as the dependent factor and the segment number as the independent factor.
Any help is highly welcome. Many thanks in advance.
Eduard Kas
<code>#pragma rtGlobals=1 // Use modern global access method.
Function PriceTrend(Startlevel)
Variable Startlevel // Price of share at time = 0
Variable Simulation = CreatePrices(Startlevel) // Fuction to simulate random walk of share
// prices
Variable Returncalc = CalcReturn(input) // Function to calculate natural logs of return
// per period
Variable Demeanedcalc = Demeaned(periodreturn) // Function to calculate demeaned returns
Variable FFactor = Fluctuationmagnitude(squareddiff) // Function to calculate local trend
// and fluctuation magnitude
End
Function CreatePrices(Startlevel) // Function to simulate random walk of share prices
Variable Startlevel //Share price at time = 0 in euros
Make/O/N=961 input // Create wave for share prices
Input[0] = Startlevel // Share price at time = 0
Input[1,960] =Input(p-1) + gnoise(0.15) // Share prices in subsequent period, where price is
// price in preceding period plus period return drawn
// from a Gaussian (noise) distribution
End
Function CalcReturn(input) // Function to calculate natural logs of return per period
Wave Input // Read share prices generated by preceding function
String OutputName = NameOfWave(input)+"_logarithm" // Store the name of wave plus
// "logartihm" into the new wave
// OuputName
Duplicate/O input $OutputName // Duplicate the wave with generated share prices as the
// wave named input_logarithm
Wave output = $OutputName // Reference input_logarithm so that you can use it
output = Ln(input) // Calculate logarithmic values of wave
Make/O/N=960 Periodreturn
Periodreturn[0]= 0 // Assume return in first period to be zero
Periodreturn[1,959] = output(p) - output(p-1) // In next period logartihmic return equals logarithmic
// share price of this period minus logarithmic
// share price in previous period
End
Function Demeaned(periodreturn) // Function to calculate demeaned returns
Wave periodreturn // Read return values generated by previous function
WaveStats/Q periodreturn // Determine statistis of return wave
Variable avg = V_avg // Determine average return
Make/O/N=960 Cumulative // Create wave that will include each period's return above or
// below the average for all periods
Cumulative[0] = Periodreturn[0]-V_avg // Determine return below or above the average for
// the first period
Cumulative[1,959] = Cumulative(p-1) + Periodreturn(p) - V_avg // Determine return below or
// above the average for all
// subsequent periods
End
Function Fluctuationmagnitude(cumulative) // Function to calculate local trend and fluctuation magnitude
Wave cumulative // Read cumulative demeaned returns from previous function
Make/O/N=960 Number // Create a new wave to show the period numbers
Variable i = 0 // Initialise i
do
Number[i] = i +1 // Add the number 1 to the level in the preceding period, so that the first
// period carries the number 1
i += 1
while(i+1<959)
CurveFit line cumulative[0,959] /x=NUMBER /D // Generate a linear regression function in which
// the y values (demeaned cumulative
// returns are regressed against the x values)
// (the period numbers)
Wave Fitted = fit_Cumulative // Read fitted regression line into Wave named 'Fitted'
Wave Squareddiff // Create wave squared differences
Squareddiff = (Cumulative - Fitted)^2 // Calculate squared differences between
// cumulative demeaned returns and fitted
// regression line
WaveStats Squareddiff // Dtermine statistics of wave squared differences
Variable Sumofsquareddiff // Create parameter sum of squared differences
Sumofsquareddiff = V_Sum //Determine sum
Variable Fluctuationmagn // Create wave Fluctuation magnitude
Fluctuationmagn = Sqrt(V_Sum/960) // Calculate fluctuation magnitude
End<pre><code class="language-igor"><code>
Function PriceTrend(Startlevel)
Variable Startlevel // Price of share at time = 0
Variable Simulation = CreatePrices(Startlevel) // Fuction to simulate random walk of share
// prices
Variable Returncalc = CalcReturn(input) // Function to calculate natural logs of return
// per period
Variable Demeanedcalc = Demeaned(periodreturn) // Function to calculate demeaned returns
Variable FFactor = Fluctuationmagnitude(squareddiff) // Function to calculate local trend
// and fluctuation magnitude
End
Function CreatePrices(Startlevel) // Function to simulate random walk of share prices
Variable Startlevel //Share price at time = 0 in euros
Make/O/N=961 input // Create wave for share prices
Input[0] = Startlevel // Share price at time = 0
Input[1,960] =Input(p-1) + gnoise(0.15) // Share prices in subsequent period, where price is
// price in preceding period plus period return drawn
// from a Gaussian (noise) distribution
End
Function CalcReturn(input) // Function to calculate natural logs of return per period
Wave Input // Read share prices generated by preceding function
String OutputName = NameOfWave(input)+"_logarithm" // Store the name of wave plus
// "logartihm" into the new wave
// OuputName
Duplicate/O input $OutputName // Duplicate the wave with generated share prices as the
// wave named input_logarithm
Wave output = $OutputName // Reference input_logarithm so that you can use it
output = Ln(input) // Calculate logarithmic values of wave
Make/O/N=960 Periodreturn
Periodreturn[0]= 0 // Assume return in first period to be zero
Periodreturn[1,959] = output(p) - output(p-1) // In next period logartihmic return equals logarithmic
// share price of this period minus logarithmic
// share price in previous period
End
Function Demeaned(periodreturn) // Function to calculate demeaned returns
Wave periodreturn // Read return values generated by previous function
WaveStats/Q periodreturn // Determine statistis of return wave
Variable avg = V_avg // Determine average return
Make/O/N=960 Cumulative // Create wave that will include each period's return above or
// below the average for all periods
Cumulative[0] = Periodreturn[0]-V_avg // Determine return below or above the average for
// the first period
Cumulative[1,959] = Cumulative(p-1) + Periodreturn(p) - V_avg // Determine return below or
// above the average for all
// subsequent periods
End
Function Fluctuationmagnitude(cumulative) // Function to calculate local trend and fluctuation magnitude
Wave cumulative // Read cumulative demeaned returns from previous function
Make/O/N=960 Number // Create a new wave to show the period numbers
Variable i = 0 // Initialise i
do
Number[i] = i +1 // Add the number 1 to the level in the preceding period, so that the first
// period carries the number 1
i += 1
while(i+1<959)
CurveFit line cumulative[0,959] /x=NUMBER /D // Generate a linear regression function in which
// the y values (demeaned cumulative
// returns are regressed against the x values)
// (the period numbers)
Wave Fitted = fit_Cumulative // Read fitted regression line into Wave named 'Fitted'
Wave Squareddiff // Create wave squared differences
Squareddiff = (Cumulative - Fitted)^2 // Calculate squared differences between
// cumulative demeaned returns and fitted
// regression line
WaveStats Squareddiff // Dtermine statistics of wave squared differences
Variable Sumofsquareddiff // Create parameter sum of squared differences
Sumofsquareddiff = V_Sum //Determine sum
Variable Fluctuationmagn // Create wave Fluctuation magnitude
Fluctuationmagn = Sqrt(V_Sum/960) // Calculate fluctuation magnitude
End<pre><code class="language-igor"><code>
You can limit a curve fit to a subset of a wave using square brackets like this:
Display testWave
CurveFit line testWave[40,80] /D
ModifyGraph rgb(fit_testWave)=(0,0,65535), lsize(testWave)=3
I recommend changing your Fluctuationmagnitude to take startPoint, endPoint parameters passed in from a new, higher-level function. The new function would create the wave now created in Fluctuationmagnitude. It would then go into a loop calling Fluctuationmagnitude 30 times, once for each segment, passing startPoint and endPoint as parameters.
In the higher level function you can create a 30-point wave to store the outcome from each invocation of Fluctuationmagnitude. Fluctuationmagnitude would return this outcome result.
BTW, this:
Variable i = 0 // Initialise i
do
Number[i] = i +1 // Add the number 1 to the level in the preceding period, so that the first
// period carries the number 1
i += 1
while(i+1<959)
can be written like this:
For details, execute:
Also, this:
does not read anything. It creates a reference to fit_Cumulative.
Likewise, this does not create any wave. Rather it creates a reference to an existing wave:
A wave reference is a symbol local to a function the references a wave. For details:
June 11, 2012 at 02:23 pm - Permalink
Wave Ywave, Xwave
Variable seglength
Variable nsegments = floor(numpnts(Ywave)/seglength)
Variable i
Make/O/D/N=(nsegments, 2) fitAandB // you probably want to make this more general by allowing a customized name
for (i = 0; i < nsegments; i += 1)
CurveFit/Q/W=2 line, Ywave[i*seglength, (i+1)*seglength - 1] /X=Xwave
Wave W_coef
fitAandB[i][] = W_coef[q]
endfor
end
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
June 11, 2012 at 02:26 pm - Permalink
Function HurstCalculation(cumulative, Xwave, length, segmlength,nsegments) // Create Hurst Calculation function
Wave cumulative, Xwave // Create waves
Variable segmlength, length, nsegments // Create variables
Variable FittedLine = SegmentedLineFit(cumulative,Xwave, length, segmlength, nsegments)
End
Function SegmentedLineFit (cumulative,Xwave, length, segmlength, nsegments) // Function to calculate segmented Curve Fit
Wave cumulative, Xwave // Create parameters cumulative (returns) and Xwave (= time scale)
Variable segmlength, length, nsegments // Create paramaters segmlength (= length of segment), length (= length of time
// series for price variable) and nsegments (= number of segments)
Variable i // Create local variable i
Make/O/N=(length-1) LogWave = Ln(XWave) // Transform time scale into natural logarithm
Variable Summedsquaredresids // Create local variable sum of squared residuals
Make/O/N=(length-1) Squaredresids // Create wave to which residuals for each of the successive curve fits are written down to
Make/O/N=(1, 1) Fluctuation // Create wave to which square root of average residuals is written down to
for (i=0; i < nsegments; i += 1) // Repeat cuve fit calculation for each equal size segment
CurveFit/W=2/Q line Cumulative[i*segmlength, (i+1)*segmlength-1] /X=LogWave /R // Carry out curve
Wave Res_Cumulative // Determine residuals for each curve
Squaredresids = Res_Cumulative^2 // Determe squared residuals for each curve fit
endfor
WaveStats/Q Squaredresids // Determine statistics for the entire wave Squaredresids
Summedsquaredresids = V_avg // Determine average value of wave
Fluctuation = Sqrt(V_avg) // Take square root of the average value
End<pre><code class="language-igor">
Eduard
June 17, 2012 at 09:47 pm - Permalink
set the first 16 points of the Xwave equal to 1 up to and including 16 and to repeat these values 60 times for an entire series length of 960 in terms of
return values (and 961 in terms of price values). (So far I created the Function SeriesCalc separately in order to test it. Later on, I would like to integrate
it with the other functions and determine the number of segments, depending on the length of a segment.)
The Function SeriesCalc does not behave like expected. If I call it by SeriesCalc(961, 16) for each of the 960 points of Xwave the value of -928 is created.
My question: what I am doing wrong.
Any help is highly welcome. Many thanks in advance.
Eduard
Function SeriesCalc(serieslength, segmlength) // Function to create variable lengths of segments
Variable serieslength, segmlength // Create parameters
Make/O/N=(serieslength -1) Xwave // Create X (time) variable equal to series length (for price series)
// minus 1
Variable nsegments = floor(serieslength-1)/segmlength // Parameter nsemgents must be an integer
Variable i, j // Create local variables
i=0
do
j=0
do
Xwave = j+1 - (i*segmlength) // Set values of Xwave equal to 1 up to latest segment value
// that is the value of 16 if segment length is equal to 16
j += 1
while (j < segmlength)
i += 1
while (i < nsegments) // Repeat Xwave values for each of the n segments
End<pre><code class="language-igor">
June 17, 2012 at 10:30 pm - Permalink
This sets every point of Xwave every time through the loop. Perhaps you mean something like:
This is equivalent to a single statement:
For details on this kind of statement:
You will probably have to read this section multiple times and do some experimentation for it to sink in.
June 17, 2012 at 11:28 pm - Permalink
Eduard
June 20, 2012 at 12:24 am - Permalink