Topics
06 Aug 2021, 15:06
 0
 1093
 3
06 Aug 2021, 11:20
 916
 2
17 Mar 2021, 17:22
 1
 1119
 4
27 Aug 2020, 11:41
 1
 968
 2
26 Aug 2020, 14:47
 1
 1175
 1
18 Jul 2020, 14:37
 1440
 3
15 Jul 2020, 21:47
 2
 840
 1
11 Jul 2020, 11:50
 1235
 2
07 Jul 2020, 12:26
 1014
 3
Replies

GridSurfer
21 Feb 2023, 13:15

Spotware said:

Dear GridSurfer,

Dragging charts and changing the order should be working. We were not able to reproduce such a problem. Are you able to record a video demonstrating this behavior?

Best regards,

cTrader Team

Could you give me an email adress? Although there is not much to see except that it doesn't work on my main computer. On another computer it works just fine so I know it must be me or something with this computer/installation.


@GridSurfer

GridSurfer
16 Jan 2023, 09:38

Hi Support,

thanks, here is the code. No parameters.

-------------------------------------------------------------------------------------------------------------

using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using System.IO;


namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.GMTStandardTime, AccessRights = AccessRights.FullAccess)]
    public class TickdataExportMultiSymbol : Robot
    {
        private string _dataDirectory = "O:\\_TradingData\\_Data_ICMarkets\\_Source";
        private string[] _symbols = {  "EURAUD", "EURGBP", "EURJPY", "EURUSD", "EURCHF", "EURCAD", "EURNZD", 
                                    "GBPUSD", "GBPJPY", "GBPCHF", "GBPCAD", "GBPAUD","GBPNZD"};

        protected override void OnStart()
        {
            // System.Diagnostics.Debugger.Launch();
        
            foreach (string ticker in _symbols)
            {
                // Read last Tick in file (Load Ticks after that)
                //
                DateTime firstDt = GetLastTickInFiles(ticker);

                // For the initial files use one month more back
                //
                DateTime firstMaxDt = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                if (firstDt.Year < DateTime.Now.Year - 1)
                    firstDt = firstMaxDt.AddMonths(-1);

                // Load Ticks
                //
                API.Ticks symbolTicks;
                symbolTicks = MarketData.GetTicks(ticker);
                while (symbolTicks[0].Time.CompareTo(firstDt.AddHours(-4)) > 0)
                {
                    symbolTicks.LoadMoreHistory();
                }

                List<TickRec> tickList = new List<TickRec>();
                DateTime lastDt = new DateTime(1970, 1, 1);

                for (int idx = 0; idx < symbolTicks.Count; idx++)
                {
                    // Adjust by 2 hours - forex trade week starts 00:00 (needs addl. 1 hour [e.g. 08.03.2020 - 29.03.2020])
                    //
                    DateTime dt = symbolTicks[idx].Time.AddHours(2);

                    // If by any chance there are two ticks with same time, add 1ms to the second tick
                    //
                    while ((dt - lastDt).TotalMilliseconds <= 0)
                        dt = dt.AddMilliseconds(1);
                    lastDt = dt;

                    if (dt.CompareTo(firstDt) > 0)
                    {
                        TickRec newTick = new TickRec();
                        newTick.Bid = symbolTicks[idx].Bid;
                        newTick.Ask = symbolTicks[idx].Ask;
                        newTick.DateTime = dt;
                        tickList.Add(newTick);
                    }
                }

                SaveTicks(ticker, tickList);
            }

            Notifications.PlaySound("C:/Windows/Media/Ring05.wav");
            
        }

        protected override void OnTick()
        {
        }

        protected override void OnStop()
        {
        }

        private DateTime GetLastTickInFiles(string Ticker)
        {
            DateTime lastTickDt = new DateTime(1970, 1, 1);
            var dirInfo = new DirectoryInfo(_dataDirectory);
            FileInfo[] files = dirInfo.GetFiles(Ticker + "_*.csv");            
            if (files.Length > 0)
            {
                // Locate the last tick file of this symbol
                // Read to the end and return DateTime of last Tick
                //
                FileInfo fInfo = files.OrderByDescending(x => x.Name).First();
                string line = "", lastLine = "";
                DateTime readDt = new DateTime(1970,1,1);
                using (StreamReader file = new StreamReader(fInfo.FullName))
                {
                    while ((line = file.ReadLine()) != null)
                        if (line.Length > 10)
                            lastLine = line;
                }
                string[] parts = lastLine.Split('\t');
                DateTime.TryParse(parts[0], out lastTickDt);
            }
            return lastTickDt;
        }

        private void SaveTicks(string Ticker, List<TickRec>TickList)
        {
            if (TickList.Count == 0)
                return;

            int loopMonth = TickList[0].DateTime.Month;
            int loopYear = TickList[0].DateTime.Year;
            bool finished = false;
            while (!finished)
            {
                string fileName = _dataDirectory + "\\" + Ticker + "_" + loopYear + "-" + loopMonth.ToString("00") + ".csv";

                StreamWriter sw = new StreamWriter(fileName, true);
                foreach (TickRec tick in TickList.Where(x => x.DateTime.Year == loopYear && x.DateTime.Month == loopMonth))
                {
                    sw.WriteLine(tick.DateTime.ToString("dd.MM.yyyy HH:mm:ss.fff") + "\t" + tick.Bid + "\t" + tick.Ask);
                }
                sw.Close();
                loopMonth++;
                if (loopMonth == 13)
                {
                    loopMonth = 1;
                    loopYear++;
                }
                finished = (TickList[TickList.Count - 1].DateTime.CompareTo(new DateTime(loopYear, loopMonth, 1)) < 0);
            }
        }
    }

    public class TickRec
    {
        public DateTime DateTime;
        public double Bid = 0;
        public double Ask = 0;
    }
}


