Open positions per Bar - OnTick

Created at 10 Jan 2024, 22:21
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!
RY

ryan.a.blake

Joined 28.01.2019

Open positions per Bar - OnTick
10 Jan 2024, 22:21


Hi,

I have been searching through all the threads in the forum and have tried almost everything. 

I am working in OnTick and understand OnBar would be the best option for this, but I need to use OnTick as my algo checks current Symbol .Bid == Bars.OpenPrices.Last(0) + 10 * Symbol.Pipsize. However, it constantly opens trades as expected, which I have controlled using -  if (Positions.Count(x => x.TradeType == TradeType.Sell && x.Label == InstanceName) == 0). 

I need it to open a trade per bar,  Bars.Count got me closer, but opened a few trades on one bar, due to it being OnTick and the condition still being met.

Am I missing an API reference that can help or is anybody aware of way to simply place trades per bar within the OnTick method?


@ryan.a.blake
Replies

PanagiotisCharalampous
11 Jan 2024, 06:33

Hi Ryan,

You can use a flag to achieve this e.g. bool CanTrade. Set it to false when a trade is taken and then set it back to true when a new bar is opened.

Best regards,

Panagiotis


@PanagiotisCharalampous

ryan.a.blake
11 Jan 2024, 16:55

RE: Open positions per Bar - OnTick

PanagiotisCharalampous said: 

Hi Ryan,

You can use a flag to achieve this e.g. bool CanTrade. Set it to false when a trade is taken and then set it back to true when a new bar is opened.

Best regards,

Panagiotis

 

Thanks Panagiotis,

I have attempted the code below, but believe I am missing something as it places multiple trades per bar, but trader per bar after bar is opened. I attempted to limit positions with Positions.Count, but that stops it being placed per bar. 

 

Have I missed something?

 

Thanks for your help.

 

private bool _canTrade;
private int barCountSinceLastPosition;
        protected override void OnStart()
        {
            _ema1 = Indicators.GetIndicator<SampleEMA>(Source1, Period1);
            _ema2 = Indicators.GetIndicator<SampleEMA>(Source2, Period2);
             _ema3 = Indicators.GetIndicator<SampleEMA>(Source3, Period3);
            _rsi = Indicators.RelativeStrengthIndex(Source3, Period3);
           
           Bars.BarOpened += Bar_Opened;
         }
        
           void Bar_Opened(BarOpenedEventArgs args)
                   {
                      _canTrade = false;
            
                   }
        
         protected override void OnTick()
        {   
           if (IncludeBreakEven == true)
                GoToBreakEven();
               
            var Ema1 = _ema1.Result.Last(0);
            var Ema2 = _ema2.Result.Last(0);
            var Ema1i = _ema1.Result.Last(2);
            var Ema2i = _ema2.Result.Last(2);
            var Ema3 = _ema3.Result.LastValue;
            var rising = _ema1.Result.IsRising();
            var falling = _ema2.Result.IsFalling();
            var rising2 = _ema2.Result.IsRising();
            var falling2 = _ema1.Result.IsFalling();
                          
             if (Ema1 > Ema2 && falling && falling2 && Symbol.Bid == Bars.OpenPrices.Last(0) - (pips * Symbol.PipSize))
            {
                
                   if (Positions.Count(x => x.TradeType == TradeType.Sell && x.Label == InstanceName) == 0)
                
                         {
                               double volume = Symbol.QuantityToVolumeInUnits(lotsize);
                               ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, InstanceName, SL, TP);
                
                           }
                               {
                                  _canTrade = true;
                               }
                                    if(_canTrade)
                                    {
                                        if (Ema1 > Ema2 && falling && falling2 && Symbol.Bid == Bars.OpenPrices.Last(0) - (pips * Symbol.PipSize))
                                         {
                                             double volume = Symbol.QuantityToVolumeInUnits(lotsize);
                                             ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, InstanceName, SL, TP);
                                         }
                                   }
                              }
                          {
                    CloseSell();
                     } 
                    
               }


