Profile Picture

a complete example of a c# indicator plugin with arguments

Posted By hairy_mug 10 Years Ago
Rated 5 stars based on 1 vote.

a complete example of a c# indicator plugin with arguments

Message
Posted Saturday June 02 2007
Here is the  complete code for my first c# indicator.

It will indicate when a peak has occured in the series.

The actual calculation is still being tweaked but this is more an example of how to do a c# plugin,

Looks best if you use the "histogram" line style...

Walt   

/********************************/

using System;

using System.Collections.Generic;

using System.Text;

using RightEdge.Common;

using RightEdge.Indicators;

namespace whisIndicators

{

[YYEIndicatorAttribute(System.Drawing.KnownColor.Crimson,

YYEIndicatorAttribute.EIndicatorGroup.Other,

Name = "peak",

Description = "indicates peak",

Id = "{2fccb6a1-79b0-4a6b-bcaf-26ba2f0ba363}")

]

[Serializable]

[SeriesInputAttribute("Input", 1)]

public class peak : SeriesCalculatorBaseWithValues

{

private int ii_width =3;

private double id_depthPct=.02;

private int ii_skew=0;

private int ii_pbarIndex=0;

private int ii_minIndex = 0;

[ConstructorArgument(Name = "Width", Type = ConstructorArgumentType.Integer, Value = "5", Order = 1)]

[ConstructorArgument(Name = "DepthPct", Type = ConstructorArgumentType.Double, Value = "0.02", Order = 2)]

[ConstructorArgument(Name = "Skew", Type = ConstructorArgumentType.Integer, Value = "0", Order = 3)]

public peak(int Width, double DepthPct, int Skew)

: base(1)

{

this.ii_width = Width;

this.ii_skew = Skew;

this.id_depthPct = DepthPct;

}

/// Calculates the next value in the indicator series.

protected override double CalcNewValue(int index)

{

int HWid;

int pkHwid;

double result;

double psk;

double nsk;

ISeries sig = inputs[0];

this.ii_pbarIndex = index;

this.ii_minIndex++;

//enough bars to check

if (this.ii_minIndex <= ii_width + 1 & ii_width>2)

{

// If not enough bars, return not a number.

return double.NaN;

}

else

{

if(( ii_width *.5) <1)

HWid=1;

else

HWid=Convert.ToInt16( Convert.ToDouble(ii_width) *.5) ;

pkHwid = 1 + HWid;

double coff = sig[this.ii_pbarIndex - HWid];

double loff = sig[this.ii_pbarIndex - ii_width];

//find highest #

double hiPoint = hhv(ii_width);

if (hiPoint < 0) hiPoint = hiPoint * -1; else hiPoint = 0;

if(ii_skew > 0) psk = 1 - (ii_skew * .01); else psk = 1;

if (ii_skew < 0) nsk = 1 - (ii_skew * .01); else nsk = 1;

double dnLeg = ws_pctdiff(hiPoint-sig[index], hiPoint-coff);

double upleg = ws_pctdiff(hiPoint-loff, hiPoint-coff);

result=Convert.ToDouble(dnLeg >=id_depthPct*nsk

& upleg >= id_depthPct*psk

& hiPoint-loff <=hiPoint-loff ) ;

if (result > 0 )

return hhv(20)*1.05;

else

return llv(20)*.95;

}

}

protected override void Reset()

{

this.ii_minIndex = 0;

}

double ws_pctdiff(double prev,double cur)

{

double fctr;

if (prev < cur) fctr = prev; else fctr = cur;

if(fctr<0)cur=cur+(fctr*-1)+10;

if(fctr<0)prev=prev+(fctr*-1)+10;

return (cur - prev) / prev;

}

double hhv( int len)

{

double fv = inputs[0][this.ii_pbarIndex];

for (int l1 = this.ii_pbarIndex - len; l1 < this.ii_pbarIndex; l1++)

{

if (l1 >= 0 & l1 <= ii_pbarIndex)

{

if (inputs[0][l1] > fv) fv = inputs[0][l1];

}

}

return fv;

}

double llv(int len)

{

double fv = inputs[0][this.ii_pbarIndex];

for (int l1 = this.ii_pbarIndex - len; l1 < this.ii_pbarIndex; l1++)

{

if (l1 >= 0 & l1 <= ii_pbarIndex)

{

if (inputs[0][l1] < fv) fv = inputs[0][l1];

}

}

return fv;

}

}

}

