Separate logic for opening and closing positions

Created at 07 Apr 2020, 12: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!
PR

Prasanna

Joined 19.03.2020

Separate logic for opening and closing positions
07 Apr 2020, 12:21


Hi,

I'm trying to modify the sample RSI cBot with following logic

Open long position when RSI crosses above 30 and close that position when RSI crosses above 70

Open Short position when RSI crosses below 70 and close that position when RSI crosses below 30

I was thinking that I need write separate logic to be mentioned for opening and closing positions. How do I mention separate logic? below is the sample RSI cBot I'm working on

Any comments on this is much appreciated. Thanks

 

// -------------------------------------------------------------------------------------------------
//
//    This code is a cTrader Automate API example.
//
//    This cBot is intended to be used as a sample and does not guarantee any particular outcome or
//    profit of any kind. Use it at your own risk.
//    
//    All changes to this file might be lost on the next application update.
//    If you are going to modify this file please make a copy using the "Duplicate" command.
//
//    The "Sample RSI cBot" will create a buy order when the Relative Strength Index indicator crosses the  level 30, 
//    and a Sell order when the RSI indicator crosses the level 70. The order is closed be either a Stop Loss, defined in 
//    the "Stop Loss" parameter, or by the opposite RSI crossing signal (buy orders close when RSI crosses the 70 level 
//    and sell orders are closed when RSI crosses the 30 level). 
//
//    The cBot can generate only one Buy or Sell order at any given time.
//
// -------------------------------------------------------------------------------------------------

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SampleRSIcBot : Robot
    {
        [Parameter("Quantity (Lots)", Group = "Volume", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }

        [Parameter("Source", Group = "RSI")]
        public DataSeries Source { get; set; }

        [Parameter("Periods", Group = "RSI", DefaultValue = 14)]
        public int Periods { get; set; }

        private RelativeStrengthIndex rsi;

        protected override void OnStart()
        {
            rsi = Indicators.RelativeStrengthIndex(Source, Periods);
        }

        protected override void OnTick()
        {
            if (rsi.Result.LastValue < 30)
            {
                Close(TradeType.Sell);
                Open(TradeType.Buy);
            }
            else if (rsi.Result.LastValue > 70)
            {
                Close(TradeType.Buy);
                Open(TradeType.Sell);
            }
        }

        private void Close(TradeType tradeType)
        {
            foreach (var position in Positions.FindAll("SampleRSI", SymbolName, tradeType))
                ClosePosition(position);
        }

        private void Open(TradeType tradeType)
        {
            var position = Positions.Find("SampleRSI", SymbolName, tradeType);
            var volumeInUnits = Symbol.QuantityToVolumeInUnits(Quantity);

            if (position == null)
                ExecuteMarketOrder(tradeType, SymbolName, volumeInUnits, "SampleRSI");
        }
    }
}


@Prasanna
Replies

Prasanna
08 Apr 2020, 12:21

Hello,

After trying I have come up with a code with above mentioned logic.

But there is a problem in the backtesting. The bot isn't taking the trades how I wanted. sometimes it's missing to close positions when the criteria met.

Please take a look at the code and let me know if something is wrong.

Very much appreciate admin help on this.

Thanks.

 

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.EAustraliaStandardTime, AccessRights = AccessRights.None)]
    public class SampleSARTrailingStop : Robot
    {
        [Parameter(DefaultValue = 10000, MinValue = 0)]
        public int Volume { get; set; }

        [Parameter("Source", Group = "RSI")]
        public DataSeries Source { get; set; }

        [Parameter("Periods", Group = "RSI", DefaultValue = 14)]
        public int Periods { get; set; }

        private RelativeStrengthIndex rsi;

        protected override void OnStart()
        {
            rsi = Indicators.RelativeStrengthIndex(Source, Periods);
        }

        protected override void OnBar()
        {
            var longPosition = Positions.Find("RSI", SymbolName, TradeType.Buy);
            var shortPosition = Positions.Find("RSI", SymbolName, TradeType.Sell);

            {
                if (rsi.Result.Last(0) > 30 && rsi.Result.Last(1) < 30 && longPosition == null)
                {
                    if (shortPosition != null)
                    {
                        ClosePosition(shortPosition);
                    }

                    ExecuteMarketOrder(TradeType.Buy, SymbolName, Volume, "RSI");
                }

                if (rsi.Result.Last(0) > 70 && rsi.Result.Last(1) < 70)
                {
                    if (longPosition != null)
                    {
                        ClosePosition(longPosition);
                    }
                }

            }

            {
                if (rsi.Result.Last(0) < 70 && rsi.Result.Last(1) > 70 && shortPosition == null)
                {
                    if (longPosition != null)
                    {
                        ClosePosition(longPosition);
                    }

                    ExecuteMarketOrder(TradeType.Sell, SymbolName, Volume, "RSI");
                }

                if (rsi.Result.Last(0) < 30 && rsi.Result.Last(1) > 30)
                {
                    if (shortPosition != null)
                    {
                        ClosePosition(shortPosition);
                    }
                }
            }
        }
    }
}


@Prasanna

PanagiotisCharalampous
08 Apr 2020, 14:39

Hi kittu.ce10,

Can you send us some information like backtesting parameters and dates where you expect the events to happen but they don't so that we can explain to you what happens?

Best Regards,

Panagiotis 

Join us on Telegram

 


@PanagiotisCharalampous

Prasanna
08 Apr 2020, 16:11

RE:

PanagiotisCharalampous said:

Hi kittu.ce10,

Can you send us some information like backtesting parameters and dates where you expect the events to happen but they don't so that we can explain to you what happens?

Best Regards,

Panagiotis 

Join us on Telegram

 

Sure,

I tested this cBot on EURUSD, Volume - 10000 and RSI period 14

dates 01/01/2020 - 31/01/2020, Initial capital - 10000, tick data, commissions zero for testing purposes.


@Prasanna

PanagiotisCharalampous
08 Apr 2020, 16:47

Hi kittu.ce10

First observation. The below condition is wrong. 

if (rsi.Result.Last(0) > 70 && rsi.Result.Last(1) < 70)

When the bar changes both values will be almost the same. The comparison should be between Last(1) and Last(2). See below

if (rsi.Result.Last(1) > 70 && rsi.Result.Last(2) < 70)

Fix this and check again if it works as you expect.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous

Prasanna
08 Apr 2020, 16:59

RE:

PanagiotisCharalampous said:

Hi kittu.ce10

First observation. The below condition is wrong. 

if (rsi.Result.Last(0) > 70 && rsi.Result.Last(1) < 70)

When the bar changes both values will be almost the same. The comparison should be between Last(1) and Last(2). See below

if (rsi.Result.Last(1) > 70 && rsi.Result.Last(2) < 70)

Fix this and check again if it works as you expect.

Best Regards,

Panagiotis 

Join us on Telegram

Hi,

Thanks for the quick reply.

Yes, that is working now perfectly.

another question though. Can I use the "HasCrossedAbove/Below" function instead

if (rsi.Result.HasCrossedAbove 70)

Is this correct?


@Prasanna

PanagiotisCharalampous
08 Apr 2020, 17:03

Hi kittu.ce10,

Yes of course you can.

Best Regards,

Panagiotis 

Join us on Telegram


@PanagiotisCharalampous