NeoTicker Forums  

Go Back   NeoTicker Forums > NeoTicker > Programming Discussion

Reply
 
Thread Tools Rating: Thread Rating: 6 votes, 5.00 average. Display Modes
  #1  
Old 02-18-2008, 01:50 AM
greaterreturn greaterreturn is offline
Regular User
 
Join Date: Feb 2008
Posts: 63
Contribution: C# Class for TrendLine Easy!!!

Folks, it now only takes these three lines to create a TrendLine....

TrendLine tl = new TrendLine();
tl.setStartPoint(40, data1.get_Close(40));
tl.setEndPoint(0, data1.get_Close(0));

That's thanks to a TrendLine C# class I created that wraps the NeoTicker interface. Several features of the class:

1. setStartPoint and setEndPoint auto convert the X bar coordinates to a date.
2. The TrendLine defaults to visible instead of the NT default of invisible.
3. The width defaults to 2 which is reasonable.
4. You can call setWidth() to override.
5. And you can call setDefaultWidth() to change the default width.
That way, the default width gets used for any new TrendLine objects.

Therefore, most of the time you simply set start and end point and your done.

I haven't figured out yet how to set the color. But the color should work the same way with a default.

Are you wondering how to get the class that does this magic? Here it is!
NOTE: You might need to change the using Neoticker at the top of each file to Interop.Neoticker depending on your version of the DLL. Just try whichever one compiles.

NOTE: Actually I'm including two classes. The second class, NTObj, holds commonly uses indicator Objects references as static variables so you don't have to be pass them into every drawing object.

My goal is to hide the complexity of the NT API in wrapper classes so that my core strategy code focuses only on that--the strategy!

Please let me know if you got any use out of this. Or post any and all improvements. Especially if you get the color setting to work!

