SmartQuant Discussion

Automated Quantitative Strategy Development, SmartQuant Product Discussion and Technical Support Forums
It is currently Fri Oct 23, 2020 3:02 pm

All times are UTC + 3 hours




Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Fri Aug 22, 2008 1:07 pm 
Offline

Joined: Tue Aug 05, 2003 3:43 pm
Posts: 6817
OpenQuant offers a possibility to develop custom user indicators and use such user indicators in OpenQuant strategy.

You can develop a custom indicator as a dll in MS Visual Studio and add to OpenQuant as a reference. You can exchange your custom indicators with another OpenQuant users this way (without need to disclose indicator code if you don't want to). Alternatively, you can add indicator code right before strategy code in OpenQuant editor and use it in this strategy.

In order to start writing a user indicator you should add

Code:
using OpenQuant.API.Plugins;


Any user indicator should derive from the UserIndicator class defined in the OpenQuant.API.Plugins namespace.

Developing a user indicator in the OpenQuant framework is quite simple. All you need to do is to override the Calculate(int index) method of the UserIndicator class using Input property of UserIndicator class.

The Input property is a reference to indicator input time series. It has ISeries type, so that it can be BarSeries, TimeSeries or another Indicator (this way you can develop indicator of indicator).

The Calculate(int index) method should return indicator value calculated for the index-th element in the Input series. It should return Double.NaN if there is no indicator value for the index-th element of the Input series (usually in case of indicators that require several past values of Input time series, for example simple moving average or momentum indicators).

Let's develop a simple Accumulated Money Flow (AMF) indicator as an example. The simplest formula will be making an upday volume negative and a down day volume positive and then adding up all the buy/sell volume from date from which the data became available.

We create a new class that we call AMF and derive this class from UserIndicator class. Then we add a constructor of AMF class that takes BarSeries as input.

Code:
public class AMF: UserIndicator
{
   public AMF(BarSeries input) : base(input)
   {
      Name = "AMF";
   }
}


Note that we use the Name property of te UserIndicator class to give a name to our indicator. This name will be displayed on the Bar chart and elsewhere.

Now if we write

Code:
AMF indicator = new AMF(Bars);


in our strategy, we will create an AMF indicator called "AMF" and Input property assigned to the Bars series of our strategy.

Now we need to override the Calculate method of our AMF indicator.

Code:
public class AMF: UserIndicator
{
   double volume = 0;

   public AMF(BarSeries input) : base(input)
   {
      Name = "AMF";
   }

   public override double Calculate(int index)
   {
      if (index > 1)
      {
         if (Input[index, BarData.Close] > Input[index-1, BarData.Close])
            volume += Input[index, BarData.Volume];
         else
            volume -= Input[index, BarData.Volume];
         
         return volume;
      }
      else
         return Double.NaN;      
   }
}


Note that we can use two techniques to work with the Input property. We can either cast it to a specific series type and use this type in our calculations, for example

Code:
BarSeries bars = Input as BarSeries;

double close = bars[index].Close;


or we can use common indexers of ISeries interface.

Code:
double close = Input[index, BarData.Close];


We use the latter techniques in our Calculation method.

The rest of Calculate code is quite simple. First we check that we have enough elements in the Input series to access previous element (bar) of the Input series. We return Double.NaN if there is no previous bar. If we do have a previous bar, we compare closing prices of the current (index) bar and previous (index - 1) bar and then adjust volume class variable accordingly.

Now we can add our indicator to a strategy and draw it on the strategy bar chart.

Code:
using System;
using System.Drawing;

using OpenQuant.API;
using OpenQuant.API.Indicators;
using OpenQuant.API.Plugins;

public class AMF: UserIndicator
{
   double volume = 0;

   public AMF(BarSeries input) : base(input)
   {
      Name = "AMF";
   }

   public override double Calculate(int index)
   {
      if (index > 1)
      {
         if (Input[index, BarData.Close] > Input[index-1, BarData.Close])
            volume += Input[index, BarData.Volume];
         else
            volume -= Input[index, BarData.Volume];
         
         return volume;
      }
      else
         return Double.NaN;      
   }
}

public class MyStrategy : Strategy
{
   public override void OnStrategyStart()
   {
      AMF AMF = new AMF(Bars);
      
      AMF.Color = Color.White;
      
      Draw(AMF, 2);
   }

   public override void OnBar(Bar bar)
   {
   }
}


Note that there are several other examples of user indicators included in the OpenQuant installation. They can be found in the Samples folder in OpenQuant Windows menu.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 12, 2009 11:46 pm 
Offline

Joined: Wed Mar 11, 2009 9:54 pm
Posts: 63
Hello, I User = new User(dased, confused, HELP!);

Please clarify a few Q for me:
1. How can I create a namespace for all custom indicators
2. In VS 2008 System.Drawing; generates error".. namespace does not exist in...namespace System?
3. If I manage somehow to create indicator with dll how to reference this in strategy?
4.Datatype conversion: double to BarSeries is it even possible?
5.What is script explorer for? Anyway creating an indicator as solution or project or script generates an error - No Strategy present

Before I write a strategy I just need to develope indicators and then use them as efficient as possible any sugestions is HIGHLY welcome!

Thank you. :oops:

_________________
xtrender


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 13, 2009 2:04 pm 
Offline

Joined: Tue Aug 05, 2003 3:43 pm
Posts: 6817
What is double to BarSeries conversion exactly?

Regards,
Anton


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 13, 2009 3:44 pm 
Offline

Joined: Wed Mar 11, 2009 9:54 pm
Posts: 63
Anton,

My appologies for posting the same Q several times.
I have explained what double to BarSeries conversion is in another post.
But again some methodes that take ISeries objects as inputs return double value. This value then needs to be passed into the indicator like SMA or RSI or MOM...However SMA doesnt have overload SMA(double, int) thus the need to convert back to BarSeries or TimeSeries type.
As Curios1 eplained this to me .Add method of TimeSeries does just that.
TimeSeries RangeSeries = new TimeSeries();
RangeSeries.Add(Bar.DateTime, range);

Amasing that I could not find any examples with Add conversion in many hours of forum search. Now it is in at least 4 posts :twisted:

I will apreciate if you can brifly reply on question 2 and 3.
Thank you for help.

_________________
xtrender


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 13, 2009 4:07 pm 
Offline

Joined: Tue Aug 05, 2003 3:43 pm
Posts: 6817
2.

OpenQuant installation folder -> Samples -> Sample Indicators...

Just put all indicators in another project in the same solution and you will have them as dll.

3.

a) Tools -> Options -> Project and Solutions -> Build -> Add Reference
b) add Using MyIndicators; or something to your stratgey

