Topics

Forum Topics not found

Replies

amusleh
31 Mar 2022, 10:44

Hi,

I just tested your code on EURUSD and it works fine, there are enough weekly bars for the moving average.

If bars.LoadMoreHistory() doesn't load enough bars then it means there is not enough historical bars for that symbol time frame.

The code I tested:

using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MTissue : Robot
    {
        [Parameter("MA TimeFrame", DefaultValue = "Weekly")]
        public TimeFrame MATimeFrame { get; set; }

        [Parameter("MA Period", DefaultValue = 200)]
        public int MAPeriod { get; set; }

        [Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MAType { get; set; }

        private MovingAverage _ma;

        protected override void OnStart()
        {
            var bars = MarketData.GetBars(MATimeFrame);

            while (bars.Count < MAPeriod * 2)
            {
                var numberOfLoadedBars = bars.LoadMoreHistory();

                Print(numberOfLoadedBars);

                if (numberOfLoadedBars < 1) break;
            }

            Print(bars.Count);

            _ma = Indicators.MovingAverage(bars.ClosePrices, MAPeriod, MAType);
        }

        protected override void OnTick()
        {
            Print("distance={0}", _ma.Result.LastValue.ToString("f2"));
        }
    }
}

Result:

31/03/2022 15:12:37.740 | CBot instance [New cBot, EURUSD, h1] started.
31/03/2022 15:12:38.599 | 1596
31/03/2022 15:12:39.662 | distance=1.15
31/03/2022 15:12:39.958 | distance=1.15
31/03/2022 15:12:40.396 | distance=1.15
31/03/2022 15:12:41.162 | distance=1.15
31/03/2022 15:12:41.505 | distance=1.15
31/03/2022 15:12:42.474 | CBot instance [New cBot, EURUSD, h1] stopped by user.

 


@amusleh

amusleh
31 Mar 2022, 10:38

RE: RE: RE:

ctid1980098 said:

Ctrader updated yesterday and this no longer works for some reason. Any thoughts? Trying to get it working. 

If i get it to work. I will post here

 

Hi,

I just tested it on cTrader 4.2 Spotware beta and it works fine, on which version it's not working?


@amusleh

amusleh
31 Mar 2022, 10:09

Hi,

To create multi option parameters you can use .NET enums, here is an example:

using cAlgo.API;

namespace NewcBot
{
    [Robot(AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter("Switch", DefaultValue = Switch.On)]
        public Switch SwitchParameter { get; set; }

        protected override void OnStart()
        {
            if (SwitchParameter == Switch.On)
            {
                Print("Switch in On");
            }
            else
            {
                Print("Switch in Off");
            }
        }


    }

    public enum Switch
    {
        On,
        Off
    }
}

 


@amusleh

amusleh
31 Mar 2022, 10:04

Hi,

There is no such issue, you can use any .NET library after referencing it on your cBot/Indicator project including Nuget packages.

I recommend you to use Visual studio when you are referencing other libraries, and also change the compiler from embeded to SDK on your cTrader dekstop settings -> Automate.

 


@amusleh

amusleh
31 Mar 2022, 10:01

Hi,

You can open your cBot/Indicator with Visual studio or any other IDE (after 4.2 release) and add folders to your indicator/cBot project like any other .NET project.

The cTrader automate code editor is a simple one file only code editor, it only shows the main code file of an indicator or cBot, to use full power of .,NET use an IDE like Visual studio or Rider, the cBot/Indicator is just a .NET project like any other, open it, and do anything you want to, and you can compile/build it from your IDE.

You can also use Git when using Visual studio.

here is an example: spotware/pattern-drawing: cTrader chart pattern drawing indicator (github.com)


@amusleh

amusleh
31 Mar 2022, 09:58

Hi,

You can put your business logic on another source file or even another assembly, and then use it on your cBot/Indicator.

You can create a wrapper interface around your cBot/Indicator class and inject it to other services that are located on other assemblies, this way you can use dependency injection and also you can perform unit testes by mocking the wrapper interface.

 

 


@amusleh

amusleh
31 Mar 2022, 09:54

Hi,

This error occurs when your deferred is timed out, if the client doesn't receive a response for your request in 5 seconds (you can change it by passing responseTimeoutInSeconds to Send method) the returned deferred will be timed out.

The cause of this issue can be invalid request, and you have to check for incoming error message after your request by listening to error message types, there are several error messages that server can return, please check the Open API documentation.


@amusleh

amusleh
31 Mar 2022, 09:50

Hi,

Please use suggestions section of the forum for suggesting a change or new feature, create a thread there.


@amusleh

amusleh
31 Mar 2022, 09:49

