Cubic splines dll

over the past year I have learnt to program DLL plugins (to some extent) with the help of some Amibroker users. I still know very little about C++ but today returned to DLL programming to try to implement a cubic spline using free resources on the internet. That was very easy! So I am a bit excited about that. Not sure if Cubic Splines have any predictive value but they can be used just like polynomials to make predictions about the future. Which makes me think about a quoted quote I just read by Paul Levine a few days ago: "Prophecy is extremely difficult, especially as regards the future!".

will post the DLL + AFL a bit later (maybe) since it looks like I have a memory leakage problem which I have to correct for

anyways looks like this, it is really fast too.

Anyone using Splines for trading?

abt

2 Likes

Never heard about it, but looks like you can try it adapting any band setup

yes not sure yet how to use it. Looks like my DLL is ok, I was having some other problem. But will check it first and then post it, maybe tomorrow. The math world has many amazing things that can be used, splines are 1 of them. Many info about Splines. I am no math expert but know a few things that are out there. There is many more

@empottasch I tried developing a cubic spline DLL using “free resources on the internet”. This was many years ago. I discovered the algorithm had future leaks and abandoned the effort. The built-in future leak detection in AmiBroker does not check for leaks in user-written DLLs. I used bar-replay to discover the future leaks. Having never seen your code, I’m not saying your code has future leaks, but it is something you may want to test.

hi Steve,

yes the curve does “repaint”. Like in my chart the top red curve => once a new point comes in that you use to calculate the spline then it will repaint. So the predictive value will only be before a new point comes in

like in this channel code I posted:

you can use only parts of the channel that do not look into the future. The lightblue channels do not look into the future of the code in that link. Similarly that can be done for splines i think

i think this memory problem was not due to my plugin. So try it out if you like. As always on your own risk. You can always just delete it from the plugin directory. I assume you know how it all works and where you need to put the plugin. The plugin is for 64bit Amibroker assuming you have installed the latest Microsoft stuff that Amibroker installes for you

below the AFL, hope the plugin uploads correctly …

no can’t upload DLL so will do some other way next few days

/*
© AFL code by E.M.Pottasch, 11/2017

DLL programming using:
Cubic Spline http://kluge.in-chemnitz.de/opensource/spline/
*/

rightstrength = Param( "Right Strength", 5, 2, 50, 1 );
leftstrength = Param( "Left Strength", 5, 2, 50, 1 );
fact = Param( "Chart Time Frame Factor", 1, 1, 10, 1 );

bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

rightStrength = rightStrength * fact;
leftStrength = leftStrength * fact;

pk = H == HHV( H, leftstrength ) AND Ref( HHV( H, rightstrength ), rightstrength ) < H;
tr = L == LLV( L, leftstrength ) AND Ref( LLV( L, rightstrength ), rightstrength ) > L;

SetChartOptions( 0, chartShowDates );
SetChartBkColor( ColorRGB( 0, 0, 0 ) );
Plot( Close, "Price", colorDefault, styleCandle, Null, Null, 0, 0, 1 );
PlotShapes( shapeSmallCircle*tr, ColorRGB( 0, 250, 0 ), 0, L, -10 );
PlotShapes( shapeSmallCircle*pk, ColorRGB( 250, 0, 0 ), 0, H, 10 );

// Spline calculations
top = bot = xarr = yarr = Null;

cnt = 0;
for( i = fvb; i < lvb; i++ )
{
	if( pk[i] )
	{
		xarr[cnt] = bi[i];
		yarr[cnt] = H[i];
		cnt = cnt + 1;
	}
}

for( i = fvb; i < lvb; i++ )
{
	top[i] = empSpline( xarr, yarr, cnt, i );
}

cnt = 0;
for( i = fvb; i < lvb; i++ )
{
	if( tr[i] )
	{
		xarr[cnt] = bi[i];
		yarr[cnt] = L[i];
		cnt = cnt + 1;
	}
}

for( i = fvb; i < lvb; i++ )
{
	bot[i] = empSpline( xarr, yarr, cnt, i );
}

Plot( top, "", colorRed, styleLine | styleNoRescale, Null, Null, 0, 0, 1 );
Plot( bot, "", colorGreen, styleLine | styleNoRescale, Null, Null, 0, 0, 1 );

if you are interested to play a bit with the plugin, it can be downloaded from here:

<<< LINK REMOVED - NO DLLs are allowed on the forum >>>

the AFL in this thread should be used to run it

1 Like

in the AFL all

i < lvb

should be replaced with

i <= lvb

then it will also draw the last point in the chart

Thank you very much for your contribution. I will work on it with a great interest.
Concerning potential applications, one is a method called EMD (empirical mode decomposition). It allows to split a signal into a trend and cyclic components. It is 100% procedural and it does not make any assumption on the nature of the signal. It is therefore well adapted for non linear and non stationary time series.
It seems quite simple to implement in AFL once you have a spline module. Nevertheless,repainting seems to limit its capacity for real trading application.
Thanks again for sharing your work.