@ryan.a.blake

PanagiotisCharalampous
12 Jan 2024, 06:59

RE: RE: Open positions per Bar - OnTick

ryan.a.blake said: 

PanagiotisCharalampous said: 

Hi Ryan,

You can use a flag to achieve this e.g. bool CanTrade. Set it to false when a trade is taken and then set it back to true when a new bar is opened.

Best regards,

Panagiotis

 

Thanks Panagiotis,

I have attempted the code below, but believe I am missing something as it places multiple trades per bar, but trader per bar after bar is opened. I attempted to limit positions with Positions.Count, but that stops it being placed per bar. 

 

Have I missed something?

 

Thanks for your help.

 

private bool _canTrade;
private int barCountSinceLastPosition;
        protected override void OnStart()
        {
            _ema1 = Indicators.GetIndicator<SampleEMA>(Source1, Period1);
            _ema2 = Indicators.GetIndicator<SampleEMA>(Source2, Period2);
             _ema3 = Indicators.GetIndicator<SampleEMA>(Source3, Period3);
            _rsi = Indicators.RelativeStrengthIndex(Source3, Period3);
           
           Bars.BarOpened += Bar_Opened;
         }
        
           void Bar_Opened(BarOpenedEventArgs args)
                   {
                      _canTrade = false;
            
                   }
        
         protected override void OnTick()
        {   
           if (IncludeBreakEven == true)
                GoToBreakEven();
               
            var Ema1 = _ema1.Result.Last(0);
            var Ema2 = _ema2.Result.Last(0);
            var Ema1i = _ema1.Result.Last(2);
            var Ema2i = _ema2.Result.Last(2);
            var Ema3 = _ema3.Result.LastValue;
            var rising = _ema1.Result.IsRising();
            var falling = _ema2.Result.IsFalling();
            var rising2 = _ema2.Result.IsRising();
            var falling2 = _ema1.Result.IsFalling();
                          
             if (Ema1 > Ema2 && falling && falling2 && Symbol.Bid == Bars.OpenPrices.Last(0) - (pips * Symbol.PipSize))
            {
                
                   if (Positions.Count(x => x.TradeType == TradeType.Sell && x.Label == InstanceName) == 0)
                
                         {
                               double volume = Symbol.QuantityToVolumeInUnits(lotsize);
                               ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, InstanceName, SL, TP);
                
                           }
                               {
                                  _canTrade = true;
                               }
                                    if(_canTrade)
                                    {
                                        if (Ema1 > Ema2 && falling && falling2 && Symbol.Bid == Bars.OpenPrices.Last(0) - (pips * Symbol.PipSize))
                                         {
                                             double volume = Symbol.QuantityToVolumeInUnits(lotsize);
                                             ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, InstanceName, SL, TP);
                                         }
                                   }
                              }
                          {
                    CloseSell();
                     } 
                    
               }

Hi Ryan,

_canTrade needs to be set to false in OnTick() and to true in OnBar()

Best regards,

Panagiotis


@PanagiotisCharalampous

ryan.a.blake
14 Jan 2024, 22:34

RE: RE: RE: Open positions per Bar - OnTick

PanagiotisCharalampous said: 

ryan.a.blake said: 

PanagiotisCharalampous said: 

Hi Ryan,

You can use a flag to achieve this e.g. bool CanTrade. Set it to false when a trade is taken and then set it back to true when a new bar is opened.

Best regards,

Panagiotis

 

Thanks Panagiotis,

I have attempted the code below, but believe I am missing something as it places multiple trades per bar, but trader per bar after bar is opened. I attempted to limit positions with Positions.Count, but that stops it being placed per bar. 

 

Have I missed something?

 

Thanks for your help.

 