Regards,
Anton


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 13, 2009 10:56 pm 
Offline

Joined: Wed Mar 11, 2009 9:54 pm
Posts: 63
Dr. Anton,

Could you please expand your example above and include OnBar method implementation as well as where one can put Init() method. The calculate function you have used in your example return volume but how do I call this volume from OnBar method ?
I have tried to use init and ran into "no suitable method to override "?
I also am wondering about the equivalent on NinjaTrader brackets[] like:Close[0]
The varName.Ago(1) gives an exception that the series is too short?

My appologies for countless questions

Thank you.

_________________
xtrender


Top
 Profile  
 
 Post subject:
PostPosted: Sun Mar 15, 2009 12:31 pm 
Offline

Joined: Tue Aug 05, 2003 3:43 pm
Posts: 6817
You can use this cutom indicators as any other indicator. Please take a look at sample strategies from OpenQuant installation (Bollinger Bands or SMA crossover).

Indeed if you have no or one element in your series Ago(1) would generate an exception... You should check that your series is not too short using Series.Count ;

Regards,
Anton


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 16, 2009 8:23 pm 
Offline

Joined: Wed Mar 11, 2009 9:54 pm
Posts: 63
Hello Dr.Anton,

I have created indicator as dll (VS 2008 class library),it is saved as solution, now how do I import or save this dll to OQ?

