Replies

ChasBrownTH
02 May 2017, 18:17

Caveat: Since the website is now offline and for sale it seems to have been abandoned?

So you can get the mt4 source here >> http://angloam.net/MT4-cAlgo-TradeCopier-OLD-files/TradeCopierProvider.mq4

The MT4 Trade Sender .ex4 is here >> http://angloam.net/MT4-cAlgo-TradeCopier-OLD-files/TradeCopierProvider.ex4

Hope this helps, remember to set the ID in both the MT4 and CTrader setups. The only problem I ever had is that MT4 sometimes moves the 'Data Area', it can be in

'C:\Users\Administrator\AppData\Roaming\MetaQuotes\Terminal\ABCDEFG12345678etc''

where it is looked for by the cAlgo bot, but sometimes MQ4 writes into

"C:\Program Files (x86)\MetaTrader 4 IC Markets\terminal.exe"

In which case the cAlgo bot cannot find the file and fails to work, so I am trying to modify the code, but it is 'very cryptic', at least to me! It would be far easier if the path was always fixed and constant, but in some cases it isn't. I think Microsoft are to blame, they 'improve' things in newere versions and abandon past users sometimes.


@ChasBrownTH

ChasBrownTH
22 Jan 2017, 21:45

RE: RE:

GeoFinex said:

cAlgo not working

Please send it to engage@spotware.com

Hi i am facing the same problem, my existing cAlgo as well as cTrader stopped working.

I tried to uninstall and reinstall it but a message displays "cannot install application contact support"

Please let me know how can i fix this issue. I already sent the error file to the said email. Regards

I had a similar problem, cAlgo loaded but did not display a window. cTrader loaded, but did not let me add any charts.

Alt-Ctrl-Shift-T did nothing at all in cAlgo .. I tried various levels of renaming and deleting, which didn't help.

As a last resort I deleted everything in /Documents and /AppData/Roaming -> THAT WORKED !!

I copied back my BOTs and everything is fine now, but I have no idea what went wrong of if it will recur ?

This all happend when I was trading LIVE, with REAL MONEY .. it was very scary!

Luckily I keep a couple of backup PC's running, plus a pair of VPS, so I was able to shut down my trades.

I LIKE cAlgo, but sometimes it is 'Out For Lunch' for no obvious reason ? Also all my instances disconnect several times a week, with no pattern I can see.

Maybe there are answers? Maybe this description helps some other User?


@ChasBrownTH

ChasBrownTH
31 Jul 2016, 19:08

re.Romanov Capital 'this can be done from within an indicator or cBot easily.' Can you please explain how?

I need to store data at specific times and it would be wonderful to just click a chart then have my Bot write to my database at that exact moment.


@ChasBrownTH

ChasBrownTH
06 Jul 2016, 04:33

RE: Memory Manager

PS - I use your Memory manager BOT and it is excellent !  Thank you for sharing it. ;)


@ChasBrownTH

ChasBrownTH
06 Jul 2016, 04:28

I have been wrestling with the same sort of problems, but in the end I think I found a workable solution. I wanted to be able to run extensive Optimisation cycles then analyse ALL the results, not just the top 20. So I use mySQL to keep very comprehensive records, then analyse it all externally, using my own Delphi creation. ;)

I can also re-create all the Equity Charts I want now, which makes it much easier to see what happened.

First I tried adding code into OnStop(), that wrote details of the BackTests out to mySQL, which works up to a point, BUT does not have access to trade.Equity.

Now I have added code into OnPositionsClosed() that does the trick, by being able to get the Account.Balance and Account.Equity for each trade as it happens.

    Incidentally Account.Equity is the same as (Account.Balance + Account.UnrealizedNetProfit), not that it helps in this case though.

For your specific case, ie. seeking the max historical equity?, then you could just keep a running total from within OnPositionsClosed()

ie. something like this: [ first create a couple of global Vars, such as MaxEquity & MinEquity, also initialize them in OnStart() ie. MaxEquity = Account.Balance etc ]

         private void OnPositionsClosed(PositionClosedEventArgs args) 

         {

              if (Account.Equity > MaxEquity)

              { MaxEquity = Account.Equity }

              if (Account.Equity < MinEquity)

              { MinEquity = Account.Equity }

         }

