Profitable cBot apart from one rogue parameter!!

Created at 15 Sep 2015, 16: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!
97

9718853

Joined 14.10.2014

Profitable cBot apart from one rogue parameter!!
15 Sep 2015, 16:54


Hi All,

 

 

I've been getting some good results with the robot below, however I have a parameter that doesn't seem to act as it should...

I'm counting up the total pips of a position with this:

int totalPips = (int)(Positions[y].Pips - Positions[y].EntryPrice);

and then using totalPips to delay when a martingale strategy is called with this

if ( totalPips <= MartingaleTrigger * Symbol.PipSize)

 

The problem is that this MartingaleTrigger value isn't doing anything related to the Symbol.Pipsize. In fact, back test results remain the same regardless of the MartingaleTrigger value. However, if I remove the parameter all together the backtest results do change!?!?

Any help or advice would be greatly appreciated...

(Backtest with EURGBP, m1) 

using System;
using System.Linq;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Requests;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class BolliBot : Robot
    {
        [Parameter("Source")]
        public DataSeries SourceSeries { get; set; }

        [Parameter("Stop Loss (pips)", DefaultValue = 1000, MinValue = 1)]
        private int StopLossInPips { get; set; }

        [Parameter("Take Profit (pips)", DefaultValue = 1000, MinValue = 1)]
        private int TakeProfitInPips { get; set; }

        [Parameter("Volume", DefaultValue = 1000, MinValue = 1000)]
        public int Volume { get; set; }

        [Parameter("RSI High Trigger", DefaultValue = 60)]
        public int highRSI { get; set; }

        [Parameter("RSI Low Trigger", DefaultValue = 40)]
        public int lowRSI { get; set; }

        [Parameter("Bollinger Bands Deviations", DefaultValue = 2.5)]
        public double Deviations { get; set; }

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

        [Parameter("Fast MA", DefaultValue = 1)]
        public int FastPeriods { get; set; }

        [Parameter("MA Type")]
        public MovingAverageType MAType { get; set; }

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

        [Parameter("Slow MA", DefaultValue = 1000)]
        public int SlowPeriods { get; set; }

        [Parameter("Martingale Trigger", DefaultValue = -5)]
        public int MartingaleTrigger { get; set; }

        [Parameter("Overall Profit Take Profit", DefaultValue = 10)]
        public int OverAllProfitTP { get; set; }

        [Parameter("Overall Loss Stop Loss", DefaultValue = -10000)]
        public int OverAllLossSL { get; set; }

        [Parameter("MartinGale Volume Multiplied By", DefaultValue = 32)]
        public int martingaleMultiplier { get; set; }

        private RelativeStrengthIndex rsi;
        private MovingAverage fastMa;
        private MovingAverage midMa;
        private MovingAverage slowMa;

        Dictionary<int, int> dic = new Dictionary<int, int>();

        BollingerBands bollingerBands;
        string label = "BolliBot";

        protected override void OnStart()
        {
            bollingerBands = Indicators.BollingerBands(SourceSeries, Periods, Deviations, MAType);
            rsi = Indicators.RelativeStrengthIndex(SourceSeries, Periods);
            fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType);
            midMa = Indicators.MovingAverage(SourceSeries, MidPeriods, MAType);
            slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType);
        }

        private void ExecuteOrder(int volume, TradeType tradeType)
        {
            ExecuteMarketOrder(tradeType, Symbol, volume, label, StopLossInPips, TakeProfitInPips);
        }

        protected override void OnBar()
        {
            var top = bollingerBands.Top.Last(1);
            var bottom = bollingerBands.Bottom.Last(1);
            var longPosition = Positions.Find(label, Symbol, TradeType.Buy);
            var shortPosition = Positions.Find(label, Symbol, TradeType.Sell);
            var FastMa = fastMa.Result.Last(0);
            var MidMa = midMa.Result.Last(0);
            var SlowMa = slowMa.Result.Last(0);
            var high = rsi.Result.Last(0);
            var low = rsi.Result.Last(0);
            var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);
            var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);

            if (Symbol.Bid > top && high > highRSI && FastMa < MidMa && MidMa < SlowMa)
            {
                ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, label, StopLossInPips, TakeProfitInPips);
                Print("Short Position. Num positions : " + Positions.Count + " Split long : " + longPositionsCount + " short : " + shortPositionsCount);
            }

            if (Symbol.Ask < bottom && low < lowRSI && FastMa > MidMa && MidMa > SlowMa)
            {
                ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, label, StopLossInPips, TakeProfitInPips);
                Print("Long Position. Num positions : " + Positions.Count + " Split long : " + longPositionsCount + " short : " + shortPositionsCount);
            }
        }

        protected override void OnTick()
        {
            var top = bollingerBands.Top.Last(1);
            var bottom = bollingerBands.Bottom.Last(1);
            var longPosition = Positions.Find(label, Symbol, TradeType.Buy);
            var shortPosition = Positions.Find(label, Symbol, TradeType.Sell);
            var FastMa = fastMa.Result.Last(0);
            var MidMa = midMa.Result.Last(0);
            var SlowMa = slowMa.Result.Last(0);
            var high = rsi.Result.Last(0);
            var low = rsi.Result.Last(0);
            var shortPositionsCount = Positions.Count(p => p.TradeType == TradeType.Sell);
            var longPositionsCount = Positions.Count(p => p.TradeType == TradeType.Buy);
            var symbolSearch = Positions.FindAll(label, Symbol);

            int posCount = Positions.Count;

            foreach (Position position in symbolSearch)

                for (int y = posCount - 1; y >= 0; y--)
                {
                    int totalPips = (int)(Positions[y].Pips - Positions[y].EntryPrice);

                    int test = 0;
                    if (!dic.TryGetValue(Positions[y].Id, out test))
                    {
                        dic[Positions[y].Id] = 0;

                    }

                    if (Positions[y].TradeType == TradeType.Sell && totalPips <= MartingaleTrigger * Symbol.PipSize && test == 0 && Positions[y].Volume < Volume * martingaleMultiplier && Symbol.Bid > top && high > highRSI && FastMa < MidMa && MidMa < SlowMa)
                    {

                        dic[Positions[y].Id] = 1;
                        ExecuteOrder((int)Positions[y].Volume * 2, Positions[y].TradeType);
                        Print("Martingale SHORT!!. Num positions : " + Positions.Count + " Split... long : " + longPositionsCount + " short : " + shortPositionsCount);
                    }

                    if (Positions[y].TradeType == TradeType.Buy && totalPips <= MartingaleTrigger * Symbol.PipSize && test == 0 && Positions[y].Volume < Volume * martingaleMultiplier && Symbol.Ask < bottom && low < lowRSI && FastMa > MidMa && MidMa > SlowMa)
                    {

                        dic[Positions[y].Id] = 1;
                        ExecuteOrder((int)Positions[y].Volume * 2, Positions[y].TradeType);
                        Print("Martingale LONG!!. Num positions : " + Positions.Count + " Split... long : " + longPositionsCount + " short : " + shortPositionsCount);
                    }

                }

            double overallProfit = 0;

            foreach (Position position in symbolSearch)
            {

                overallProfit += position.GrossProfit;
            }

            if (overallProfit >= OverAllProfitTP)
            {
                Print("OVERALL Profit TOTAL = " + overallProfit + " Closing All Positions. Num positions: " + Positions.Count);

                foreach (Position position in symbolSearch)
                {
                    ClosePosition(position);
                }
            }

            if (overallProfit <= OverAllLossSL)
            {
                Print("OVERALL Loss TOTAL = " + overallProfit + " Closing All Positions. Num positions: " + Positions.Count);

                foreach (Position position in symbolSearch)
                {
                    ClosePosition(position);
                }
            }
        }
    }
}

 


@9718853
Replies

moneybiz
15 Sep 2015, 22:45

RE:

9718853 said:

int totalPips = (int)(Positions[y].Pips - Positions[y].EntryPrice);

and then using totalPips to delay when a martingale strategy is called with this

if ( totalPips <= MartingaleTrigger * Symbol.PipSize)

 Positions[y].Pips is already gibing you the profit or loss in pips.

Subtracting Positions[y].EntryPrice from pips is not logical. One is a value like 10 (pips) and the other is a value like 1.12345.

int totalPips = Positions[y].Pips is enough.

What does the MartingaleTrigger represent, pips or price? If pips then totalPips <= MartingaleTrigger is enough.

You use multiplication with Symbol.PipSize only when you want to add/subtract some pips from a price value.

Say you want to set a take profit price position as 10 pips from the entry price.

var takeProfit = Positions[y].EntryPrice + (TakeProfitPips * Symbol.PipSize);

var takeProfit = 1.12345 + (10 * 0.0001) = 1.12445


@moneybiz

9718853
21 Sep 2015, 13:16

 

Thank you so much for such a concise answer.... I'm currently going through the logic and running new tests, I'll post results if they are worth posting!

Thanks again...


@9718853