5 stars.
Posted Saturday June 02 2007
Wow, that's awesome.  Thanks for sharing!  Would you mind zipping it up and adding it to the trading system library?  I just added a "type" Indicator Plugin.
Posted Saturday June 02 2007
got both Trough & Peak done... will zip and post after I clean-up & document
DoQ
Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)
Posted Thursday July 05 2007
I am trying to code up my first indicator plugin for reusability using the above example as a template. At this point I am completely confused as to the different classes available and when to use them, even after looking at the included examples.

Basically, how can I access BarData (o,h,l,c,v) within this code without explicitly forcing a user selectable seriesinputattribute.....

losing hair quickly...but I know the solution is simple, help!

thx


DoQ_Indicators
"better is the enemy of good enough"
Posted Thursday July 05 2007
DoQ (7/5/2007)
I am trying to code up my first indicator plugin for reusability using the above example as a template. At this point I am completely confused as to the different classes available and when to use them, even after looking at the included examples.

Basically, how can I access BarData (o,h,l,c,v) within this code without explicitly forcing a user selectable seriesinputattribute.....

losing hair quickly...but I know the solution is simple, help!

thx

If you want to access the bar data, you should derive from IndicatorBase instead of one of the SeriesCalculator classes.  You can perform your calculation in the CalcNextValue method.  If you store any state in your class, you should override CalcSeriesValues and reset the state before calling the base class version of the method.  There is an IndicatorBaseIndicator sample you can refer to.

Thanks,
Daniel

DoQ
Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)
Posted Thursday July 05 2007
Ok, will try, but was having trouble then with constructor arguments, could be just a porting issue, will try from scratch using IndicatorBase.

thx


DoQ_Indicators
"better is the enemy of good enough"
DoQ
Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)
Posted Thursday July 05 2007
Using IndicatorBase, can I have:

[SeriesInputAttribute("X", 1)]

and

[ConstructorArgument("Y", ConstructorArgumentType.Integer, "10", 1)]?

 

I keep getting errors and can't figure out why. The error is

The best overloaded method match for 'RightEdge.Common.IndicatorBase.IndicatorBase(bool)' has some invalid arguments (CS1502)

 

Any examples of IndicatorBase that uses BarData and accepts and InputSeries and allows an argument would be helpful..




DoQ_Indicators
"better is the enemy of good enough"
Posted Thursday July 05 2007
It looks like your problem is with how your are calling the base constructor, not with the attributes you are trying to use.  Can you post what your constructor looks like?

Also you can't use SeriesInputAttribute on IndicatorBase.  It won't give you an error, but it just won't be used.  Are you trying to use a user-defined input series as well as access the bar data?

Daniel

DoQ
Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)Supreme Being (11,393 reputation)
Posted Friday July 06 2007
dplaisted (7/5/2007)
It looks like your problem is with how your are calling the base constructor, not with the attributes you are trying to use.  Can you post what your constructor looks like?

Also you can't use SeriesInputAttribute on IndicatorBase.  It won't give you an error, but it just won't be used.  Are you trying to use a user-defined input series as well as access the bar data?

Daniel

 

That explains it: Constructor expected (incorrectly) 2 input series, i.e. :base(2), which was an error I was going to get to after this one. Removing it eliminates all errors.

So is there any way to have BarData access, Argument access,  and Input Series access too?

 

thx


DoQ_Indicators
"better is the enemy of good enough"

Edited: Friday July 06 2007 by DoQ
Posted Friday July 06 2007
DoQ (7/6/2007)
So is there any way to have BarData access, Argument access,  and Input Series access too?

All indicators can have constructor arguments.  But you need to choose between a "Series Calculator" which takes input series, and an "Indicator" which gets bar data.

There are ways to use both, but they are slightly more complicated.  You can use a series calculator and just define a seperate input series for each bar element you need access to.

Alternatively, you can implement the ISystemAccess interface in your series calculator.  The Initialize method will be called, passing in a reference to the SystemData instance, as well as which symbol the indicator is tied to.  You can then access the bar history for that symbol through the SystemData object.

Note that if you use ISystemAccess, your indicator will only work from within a trading system.  In other words, you won't be able to drag and drop it directly onto a chart, since in that case there is no SystemData object.

Thanks,
Daniel



Similar Topics


Reading This Topic


2005-2017 © RightEdge Systems