Topics
Replies

firemyst
24 Nov 2020, 09:56

If it's a "point a pip", then -2.1 pip SL would place it above the chart because it would be at roughly 45.15, which is 2.1 pips above 43.05.

 

Different brokers also do different sizes for pips.

Example: IC Markets with forex -- if you put "20" for a stop loss, that's the equivalent of "2" when using Pepperstone for the exact same currency.

 


@firemyst

firemyst
24 Nov 2020, 09:46

Not sure what you're asking?

When you first enter a trade, typically you're negative a few pips depending on your spread.


@firemyst

firemyst
23 Nov 2020, 04:04

Can't you just use a simple formula such as:

 

(starting price - current price) / (starting price time - elapsed time)

 

??


@firemyst

firemyst
22 Nov 2020, 14:41

I am experiencing the same issue too, so you are not alone.

 

I wonder if it has anything to do with this forum being hacked from all the spam messages being posted?


@firemyst

firemyst
11 Nov 2020, 14:10

Link on Spotware's site on how to include custom indicators witihn indicators. It's the same for bots.


@firemyst

firemyst
05 Nov 2020, 14:20

RE:

ctid2032775 said:

Dear Panagiotis,

I know that there is a way to programmatically Stop() a cBot. But is there a way to "restart" a cBot, as well?

The reason of my question is that one of my cBots uses an automatic optimization method when started and a "drop-out" scenario under certain conditions. It would be great to just restart the cBot if those conditions are met instead of implement a second optimization logic for this case...

Many thanks and best regards,
Christian

Why "stop" and "Start" the bot?

I think a good work around in your case is to just set a global boolean flag.

Call it "bool _dropOut" and when the bot first starts, set it to "false".

In your OnTick and OnBar methods, check the flag before you do anything.

Eg:

protected override void OnTick()
{
    if (!_dropOut)
    {
       //do your normal ontick code logic
    }
    else
    {
        //check for the conditions to set _dropOut = false
    }
}

protected override void OnBar()
{
    if (!_dropOut)
    {
       //do your normal onbar code logic
    }
}

 

Your bot will always be running, it won't execute any OnTick or OnBar code unless set to false.

thus, no need to worry about stopping and restarting.

Easy peazy :-)

 


@firemyst

firemyst
19 Oct 2020, 04:03

RE: RE: RE:

prosteel1 said:

firemyst said:

caglar_G said:

What is the best method for initating a wait for a bot, example: The bot made a trade and closed, after closing you want it to wait for an x amount of time. Is threading.sleep sufficient?

I'd rather not use threading.sleep as it basically suspends the bot for a set amount of time, I might want the bot to do some calulations in the meantime. Is there an alternative to threading.sleep to achieve something like that? Thanks!  

You have multiple options depending on how you want to wait.

Example #1: you want to wait until a new bar is opened. That's easy. Just create a bool flag such as "closedThisBar". In your Positions_Closed event method, set "closedThisBar" to true. In the OnBar method, set "closedThisBar" to false. Then whenever you're wanting to open a position, check the flag before opening the position.

eg, if (!closedThisBar) { OpenPosition.... }

 

Example #2: you want to wait x-minutes/second. That's a bit more involved, but not difficult. Use the timer. In the timer event method, when the number of seconds/minutes has passed, again set a flag to indicate it's ok to open positions again.

 

Example #3: you want to wait x-ticks. Similar to #1 except you also need a variable to count the number of ticks. When a position is closed, reset your tick count to zero. When your tick count reaches your set threshold, set the boolean flag to true so you can open positions again.

 

That's just 3 ways off the top of my head.

Hope it helps :-)

I like your Example #1 solution, as waiting for the current bar to close before opening a new trade if the last trade closed in loss is something I've been wanting to impliment, this is how I would do it that can run OnTick and use a different timeframe to the chart timeframe.

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter("Timeframe0", DefaultValue = "Hour4")]
        public TimeFrame tf0 { get; set; }
        int i = 0;
        protected override void OnStart()
        {
            Positions.Closed += PositionsOnClosed;
        }

        protected override void OnTick()
        {
            // Insert code to only run after count is larger than the count when the last position was closed
            Bars series = MarketData.GetBars(tf0);
            if (i == 0 || i < series.Count - 1)
            {
                // Insert normal Trading code
                Print("series.Count - 1 = " + (series.Count - 1));
            }
            else
            {
                // Insert other Calculations
            }
        }
        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            // Get Bars on the specified timeframe then write the current bar to i
            Bars series = MarketData.GetBars(tf0);
            int i = series.Count - 1;
        }
        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 