private bool _canTrade;
private int barCountSinceLastPosition;
        protected override void OnStart()
        {
            _ema1 = Indicators.GetIndicator<SampleEMA>(Source1, Period1);
            _ema2 = Indicators.GetIndicator<SampleEMA>(Source2, Period2);
             _ema3 = Indicators.GetIndicator<SampleEMA>(Source3, Period3);
            _rsi = Indicators.RelativeStrengthIndex(Source3, Period3);
           
           Bars.BarOpened += Bar_Opened;
         }
        
           void Bar_Opened(BarOpenedEventArgs args)
                   {
                      _canTrade = false;
            
                   }
        
         protected override void OnTick()
        {   
           if (IncludeBreakEven == true)
                GoToBreakEven();
               
            var Ema1 = _ema1.Result.Last(0);
            var Ema2 = _ema2.Result.Last(0);
            var Ema1i = _ema1.Result.Last(2);
            var Ema2i = _ema2.Result.Last(2);
            var Ema3 = _ema3.Result.LastValue;
            var rising = _ema1.Result.IsRising();
            var falling = _ema2.Result.IsFalling();
            var rising2 = _ema2.Result.IsRising();
            var falling2 = _ema1.Result.IsFalling();
                          
             if (Ema1 > Ema2 && falling && falling2 && Symbol.Bid == Bars.OpenPrices.Last(0) - (pips * Symbol.PipSize))
            {
                
                   if (Positions.Count(x => x.TradeType == TradeType.Sell && x.Label == InstanceName) == 0)
                
                         {
                               double volume = Symbol.QuantityToVolumeInUnits(lotsize);
                               ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, InstanceName, SL, TP);
                
                           }
                               {
                                  _canTrade = true;
                               }
                                    if(_canTrade)
                                    {
                                        if (Ema1 > Ema2 && falling && falling2 && Symbol.Bid == Bars.OpenPrices.Last(0) - (pips * Symbol.PipSize))
                                         {
                                             double volume = Symbol.QuantityToVolumeInUnits(lotsize);
                                             ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, InstanceName, SL, TP);
                                         }
                                   }
                              }
                          {
                    CloseSell();
                     } 
                    
               }

Hi Ryan,

_canTrade needs to be set to false in OnTick() and to true in OnBar()

Best regards,

Panagiotis

Thanks Panagiotis,

Could you share an example code for this? 

I have added OnBar() but multiple trades are still opening. Have I placed everything correctly? 

    private SampleEMA _ema1 { get; set; }
        private SampleEMA _ema2 { get; set; }
         private SampleEMA _ema3 { get; set; }
        private RelativeStrengthIndex _rsi { get; set; }

private bool _canBuy;
 private bool _canSell;

        protected override void OnStart()
        {

            _ema1 = Indicators.GetIndicator<SampleEMA>(Source1, Period1);
            _ema2 = Indicators.GetIndicator<SampleEMA>(Source2, Period2);
             _ema3 = Indicators.GetIndicator<SampleEMA>(Source3, Period3);
            _rsi = Indicators.RelativeStrengthIndex(Source3, Period3);
      
        }            
                
