Multiple cbots and only one position at a time

Created at 28 Dec 2023, 17:54
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
The_Dark_Knight's avatar

The_Dark_Knight

Joined 26.12.2023

Multiple cbots and only one position at a time
28 Dec 2023, 17:54


Hi, I have some bots running independently, but my idea is to prevent the bots' positions from overlapping, so that a new position is opened only when the current one has been closed. I tried to initialize a static variable in one of the bots, and applied the variable to the rest of the bots. Could you please tell me if this code is correct?

Variable applied in the first bot:


        private static bool isPositionAllowed;


        protected override void OnStart()
        {           
            if (!isPositionAllowed)
        {
            isPositionAllowed = true; 
        }

 

 

Variable applied in the rest of the bots (example):

 

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class CustomStrategy : Robot
    {
       
                
        [Parameter("Williams 20", DefaultValue = 20, Group = "BUY")]
        public int WilliamsPeriods20 { get; set; }
        
        [Parameter("Take Profit Pips", DefaultValue = 20, Group = "BUY")]
        public double TakeProfitPips { get; set; }

        [Parameter("Stop Loss Pips", DefaultValue = 20, Group = "BUY")]
        public int StopLossPips { get; set; }
        
        
        
        private WilliamsPctR williamsPercentR20;
        
              
        private static bool isPositionAllowed;
        
        
        
        protected override void OnStart()
        {
            
            williamsPercentR20 = Indicators.WilliamsPctR(WilliamsPeriods20);            
                
        }


        protected override void OnBar()
    {       
   
       if (isPositionAllowed)
    {
    
    
       if (ShouldEnterLong())
    {         
        var tradeSize = Symbol.QuantityToVolumeInUnits(0.01);  
        ExecuteMarketOrder(TradeType.Buy, SymbolName, tradeSize, "Long Entry", StopLossPips, TakeProfitPips); 
        
        isPositionAllowed = false;        
    }
    
    
       if (ShouldExitLong())
    {
        CloseLongPositions();
        
        isPositionAllowed = true; 
    }
    }
    }
  
     
        private bool ShouldEnterLong()
     
{    
    
           return      
                       
                   
                      williamsPercentR20.Result.Last(0) < -80
                       
 ;  
 }     
                
        private bool ShouldExitLong()       
       {    
          
           return
           
                     
                     williamsPercentR20.Result.Last(0) > -20
                 
;
}


        private void CloseLongPositions()
        {
            foreach (var position in Positions)
            {
                if (position.TradeType == TradeType.Buy && ShouldExitLong())
                {
                    ClosePosition(position);
                    isPositionAllowed = true;
       }
      
      }}}}


@The_Dark_Knight
Replies

PanagiotisCharalampous
29 Dec 2023, 06:09

Hi there,

It would be simpler to check if there are any positions open instead of using this method. You can use Positions.Count to do this.

Best regards,

Panagiotis


@PanagiotisCharalampous

The_Dark_Knight
29 Dec 2023, 21:41 ( Updated at: 30 Dec 2023, 07:09 )

RE: Multiple cbots and only one position at a time

PanagiotisCharalampous said: 

Hi there,

It would be simpler to check if there are any positions open instead of using this method. You can use Positions.Count to do this.

Best regards,

Panagiotis


Thanks Panagiotis, I'll try it and see how it works. I know more about trading than programming, and ChatGPT helps a lot, but sometimes it overcomplicates things.

Happy end of year.

Kind regards, Santiago


@The_Dark_Knight

firemyst
30 Dec 2023, 09:54

If you don't want positions of the same symbol to overlap, then you need to find all positions first of the current symbol, and then doing a Positions.Count on that.

Doing a generic “Positions.Count” will count all open positions, even if you have several not open on the current symbol your bot instance is running.

For example, you could have an AUDUSD position open, a EURUSD position open, and EURJPY position open. If you only want to limit your bot so that you don't open another EURJPY position, then you need to search all positions that are just EURJPY.

Example:

int numPositionsAlreadyOpen = Positions.FindAll(p.Label, Symbol.Name).Count();