I think that ought to work ?  ;)                   

my own working example collects everything: [ sample here, or at least the key parts of it ]

        /// <summary>
        /// OnPositionsClosed - called after every Order is closed
        /// </summary>
        /// <param name="args"></param>
        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            if (IsBacktesting)
            {
                // mysql query to report backtest Trade HISTORY
                string query = "INSERT INTO backtest_history (uniqueid, finished, Balance, Equity, balunreal, Trades, BotVer) VALUES ('" + strUniqueBacktestID + "','" + Server.Time.ToUniversalTime() + "','" + Math.Round(Account.Balance, 2).ToString("0000000.00") + "','" + Math.Round(Account.Equity, 2).ToString("0000000.00") + "','" + Math.Round((Account.Balance + Account.UnrealizedNetProfit), 2).ToString("0000000.00") + "','" + History.Count.ToString() + "','" + BotVer.ToString() + "')";

                // add copy to Log file for easy viewing
                Print("OnClosed: " + query);

                OpenSQLconnection();
                //create command and assign the query and connection from the constructor
                MySqlCommand cmd = new MySqlCommand(query, mySQLconnection);
                //Execute command
                cmd.ExecuteNonQuery();
                // cleanup mySQLconnection
                CloseSQLconnection();
            }

I hope this helps? One limitation is that I have to dump the history of losing sequences, since I see no way to filter them.

But using OnStop I can have

                if ((NetProfit > 0) && (Account.Equity > 0))
                {
                    foreach (HistoricalTrade trade in History)
                    {

BUT no access to the all important trade.Equity figure .. maybe Spotware will add it to the History collection sometime in the future ?

 


@ChasBrownTH

ChasBrownTH
29 May 2016, 20:26

The VSExtension.vsix file structure, as well as how to edit it, is explained here and it works!

   /forum/calgo-support/8502?page=1#2

There is also a working copy kindly provided ClickAlgo.com on their site, if you search for it.


@ChasBrownTH

ChasBrownTH
29 May 2016, 20:10

RE:

Marvellous, that worked perfectly !  Thank you so very much. ;)

re. The vsix is simply a zipped file

 


@ChasBrownTH

ChasBrownTH
27 May 2016, 14:50

No offence but it sounds like you want us to give you ideas, for Free, then pay you to try to write them?

Perhaps if you offered some sort of Samples of your work it might be more believable, but you have not shared or uploaded anything at all.

I believe there is also a 'Protocol' for would be 'Consultants', some sort of Registration?

Good luck, reply if you want to chat, I have what I think are good ideas, but they are not Free. ;)

 


@ChasBrownTH

ChasBrownTH
27 May 2016, 14:43

RE:

ChasBrownTH said:

How very bizarre, but neither of these 'errors' happens with a blank New Robot.

Therefore it has to be something 'odd' or 'broken' in my Robot, OOooooops ! 

I shall review every line, but what on earth could cause the Log file to get truncated and Server.Time to get mangled?

My apologies to Spotware for reporting a non existent error, and my thanks to them for helping me find 'the error of my ways'. ;)

Mea Culpa, so time for me to go and find my hair shirt I think, plus the flail! ;)


@ChasBrownTH

ChasBrownTH
03 Feb 2016, 07:32

RE:

Thanks Paul, as usual you are very helpful. MANY THANKS  ;)