protected override void OnBar()
               
               {
            _canSell = true;       
               }
               
         protected override void OnTick()
        {
        Print("OnTick");
        
     
           if (IncludeBreakEven == true)
                GoToBreakEven();
               

            var Ema1 = _ema1.Result.Last(0);
            var Ema2 = _ema2.Result.Last(0);
            var rising = _ema1.Result.IsRising();
            var falling = _ema2.Result.IsFalling();
            var rising2 = _ema2.Result.IsRising();
            var falling2 = _ema1.Result.IsFalling();
                    
             if (Ema1 < Ema2 && rising && rising2 && Symbol.Bid == Bars.OpenPrices.Last(0) + (pips * Symbol.PipSize))
              
            {
                _canBuy = false;
            }
                            
                     {
                      CloseBuy();
                      }
                      
                      
             
             if (Ema1 > Ema2 && falling && falling2 && Symbol.Bid == Bars.OpenPrices.Last(0) - (pips * Symbol.PipSize))
            {           
                   
                  double volume = Symbol.QuantityToVolumeInUnits(lotsize);
                ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, InstanceName, SL, TP);
                }
                
                
                if(_canSell == true)
                 
                {
            if (Positions.Count(x => x.TradeType == TradeType.Sell && x.Label == InstanceName) >= 2)
            {
            _canSell = false;
             
               
                }
             
               }
               {
                    CloseSell();
                }
               
               }
                        
 
               
        private void CloseSell()
        {
        var Ema1 = _ema1.Result.Last(0);
            var Ema2 = _ema2.Result.Last(0); 
            foreach (var position in Positions)
                if (Ema1 < Ema2 && position.TradeType == TradeType.Sell)
                
                {
                    ClosePosition(position);
                }
        }


   private void CloseBuy()
        {
             var Ema1 = _ema1.Result.Last(0);
            var Ema2 = _ema2.Result.Last(0);
            foreach (var position in Positions)
                if (Ema1 > Ema2 && position.TradeType == TradeType.Buy)
                {
                    ClosePosition(position);
                }
        }


@ryan.a.blake

PanagiotisCharalampous
15 Jan 2024, 07:58

RE: RE: RE: RE: Open positions per Bar - OnTick

ryan.a.blake said: 

PanagiotisCharalampous said: 

ryan.a.blake said: 

PanagiotisCharalampous said: 

Hi Ryan,

You can use a flag to achieve this e.g. bool CanTrade. Set it to false when a trade is taken and then set it back to true when a new bar is opened.

Best regards,

Panagiotis

 

Thanks Panagiotis,

I have attempted the code below, but believe I am missing something as it places multiple trades per bar, but trader per bar after bar is opened. I attempted to limit positions with Positions.Count, but that stops it being placed per bar. 

 

Have I missed something?

 

Thanks for your help.

 

private bool _canTrade;
private int barCountSinceLastPosition;
        protected override void OnStart()
        {
            _ema1 = Indicators.GetIndicator<SampleEMA>(Source1, Period1);
            _ema2 = Indicators.GetIndicator<SampleEMA>(Source2, Period2);
             _ema3 = Indicators.GetIndicator<SampleEMA>(Source3, Period3);
            _rsi = Indicators.RelativeStrengthIndex(Source3, Period3);
           
           Bars.BarOpened += Bar_Opened;
         }
        
           void Bar_Opened(BarOpenedEventArgs args)
                   {
                      _canTrade = false;
            
                   }
        
         protected override void OnTick()
        {   
           if (IncludeBreakEven == true)
                GoToBreakEven();
               
            var Ema1 = _ema1.Result.Last(0);
            var Ema2 = _ema2.Result.Last(0);
            var Ema1i = _ema1.Result.Last(2);
            var Ema2i = _ema2.Result.Last(2);
            var Ema3 = _ema3.Result.LastValue;
            var rising = _ema1.Result.IsRising();
            var falling = _ema2.Result.IsFalling();
            var rising2 = _ema2.Result.IsRising();
            var falling2 = _ema1.Result.IsFalling();
                          
             if (Ema1 > Ema2 && falling && falling2 && Symbol.Bid == Bars.OpenPrices.Last(0) - (pips * Symbol.PipSize))
            {
                
                   if (Positions.Count(x => x.TradeType == TradeType.Sell && x.Label == InstanceName) == 0)
                
                         {
                               double volume = Symbol.QuantityToVolumeInUnits(lotsize);
                               ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, InstanceName, SL, TP);
                
                           }
                               {
                                  _canTrade = true;
                               }
                                    if(_canTrade)
                                    {
                                        if (Ema1 > Ema2 && falling && falling2 && Symbol.Bid == Bars.OpenPrices.Last(0) - (pips * Symbol.PipSize))
                                         {
                                             double volume = Symbol.QuantityToVolumeInUnits(lotsize);
                                             ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, InstanceName, SL, TP);
                                         }
                                   }
                              }
                          {
                    CloseSell();
                     } 
                    
               }