Also if you can please clarify for me in the code bellow do I need to populate TimeSeries RSIseries via Add method? And if yes what should I pass in as second argument?

private TimeSeries RSISeries;

public UserMadeIndicator(ISeries series, int length, BarData barData)
: base(series)
{
this.length = length;
this.Name = "User Indicator, Length = " + length;
this.barData = barData;
IndicatorSeries = new TimeSeries();
}
public UserMadeIndicator(ISeries series, int length)
: this(series, length, BarData.Close)
{
}


public double CalculateUserIndicator (int index)
{

if (index >= length)
{


RSI1 = new RSI(RSISeries, RSILength);
SMA1 = new SMA(RSI1, SMALength1);

double result = SMA1.Last;

// RSISeries.Add(Input.GetDateTime(index), ????????? );

return result;
}
else
return Double.NaN;

}
}
I am having realy hard time to transfer indicators from NinjaTrader to OQ
I would truly apreciate your help

Sincerely,

_________________
xtrender


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 17, 2009 5:04 am 
Offline

Joined: Wed Mar 11, 2009 9:54 pm
Posts: 63
OK, I am getting somewhere...the land of confusion...
It compiles, but...
What this exception means?
I have added dll reference and copied the project(solution) into OQ project
folder
Method OnStrategy Start
Could not load file or assembly...Custom.dll,Version=1.0.0.0,
Culture=neutral,PublickKeyToken=null' or one of it dependencies. The sytem cannot find the fole specified

using System;
using System.Drawing;

using Custom_Indicators_dll;//custom dll

using OpenQuant.API;
using OpenQuant.API.Indicators;

public class MyStrategy : Strategy
{
BarSeries compSeries;
public override void OnStrategyStart()
{
compSeries = new BarSeries();
UserCompInd CompInd = new UserCompInd(compSeries,14);
CompInd.Color = Color.Yellow;
Draw(CompInd, 0);
}

public override void OnBar(Bar bar)
{
compSeries.Add(Bar);
Console.WriteLine("{0}, {1}", bar.DateTime, bar.Close);
DataManager.Add(Instrument, bar);
BuyLimit(1, bar.Close);

}
}

I am sooo LOST, PLEASE HELP.

_________________
xtrender


Top
 Profile  
 
 Post subject:
PostPosted: Tue Mar 17, 2009 4:05 pm 
Offline

Joined: Wed Mar 11, 2009 9:54 pm
Posts: 63
Good Morning Dr. Anton,

I am just going to post my progress with dll, just to save time.
I have created a second test dll fro sample UserRSI indicator and I have got the same exception. So it is obvious this solution must be imported somehow to OQ. Just adding a reference seems to be not enough. Strategy compiles, but at run complains that file can not be found.
What is the procedure that one should follow to use indicator as dll?
Or maybe it is a bug in OQ?

Thank you.

_________________
xtrender


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 19, 2009 11:49 pm 
Offline

Joined: Wed Mar 11, 2009 9:54 pm
Posts: 63
No Bugs...It works :P

_________________
xtrender


Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 03, 2009 7:00 pm 
Offline

Joined: Sat Sep 26, 2009 12:08 am
Posts: 62
Location: Ireland
How do I add the indicators in my custom indicators dll to OQ's list of standard fx Indicators?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 04, 2009 1:45 pm 
Offline

Joined: Thu Sep 20, 2007 6:43 pm
Posts: 122
Location: Poland
Hi :)

warren631 wrote:
How do I add the indicators in my custom indicators dll to OQ's list of standard fx Indicators?