At first I could not get the timer to close, but when I added it initialisation as a private variable my Robot built correctly, plus it closed the Timer at last! Also I have now added a mySQL connection.Close(). BUT if that had been there all along then I would not have known about the timer still being alive. Serendipity perhaps ?

       #region private fields

         // setup extra timer to invoke tasks each minute - checks environment etc
        private System.Timers.Timer OneMinuteTimer = new System.Timers.Timer();

         #endregion private fields

         OnStart()

         {

             // configure private 1 minute timer
            OneMinuteTimer.Elapsed += new ElapsedEventHandler(OnMinuteTimer);
            OneMinuteTimer.Interval = 60000;
            OneMinuteTimer.Enabled = true;

          }

         public void OnMinuteTimer(object sender, ElapsedEventArgs ev)

        {
            if (!IsBacktesting)
            {
                // WriteIsAliveToSQL();
                SQLInsertIsAliveInfo();)

            }

        }

          OnStop()

          {

                  OneMinuteTimer.Enabled = false;

                   connection.Close();  // close mySQL connection

          }

Paul_Hayes said:

declare this as a private variable in the class

     OneMinuteTimer.Enabled = false;

Now you can use the private variable in the scope of the class to stop it, even the OnStop event class of cAlgo, you are correct this will stop the timer and it is not threaded. There could be a possibility that when you stop the robot the instance is still in memory. IT WAS! The robot instance should really unload from memory when you stop the instance in cAlgo. IT DOESN'T!

One other thing is that I would add clean up code to disconnect from the database, kill any session objects etc, even though the .NET framework uses a garbage collector to do all this, it is still good housekeeping to make you clean up after the party.


@ChasBrownTH

ChasBrownTH
29 Jan 2016, 06:02

RE:

Hello Spotware. Thank you for replying. I already sent you my Robot for you to look at, but I can well understand that you do not want that, only a 'simple example', which unfortunately is often not at all easy to create. However I persevered and worked it out myself.  ;)

After carefully analysing many hours of mySQL logs I realized that the root of the problem was with internal timers in my Robot. One of them was not stopping, even when the parent Robot was stopped that timer kept running, but divorced from its origin and source of valid data. That explained the 'nonsense' Postions.Count() data I was getting, it came from an an almost 'dead' thread, left running within the old shell of my Robot. 

I believe that stopping a Robot in cAlgo is not closing all activities it opened, but perhaps the programmer ought to do that?

Meanwhile I have tried to prevent the Timer problem by simply removing it, instead I now drive the one minute events using the 1 minute OnBar() method, which seems to work. But I think the wider issue needs to be resolved. My 'temporary solution' works for me, BUT it is quite inconvenient having to use a 1min chart to drive my Robot's housekeeping functions, I prefer to look at a 1hr timeframe normally, for a clearer overview.  I would be grateful to be taught how to stop the Timer correctly.

How to see it happening:

To reproduce the Timer problem, I believe that adding the timer creation code, listed below, into OnStart(), then have it call a private function such as writing to a file or mySQL will give the strange results I have seen. You should see that when the Robot is stopped that Timer keeps running, since it never gets stopped within the Robot.

// setup extra timer to invoke tasks each minute - checks environment etc

            System.Timers.Timer OneMinuteTimer = new System.Timers.Timer();

            OneMinuteTimer.Elapsed += new ElapsedEventHandler(OnMinuteTimer);

            OneMinuteTimer.Interval = 60000;

            OneMinuteTimer.Enabled = true;

// this Timer was created within OnStart()

In my Robot 'OnMinuteTimer' did 'housekeeping, including writing an 'Alive' status report to mySQL.

        /// <summary>

        /// every minute do housekeeping tasks

        /// </summary>

        /// OnMinuteTimer()

    public void OnMinuteTimer()

    {

        // do various regular housekeeping tasks

        SQLInsertAliveInfo

    }

 

