API Support Forum
OEC API > User Interface > How do I debug Custom Indicators written in C#
Author Topic: How do I debug Custom Indicators written in C#
(6 messages, Page 1 of 1)
Moderators: VPfau
JGronemus87
Posts: 14
Joined: Nov 28, 2007


Posted: May 27, 2010 @ 11:12 AM             Msg. 1 of 6
Hello,

I'm writing some custom indicators in C#. How do I debug the code? I tried writing variables to a file, but there are security exceptions thrown. I tried displaying variables in a messagebox, but same security problem.

It is difficult to debug the logic if I can't see the variable values.

Thanks
John

John
VictorV
Posts: 746
Joined: May 08, 2007


Posted: Jun 01, 2010 @ 11:56 AM             Msg. 2 of 6
Hello,

you can use void Print(params object[] p) method or Log field (that is LogWriter class) of CustomIndicator class to place text to the log file. You can find out this log file in the next folder: Documents and Settings\<your windows username>\Local Settings\Application Data\OEC\OEC Trader\Demo 3.5 or Prod 3.5. These files will have extension *.ci
JGronemus87
Posts: 14
Joined: Nov 28, 2007


Posted: Jun 03, 2010 @ 02:34 PM             Msg. 3 of 6
Can you give a code example? I tried the following and was not able to find the *.ci file.

// Can't find Log file.
public override void Recalculate(RecalculateArg arg)
{
Print(arg.Stock);
}


// Can't find Log file.
public override void Recalculate(RecalculateArg arg)
{
Log.WriteLine("Hello From Recalculate");
}


I tried this and was able to produce the *.ci file after I exited the program...


// Can't find Log file.
public override void Recalculate(RecalculateArg arg)
{
throw new Exception("Hello From Recalculate");
}


thanks,
John

John
VictorV
Posts: 746
Joined: May 08, 2007


Posted: Jun 04, 2010 @ 08:58 AM             Msg. 4 of 6
John,

this is correct code (all three of them).

actually, OEC Charts loads indicators to memory as an "untrusted" assemblies in two cases: the indicator is included in a package from Indicator Store or compiled binary file has DLL extension (for example, it is compiled by third-party tools to like Visual Studio). In this case, you need to mark the package or DLL as "trusted" in Custom Indicator Library ("Trust" menu item in right-click menu). After that you can use any available .NET functionality without restriction from OEC Charts.

Victor Vins
Software Developer
JGronemus87
Posts: 14
Joined: Nov 28, 2007


Posted: Jun 04, 2010 @ 10:56 AM             Msg. 5 of 6
I have more details...

I'm running Windows Vista. Not sure if that makes a difference with it's different security model. Also, I'm not using a deployed indicator. I'm just writing and indicator myself so there is no way to set it to "Trust" as it is not a deployed binary.

Attached is the exception that gets thrown when I use the following code...

using(StreamWriter w = File.AppendText("log.txt"))
{
w.WriteLine("Contructor Called");
w.Close();
}

This same exception is thrown if I have it in the Recalculate Method. Is there a security attribute on the method that I need to set or something?

There is no exception thrown if I use the "Log" and "Print" methods of the CustomIndicator class (at least no exception that is not caught). I just can't find the ci file that gets created.

There is something else going on here and I think it has to do with Vista security. I tried running OECTrader with Administrator privileges, but that didn't work either.

Let me know if you have any other suggestions.

Thanks,
John

Here is the exception....

An error occurred. Please contact support with following information:

6/4/2010 9:45:30 AM, Rhythm Trader Demo 3.5 Ver:3.5.0.9, User:JGronemus12, OS: Microsoft Windows NT 6.0.6002 Service Pack 2
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.StreamWriter.CreateFile(String path, Boolean append)
at System.IO.StreamWriter..ctor(String path, Boolean append, Encoding encoding, Int32 bufferSize)
at System.IO.StreamWriter..ctor(String path, Boolean append)
at System.IO.File.AppendText(String path)
at OEC.Chart.Custom.Sandbox.LOSKP..ctor()
The action that failed was:
Demand
The type of the first permission that failed was:
System.Security.Permissions.FileIOPermission
The first permission that failed was:
<IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Append="C:\Program Files\Rhythm Trader\Demo 3.5\log.txt"/>

The demand was for:
<IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Append="C:\Program Files\Rhythm Trader\Demo 3.5\log.txt"/>

The granted set of the failing assembly was:
<PermissionSet class="System.Security.PermissionSet"
version="1">
<IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Read="C:\Users\jgronemus\AppData\Local\OEC\CustomIndicators\bin.3.5.0.9\;C:\Program Files\OEC\Plugins\demo 3.5\;C:\Program Files\Rhythm Trader\Demo 3.5\"
PathDiscovery="C:\Users\jgronemus\AppData\Local\OEC\CustomIndicators\bin.3.5.0.9\;C:\Program Files\OEC\Plugins\demo 3.5\;C:\Program Files\Rhythm Trader\Demo 3.5\"/>
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="Execution"/>
<IPermission class="System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Window="AllWindows"/>
<IPermission class="System.Security.Permissions.StrongNameIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
PublicKeyBlob="002400000480000094000000060200000024000052534131000400000100010019C33EAC3BD6CD5E685AF01C9BE78CEEE0A937EA92FD9CB60BCE384A49D5B1189A903A64BCCD5D24C939B9A2C0483F5A628C8CDFD195F243D1A3715EAE163DB44A01D2E665A0C072D32B559A1764E061175D0AF271E2410D3B6685EF1AED36E97C01AC55E0E893C5A269E8CC65C44A70BF200EB5443BF128EF9EB7916E207FCD"
Name="Trader"
AssemblyVersion="3.5.0.9"/>
<IPermission class="System.Security.Permissions.UrlIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Url="C:\Users\jgronemus\AppData\Local\OEC\CustomIndicators\bin.3.5.0.9\LOSKP.ind"/>
<IPermission class="System.Security.Permissions.ZoneIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Zone="MyComputer"/>
</PermissionSet>

The assembly or AppDomain that failed was:
LOSKP, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
The Zone of the assembly that failed was:
MyComputer
The Url of the assembly that failed was:
C:\Users\jgronemus\AppData\Local\OEC\CustomIndicators\bin.3.5.0.9\LOSKP.ind
--- End of inner exception stack trace ---
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandle& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean fillCache)
at System.RuntimeType.CreateInstanceImpl(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at OEC.Chart.TimeSeriesFactory.Create(Type type)
at OEC.Chart.TimeSeriesFactory.Create(TimeSeriesAttribute attribute)
at OEC.Chart.ChartPanel.AddIndicator(TimeSeriesAttribute attribute, AreaProfile SelectedArea, TimeSeriesBase SelectedTimeSeries)
at OEC.Chart.ChartPanel.actIndicatorAdd_CaseClick(Action sender, Object Case)
at OEC.UI.Actions.Action.OnCaseClick(Object obj)
at OEC.UI.Actions.ActionSupportToolStripItem.ClickCase(Object sender, EventArgs args)
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)





John
VictorV
Posts: 746
Joined: May 08, 2007


Posted: Jun 04, 2010 @ 03:45 PM             Msg. 6 of 6
Vista doesn't like to allow programs to write to Program Files: C:\Program Files\Rhythm Trader\Demo 3.5\log.txt. BTW, if you are using Rhythm Trader, you need to search the log file in AppData\Local\Tradecom\Rhythm Trader\Demo 3.5

Victor Vins
Software Developer