Doing a quick read of your code, I see a few potential issues:

1) you declare the variable "i" twice in two different scopes. You have it at the class level, and then also within the PositionsOnClosed method. This could be your intention. However, the value for the variable "i" in PositionsOnClosed will never be the same as the value for "i" declared under the TimeFrame class variable.

2) Why do you do this multiple times?

Bars series = MarketData.GetBars(tf0);

Every time a tick comes in or a position is closed, your bot has to wait (and could be a while!) for ALL bar data to load!

You should declare "series" at the class level, and initialize it ONCE in the "OnStart" method. Then you can reference it anywhere else in the bot, and you won't slow down your bot on every tick waiting for all the data to constantly load over and over again.

Your code rewritten quickly (may contain errors as I'm not in front of a compiler or cTrader):

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter("Timeframe0", DefaultValue = "Hour4")]
        public TimeFrame tf0 { get; set; }

	//why are you doing this twice? you declare it here and in "PositionsOnClosed". 
        int i = 0;

	//Declare once!
	Bars series;

        protected override void OnStart()
        {
		//
		//Just call it once.
		//"series" will henceforth always be updated with the latest every time a new bar is created.
		//
            series = MarketData.GetBars(tf0);

	//You can also include multiple time frames and initalize each one once
	//    series2 = MarketData.GetBars(tf1);
	//etc etc
	//just declare the variables at the higher class level scope as shown above and then 
	//you can reference anywhere in your code below.

            Positions.Closed += PositionsOnClosed;
        }

        protected override void OnTick()
        {
            // Insert code to only run after count is larger than the count when the last position was closed

		//
		//This "i" will always be zero because that's what you set it to up above. 
		//
            if (i == 0 || i < series.Count - 1)
            {
                // Insert normal Trading code
                Print("series.Count - 1 = " + (series.Count - 1));
            }
            else
            {
                // Insert other Calculations
            }
        }
        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            // Get Bars on the specified timeframe then write the current bar to i

		//
		//why are you declaring i twice in two different scopes? 
		//The value for "i" here won't be the same as "i" used in "OnTick" because that "i" is the class scope.
		//
            int i = series.Count - 1;
        }
        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

 


@firemyst

firemyst
18 Oct 2020, 17:45

Easiest way is to multiply the ATR value by a fixed value, such as 100 or 1000 so its values are around the same as the tick volumes.


@firemyst

firemyst
18 Oct 2020, 17:43

RE:

caglar_G said:

What is the best method for initating a wait for a bot, example: The bot made a trade and closed, after closing you want it to wait for an x amount of time. Is threading.sleep sufficient?

I'd rather not use threading.sleep as it basically suspends the bot for a set amount of time, I might want the bot to do some calulations in the meantime. Is there an alternative to threading.sleep to achieve something like that? Thanks!  

You have multiple options depending on how you want to wait.

Example #1: you want to wait until a new bar is opened. That's easy. Just create a bool flag such as "closedThisBar". In your Positions_Closed event method, set "closedThisBar" to true. In the OnBar method, set "closedThisBar" to false. Then whenever you're wanting to open a position, check the flag before opening the position.

eg, if (!closedThisBar) { OpenPosition.... }

 

Example #2: you want to wait x-minutes/second. That's a bit more involved, but not difficult. Use the timer. In the timer event method, when the number of seconds/minutes has passed, again set a flag to indicate it's ok to open positions again.

 

Example #3: you want to wait x-ticks. Similar to #1 except you also need a variable to count the number of ticks. When a position is closed, reset your tick count to zero. When your tick count reaches your set threshold, set the boolean flag to true so you can open positions again.

 

That's just 3 ways off the top of my head.

Hope it helps :-)


@firemyst

firemyst
18 Oct 2020, 09:02 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE: RE:

mpistorius said:

firemyst said:

Spotware said:

You can specify label and comment in ExecuteMarketOrder, PlaceLimitOrder and PlaceStopOrder methods. If you would like to modify label and comment after that please post your idea to vote.spotware.com.

Hi there:

Are "comments" displayed anywhere? They don't appear in our "History" or "Events" tabs when backtesting.

Can you confirm if they are only displayed in the "Log" tab when we do the following:

Position p = Positions.Find(myLabel);
Print(p.Comment);

??? Or somewhere else?

Thank you

Also searched for this, but the info in this thread seems to suggest this feature is not available.  Actually, if you right-click on the headers in the History tab, you can select additional columns, including one to show comments.

You can find comments here (if you don't see the column, you need to right click and select it to show):

Or printed here in Logs as a result of the print statement:

If you don't have the "log" tab, you need to be under "automate".

 


@firemyst

firemyst
12 Oct 2020, 08:58

RE: RE: RE:

Shares4UsDevelopment said:

Just write your own indicators. If that works you've proven the error and let them solve it.

If they have an error in something as basic as an rsi or ema they need to solve it fast because it affects many and it 
points at bad programming/testing in the platform."

In defense of @Panagiotis and @Spotware:

1) they have had EMAs, SMAs, and RSI in cTrader for years with no reported problems/issues. You're one person who has reported an issue out of thousands who use those indicators in their bots without any issues (myself included)

2) how do you know your replicated-indicators that you wrote are correct? They might not throw an error, but that doesn't prove they're right/working/calculating values correctly.

3) your boss is wrong when he/she says, "it affects many". Obviously not if you're the only individual who has ever reported the problem.

So it gets back to the point you need to write simplified code to prove there's an issue with cTrader since nobody else is/has.

 

 


@firemyst

firemyst
11 Oct 2020, 16:36

RE:

Shares4UsDevelopment said:

 

(No, I'm not allowed to send you the cBot code)
But this info should be sufficient for your developers.

 

So you can't provide the cBot code, but you should be able to provide code that reproduces the problem.

Are you able to do that?

 


@firemyst

firemyst
10 Oct 2020, 04:29

RE: RE: RE:

Hi @Xammo:

I have been using NYC Servers for years and have never experienced any of the issues you're reporting. I'm using the standard cTrader set up and typically have 2-3 instances of cTrader running with multiple bot-instances of each executing. Mine don't send emails or have any of those event handlers you're using though.

What I would suggest is having them wipe down and re-image your VM so you start from a clean slate.

Also, if you submit a support ticket, as for "Nick Esposito" as he's the person who I have been dealing with the entire time.

Hope you figure out what's happening.


@firemyst

firemyst
09 Oct 2020, 17:53

RE: Break Even Price

fxtradersystems said:

The way I thought about it, was that the costs were fixed for the trade (now NetProfit includes both way commisions), but the profit fluctuated. You could therefore calculate the fixed cost as a proportionate distance of the Bid from the entry price.

My calculations look like:

// Calculate the distance of the trade, less the spread.
double distance = Bid - (position.EntryPrice + Symbol.Spread);
// Figure out how much the costs of the trade are versus the Gross profit.
double cost_fraction = (position.GrossProfit - position.NetProfit) / position.GrossProfit;
// The gross profit is spread out over the entire distance of the trade from the entry price
// therefore add this fraction of the distance on to the entry price.
double breakEven = position.EntryPrice + cost_fraction * distance;

// Equivalently for a sell position:
double distance = (position.EntryPrice - Symbol.Spread) - Bid;
double cost_fraction = (position.GrossProfit - position.NetProfit) / position.GrossProfit;
double breakEven = position.EntryPrice - cost_fraction * distance;

 

I believe your calculations are incorrect.

For starters, you're using BID price everywhere. On Long/buy positions, you get the ASK price, not the BID price.

In your calculation, your value could be negative as a result. For instance, assume ASK is 5, BID is 4, with a 1 pip spread. Thus your entry would be 5 (because the ASK could have been 5), so 4 - (5 + 1) = -2. For a long/buy position, the break even should be above the ASK price (obviously) and not below the BID price.

Second, your calculation (position.EntryPrice + Symbol.Spread) is adding a price value plus pips. You need to add price value plus the equivalent value in pips, so it should be:

(position.EntryPrice + (Symbol.Spread * Symbol.PipSize))

Hope that helps :-)

 

 


@firemyst

firemyst
02 Oct 2020, 08:17

RE:

PanagiotisCharalampous said:

Hi firemyst,

You can use Open API to retrieve the symbol information.

Best Regards,

