Category Other  Published on 06/05/2019

Manual Strategy Tester with Source Code

Description

This bot is usefull to check your manual strategy.

You can choose some past days and trade on ctrader in backtesting.

To use this bot you must set visual mode flag in backtesting and run the back testing.

After start the back testing you will see a windows form where you can buy and sell by hand.

There is also a combobox where you can choose one of open positions and change the stop loss, the take profit and the volume.

Enjoy

Amerigo

 

 


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

//using System;
using System.ComponentModel;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace cAlgo
{

    public class CmdForm : Form
    {
        public Interactive theRobot;
        TextBox txtSL;
        TextBox txtTP;
        TextBox txtVol;
        ComboBox cbPositions;

        public CmdForm()
        {
            Text = "Command Board";
            AddLabel("Positions", 13, 13);
            AddLabel("Lots", 13, 43);
            AddLabel("Stop Loss", 13, 73);
            AddLabel("Take Profit", 13, 103);
            AddButton("Buy", 13, 133, 50, (s, e) => { CmdBuy(); });
            AddButton("Sell", 63, 133, 50, (s, e) => { CmdSell(); });
            AddButton("Set", 150, 133, 50, (s, e) => { CmdSet(); });
            AddButton("Close", 200, 133, 50, (s, e) => { CmdClose(); });
            txtVol = AddTextBox(100, 43, 100);
            txtSL = AddTextBox(100, 73, 100);
            txtTP = AddTextBox(100, 103, 100);
            txtVol.Text = "1";
            cbPositions = AddComboBox(100, 13, 100, (s, e) => { UpdateForm(); });
            TopMost = true;
        }

        private void AddLabel(string text, int x, int y)
        {
            Label lbl = new Label();
            lbl.Location = new Point(x, y);
            lbl.Text = text;
            lbl.AutoSize = true;
            Controls.Add(lbl);

        }

        private ComboBox AddComboBox(int x, int y, int width, EventHandler eh)
        {
            ComboBox cb = new ComboBox();
            cb.Location = new Point(x, y);
            cb.Width = width;
            cb.SelectedIndexChanged += eh;
            Controls.Add(cb);
            return cb;
        }

        private TextBox AddTextBox(int x, int y, int width)
        {
            TextBox txt = new TextBox();
            txt.Location = new Point(x, y);
            txt.Width = width;
            txt.Height = 30;
            txt.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
            Controls.Add(txt);
            return txt;
        }

        private void AddButton(string text, int x, int y, int width, EventHandler eh)
        {
            Button btn = new Button();
            btn.Location = new Point(x, y);
            btn.Text = text;
            btn.Click += eh;
            btn.Width = width;
            Controls.Add(btn);

        }

        protected void UpdateForm()
        {
            if (cbPositions.SelectedItem != null)
            {
                string text = cbPositions.GetItemText(cbPositions.SelectedItem);
                int posId = Int32.Parse(text);
                var t = new Thread(() =>
                {
                    Position p = theRobot.FindPos2(posId);
                    if (p != null)
                    {
                        double? sl = p.StopLoss;
                        double? tp = p.TakeProfit;
                        double vol = p.VolumeInUnits / 100000;
                        if (sl != null)
                            sl = Math.Round((double)(p.EntryPrice - sl) / theRobot.PipSize * (p.TradeType == TradeType.Buy ? 1 : 1), 1);
                        if (tp != null)
                            tp = Math.Round((double)(tp - p.EntryPrice) / theRobot.PipSize * (p.TradeType == TradeType.Buy ? 1 : 1), 1);

                        UpdateForm2(vol, sl, tp);
                    }
                });

                t.Start();
            }

        }

        delegate void SafeCallUpdateForm2(double vol, double? sl, double? tp);
        delegate void SafeCallUpdateComboBox(Positions pos);

        protected void UpdateForm2(double vol, double? sl, double? tp)
        {
            if (txtSL.InvokeRequired)
            {
                var d = new SafeCallUpdateForm2(UpdateForm2);
                Invoke(d, new object[] 
                {
                    vol,
                    sl,
                    tp
                });
            }
            else
            {
                txtSL.Text = "";
                txtTP.Text = "";
                if (sl != null)
                    txtSL.Text = sl.ToString();
                if (tp != null)
                    txtTP.Text = tp.ToString();
                txtVol.Text = vol.ToString();
            }
        }

        protected void CmdBuy()
        {
            double? sl = null, tp = null;
            double? vol = 0;
            sl = Parse(txtSL.Text);
            tp = Parse(txtTP.Text);
            vol = Parse(txtVol.Text);

            if (vol == null)
                return;
            double volume = (double)vol;

            var t = new Thread(() => theRobot.OpenPos(TradeType.Buy, volume, sl, tp));
            t.Start();

        }

        public void UpdateComboBox(Positions pos)
        {
            if (cbPositions.InvokeRequired)
            {
                var d = new SafeCallUpdateComboBox(UpdateComboBox);
                Invoke(d, new object[] 
                {
                    pos
                });
            }
            else
            {
                cbPositions.Items.Clear();
                foreach (var p in pos)
                    cbPositions.Items.Add(p.Id.ToString());
                if (cbPositions.Items.Count > 0)
                    cbPositions.SelectedIndex = cbPositions.Items.Count - 1;
            }

        }

        protected void CmdSell()
        {
            double? sl = null, tp = null;
            double? vol = 0;
            sl = Parse(txtSL.Text);
            tp = Parse(txtTP.Text);
            vol = Parse(txtVol.Text);

            if (vol == null)
                return;
            double volume = (double)vol;

            var t = new Thread(() => theRobot.OpenPos(TradeType.Sell, volume, sl, tp));
            t.Start();

        }

        protected void CmdClose()
        {
            if (cbPositions.SelectedItem != null)
            {
                string text = cbPositions.GetItemText(cbPositions.SelectedItem);
                int posId = Int32.Parse(text);
                var t = new Thread(() => theRobot.ClosePos(posId));
                t.Start();
            }
        }

        protected void CmdSet()
        {
            if (cbPositions.SelectedItem != null)
            {
                string text = cbPositions.GetItemText(cbPositions.SelectedItem);
                int posId = Int32.Parse(text);
                double? sl = null, tp = null;
                double? vol = 0;
                sl = Parse(txtSL.Text);
                tp = Parse(txtTP.Text);
                vol = Parse(txtSL.Text);

                if (vol == null)
                    return;

                double volume = (double)vol;
                var t = new Thread(() => theRobot.SetPosPips(posId, volume, sl, tp));
                t.Start();
            }
        }

        private double? Parse(string text)
        {
            double result;
            bool e = Double.TryParse(text, out result);
            return e ? (double?)result : (double?)null;
        }

    }

    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class Interactive : Robot
    {
        [Parameter()]
        public DataSeries SourceSeries { get; set; }

        const string filename = "c:\\calgodb\\cmd.txt";
        const string label = "manual";
        /* 
        [Parameter ("Quantity (Lots)", DefaultValue = 0.1, MinValue = 0.01, Step = 0.01)]
        public double Quantity { get; set; }
        */
        CmdForm form;
        protected override void OnStart()
        {
            Thread t = new Thread(() =>
            {
                Application.EnableVisualStyles();
                form = new CmdForm();
                form.theRobot = this;
                Application.Run(form);
            });
            t.Priority = ThreadPriority.BelowNormal;
            t.IsBackground = true;
            t.Start();
            Positions.Closed += onClosed;
            Positions.Opened += onOpened;
        }

        protected void onClosed(PositionClosedEventArgs e)
        {
            form.UpdateComboBox(Positions);
        }

        protected void onOpened(PositionOpenedEventArgs e)
        {
            form.UpdateComboBox(Positions);
        }

        protected override void OnStop()
        {
        }

        private Position FindPos(string pos)
        {
            foreach (var p in Positions.FindAll(label, Symbol))
                if (p.Comment == "#" + pos)
                    return p;
            return null;
        }

        public Position FindPos2(int id)
        {
            foreach (var p in Positions.FindAll(label, Symbol))
                if (p.Id == id)
                    return p;
            return null;
        }

        public double PipSize
        {
            get { return Symbol.PipSize; }
        }

        public int OpenPos(TradeType trade, double vol, double? sl, double? tp)
        {
            var ts = ExecuteMarketOrder(trade, Symbol, VolumeInUnits(vol), label, sl, tp);
            if (!ts.IsSuccessful)
                return ts.Position.Id;
            return 0;
        }

        public void ClosePos(int posId)
        {
            Position p = FindPos2(posId);
            if (p != null)
                p.Close();
        }

        public void SetPosPips(int posId, double vol, double? sl, double? tp)
        {
            Position p = FindPos2(posId);
            if (p != null)
            {
                if (p.VolumeInUnits != VolumeInUnits(vol))
                    p.ModifyVolume(VolumeInUnits(vol));
                p.ModifyTakeProfitPips(tp);
                p.ModifyStopLossPips(sl);
            }
        }

        public void SetPosPrices(int posId, double vol, double? sl, double? tp)
        {
            Position p = FindPos2(posId);
            if (p != null)
            {
                if (p.VolumeInUnits != VolumeInUnits(vol))
                    p.ModifyVolume(VolumeInUnits(vol));
                p.ModifyTakeProfitPrice(tp);
                p.ModifyStopLossPrice(sl);
            }
        }

        protected override void OnTick()
        {

            if (false)
                if (File.Exists(filename))
                {
                    string text = System.IO.File.ReadAllText(filename);
                    text = text.Replace("\n", "").Replace("\r", "");
                    Print("[{0}]", text);
                    File.Delete(filename);
                    Position pos = null;
                    double? sl = null;
                    double? tp = null;
                    TradeType trade = TradeType.Buy;
                    bool deal = false;
                    bool change = false;
                    string posNumber = "";
                    double vol = 1;
                    bool toClose = false;

                    foreach (var cmdfull in text.Split(';'))
                    {
                        var ops = cmdfull.Split(':');
                        var cmd = ops[0];
                        var arg = ops[1];
                        Print("[{0}] [{1}]", cmd, arg);
                        switch (cmd)
                        {
                            case "VOL":
                                vol = Double.Parse(arg);
                                break;

                            case "CMD":
                                switch (arg)
                                {
                                    case "SELL":
                                        trade = TradeType.Sell;
                                        deal = true;
                                        break;
                                    case "BUY":
                                        trade = TradeType.Buy;
                                        deal = true;
                                        break;
                                    case "CLOSE":
                                        toClose = true;
                                        break;
                                    case "SET":
                                        change = true;
                                        break;
                                }
                                break;
                            case "POS":
                                pos = FindPos(arg);
                                posNumber = arg;
                                break;

                            case "TP*":
                                tp = Double.Parse(arg);
                                if (change && pos != null)
                                    pos.ModifyTakeProfitPips(tp);
                                break;
                            case "SL*":
                                sl = Double.Parse(arg);
                                if (change && pos != null)
                                    pos.ModifyStopLossPips(sl);
                                break;
                            case "TP":
                                tp = Double.Parse(arg);
                                if (change && pos != null)
                                    pos.ModifyTakeProfitPrice(tp);
                                break;
                            case "SL":
                                sl = Double.Parse(arg);
                                if (change && pos != null)
                                    pos.ModifyStopLossPrice(sl);
                                break;
                        }
                    }

                    if (deal)
                        ExecuteMarketOrder(trade, Symbol, VolumeInUnits(vol), label, sl, tp, null, "#" + posNumber);

                    if (toClose && pos != null)
                        pos.Close();
                }

        }

        private double VolumeInUnits(double vol)
        {
            var v = Symbol.QuantityToVolumeInUnits(vol);
            v = Symbol.NormalizeVolumeInUnits(v, RoundingMode.Down);
            return v;
        }
    }
}


