GDPR-83_694920's avatar
GDPR-83_694920
Blocked user by Spotware at 16 Jan 2024, 06:52
0 follower(s) 0 following 0 subscription(s)
Replies

GDPR-83_694920
31 May 2019, 10:28

Hi Panagiotis

Ok many thanks for confimring about the event driven programming and that they run independantly/it is not multithreading

Yes that is exactly what I am trying to achieve - trigger the new order only once the last of the group of closing trades has completed through the OnPositionsClosed method

Here is an example code I quickly put together - slightly different from the original question in that I am actually using a CloseAllPositions method to trigger the closing of a group of trades and also obviously this code is not complete but hopefully is enough to give you an idea

        protected override void OnStart()
        {
            Positions.Closed += OnPositionsClosed;
        }
        protected override void OnTick()
        {
            Counter=0;
            if (x=y)
               CloseAllPostions();
        }
        private void CloseAllPositions()
        {
            foreach (Position p in Positions.Where(p => p.Label == BotLabel).ToArray())
                ClosePosition(p);
        }
        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            Position pos = args.Position;
            if (pos.Label == BotLabel)
            {
                ++Counter;
                if (Counter == 1)
                    ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, BotLabel, null, null);
            }
        }

Obviously this will trigger the new trade when the first of the group of closing trades loops through the OPC method and yes as you say I would much rather do this only when the last of the group of trades has looped through the OPC so another way I tried was to count the number of open positions in the CloseAllPositions method before they were closed and trigger the new order in the OPC method only when the number of orders are zero

        private void CloseAllPositions()
        {
         OpenPositionsCount = Positions.Where(p => p.Label == BotLabel).Count();
         foreach (Position p in Positions.Where(p => p.Label == BotLabel).ToArray())
                ClosePosition(p);
        }
        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            Position p = args.Position;
            if (p.Label == BotLabel)
            {
             if (OpenPositionsCount==0)
                    ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, BotLabel, null, 5);
            }
        }

It was very quickly clear that this doesn't work though (it was an early attempt at figuring this out but wanted to put it in as one of the alternative ideas) as the number of orders are already zero by the time the first loop of the OPC occurs as they have all been closed already and it is only the event driven programming that is processing these closures through the OPC so 10 new orders are triggered as they loop through the OPC

There are quite a few other ways I tried but all had their own problems and as I say the ++Counter approach seems to work the best but gets messed up if a tick occurs in the time that the group of closing orders are being processed through the OPC

Hope that is what you are after in terms of a better explanation - basically I guess the question is "how is it possible to properly 'detect' that event driven programming processes have properly completed?"

(Although I think that is not really a correct/impossible to answer question but hopefully it makes some sense!)

Many thanks

Max


GDPR-83_694920
28 Feb 2019, 14:37

I don't honestly know what an overload actually is haha ;) and am amazed I actually got something 'right' (relatively new to C# and cAlgo) but good to know it does work thanks for confirming!


GDPR-83_694920
28 Feb 2019, 12:41

Great! Thank you so much for confirming - my code is minimal and stragithforward so there should never (...! ;) be any bad volume etc. issues and it is only the completion of the order execution that concerns me so want the code to retry placing the order again and again until sucesful so will go with the above and continue forward testing to see how things go

Many thanks again very much appreciated!


GDPR-83_694920
28 Feb 2019, 12:33

Hi Panagiotis

Many thanks for the reply and yes was also concerned about an infinite loop but can I please confirm if I am understanding the '.IsSuccesful' correcty

Is the usage meant only for detecting technical problems due to issues with the code (bad volume etc.) or also for detecting completion of actual order execution (order does not complete at the broker for whatever reason therefore order is 'unsuccessful' and I want to retry/place the order again ASAP)


GDPR-83_694920
27 Feb 2019, 19:38

Hi

Not sure if I am understanding this correctly but I was using this ATR Hugoman built and posted in the Indicators Section until I realised it was possible to use built in indicators and ever since I have been using the built in ATR so this post got me worried it is not actually working MTF so quickly put together the below code to test and MTF on built in ATR seems to be working fine (or as I say perhaps I am misunderstanding something somehwere here!?)

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        private AverageTrueRange ATRM5;
        private AverageTrueRange ATRM15;
        private AverageTrueRange ATRH;
        private AverageTrueRange ATRD;

        private MarketSeries TFSM5;
        private MarketSeries TFSM15;
        private MarketSeries TFSH;
        private MarketSeries TFSD;

        protected override void OnStart()
        {
            TFSM5 = MarketData.GetSeries(TimeFrame.Minute5);
            TFSM15 = MarketData.GetSeries(TimeFrame.Minute15);
            TFSH = MarketData.GetSeries(TimeFrame.Hour);
            TFSD = MarketData.GetSeries(TimeFrame.Daily);

            ATRM5 = Indicators.AverageTrueRange(TFSM5, 14, MovingAverageType.Exponential);
            ATRM15 = Indicators.AverageTrueRange(TFSM15, 14, MovingAverageType.Exponential);
            ATRH = Indicators.AverageTrueRange(TFSH, 14, MovingAverageType.Exponential);
            ATRD = Indicators.AverageTrueRange(TFSD, 14, MovingAverageType.Exponential);
        }

        protected override void OnTick()
        {
            double ATRMinute5 = Math.Round(ATRM5.Result.LastValue, Symbol.Digits);
            double ATRMinute15 = Math.Round(ATRM15.Result.LastValue, Symbol.Digits);
            double ATRHour = Math.Round(ATRH.Result.LastValue, Symbol.Digits);
            double ATRDaily = Math.Round(ATRD.Result.LastValue, Symbol.Digits);

            Print("M5 {0}  M15 {1}  H {2}  D {3}", ATRMinute5, ATRMinute15, ATRHour, ATRDaily);
        }
    }
}