You can't add your custom indicators to standard indicators.

Regards
MaRCHeW

_________________
"Your worst day with OpenQuant is better than your best day with most of the other stuff."


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 15, 2009 1:24 am 
Offline

Joined: Thu Jun 08, 2006 3:56 pm
Posts: 537
Location: BC Canada
I looked at all the sample user indicators in the OQ Samples directory, but could not find one that accepted both a TimeSeries and BarSeries as an input ISeries.

In particular, I don't know how to reference the Input series if the indicator was actually constructed by passing in a TimeSeries. Could someone please post a code example to this thread showing how?

Here is what I want to do:
Code:


// constructor
public
MyIndic (ISeries series)
    : base (series) {
    Name = "MyIndic";
}

public
MyIndic (ISeries series, int length)
    : base (series) {
    // this constructor accepts any ISeries type as input
    // so you can feed it TimeSeries or BarSeries or Indicator types
    // Notice I use BASE (series) in this constructor
    m_Length = length;
}

public
MyIndic (TimeSeries series, int length)
    : this (series) {
    // this constructor accepts a TimeSeries as input
    // but you don't need it if you have the constructor above
    // Notice I use THIS (series) in this constructor
    m_Length = length;
}

public
MyIndic (BarSeries series, int length)
    : this (series) {
    // this constructor accepts a BarSeries as input
    // but you don't need it if you have the constructor above
    // Notice I use THIS (series) in this constructor
     m_Length = length;
}

public override double
Calculate (int idx) {

    // if input was a TimeSeries, I would want to use
    double foo = Input[idx];

    // if input was a BarSeries, I would want to use
    double foo = Input[idx, BarData.Close];

    // But because the syntaxes are different, the same line of code
    // cannot be used to access both Bar and Time series.

    // So I tested for the data type of the series, and wrote 
    // two blocks of code, one to work with TimeSeries and
    // one to work with BarSeries, like so:

    // now test for the input series and use the appropriate syntax
    if (Input is BarSeries)
         foo = Input[idx, BarData.Close];

    else if (Input is TimeSeries) {
         // convert idx number to something for Input.Ago(ago_idx)
         int ago_idx = cv_idx_to_ago(idx);
         foo = Input.Ago(ago_idx);

         // I had to use Ago(ago_idx) instead of Input[idx] because I
         // got a "no overload for 'this' takes 1 argument" error.
         // Which means that no Input method overload in the
         // UserIndicator class takes 1 input, I guess.
     }
 
    else if (Input is Indicator) {
        // I never tried this, but I think it would be the same as
        // TimeSeries, so you would probably have to use Ago.
     }

    return foo;
}

private int
cv_idx_to_ago (int idx) {
    // suppose there are count=4 elements in Input: idx = 0, 1, 2, 3
    // idx 3 = ago 0 = ago (count - idx - 1) = (4 - 3 -1) = 0
    // idx 2 = ago 1 = ago (count - idx - 1) = (4 - 2 -1) = 1
    // idx 1 = ago 2 = ago (count - idx - 1) = (4 - 1 -1) = 2
    return Input.Count - idx - 1;
}


This kind of code structure worked fine, and now my indicator can accept both TimeSeries and BarSeries as input series.

Here is another good thread on user indicators:

http://www.smartquant.com/forums/viewtopic.php?t=7203&highlight=sum+userindicator


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 05, 2010 10:13 pm 
Offline

Joined: Tue Feb 23, 2010 10:25 pm
Posts: 5
Location: Poland
Hi,

im trying to develop an indicators with 2 diference timeframe.
But all of my idea doesn't work.

This doesn't work in indicator(I try use 2 barserie in userindicator):
Code:
SMA(GetBars(6000), period)


This doesn't work in OnStrategyStart(i Try send as parameter two different barseries):
Code:
bar=GetBars(6000);


It's possible to use two different timeframe in userindicator?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC + 3 hours


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group