/// <summary>

        /// write 'alive info' to SQL table

        /// </summary>

        /// SQLInsertAliveInfo()

        public void SQLInsertAliveInfo()

        {

            // Current UNIX timestamp

            Int32 UNIXStamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

            double spread = ((Symbol.Ask - Symbol.Bid) / Symbol.PipSize);

            double volatility = 0;

            Positions.FindAll(Label);

            int totalPositions = Positions.Count;

            int buyPositionsCount = PositionsCount(TradeType.Buy);

            int sellPositionsCount = PositionsCount(TradeType.Sell);

 

            if (!IsBacktesting)

            {

                // add volatility report        

                minuteSeries = MarketData.GetSeries(Symbol, TimeFrame.Minute);

                double lastHigh = (minuteSeries.High.LastValue);

                double lastLow = (minuteSeries.Low.LastValue);

                volatility = ((lastHigh - lastLow) / Symbol.PipSize);

            }

 

            // mysql query

            // string query = "INSERT INTO alive (UNIXtime, time, date, balance, equity, spread, volatility, instance, accountid, botversion, stoploss, takeprofit, multiplier, maxlt, buys, sells) VALUES('" + UNIXStamp + "','" + Server.Time.ToString("HH:mm:ss") + "','" + Server.Time.Date.ToString("dd/MM/yyyy") + "','" + Account.Balance + "','" + Account.Equity + "','" + spread.ToString("0.00") + "','" + volatility.ToString("0.00") + "','" + Instance + "','" + Account.Number + "','" + BotVersion.Substring(7, 5) + "','" + ParamStopLoss.ToString("0") + "','" + ParamTakeProfit.ToString("0") + "','" + ParamVolumeMultiplier.ToString("0.0") + "','" + ParamMaxLosingTrades.ToString("0") + "','" + buyPositionsCount.ToString("0") + "','" + sellPositionsCount.ToString("0") + "')";

            string query = "INSERT INTO alive (UNIXtime, time, date, balance, equity, spread, volatility, instance, accountid, botversion, stoploss, takeprofit, multiplier, maxlt, orders, buys, sells) VALUES('" + UNIXStamp + "','" + Server.Time.ToString("HH:mm:ss") + "','" + Server.Time.Date.ToString("dd/MM/yyyy") + "','" + Account.Balance + "','" + Account.Equity + "','" + spread.ToString("0.00") + "','" + volatility.ToString("0.00") + "','" + Instance + "','" + Account.Number + "','" + BotVersion.Substring(7, 5) + "','" + ParamStopLoss.ToString("0") + "','" + ParamTakeProfit.ToString("0") + "','" + ParamVolumeMultiplier.ToString("0.0") + "','" + ParamMaxLosingTrades.ToString("0") + "','" + totalPositions.ToString("0") + "','" + buyPositionsCount.ToString("0") + "','" + sellPositionsCount.ToString("0") + "')";

            Print(query);

            //create command and assign the query and connection from the constructor

            MySqlCommand cmd = new MySqlCommand(query, connection);

            //Execute command

            cmd.ExecuteNonQuery();

        }


@ChasBrownTH

ChasBrownTH
28 Jan 2016, 19:46

Conclusion: I now think some of the odd behaviour is because the Robot uses two timers, one of which is not being stopped at shut-down. It seems that it continues running in the background, divorced from its original environment, hence the nonsensical Positions.Count() results, they are coming from 'thin air', driven by a Timer that ought to have stopped, but didn't.

The first timer is simple:

            // start first timer with 2 second interval
            Timer.Start(2);

So in 'OnStop' I have added a Stop instruction.

         protected override void OnStop()
        {
            Timer.Stop();

        }

The second timer is not so simple, it uses 'fancy' code not written by me.

             // setup extra timer to invoke tasks each minute - checks environment etc
            System.Timers.Timer OneMinuteTimer = new System.Timers.Timer();
            OneMinuteTimer.Elapsed += new ElapsedEventHandler(OnMinuteTimer);
            OneMinuteTimer.Interval = 60000;
            OneMinuteTimer.Enabled = true;

It works very well, too well, in fact it never stops!

Has anybody got an idea how to correctly stop it ?

             OneMinuteTimer.Enabled = false;

Seems like the obvious way, but does not Build because it doesn't exist in the OnStop() context.

I am no C# expert, but I suspect it is running in a separate thread?

So can anybody tell me how do to stop it? It survives stopping the parent Robot, sometimes it even survives stopping and re-starting cAlgo itself.


@ChasBrownTH

ChasBrownTH
28 Jan 2016, 18:23 ( Updated at: 21 Dec 2023, 09:20 )

RE: RE:

