Custom Class - Print or Write logs

Created at 24 Sep 2013, 18:16
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
BH

bhoja

Joined 12.11.2012

Custom Class - Print or Write logs
24 Sep 2013, 18:16


Hi there,

 

I've multiple custom classes which I need to test and check for errors.  The Print Command (cAlgo.API.Internals.Algo.Print) is protected, so I cannot Print to the Log.  Is there a way around this?

I wanted to keep the custom classes separate from the Robot inherited Class.

 

Many Thanks,


@bhoja
Replies

hichem
24 Sep 2013, 18:19

RE:

You can use reflection. Pass the current Robot or indicator as an argument to your class and use reflection to get to the Print Method. Affect it to a delegate, then call that delegate

 

bhoja said:

Hi there,

 

I've multiple custom classes which I need to test and check for errors.  The Print Command (cAlgo.API.Internals.Algo.Print) is protected, so I cannot Print to the Log.  Is there a way around this?

I wanted to keep the custom classes separate from the Robot inherited Class.

 

Many Thanks,

 


@hichem

bhoja
24 Sep 2013, 18:24

RE: RE:

Thanks for the quick reply.  I'll give it a whirl.

 

hichem said:

You can use reflection. Pass the current Robot or indicator as an argument to your class and use reflection to get to the Print Method. Affect it to a delegate, then call that delegate

 

bhoja said:

Hi there,

 

I've multiple custom classes which I need to test and check for errors.  The Print Command (cAlgo.API.Internals.Algo.Print) is protected, so I cannot Print to the Log.  Is there a way around this?

I wanted to keep the custom classes separate from the Robot inherited Class.

 

Many Thanks,

 

 


@bhoja

bhoja
24 Sep 2013, 19:12

RE: RE: RE:

I tried a few different combinations of code but none seem to be working for me.  I've attached the snippet of code.  Many Thnks.

     public class CustomClass
    {
        private cAlgo.API.Robot _Robot;

        public CustomClass(cAlgo.API.Robot robot)
        {
            _Robot = robot;
            Print(new string[1] 
            {
                "test"
            });
        }

         public void Print(string[] message)
        {
            BindingFlags eFlags = BindingFlags.InvokeMethod;
            MethodInfo mInfoMethod = typeof(cAlgo.API.Robot).GetMethod("Print", eFlags);
            mInfoMethod.Invoke(_Robot, message);
        }

    }

bhoja said:

Thanks for the quick reply.  I'll give it a whirl.

 

hichem said:

You can use reflection. Pass the current Robot or indicator as an argument to your class and use reflection to get to the Print Method. Affect it to a delegate, then call that delegate

 

bhoja said:

Hi there,

 

I've multiple custom classes which I need to test and check for errors.  The Print Command (cAlgo.API.Internals.Algo.Print) is protected, so I cannot Print to the Log.  Is there a way around this?

I wanted to keep the custom classes separate from the Robot inherited Class.

 

Many Thanks,

 

 

 


@bhoja

Kate
25 Sep 2013, 09:28

You can declare public method in robot:

public class MyRobot : Robot
{
    public void PrintToLog(string message)
    {
        Print(message);
    }
}

 

And then call it from another class:

public class CustomClass
{
    private cAlgo.API.Robot _robot;

    public CustomClass(cAlgo.API.Robot robot)
    {
        _robot = robot;
    }

    public void Print(string message)
    {
         _robot.PrintToLog(message)
    }
}

 


@Kate

hichem
25 Sep 2013, 09:32

RE:

Have you actually tries to compile this ?

this line will throw an error:

_robot.PrintToLog(message)

PrintToLog is not defined in cAlgo.API.Robot

Kate said:

You can declare public method in robot:

public class MyRobot : Robot
{
    public void PrintToLog(string message)
    {
        Print(message);
    }
}

 

And then call it from another class:

public class CustomClass
{
    private cAlgo.API.Robot _robot;

    public CustomClass(cAlgo.API.Robot robot)
    {
        _robot = robot;
    }

    public void Print(string message)
    {
         _robot.PrintToLog(message)
    }
}

 

 


@hichem

atrader
25 Sep 2013, 10:17

RE: RE:

hichem said:

Have you actually tries to compile this ?

this line will throw an error:

_robot.PrintToLog(message)

PrintToLog is not defined in cAlgo.API.Robot

 

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC)]
    public class PrintRobot : Robot
    {
        public void PrintToLog(string message)
        {
            Print(message);
        }
    }

    public class CustomClass
    {
        private PrintRobot _robot;

        public CustomClass(PrintRobot robot)
        {
            _robot = robot;
        }

        public void Print(string message)
        {
            _robot.PrintToLog(message);
        }
    }
}

 


@atrader

Kate
25 Sep 2013, 10:43

Right, this is wrong. You need to pass your exact robot type to custom class:

public class CustomClass
{
    private MyRobot _robot;
 
    public CustomClass(MyRobot robot)
    {
        _robot = robot;
    }
 
    public void Print(string message)
    {
         _robot.PrintToLog(message)
    }
}

 

 


@Kate

WhiteSage
04 Oct 2014, 11:07

Is there a better method? This doesn't work with classes used only as a set of functions ( as its never instantiated).


@WhiteSage

AlexanderRC
10 Oct 2014, 13:57

RE:

WhiteSage said:

Is there a better method? This doesn't work with classes used only as a set of functions ( as its never instantiated).


If all of your methods in your custom helper class are static, then you need to store the reference to the currently running cBot in a static field of your custom class. You can do that in a constructor of a cBot or in the OnStart() method before using any of the static methods of the custom helper class. Print() methods are now public and do not require a subclass exposing them as public via some proxy methods. As every cBot seems to be running in its own AppDomain storing in a static member should be safe. But I may be wrong here as all cBots may be running in a separate, but shared AppDomain, I have not investigated that yet. If the AppDomain is shared, then if one of the cBots is stopped, the stored reference would prevent it from being garbage collected. The consequences of that are unknown.

Another approach would be to poke around with a Reflector tool and find the eventual method which is used in printing to the log. If I remember correctly the internals, the eventual call is static so you would not need an instance of a Robot (Algo) class for that. But that is a very hacky and unreliable way to do that as internals may be changing from release to release. Also, you may need to work around some security issues to call non-public methods via reflection.
 


@AlexanderRC