@GridSurfer

GridSurfer
16 Jan 2023, 08:36

Thanks firemyst for your thoughts, but yes it is a valid date. Usually 1 week before, because I update my tick data on the weekend. I have been using the script for years now.

I watched the execution with a debugger as well. The first few times it executes LoadMoreHistory() - which is always a 3 hour chunk of tickdata - works almost fine, then it gets slower and slower until it stops working.

 


@GridSurfer

GridSurfer
07 Nov 2022, 14:45

Spotware said:

It's a very vague discussion. We will be able to advise if you share your source code and explain in detail the issue you are experiencing.

I will prepare and share, of course, but first I need to know what the desired outcome is supposed to be.

I have a bot running, it has positions, it is waiting for events OnTick() etc. --> If the connection is lost, cTrader logs out and when the connection comes back cTrader reconnects.

It is not a "vague discussion" - actually it is a simple question:Does the bot continue running as if there were no disconnect or is there some reset, re-initialize, break, etc.?


@GridSurfer

GridSurfer
04 Nov 2022, 15:33

Hi Support,

thanks for your quick reply. If "it depends on your cBot's implementation", what do I need to do to keep my bot alive.

Given the simplest of all bots (e.g. your sample of a basic bot), what is supposed to happen, when cTrader loses connection and reconnects with the last account?

If it is anything but the bot keeps running, keeps all previous conditions, session, trades, variables, etc. - what can I do to make sure my bot keeps running, unless I close cTrader completely or stop the bot? Is there a way to ensure the disconnect, reconnect doesn't affect the bot running?

Cheers

 


@GridSurfer

GridSurfer
04 Nov 2022, 12:11

RE:

Spotware said:

Dear GridSurfer,

Can you please share your cBot so that we can investigate further?

Best regards,

cTrader Team

Thank you. Unfortunately the code is huge with lots of necessary setups (files, paths etc.). I will wite a simple bot and test it with it.

For my understanding:

1. When cTrader loses connection (no matter how long) and reconnects, the running bot should continue working as if there were no disruption?
2. The ticks that occured during this time are not re-send. I could get them from the server via MarketData.GetTicks()
3. But basically I wouldn't know that there was a disconnect without data feed during a certain time, right? Or is there a way to verify that all ticks have arrived?

For the time being I am only concerned with 1. I know of this approx. 1 minute disruption of the connection which sends the system sometimes into nirvana.


@GridSurfer

GridSurfer
18 Mar 2021, 16:26

PanagiotisCharalampous said:

Hi GridSurfer,

When you expand/contract the positions it now switches the chart symbol as well. (New in 4.0)

You can switch this off from here

 

Best Regards,

Panagiotis 

Join us on Telegram

Perfect, works! Thanks!

Then only these suggestion remain (may only be relevant for automated trading -> lots of positions and/or symbols)
- Keep the information if positions are expanded or contracted (in profile or somewhere) or have some permanent switch (always contracted/always expanded)
- Update the sorting when new positions arrive

Cheers


@GridSurfer

GridSurfer
26 Aug 2020, 13:39