Hi,

You can remove the cloud attribute:

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Bands : Indicator
    {
        [Parameter("Distance (Pips)", DefaultValue = 10)]
        public double Distance { get; set; }

        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Output("Top", PlotType = PlotType.Line, LineColor = "Yellow")]
        public IndicatorDataSeries Top { get; set; }

        [Output("Bottom", PlotType = PlotType.Line, LineColor = "Yellow")]
        public IndicatorDataSeries Bottom { get; set; }

        protected override void Initialize()
        {
            Distance *= Symbol.PipSize;
        }

        public override void Calculate(int index)
        {
            Top[index] = Source[index] + Distance;
            Bottom[index] = Source[index] - Distance;
        }
    }
}

 


@amusleh

amusleh
30 Mar 2022, 09:12

RE: RE: Hello again Amusleh. Been trying to work it out but failed. Don't know how to get the X1 & X2. Here is what I did can you please assist me further thanks.

newbee said:

 private double GetAngle(int x1, double y1, int x2, double y2)
        {
            double xDiff = x2 - x1;
            var yDiff = ema20.Result.Last(2) - ema20.Result.Last(1);

            return Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI;
        }

Hi,

You should use the method, you don't have to change the variables inside the method, ex:

using System;
using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Angle : Indicator
    {
        private ExponentialMovingAverage _ema;

        protected override void Initialize()
        {
            _ema = Indicators.ExponentialMovingAverage(Bars.ClosePrices, 10);
        }

        public override void Calculate(int index)
        {
            // If you are using it on a cBot you can get index like this
            /// var index = Bars.Count - 1;
            // This will give you the angle between current EMA value and 10 previous value
            var angle = GetAngle(index, _ema.Result[index], index - 10, _ema.Result[index - 10]);

            Print(angle);
        }

        private double GetAngle(int x1, double y1, int x2, double y2)
        {
            double xDiff = x2 - x1;
            var yDiff = y2 - y1;

            return Math.Atan2(yDiff, xDiff) * 180.0 / Math.PI;
        }
    }
}

 


@amusleh

amusleh
30 Mar 2022, 09:05

Hi,

You can use a global variable to check if the position is already opened or not, ex:

isPositionsRequestSent = False
def onMessageReceived(client, message): # Callback for receiving all messages
    if message.payloadType in [ProtoHeartbeatEvent().payloadType, ProtoOAAccountAuthRes().payloadType, ProtoOAApplicationAuthRes().payloadType, ProtoOASymbolsListRes().payloadType, ProtoOAGetTrendbarsRes().payloadType]:
        return
    print("\nMessage received: \n", Protobuf.extract(message))
    
    
    if message.payloadType == ProtoOAExecutionEvent().payloadType:
        print("Execution event received")
        executionEvent = Protobuf.extract(message)
        print(executionEvent.position.positionId)
        positionId = executionEvent.position.positionId
        
      
    if isPositionsRequestSent is False:
        global isPositionsRequestSent
        isPositionsRequestSent = True
        symbolId = 1106
        clientMsgId = None
        volume = 2

        request = ProtoOANewOrderReq()
        request.ctidTraderAccountId = currentAccountId

        request.symbolId = int(symbolId)
        request.orderType = ProtoOAOrderType.MARKET
        request.tradeSide = ProtoOATradeSide.SELL
        request.volume = int(volume) * 100 


        deferred = client.send(request, clientMsgId = clientMsgId)
        deferred.addErrback(onError)

There are other solutions too, but this one is simplest one, it all depends on what you want to do and your design and architecture.

It's not something related to Open API or our package, these are basic programming stuff that you should know.


@amusleh

amusleh
30 Mar 2022, 09:00

RE: RE:

robson_T said:

amusleh said:

Hi,

We got his error report on Github issues too, we tested the package on Windows and Ubuntu and it works fine.

This issue is not related to OpenApiPy, it's related to Twisted.

Related Github issue: Cannot start ConsoleSample · Issue #10 · spotware/OpenApiPy (github.com)

Very good, fine, super... only this part on Github not helpful at all. So far I can't use this tool either. You just write: It works for me, I don't know what you mean, I'm closing. I don't know, but it seems to me that it would be more important to fix it instead of ignoring it.

Hi,

Please check the Gihub issue, the user who opened the issue found a solution for this issue.


@amusleh

amusleh
29 Mar 2022, 19:26 ( Updated at: 29 Mar 2022, 19:27 )

Hi,

Try to increase the timer interval, ex:

using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class z : Robot
    {
        [Parameter("Max time position open(hours)", DefaultValue = 2, MinValue = 1)]
        public int MaxTimeOpen { get; set; }

        protected override void OnStart()
        {
            Timer.Start(3600);

            // Put your initialization logic here
            Print("Start robot: ", Server.Time.Hour);
            if (Server.Time.Hour == 0)
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, 10000, "", 100, 100);
            }
        }

        protected override void OnTimer()
        {
            foreach (var position in Positions)
            {
                var timeElapsedSincePositionEntryTime = Server.TimeInUtc - position.EntryTime;

                Print("timeElapsedSincePositionEntryTime: {0}", timeElapsedSincePositionEntryTime);

                if (timeElapsedSincePositionEntryTime.TotalHours >= MaxTimeOpen)
                {
                    ClosePosition(position);
                }
            }
        }
    }
}

 


@amusleh

amusleh
29 Mar 2022, 19:25

Hi,

Most probably your cBot is causing this issue, you have to post the cBot code then we will be able to help you.


@amusleh

amusleh
29 Mar 2022, 19:24

Hi,

If you are using cTrader desktop you can use Go To Date Indicator: Go To Date Indicator | Algorithmic Forex Trading | cTrader Community


@amusleh

amusleh
29 Mar 2022, 14:22

RE: RE:

robson_T said:

amusleh said:

Hi,

We got his error report on Github issues too, we tested the package on Windows and Ubuntu and it works fine.

This issue is not related to OpenApiPy, it's related to Twisted.

Related Github issue: Cannot start ConsoleSample · Issue #10 · spotware/OpenApiPy (github.com)

Very good, fine, super... only this part on Github not helpful at all. So far I can't use this tool either. You just write: It works for me, I don't know what you mean, I'm closing. I don't know, but it seems to me that it would be more important to fix it instead of ignoring it.

Hi,

As it's not related to OpenApiPy we can't fix it, the exception is thrown by Twisted.

Which OS you are using?


@amusleh

amusleh
29 Mar 2022, 13:56

RE: RE:

firemyst said:

amusleh said:

Hi,

It does work, but it depends on the email service you are using, some services doesn't allow old SMTP authentication anymore like Gmail as it causes security issues.

I tested it on my own email server and it works fine.

cTrader automate API just provide a wrapper over .NET SMTP API to make it easier.

 

 

So it definitely works with gmail? I can set up a test gmail account, keep the same indicator code (except changing the email addresses as appropriate), and all should work "as is"?

Also, what do you mean by "old smtp authentication"? All the links I found, and posted in my original post, explain how to set up SMTP authentication with the parameters required by cTrader.

Thank you.

Hi,

No, it doesn't work with Gmail as far as I know, there was an option in Gmail settings that would allow SMPT authentication but I'm not sure if it's still possible or not.

As I said on my previous post, it all depends on your email provider, if they allow SMPT authentication then it should work fine without any issue, if they are using some other way for authentication then it will not work.


@amusleh

amusleh
29 Mar 2022, 10:55

Hi,

It does work, but it depends on the email service you are using, some services doesn't allow old SMTP authentication anymore like Gmail as it causes security issues.

I tested it on my own email server and it works fine.

cTrader automate API just provide a wrapper over .NET SMTP API to make it easier.

 


@amusleh

amusleh
29 Mar 2022, 10:50

Hi,

Try this:

using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class z : Robot
    {
        [Parameter("Max time position open(hours)", DefaultValue = 2, MinValue = 1)]
        public int MaxTimeOpen { get; set; }

        protected override void OnStart()
        {
            Timer.Start(1);

            // Put your initialization logic here
            Print("Start robot: ", Server.Time.Hour);
            if (Server.Time.Hour == 0)
            {
                ExecuteMarketOrder(TradeType.Sell, SymbolName, 10000, "", 100, 100);
            }
        }

        protected override void OnTimer()
        {
            foreach (var position in Positions)
            {
                var timeElapsedSincePositionEntryTime = Server.TimeInUtc - position.EntryTime;

                Print("timeElapsedSincePositionEntryTime: {0}", timeElapsedSincePositionEntryTime);

                if (timeElapsedSincePositionEntryTime.TotalHours >= MaxTimeOpen)
                {
                    ClosePosition(position);
                }
            }
        }
    }
}

 


@amusleh

amusleh
28 Mar 2022, 14:13

RE:

swapd0 said:

The checksum is right or I won't be able to login, ask for the symbol list or subscribe to a symbol.

I'm on an OSX machine, and I don't code in Python.

Hi,

We can't develop a sample for all languages, you can run the Python sample on your OSX machine if you want to.

Or use the QuickFIX library: quickfix/quickfix: QuickFIX C++ Fix Engine Library (github.com)


@amusleh