Panagiotis 

Join us on Telegram

Hi @Panagiotis:

How do I use Open API from within a bot or indicator to retrieve the commission from the symbol information? I thought commission information isn't available?

Thank you.


@firemyst

firemyst
30 Sep 2020, 10:34

RE:

PanagiotisCharalampous said:

Hi firemyst,

Not it hasn't. At the moment you set the commissions yourself, through the backtesting settings.

Best Regards,

Panagiotis 

Join us on Telegram

I'm looking for a way to estimate commissions in indicators and bots _before_ a position is opened while a bot or indicator is running. I can hard-code a fixed figure, but obviously that wouldn't be accurate. This isn't for any sort of back-testing.

Any "creative ways" to figure that out? :-)

 


@firemyst

firemyst
29 Sep 2020, 08:43

RE:

Spotware said:

You can not retrieve such information at the moment. At some point we will add Commissions to the Symbol object.

Please vote for your favorite features: http://vote.spotware.com/forums/229166-ideas-and-suggestions-for-ctrader-and-calgo/category/76800-calgo

@Panagiotis / @Spotware:

Has this feature been implemented yet?

I don't see any kind of "commission" property yet directly available from the "Symbol" object.

 

Thank you.


@firemyst

firemyst
28 Sep 2020, 08:52 ( Updated at: 21 Dec 2023, 09:22 )

RE:

Hi @Panagiotis:

Thank you for the "inventive" solution!

It does lead to, however, an issue I've pointed out earlier with the short-comings of cTrader which I think your team at @Spotware really needs to consider implementing.

Look at the screen capture. What do you think is more "user friendly" and that users would appreciate more?

Having the configurations displayed as they are under the "Lines" section (2) ? Or having to create separate parameters for the color and styles without any sort of previews (1)?

Options #2 is definitely more "user friendly" and I think @Spotware seriously needs to consider allowing through the API the ability to access the color, style, size properties of "lines".

In this case, I would want to create an indicator data series (that holds nothing and just set to null) so I can allow users to select the color/style/size options nicely. Then in the API read those settings, and apply those to the chart icons drawn.

 

Thank you again though for the sample code solution.

 


@firemyst

firemyst
25 Sep 2020, 13:40

RE:

Hi @Panagiotis:

Your code works for drawings, but how do you get it to work for indicators?

Example. Take the code below. Insert it on an H1 chart and set the timeframe of the indicator to be M5. I'd expect to see 12 psar dots in the space of one bar (60 / 5 = 12).

I can't get it to work because of the Result[index] that's needed; I've tried doing it with Result[altIndex] to no avail.

using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
    public class Test : Indicator
    {
        [Parameter()]
        public TimeFrame SourceTimeFrame { get; set; }

        [Parameter("Min AF", DefaultValue = 0.02)]
        public double MinAF { get; set; }

        [Parameter("Max AF", DefaultValue = 0.2)]
        public double MaxAF { get; set; }

        [Output("Main", PlotType = PlotType.Points, LineStyle = LineStyle.Dots, LineColor = "White", Thickness = 2)]
        public IndicatorDataSeries Result { get; set; }

        private Bars _marketSeries;
        private ParabolicSAR _psar;

        int previousAltIndex = 0;

        protected override void Initialize()
        {
            if (SourceTimeFrame != null)
                _marketSeries = MarketData.GetBars(SourceTimeFrame, Symbol.Name);
            else
                _marketSeries = MarketData.GetBars(Bars.TimeFrame, Symbol.Name);

            _psar = Indicators.ParabolicSAR(_marketSeries, MinAF, MaxAF);
        }


        public override void Calculate(int index)
        {
            int altIndex = index;

            if (Bars.TimeFrame != _marketSeries.TimeFrame)
            {
                altIndex = _marketSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
            }

            Result[index] = _psar.Result[altIndex];

            //if (Bars.TimeFrame != _marketSeries.TimeFrame)
            //{
            //    altIndex = _marketSeries.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
            //    for (int i = previousAltIndex; i < altIndex; i++)
            //    {
            //        Chart.DrawVerticalLine(_marketSeries.OpenTimes[i].ToString(), _marketSeries.OpenTimes[i], Color.Red);
            //    }
            //    altIndex = previousAltIndex;
            //}

            // blah blah blah

        }
    }
}

 


@firemyst