Category Other  Published on 15/09/2016

Tunneling Martingale

Description

This bot is useful when you don't know direction, but there's a big move on either direction expected.

Since it's a tunneling strategy, it's only a martingale if the # of attemps is absurdely high, like 10 or more.

Would recommend 4 to 5 attemps at most.

Please let me know if there's any bug I'll quickly fix it.

Mail: waxavi@outlook.com

 


//--------------------------------------------------------------------
//                                              Tunneling Martingale |
//                                       Made for the CTDN Community |
//                                       Contact: Waxavi@outlook.com |
//--------------------------------------------------------------------


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 TunnelingMartingale : Robot
    {
        [Parameter("Long Entry Price", DefaultValue = 1.0)]
        public double _LongEntry { get; set; }
        [Parameter("Short Entry Price", DefaultValue = 1.0)]
        public double _ShortEntry { get; set; }
        [Parameter("Lot Size", DefaultValue = 0.01)]
        public double _LotSize { get; set; }
        [Parameter("$ Target", DefaultValue = 50)]
        public double _MoneyTarget { get; set; }
        [Parameter("Max attemps", DefaultValue = 5)]
        public int _MaxAttemps { get; set; }

        string _Label = "label";
        TradeType _Buy = TradeType.Buy;
        TradeType _Sell = TradeType.Sell;

        double _NetProfit = 0;
        int _CurrentAttemps = 1;

        private void PositionsOnOpened(PositionOpenedEventArgs args)
        {
            if (args.Position.Label == _Label)
            {
                Print("Current Attempt: {0}", _CurrentAttemps);
                var _pending = PendingOrders.Where(item => item.Label == _Label);
                if (_pending.Count() != 0)
                    CancelPendingOrder(_pending.First());
            }
        }

        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            if (args.Position.NetProfit + _NetProfit >= _MoneyTarget)
                return;

            _NetProfit += args.Position.NetProfit;
            _CurrentAttemps++;

            if (_CurrentAttemps > _MaxAttemps)
                Stop();
            else
            {
                TradeType _tt = args.Position.TradeType == _Buy ? _Sell : _Buy;

                if (args.Position.TradeType == _Buy)
                {
                    ExecuteMarketOrder(_Sell, Symbol, Symbol.QuantityToVolume(_LotSize * 2), _Label, (_LongEntry - _ShortEntry) / Symbol.PipSize, null);
                }
                else
                {
                    ExecuteMarketOrder(_Buy, Symbol, Symbol.QuantityToVolume(_LotSize * 2), _Label, (_LongEntry - _ShortEntry) / Symbol.PipSize, null);
                }

            }

        }

        //Get a custom label for the trades of this instance
        protected string GetLabel(string _TType)
        {
            int x = Server.Time.Millisecond;
            bool quit = false;
            _Label = _TType + x.ToString() + this.TimeFrame.ToString();

            var _CLD = History.FindLast(_Label);
            var _CLO = Positions.Find(_Label);
            while (_CLD != null || _CLO != null)
            {
                x++;
                _Label = _TType + x.ToString();
                _CLD = History.FindLast(_Label);
                _CLO = Positions.Find(_Label);
                Print("Theres a duplicated Label, finding another one");
            }

            if (PendingOrders.Count != 0)
            {
                while (true)
                {
                    foreach (var pen in PendingOrders)
                    {
                        if (pen.Label == _Label)
                        {
                            _Label = _TType + x.ToString();
                            Print("Theres a duplicated Label, finding another one");
                            break;
                        }
                        else if (pen == PendingOrders.Last())
                        {
                            quit = true;
                        }
                    }

                    if (quit)
                    {
                        break;
                    }
                }
            }

            return _Label;
        }


        protected override void OnStart()
        {
            Positions.Opened += PositionsOnOpened;
            Positions.Closed += PositionsOnClosed;

            if (_LongEntry < _ShortEntry)
                Stop();

            if (Symbol.Ask > _LongEntry || Symbol.Bid < _ShortEntry)
                Stop();

            PlaceStopOrder(_Buy, Symbol, Symbol.QuantityToVolume(_LotSize), _LongEntry, _Label, (_LongEntry - _ShortEntry) / Symbol.PipSize, null, null);
            PlaceStopOrder(_Sell, Symbol, Symbol.QuantityToVolume(_LotSize), _ShortEntry, _Label, (_LongEntry - _ShortEntry) / Symbol.PipSize, null, null);
        }

        protected override void OnTick()
        {
            var _pos = Positions.Find(_Label);
            if (_pos != null)
            {
                if (_pos.NetProfit + _NetProfit >= _MoneyTarget)
                {
                    ClosePosition(_pos);
                    Stop();
                }
            }
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}


Waxy's avatar
Waxy

Joined on 12.05.2015

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: TunnelingMartingale.algo
  • Rating: 0
  • Installs: 3583
  • Modified: 13/10/2021 09:55
Comments
Log in to add a comment.
MI
mikefox · 1 year ago

Its not meant to work in backtesting its a breakout tool. I Havent tried it becouse there are no mention of how to set the straddle? Do you use fixed price? one user mentions money levels. Thats abit odd. I Would prefeer a trendline based version but there are no such tools online anywhere unfortunatly and i find that in itself wery funny. 

OM
Omega · 3 years ago

Hi,

Also can you change this so you an enter a target pips instead of dollar target?

Thanks...

OM
Omega · 3 years ago

Hi,

Does this double the lots each loss?

Thanks...

Waxy's avatar
Waxy · 8 years ago

This is not a standalone system, it's more of a breakout setup with multiple attemps.

To get it working in backtesting, the starting price at the backtesting date must be between the long and short entry parameters, that's how you can make it work for a backtesting, example:

Starting price of EURUSD on 1/Jun: 1.1330


Long Entry at: 1.1350
Short Entry at: 1.1310

A9
a9mtr · 8 years ago

Cant get it to work in backtesting whatsoever