AS
astevani

Joined on 11.03.2019

  • Distribution: Free
  • Language: C#
  • Trading platform: cTrader Automate
  • File name: InteractiveForm.algo
  • Rating: 5
  • Installs: 4781
  • Modified: 13/10/2021 09:54
Comments
Log in to add a comment.
BA
barriervacuumbags · 1 year ago

At Give Engineering, we are committed to providing cutting-edge engineering services that drive innovation, transform industries, and shape the future. Our team of highly skilled engineers, designers, and technologists is passionate about pushing boundaries and delivering solutions that exceed expectations.

Learn more:- Advanced engineering services

 

GI
give.engineering · 1 year ago

Give Engineering's top-notch engineering consulting services firm Our dedicated experienced engineers, designers, and team-driven advanced technology ensure efficiency, accuracy, and cost-effectiveness, allowing us to deliver projects on time and within budget.

 

ZI
zimapasubasu · 1 year ago

Dramacool official: Browse all Korean dramas and other Asian shows at DramacoolDramacool for everyone!

miplconsulting1's avatar
miplconsulting1 · 1 year ago

????I  read your articles regularly as I get a lot of knowledge. You should also visit our website! We provide ????IT Consulting Services, Website Design and Development Etc.

 

IA
iamserialapk · 1 year ago