Hi Ryan,

_canTrade needs to be set to false in OnTick() and to true in OnBar()

Best regards,

Panagiotis

Thanks Panagiotis,

Could you share an example code for this? 

I have added OnBar() but multiple trades are still opening. Have I placed everything correctly? 

    private SampleEMA _ema1 { get; set; }
        private SampleEMA _ema2 { get; set; }
         private SampleEMA _ema3 { get; set; }
        private RelativeStrengthIndex _rsi { get; set; }

private bool _canBuy;
 private bool _canSell;

        protected override void OnStart()
        {

            _ema1 = Indicators.GetIndicator<SampleEMA>(Source1, Period1);
            _ema2 = Indicators.GetIndicator<SampleEMA>(Source2, Period2);
             _ema3 = Indicators.GetIndicator<SampleEMA>(Source3, Period3);
            _rsi = Indicators.RelativeStrengthIndex(Source3, Period3);
      
        }            
                
protected override void OnBar()
               
               {
            _canSell = true;       
               }
               
         protected override void OnTick()
        {
        Print("OnTick");
        
     
           if (IncludeBreakEven == true)
                GoToBreakEven();
               

            var Ema1 = _ema1.Result.Last(0);
            var Ema2 = _ema2.Result.Last(0);
            var rising = _ema1.Result.IsRising();
            var falling = _ema2.Result.IsFalling();
            var rising2 = _ema2.Result.IsRising();
            var falling2 = _ema1.Result.IsFalling();
                    
             if (Ema1 < Ema2 && rising && rising2 && Symbol.Bid == Bars.OpenPrices.Last(0) + (pips * Symbol.PipSize))
              
            {
                _canBuy = false;
            }
                            
                     {
                      CloseBuy();
                      }
                      
                      
             
             if (Ema1 > Ema2 && falling && falling2 && Symbol.Bid == Bars.OpenPrices.Last(0) - (pips * Symbol.PipSize))
            {           
                   
                  double volume = Symbol.QuantityToVolumeInUnits(lotsize);
                ExecuteMarketOrder(TradeType.Sell, SymbolName, volume, InstanceName, SL, TP);
                }
                
                
                if(_canSell == true)
                 
                {
            if (Positions.Count(x => x.TradeType == TradeType.Sell && x.Label == InstanceName) >= 2)
            {
            _canSell = false;
             
               
                }
             
               }
               {
                    CloseSell();
                }
               
               }
                        
 
               
        private void CloseSell()
        {
        var Ema1 = _ema1.Result.Last(0);
            var Ema2 = _ema2.Result.Last(0); 
            foreach (var position in Positions)
                if (Ema1 < Ema2 && position.TradeType == TradeType.Sell)
                
                {
                    ClosePosition(position);
                }
        }


   private void CloseBuy()
        {
             var Ema1 = _ema1.Result.Last(0);
            var Ema2 = _ema2.Result.Last(0);
            foreach (var position in Positions)
                if (Ema1 > Ema2 && position.TradeType == TradeType.Buy)
                {
                    ClosePosition(position);
                }
        }

Hi Ryan,

The flag needs to be set to false immediately after the order is executed. You seem to set it to false at random positions. Unfortunately I do not have the time to write the entire strategy for you. If you are not able to code this yourself, you can request for professional assistance.

Best regards,

Panagiotis


@PanagiotisCharalampous

ryan.a.blake
15 Jan 2024, 18:10

RE: RE: RE: RE: RE: Open positions per Bar - OnTick

Hi Panagiotis,

Thanks for your help.

I worked it out and it works as expected.

Thanks.


@ryan.a.blake