This is getting too ridiculous for words, so here are some pictures to clarify the problems .. note that the server was STOPPED at 15:48, the 'RED' Go changed to 'BLUE'. By all logic it ought to be OFF, not running, doing nothing at all .. quite by chance I checked the mySQL tables for an earlier issue and noticed that IT WAS STILL RUNNING !! In so far as some of the code was still actively sending mySQL table updates, five minutes AFTER I stopped the Robot. Also please note that not one but TWO copies were 'GHOST' running, notice that one has a MaxLT/MLT of 4 and the other an MLT of 20. [ MLT = max losing trades ] but the Robot simply cannot have two values for the same variable at the same time.

UPDATE: half an hour later it is still running. clearly the only way to stop it is to close cAlgo.   So every time we update our Robot we need a 'clean re-start' ?


@ChasBrownTH

ChasBrownTH
28 Jan 2016, 16:19 ( Updated at: 21 Dec 2023, 09:20 )

RE:

Latest update: this just keeps getting stranger .. I can now see, thanks to the mySQL 'history' I am keeping, that it is not simply the Positions.Count() method that is failing, but also the entire routine that calls it, sometimes. I always run many virtual instances of the same Robot, some on remote VPS systems, geographically separate, precisely to look for such glitches. While some run smoothly others exhibit 'weird' behaviour, such as I described in the original posting.

However I have now identified a second set of problems, whereby in some cases some segments of the Robot stop working, but other segments continue. It is all very odd.

Thirdlysometimes when I add a newer version of a Robot the older version keeps running 'in the background', even though I deleted it. I can sometimes see output coming from both versions, because I Log most key activities into mySQL and include the Version as well as the data. So then I have to completely Stop cAlgo, then reload it with only the newer version, or it keeps a 'shadow' copy, presumably somewhere in memory. It is very strange to see when I have only one instance of cAlgo running, but it is giving Dual output, including output from a deleted Robot, that was first stopped. I repeat the old Robot was DELETED! But it is still active, somewhere in 'never never land' ...

I have pages and pages of mySQL tables if anybody wants to see proof! Unfortunately I cannot send 'a stripped down sample' to Spotware so easily. Though I am trying, but they seem totally unwilling to even consider the possibility that any of this is happening, which is very disturbing. I also tried explaining it and demonstrating it to 'Consultants' with no success.

As always if anybody has any suggestions then I would be very grateful to hear them. If any reader wants to see 'proof' please contact me -> charles AT angloam DOT net


@ChasBrownTH

ChasBrownTH
27 Jan 2016, 15:31

RE:

Thank you again Lucian, I have added those changes and they certainly work, but as before I will not not be sure if it fixes the problem until after the 'old' code produces problems, which hopefully the new code will not. I am VERY grateful to you for your time and effort. I can understand the logic you have introduced, so maybe I can learn to write better C# in the future.

Lucian said:

try:

int totalPositions= positions.Lenght;

and:

 private int PositionsCount(TradeType tradeType)

{
            var count = 0;
            foreach (var position in Positions)
            {
                if (position.Label == Label && position.SymbolCode == Symbol.Code)
                {
                    if (position.TradeType == tradeType)
                        count++;
                }            
            }
            return count;
 }


@ChasBrownTH

ChasBrownTH
27 Jan 2016, 07:05

SORRY for so many replies, I am learning as I go along  ;)

I added parentheses to positions.Count() and it now builds !

            var positions= Positions.FindAll(Label);
            int totalPositions = positions.Count();

At least it builds, I still do not know if it produces an accurate count.


@ChasBrownTH

ChasBrownTH
27 Jan 2016, 07:02

Oooops, I spoke too soon !

I tried to use:

            var positions = Positions.FindAll(Label);
            int totalPositions = positions.Count;

But found that variation will not build.

  Error CS0428: Cannot convert method group 'Count' to non-delegate type 'int'. Did you intend to invoke the method?


@ChasBrownTH

ChasBrownTH
27 Jan 2016, 06:47

Thanks Lucian