Hope that helps you even more :-)


@firemyst

The_Dark_Knight
30 Dec 2023, 11:24 ( Updated at: 30 Dec 2023, 11:26 )

RE: Multiple cbots and only one position at a time

firemyst said: 

If you don't want positions of the same symbol to overlap, then you need to find all positions first of the current symbol, and then doing a Positions.Count on that.

Doing a generic “Positions.Count” will count all open positions, even if you have several not open on the current symbol your bot instance is running.

For example, you could have an AUDUSD position open, a EURUSD position open, and EURJPY position open. If you only want to limit your bot so that you don't open another EURJPY position, then you need to search all positions that are just EURJPY.

Example:

int numPositionsAlreadyOpen = Positions.FindAll(p.Label, Symbol.Name).Count();

Hope that helps you even more :-)

 

Thanks Firemyst, that's also very helpful. I found something like that in the forum.

For now, I will apply this logic by grouping the long and short positions separately, in order to decrease exposure at times where the pairs are correlated. According to the results of QuantAnalyzer, this would greatly soften the portfolio curve, but I don't know how much to trust those hypothetical results. I'll try it first in demo.

I added it like this in each cbot. Please correct me if that´s wrong:

 

protected override void OnBar()
{   

var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);

var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);

 

 

if (longPositionsCount == 0 && ShouldEnterLong())    { logic }

if (ShouldExitLong()) {CloseLongPositions();}

 

if (shortPositionsCount == 0 && ShouldEnterShort())    { logic }

if (ShouldExitShort()) {CloseShortPositions();}    

}

 


@The_Dark_Knight

firemyst
30 Dec 2023, 12:00 ( Updated at: 31 Dec 2023, 16:08 )

RE: RE: Multiple cbots and only one position at a time

The_Dark_Knight said: 

firemyst said: 

If you don't want positions of the same symbol to overlap, then you need to find all positions first of the current symbol, and then doing a Positions.Count on that.

Doing a generic “Positions.Count” will count all open positions, even if you have several not open on the current symbol your bot instance is running.

For example, you could have an AUDUSD position open, a EURUSD position open, and EURJPY position open. If you only want to limit your bot so that you don't open another EURJPY position, then you need to search all positions that are just EURJPY.

Example:

int numPositionsAlreadyOpen = Positions.FindAll(p.Label, Symbol.Name).Count();

Hope that helps you even more :-)

 

Thanks Firemyst, that's also very helpful. I found something like that in the forum.

For now, I will apply this logic by grouping the long and short positions separately, in order to decrease exposure at times where the pairs are correlated. According to the results of QuantAnalyzer, this would greatly soften the portfolio curve, but I don't know how much to trust those hypothetical results. I'll try it first in demo.

I added it like this in each cbot. Please correct me if that´s wrong:

 

protected override void OnBar()
{   

var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);

var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);

 

 

if (longPositionsCount == 0 && ShouldEnterLong())    { logic }

if (ShouldExitLong()) {CloseLongPositions();}

 

if (shortPositionsCount == 0 && ShouldEnterShort())    { logic }

if (ShouldExitShort()) {CloseShortPositions();}    

}

 

I can't tell you if it's right or wrong because I'm not 100% sure what you want to do.

What your code will do though is found the number of buy positions and sell positions open across all active bot instances and won't open a long position for any symbol if you have a long position open anywhere in any account; likewise your code won't open a short position for any symbol if you have a short position open anywhere.


@firemyst

The_Dark_Knight
31 Dec 2023, 17:00

RE: RE: RE: Multiple cbots and only one position at a time

firemyst said: 

I can't tell you if it's right or wrong because I'm not 100% sure what you want to do.

What your code will do though is found the number of buy positions and sell positions open across all active bot instances and won't open a long position for any symbol if you have a long position open anywhere in any account; likewise your code won't open a short position for any symbol if you have a short position open anywhere.

 

Yes, perfect! that's exactly the idea. Thanks Firemyst


@The_Dark_Knight