/*
* Created by SharpDevelop.
* User: Compaq_Owner
* Date: 2/18/2008
* Time: 12:13 AM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/

using System;
using NeoTicker;

namespace NTUtil
{
/// TrendLine wrapper to simplify using NeoTicker trendlines.
public class TrendLine
{
private IDrawingObjectsObj drawingObjs;
private int id;
private static int defaultWidth = 2;
public TrendLine()
{
drawingObjs = NTObj.indicatorObjects.DrawingObjects();
id = (int) drawingObjs.Add( ChartObjectType.cotTrendline);
drawingObjs.set_YStyle(id, ChartObjectCoordinate.cocValue);
// Default to visible. Silly to have to turn this on each time.
setVisible(true);
setWidth(defaultWidth);
}
// This function makes the TrendLine appear fixed on the screen at
// certain percentage from left and right or up and down.
public void setScreenPercent() {
drawingObjs.set_XStyle(id, ChartObjectCoordinate.cocPercent);
drawingObjs.set_YStyle(id, ChartObjectCoordinate.cocPercent);
}
public void setStartPoint( int bar, double value) {
drawingObjs.set_XStyle(id, ChartObjectCoordinate.cocValue);
drawingObjs.SetPoint(id, 0, NTObj.ItSelf.get_DateTime(bar), value);
}
public void setEndPoint( int bar, double y) {
drawingObjs.set_XStyle(id, ChartObjectCoordinate.cocValue);
drawingObjs.SetPoint(id, 1, NTObj.ItSelf.get_DateTime(bar), y);
}
public void setWidth(int width) {
drawingObjs.set_PenWidth(id, width);
}
public void setColor(int color) {
// drawingObjs.set_Color(id, color);
}
public void setVisible(bool visible) {
drawingObjs.set_Visible(id, visible);
}
public void setDefaultWidth(int width) {
defaultWidth = width;
}
}
}


/*
* Created by SharpDevelop.
* User: Compaq_Owner
* Date: 2/18/2008
* Time: 1:35 AM
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/

using System;
using NeoTicker;

namespace NTUtil
{
/// <summary>
/// Description of NTObjects.
/// </summary>
public class NTObj
{
public static NTIndicatorObjects indicatorObjects;
public static IItselfObj ItSelf;
public static IDataObj data1;
}
}
Reply With Quote
  #2  
Old 02-18-2008, 08:00 AM
Bruce DeVault's Avatar
Bruce DeVault Bruce DeVault is offline
Regular User
 
Join Date: Jul 2006
Location: Washington DC
Posts: 9,246
If you're adding a COM reference in your project to NeoTicker (and providing your own interop file), the usage would be "using NeoTicker". If you're using the default distribution interop file, the usage would be "using interop.NeoTicker".

There are a number of things worth comment here. First, if you're saving a static class-wide reference to NTIndicatorObjects, for best practices you should update it at the start of each IDLCallEx, because it's not strictly speaking guaranteed not to change. You didn't post this part of your code, but I want to make sure you know about this just in case. It may happen to work if you don't do this, but that doesn't mean the next build won't break it.

If you're planning to save a persistent copy of your trend line class object between invocations to IDLCallEx and not just use this object entirely within a single invocation, you have a philosophical problem as follows: you're saving a private int "id" in the trend line class, but in fact, this is an index into an array in NeoTicker API. In other words, if you add two trendlines, the first id will be "0", and the second "1". If you then delete the first one, the second trend line added will be "0". Your saved private variable "id" will still say 1, which will make you unable to control the trendline.

If you're wanting to control them between IDLCallEx invocations, you should set a tag property to something unique, so that you can find them again. As an example, you could have a static count of all of the trend line objects you've ever created, and then when you create one, set the Tag to some unique constant / magic number plus that count, and save the Tag in your private variable. Then, in later IDLCallEx invocations, you can look up the current "id" by the saved Tag using GetIndexByTag.

It's important that you understand "id" isn't persistent - as a concept it's an index into an array that's valid only while you don't delete any of the earlier elements in the array, so it makes me nervous to see you saving this across invocations - that makes me think you don't yet realize it can change.

There are some valid reasons to not have drawing objects be visible by default. It's in keeping with general Windows graphics programming principles that say you don't want things you create to flicker - if you create them (visible) and then set them invisible, you may see a flash, whereas if you create them invisible, and set them visible, it looks normal. I understand what you're saying about creating a class that has some "common defaults" for the way you like to do things, but understand NeoTicker caters to a very wide variety of interests including sophisticated commercial ones, and they need the most general functionality possible.

The color property is in fact the right way to set the color of a trendline. Remember the argument to the set_Color accessor is an RGB color (integer). Try for instance sending it the number 255 for red.

There are plenty of folks who can give you feedback on this type of project, but these are a few of the sorts of things to consider at the outset. The NeoTicker API architecture doesn't always lend itself to creating an object for everything... and in some cases, providing an object wrapper for something that doesn't act like an object on the inside means doing a lot of busywork behind the scenes to fit a square peg into a round hole, so to speak. In most ways, the NeoTicker API is optimized for performance (hence array accessors rather than list objects with iterator interfaces, etc.), and NeoTicker is also language independent, so as such, all of the NeoTicker API needs to work equally well in every supported language, many of which are not object oriented at all (e.g. DelphiScript, etc.). What this means is that you definitely can make an object around the outside some of the NeoTicker features, and lots of folks have done this for their own projects - but you need to be prepared that they won't always act like an object on the inside and this means not a small amount of busywork to make the transition and to control for the unexpected.
__________________
Bruce DeVault
bdevault@quantevo.com
www.quantevo.com

Last edited by Bruce DeVault; 02-18-2008 at 09:40 AM.
Reply With Quote
  #3  
Old 02-18-2008, 09:43 AM
Bruce DeVault's Avatar
Bruce DeVault Bruce DeVault is offline
Regular User
 
Join Date: Jul 2006
Location: Washington DC
Posts: 9,246
For an example of exactly how this type of color definition works internally (how it knows how much red, etc. to display) see my example at http://forums.neoticker.com/showpost...2&postcount=14 which demonstrates a dynamically changing plot color.
__________________
Bruce DeVault
bdevault@quantevo.com
www.quantevo.com
Reply With Quote
  #4  
Old 02-18-2008, 05:09 PM
han's Avatar
han han is offline
Regular User
 
Join Date: Jan 2006
Posts: 721
Quote:
1. setStartPoint and setEndPoint auto convert the X bar coordinates to a date.
Great of you to share the fruits of your exploration, greaterreturn. Does the above quote mean this great contribution is specific to time based charts, or is there are a way to apply it to tick based and superposition charts?
Reply With Quote
  #5  
Old 02-18-2008, 05:15 PM
greaterreturn greaterreturn is offline
Regular User
 
Join Date: Feb 2008
Posts: 63
Wow. That was very useful !

Bruce,


1. First, the problem with color is that the name of the color is undefined in C# and I can't figure out by guess work, which class contains that enum. I figured out the rest. So how to I get it included? Or just define my own RGB colors, I guess.

2. Second, I noticed the ability to set a tag without understanding why. Now I do understand.

So to answer your question, I think these trendlines should stay persistent between bars so it's easy to get the current value on a later bar. I see the documentation for scripts has an easy reference to compare the value later. I want that too. So maybe it's just another call to the IDL.

Therefore, I will implement the tag setting suggestion.

Also, that feature will generally apply to all the drawing objects so I can extract it to a "DrawingObject" class as a super class to the rest.

Right now, I only needs some moving averages and trendlines, but this could expand.

Also, I'm not criticising the IDL interface. It's AWESOME. It allows us to code in a variety of languages like C#!!!!

However, a lightweight framework for C# will be very helpful when it solves these issues you bring up.

3. Your wonderful point about setting the static variable at the start of each bar is very good and at least that part I already accounted for. In fact, I'm visioning making a standard MainIDL class that does these things and any other necessary setup at the beginning of each call and then calls out to the main "Strategy" or "Indicator" class..

4. I'm wondering Bruce, if threading is an issue with multiple charts, strategies running? My thought is to set all of these fresh each time because it might be a different thread calling with different ID's, etc. Secondingly, I think the MainIDL should instantiate a fresh Strategy object for each time for the same reason. That way the Strategy class can do it's job without concern for threads.

Your programming talent is outstanding. I feel indepted for the time you spent analyzing this!!!! And I will use your advice.

Sincerely,
Wayne
Reply With Quote
  #6  
Old 02-18-2008, 05:16 PM
Bruce DeVault's Avatar
Bruce DeVault Bruce DeVault is offline
Regular User
 
Join Date: Jul 2006
Location: Washington DC
Posts: 9,246
Quote:
Originally Posted by han
Great of you to share the fruits of your exploration, greaterreturn. Does the above quote mean this great contribution is specific to time based charts, or is there are a way to apply it to tick based and superposition charts?
If you take a look at the methods above, they pull the datetime for a given bar. If you're using bar-driven mode, you would use cocExact instead and specify the bar number as the X axis directly. You could easily modify the methods to do this.
__________________
Bruce DeVault
bdevault@quantevo.com
www.quantevo.com
Reply With Quote
  #7  
Old 02-18-2008, 05:25 PM
Bruce DeVault's Avatar
Bruce DeVault Bruce DeVault is offline
Regular User
 
Join Date: Jul 2006
Location: Washington DC
Posts: 9,246
Quote:
Originally Posted by greaterreturn
4. I'm wondering Bruce, if threading is an issue with multiple charts, strategies running? My thought is to set all of these fresh each time because it might be a different thread calling with different ID's, etc. Secondingly, I think the MainIDL should instantiate a fresh Strategy object for each time for the same reason. That way the Strategy class can do it's job without concern for threads.
Currently, there is only a single thread which runs all NeoTicker indicators on a time chart in series. This is because determining the dependency chain can be complex, and because of the need to support some fairly simplisticly implemented scripting languages that really don't handle multithreading. There is some discussion of this changing in the future, but at the present moment you can assume that you won't be called from multiple threads at the same time. You can determine which instance of the indicator you have if there is more than one by referencing ItSelf.UniqueId, and you'll typically use this to keep your instances separated with their own local information in objects.

Unlike the other supported languages such as Delphi, etc. different IDL definitions referencing the same .NET DLL file do not run in the same context, so if you have class-level static variables, they'll only be shared across instances of the same IDL file / function name (which you can identify with ItSelf.FuncName).
__________________
Bruce DeVault
bdevault@quantevo.com
www.quantevo.com

Last edited by Bruce DeVault; 02-18-2008 at 05:29 PM.
Reply With Quote
  #8  
Old 02-18-2008, 05:30 PM
greaterreturn greaterreturn is offline
Regular User
 
Join Date: Feb 2008
Posts: 63
Han,

My plan for handling bar charts would be the following:

In the other post I linked to above, Bruce said the indicator can ask NT whether it's on a bar or time chart. I plan to add that into the class so it automatically just "knows".

In that case, you can STILL pass in a bar number to the function and it will internally translate it to the correct time.

Are you a programmer? I'm willing to add that for you.

Automated trendlines are crucial to my personal strategy so I'm willing to work on perfecting this. I'll eventually use all the features. Then other can imitate the code and hopefully suffer less figuring it all out.

Sincerely,
Wayne
Reply With Quote
  #9  
Old 02-18-2008, 05:32 PM
Bruce DeVault's Avatar
Bruce DeVault Bruce DeVault is offline
Regular User
 
Join Date: Jul 2006
Location: Washington DC
Posts: 9,246
Quote:
Originally Posted by greaterreturn
In the other post I linked to above, Bruce said the indicator can ask NT whether it's on a bar or time chart. I plan to add that into the class so it automatically just "knows".

In that case, you can STILL pass in a bar number to the function and it will internally translate it to the correct time.
Use ItSelf.TimeDriven to determine if you are in time-driven charting mode. If the return is false, you're in bar-driven charting mode. In bar-driven charting mode, you can use cocExact for the X-axis and send the bar number directly, which is more precise for the case where there are multiple bars per second, since DateTime has a precision of 1 second.
__________________
Bruce DeVault
bdevault@quantevo.com
www.quantevo.com
Reply With Quote
  #10  
Old 02-19-2008, 12:25 AM
greaterreturn greaterreturn is offline
Regular User
 
Join Date: Feb 2008
Posts: 63
Bruce,

I did all the above. I removed Visible as a default. It stores the tag now instead of the id and gets the id as needed. Color works now also.

One big improvement is that I made a DrawingObject that has all the basics like color, width, setPoint. That will makes TrendLine class and any others we want to create much easier.

I also made it internally smart about whether it's on a bar chart or time driven chart.

NOTE: I also added a setScreenPercent() to use the other feature of drawing a fixed line on the screen. But I can't get that to work, and don't care right now since I don't need that. If you see what's wrong with the code, I'll fix it.

To test it, I made different lines to for observing all the features.

It works on time charts, but on bar charts, I can't figure out how to get enough bars to display to them all because I'm still climbing the learning curve on the user interface. But it's only been 2 days.

I'll have time again on Wednesday to post all the code.

All in all, I'm quite happy with NeoTicker. The big features I was looking for was a full fledged programming language with debugger and object oriented ability, using my brokers API and data, and the other backtesting and portfolio pieces.

It's exciting to be using a real IDE with debugger and code completion. I hope somebody can get me an newer DLL that supports code completion.

Wayne
Reply With Quote
  #11  
Old 02-19-2008, 08:23 AM
Bruce DeVault's Avatar
Bruce DeVault Bruce DeVault is offline
Regular User
 
Join Date: Jul 2006
Location: Washington DC
Posts: 9,246
Wayne,

I've provided step-by-step instructions in the thread http://forums.neoticker.com/showthread.php?t=10081 on how to use the Interop.NeoTicker namespace and still have code completion working. It's not that the DLL doesn't support code completion per se (this is an IDE feature, not a feature of the DLL), but your reference is just to the wrong file. Just let us know if any questions.
__________________
Bruce DeVault
bdevault@quantevo.com
www.quantevo.com

Last edited by Bruce DeVault; 02-19-2008 at 08:27 AM.
Reply With Quote
  #12  
Old 02-19-2008, 08:29 AM
Bruce DeVault's Avatar
Bruce DeVault Bruce DeVault is offline
Regular User
 
Join Date: Jul 2006
Location: Washington DC
Posts: 9,246
Quote:
Originally Posted by greaterreturn
NOTE: I also added a setScreenPercent() to use the other feature of drawing a fixed line on the screen. But I can't get that to work, and don't care right now since I don't need that. If you see what's wrong with the code, I'll fix it.
Make sure XStyle and YStyle are cocPercent, then you can use SetPoint on the two corners to position it relative to the time chart function window's client area.
__________________
Bruce DeVault
bdevault@quantevo.com
www.quantevo.com
Reply With Quote
  #13  
Old 02-19-2008, 08:30 AM
Bruce DeVault's Avatar
Bruce DeVault Bruce DeVault is offline
Regular User
 
Join Date: Jul 2006
Location: Washington DC
Posts: 9,246
Quote:
Originally Posted by greaterreturn
It works on time charts, but on bar charts, I can't figure out how to get enough bars to display to them all because I'm still climbing the learning curve on the user interface. But it's only been 2 days.
Right click on the chart and use Chart Manager, Data Settings tab to increase the number of days to load.
__________________
Bruce DeVault
bdevault@quantevo.com
www.quantevo.com
Reply With Quote
  #14  
Old 05-14-2008, 11:00 AM
han's Avatar
han han is offline
Regular User
 
Join Date: Jan 2006
Posts: 721
Greaterreturn, has the code in your first post been updated with the improvements you made? I'd like to try it. Thanks for teaching it to differentiate between bar and time-driven charts. (Missed your question above -- yes I am a programmer, using Delphi)

Han

Last edited by han; 05-14-2008 at 11:15 AM.
Reply With Quote
Reply

Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 01:49 AM.


Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Copyrightę 2000-2010 TickQuest, Inc.