Personally I would love the solution of having the developer being able to edit the bars layer and access the bars like any other time based bars - all issues of Better Renko, Mean Renko, Range, Timed Range, etc. would be solved. No workaround with indicators.
However, besides the framework changes, some instruments have huge tick counts and keeping it in memory or having slow online loading wouldn't work - especially on VPSs. But this is a suggestion box, so I wish ;-)  and in the meantime I give my vote for Renko Tails.

 


 


@GridSurfer

GridSurfer
19 Aug 2020, 18:03

In NinjaTrader it is possible to create your own custom bars, display them, backtest on them, etc. Even in realtime on the tick-data: your own bar creation!
In Amibroker you have the option to generate bars and display them (e.g. as indicator - e.g. Volatility Bars)

This is an incredible feature and would open up all kinds of new options in cTrader.
Various Renko, Tick/Time combination bars, kase Bars, etc. would not only be displayable as chart, but you could also base your indicators on it and backtest on it.

Two thumbs up on this one. Once inplemented programmers could generate their own bars from ticks.
I hope everyone who voted for different Renko Ticks, backtest on Renko, Haikin Ashi etc. will vote for this one, too!


@GridSurfer

GridSurfer
10 Aug 2020, 23:22

RE:

Hi Waxy,

you just need to repeat the LoadMoreHistory() until you have enough history data.

API.Ticks symbolTicks;
DateTime firstDt = new DateTime(2020, 8, 1);

symbolTicks = MarketData.GetTicks();
while (symbolTicks[0].Time.CompareTo(firstDt) > 0)
{
     symbolTicks.LoadMoreHistory();
}

Maybe Panagiotis will post the snipplet in the API-Reference. I was looking for it before as well.

Cheers
GridSurfer


@GridSurfer

GridSurfer
23 Jul 2020, 23:28

I assume this would work.

foreach (var position in positions)
{
	if (position.NetProfit >= TargetMoney)
		ClosePosition(position);         
}

 


@GridSurfer

GridSurfer
20 Jul 2020, 18:07

Hi Panagiotis,

thanks, I got it corrected already.
I am using ExecuteMarketOrderAsync(), ClosePositionAsync() and ModifyPositionAsync() and catch the event with the TradeResult.

I assumed that I get the deal / closedDealId with the TradeResult, but I needed to differentiate between Buy/Sell and Close/Modify.

Cheers
GridSurfer


@GridSurfer

GridSurfer
20 Jul 2020, 17:51

PanagiotisCharalampous said:

Check this post.

 

Hi Panagiotis,

perfect, thank you!
I knew I saw it somewhere. Awesome post, lot's of samples.You should also link to it from the reference samples page.

Cheers
GridSurfer


@GridSurfer

GridSurfer
10 Jul 2020, 16:34

O.k., now I got it.

You have to tap on the header until the Equity header appears (the other headers are Trading time and margin)


@GridSurfer

GridSurfer
10 Jul 2020, 09:15

I'm afraid no. I only get the big blue button "+Add Symbols" at the bottom of the screen (2nd screen - watchlist popular markets)

I am using cTrader mobile on the ipad - version 3.11

So I closed everything to check for updates and restart. But now it doesn't even start. Screen comes up and closes immediately. Same on my iphone :-(

I check on it later again.


@GridSurfer

GridSurfer
09 Jul 2020, 21:12

RE:

PanagiotisCharalampous said:

Hi GridSurfer,

When you start following a strategy provider, your funds are transferred into a separate subaccount and deducted from your main one. The trades are not executed on your main account but on your subaccount, which is accessible only via cTrader Copy.

Best Regards,

Panagiotis 

Join us on Telegram

 

Thanks for the info. I never looked at cTrader Copy before. 
I am very impressed with what progress the platform (mobile & desktop) have made over the past couple of years. Really good job!

An integration of cTrader Copy into the desktop and mobile will be further milestones.


@GridSurfer

GridSurfer
03 Jul 2020, 09:38

Thank you for the example.

I was looking everywhere to find some/any expample on how to use the Tick history.
Maybe I am missing something, but it would be great if there were short examples here or there in the API reference on how to use the function, event or interface.


@GridSurfer

GridSurfer
28 Aug 2019, 16:48

Hi Panagiotis,

thanks for the reply. However, as you sure know, any serious trader using automated trading uses a VPS close to the datacenter, so you always get < 2 Milliseconds to the broker (NY, London, Frankfurt). But in case of cTrader the gateway is London (Spotware), and all transactions are routed to NY where most liquidity providers of my broker are. It doesn't make much sense to me since all the execution advantage the cTrader framework has over established platforms like MT4/MT5 go to waste. But I guess not enough people care.

Cheers
GridSurfer


@GridSurfer