thanks, I will look into it.

with respect to repainting, it is a matter of how you use it. I will make an example, similar to the channel code I posted.

here is an example how you could use it without the fear of repainting (to run this code you need the plugin)

with the mouse you can select a bar in the chart. The data before that bar (blue separator) is used to calculate the spline, the data after that bar is the extended spline and does not use data after the vertical blue separator. In the chart the light blue and violet curve is the extended (non-repainting) spline.

ext

/*
© AFL code by E.M.Pottasch, 11/2017

Example of extended spline

DLL programming using:
Cubic Spline http://kluge.in-chemnitz.de/opensource/spline/
*/

rightstrength = Param( "Right Strength", 5, 2, 50, 1 );
leftstrength = Param( "Left Strength", 5, 2, 50, 1 );
fact = Param( "Chart Time Frame Factor", 1, 1, 10, 1 );

bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

rightStrength = rightStrength * fact;
leftStrength = leftStrength * fact;

pk = H == HHV( H, leftstrength ) AND Ref( HHV( H, rightstrength ), rightstrength ) < H;
tr = L == LLV( L, leftstrength ) AND Ref( LLV( L, rightstrength ), rightstrength ) > L;

SetChartOptions( 0, chartShowDates );
SetChartBkColor( ColorRGB( 0, 0, 0 ) );
Plot( Close, "Price", colorDefault, styleCandle, Null, Null, 0, 0, 1 );
PlotShapes( shapeSmallCircle*tr, ColorRGB( 0, 250, 0 ), 0, L, -10 );
PlotShapes( shapeSmallCircle*pk, ColorRGB( 250, 0, 0 ), 0, H, 10 );

dn = DateTime();
sd = SelectedValue( dn );
start = dn == sd;
stidx = LastValue( ValueWhen( start, BarIndex() ) );

// Spline calculations
top = extendtop = xarr = yarr = Null;
cnt = 0;

for( i = fvb; i <= stidx; i++ )
{
    if( pk[i] )
    {
        xarr[cnt] = bi[i];
        yarr[cnt] = H[i];
        cnt = cnt + 1;
    }
}

for( i = fvb; i <= stidx; i++ )
{
    if( cnt > 0 )
        top[i] = empSpline( xarr, yarr, cnt, i );
}

for( i = stidx + 1; i <= lvb; i++ )
{
    if( cnt > 0 )
        extendtop[i] = empSpline( xarr, yarr, cnt, i );
}

Plot( top, "", colorRed, styleLine | styleNoRescale, Null, Null, 0, 0, 1 );
Plot( extendtop, "", ColorRGB( 0, 255, 255 ), styleLine | styleNoRescale, Null, Null, 0, 0, 2 );

bot = extendbot = xarr = yarr = Null;
cnt = 0;

for( i = fvb; i <= stidx; i++ )
{
    if( tr[i] )
    {
        xarr[cnt] = bi[i];
        yarr[cnt] = L[i];
        cnt = cnt + 1;
    }
}

for( i = fvb; i <= stidx; i++ )
{
    if( cnt > 0 )
        bot[i] = empSpline( xarr, yarr, cnt, i );
}

for( i = stidx + 1; i <= lvb; i++ )
{
    if( cnt > 0 )
        extendbot[i] = empSpline( xarr, yarr, cnt, i );
}

Plot( bot, "", colorGreen, styleLine | styleNoRescale, Null, Null, 0, 0, 1 );
Plot( extendbot, "", ColorRGB( 255, 0, 255 ), styleLine | styleNoRescale, Null, Null, 0, 0, 2 );
Plot( bi == stidx, "", colorDarkBlue, styleHistogram | styleOwnScale | styleNoLabel | styleNoRescale, 0, 1, 0, -2, 10 );

looks indeed like you can use it to extrapolate but it is not very good in doing so, meaning that the predictive value is low. As I come to understand, Splines are very well suited for interpolation but not for extrapolation. So for forecasting we need some other functions

I agree with you, potential for real trading is limited. Moreover, there is no room for backtesting.
By the way, I have downloaded your dll but it is a 64 bits and I cannot run it on my 32bits AB. Would you have a 32 bits version?

for some reason Google sites does not allow me to put it on my site all of a sudden.

i can email it to you if you give me your email here or at empottasch@gmail.com

my view is that it can be used for backtesting. The question is if it is worth the effort. But I guess it will be not much worse than least squares

the dll I uploaded yesterday I removed but Google sites will not allow me to upload it again. Time to start using something else

i was asked about this plugin via email. Now since we have the Python plugin we can use Python instead. How to install the plugin, see instructions here:

To do similar things use this AFL:

PyLoadFromFile( "spline1", "C:\\Users\\win 10\\AppData\\Local\\Programs\\Python\\Python38\\mypython\\fitting\\CubicSplineForAB.py" );

rightstrength = Param( "Right Strength", 5, 2, 50, 1 );
leftstrength = Param( "Left Strength", 10, 2, 50, 1 );
extend = Param( "Extend (bars)", 60, 1, 50, 1 );

bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );
Lx = LastValue( bi );

pk = H == HHV( H, leftstrength ) AND Ref( HHV( H, rightstrength ), rightstrength ) < H;
pk AND Lx - ValueWhen( pk, bi ) > rightStrength;
tr = L == LLV( L, leftstrength ) AND Ref( LLV( L, rightstrength ), rightstrength ) > L;
tr AND Lx - ValueWhen( tr, bi ) > rightStrength;

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
SetChartOptions( 0, chartShowArrows | chartShowDates );
Plot( C, "C", colorWhite, styleCandle, Null, Null, 0, 0, 0 );
PlotShapes( shapeSmallCircle*pk, ColorRGB( 250, 0, 0 ), 0, H, 10 );
PlotShapes( shapeSmallCircle*tr, ColorRGB( 0, 250, 0 ), 0, L, -10 );

// tops
svb = LastValue( SelectedValue( ValueWhen( pk, bi ) ) );

// fill x array, y array and xnew array
xarr = yarr = xnew = 0;
cnt = 0;

for( i = fvb; i <= lvb; i++ )
{
    xnew[i] = bi[i]; // index where interpolated values will be stored

    if( pk[i] AND i <= svb )
    {
        // points used to calculate the spline
        xarr[cnt] = bi[i];
        yarr[cnt] = H[i];
        cnt = cnt + 1;
    }
}

if( cnt > 3 )
{
    ynew = PyEvalFunction( "spline1", "splineInput", xarr, yarr, cnt, xnew );
    ynew = IIf( bi >= svb + extend, Null, ynew );
    Plot( IIf( bi <= svb, ynew, Null ), "", colorRed, styleLine | styleNoRescale, Null, Null, 0, 0, 1 );
    Plot( IIf( bi > svb + rightStrength, ynew, Null ), "", colorRed, styleDots | styleNoLine | styleNoRescale, Null, Null, 0, 0, 1 );
    Plot( IIf( bi >= svb AND bi <= svb + rightStrength, ynew, Null ), "", colorLightGrey, styleDots | styleNoLine | styleNoRescale, Null, Null, 0, 0, 1 );
    Plot( bi == svb, "", ColorRGB( 60, 0, 0 ), styleHistogram | styleOwnScale | styleNoLabel, 0, 1, 0, -1, 10 );
}

// bottoms
svb = LastValue( SelectedValue( ValueWhen( tr, bi ) ) );

// fill x array, y array and xnew array
xarr = yarr = xnew = 0;
cnt = 0;

for( i = fvb; i <= lvb; i++ )
{
    xnew[i] = bi[i]; // index where interpolated values will be stored

    if( tr[i] AND i <= svb )
    {
        // points used to calculate the spline
        xarr[cnt] = bi[i];
        yarr[cnt] = L[i];
        cnt = cnt + 1;
    }
}

if( cnt > 3 )
{
    ynew = PyEvalFunction( "spline1", "splineInput", xarr, yarr, cnt, xnew );
    ynew = IIf( bi >= svb + extend, Null, ynew );
    Plot( IIf( bi <= svb, ynew, Null ), "", colorBrightGreen, styleLine | styleNoRescale, Null, Null, 0, 0, 1 );
    Plot( IIf( bi > svb + rightStrength, ynew, Null ), "", colorBrightGreen, styleDots | styleNoLine | styleNoRescale, Null, Null, 0, 0, 1 );
    Plot( IIf( bi >= svb AND bi <= svb + rightStrength, ynew, Null ), "", colorLightGrey, styleDots | styleNoLine | styleNoRescale, Null, Null, 0, 0, 1 );
    Plot( bi == svb, "", ColorRGB( 0, 60, 0 ), styleHistogram | styleOwnScale | styleNoLabel, 0, 1, 0, -1, 10 );
}

in combination with this Python code:

# https://docs.scipy.org/doc/scipy/reference/interpolate.html
# https://docs.scipy.org/doc/scipy/reference/tutorial/interpolate.html

from scipy import interpolate
import numpy as np
import AmiPy

def splineInput( x, y, cnt, xnew ):
    xarr = x[0:int(cnt)]
    yarr = y[0:int(cnt)]
    tck = interpolate.splrep(xarr, yarr, s=0)
    ynew = interpolate.splev(xnew, tck, der=0)
    return ynew

this is how it looks like:
PL

4 Likes