That looks promising, I am hoping it will 'initialize' the Positions counter. Fingers crossed, but I need a few days to confirm it has worked. The error is not continuous, it often shows up later in the week, when the market gets frantic and orders are opening and closing at high speed.

For test purposes I have left the old code and put the new code alongside, so I can compare two sets of output.

I think I have the same problem in these two code fragments, can you suggest how I might modify them please ?

         protected int PositionsCount(TradeType tradeType)
        {
            return Positions.FindAll(Label, Symbol, tradeType).Length;
        }

The above sometimes fails to return correct results, but I am unsure how to fix it.

         protected void CheckStopLossAndTakeProfit()
        {
            foreach (Position position in Positions.FindAll(Label, Symbol))
            {
                //RefreshData();
                if (!position.StopLoss.HasValue)
                {
                    SetStopLoss(position);
                }
                if (!position.TakeProfit.HasValue)
                {
                    SetTakeProfit(position);
                }
            }
        }

I think this code works, it is slightly different. I did not write either of them, only the code in my original question is mine.

Many many thanks for replying Lucian, I am very grateful for your help, this has been driving me Nuts for many months  ;)


@ChasBrownTH

ChasBrownTH
26 Jan 2016, 08:33

RE: RE:

ChasBrownTH says:

Once again Spotware makes it impossible to directly answer their comments, so I will 'talk to myself', which seems to be the only solution available.

>> Spotware said:
>>    Dear Trader,
>>    We would like to inform you that we do not provide coding assistance services.

I see, so you do not want the actual Robot, but 'the simplest code that reproduces it'? 

So now I need to write a 'partial' Robot that 'fails' so that you can more easily see what may be wrong with cAlgo?

An interesting idea! So I will try to do that, since I cannot make progress with my robot until this problem is fixed.

>> Spotware said:
>>    We more than glad to assist you with specific questions about cAlgo.API. 

I take it from your lack of suggestions that there is nothing clearly and obviously wrong in the way I am already calling the method?

I believe I have asked a valid question already. HOW do I call the Positions.Count method? So far I have not received an answer to that very simple question.

>> Spotware said:
>>    You can contact one of our Partners 
>>    or post a job in Development Jobs section for further coding assistance.

I have worked with two 'Listed Developers' during the past 9 months, and paid for help, but so far neither was able to identify the cause of this problem. 

But it most definitely exists!


@ChasBrownTH

ChasBrownTH
25 Jan 2016, 09:24 ( Updated at: 21 Dec 2023, 09:20 )

RE:

I don't seem to be able to reply to Spotware's message on this page, so I am replying to myself.

Hopefully there is nothing wrong with the cAlgo methods, I already said that I may be calling the method wrongly. But in that case what am I doing wrong ?

I already posted the code I am using above, it is simple but clearly 'defective', in which case how is it wrong? It is repeated here:-

            Positions.FindAll(Label);
            int totalPositions = Positions.Count;
            int buyPositionsCount = PositionsCount(TradeType.Buy);
            int sellPositionsCount = PositionsCount(TradeType.Sell);

            strStats += string.Format("\nPositions: {0}  Buys: {1}  Sells: {2}", totalPositions, buyPositionsCount, sellPositionsCount);

            ChartObjects.DrawText("stats", strStats, StaticPosition.TopLeft);

I posted a picture, repeated here.

The information coming in from the Positions.Count; is nonsense, it has produced hours and hours of nonsense on many different machines over a period of days & weeks, but I did not realize at first since I assumed that the method could not be at fault. Instead I looked for the 'obvious error' in my own code ? Which nobody seems able to pinpoint.

Therefore I will send a copy of my Robot to troubleshooting@spotware.com  and ask that they run their own tests on it - Many thanks!

ChasBrownTH said:

Sorry, wish I could edit my earlier message, but that seems impossible ?

I should have mentioned that the mySQL history proves cAlgo is returning 'Nonsense' for HOURS, long after it was true ;(

I have instances with no open trades, but minute by minute 'reports' claiming there are trades Open .. 

It baffles me .. can anybody HELP please ?  Hello Spotware, is anybody there ?  ;)

 


@ChasBrownTH