Dear Ishq Hindi Drama Desi Serial Full Episode Download Free, DIS1 Today Episode at Dailymotion, Watch HotStar Serial Dear Ishq all the latest. Dear Ishq Watch Online

IA
iamserialapk · 1 year ago

Maddam Sir Today Episode Latest Episodes Online in full HD on Sony LIV. Enjoy Maddam Sir best trending moments, video clips, and promos online

IA
iamserialapk · 1 year ago

ApneTv - Hindi Serials Online. Bollywood Movies, Latest Bollywood News and Much More Apne Tv On Hindi serials are dramas composed, created, shot in India,

TV
tvrdjan · 3 years ago

System.NullReferenceException: Object reference not set to an instance of an object.
   at cAlgo.CmdForm.<>c__DisplayClass11.<CmdSell>b__10()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
IS WORKING BUT CRASSSSSS

nh.zadeh's avatar
nh.zadeh · 4 years ago

Hi, It is nice job. I have problem to use this Cbot.

1. I installed it and in backtesing I tick the visual mode.

2. When I run the Cbot in backtesting it opens a window which is dashboard (includes the risk%, Trade lot, spread, Execute order, Pending Order, Change selected and close selected)

3. When I push the "execute order" I opens a buy order.

I can not find how to sell?

I can not find how to change the stop loss and take profit

 

please advise

DY
dynamites · 4 years ago

Hello. Nice job.

But could you add the support for renko bars?

Thanks.

jani's avatar
jani · 5 years ago

I tried this one out, very nice thank you. just that my cTrader platform keeps crashing on my tabletop. Took out some indies but still crashing

GA
gastaodm · 5 years ago

Hi, I am afraid I cannot change the stop loss level, because it changes the lot size instead.

GA
gastaodm · 5 years ago

Hi, I am enjoying a lot your robot. It would be wonderful to have pending orders.
Thanks.

AS
astevani · 5 years ago

thanks

jumpycalm's avatar
jumpycalm · 5 years ago

Nice job!