VE
velu130486
Blocked user by Spotware at 30 Dec 2023, 11:08
0 follower(s) 0 following 34 subscription(s)
Topics
26 Sep 2022, 14:34
 1010
 1
29 Dec 2020, 07:44
 798
 1
25 Sep 2020, 11:34
 836
 1
21 Sep 2020, 10:11
 767
 1
Replies

velu130486
08 Dec 2022, 04:43

RE:

Dear Spotware,

If you refer to the Left Top of the chart, some position statistics are displayed based on chart symbol. If you watch it when I change the symbol, Buy profit/sell profit shows the value and immediately it changes to wrong value.

Upto previous update this indicator was working fine, but recently it changes value like this. Attached herewith the indicator code I got from this website.

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

namespace cAlgo
{
    [Indicator(AccessRights = AccessRights.None)]
    public class PositionStats : Indicator
    {
        [Parameter("Show balance", DefaultValue = true)]
        public bool showBalance { get; set; }

        [Parameter("Show equity", DefaultValue = true)]
        public bool showEquity { get; set; }

        [Parameter("Buy/Sell Amount", DefaultValue = true)]
        public bool showBuySellAmount { get; set; }

        [Parameter("Buy/Sell Count", DefaultValue = true)]
        public bool showBuySellCount { get; set; }

        [Parameter("Total amount", DefaultValue = true)]
        public bool showTotalAmount { get; set; }

        [Parameter("Total count", DefaultValue = true)]
        public bool showTotalCount { get; set; }

        [Parameter("Pip cost", DefaultValue = true)]
        public bool showPipCost { get; set; }

        [Parameter("Margin Level", DefaultValue = true)]
        public bool showMarginLevel { get; set; }

        [Parameter("Chart corner, 1-6", DefaultValue = 1, MinValue = 1, MaxValue = 6)]
        public int corner { get; set; }

        [Parameter("Show labels", DefaultValue = true)]
        public bool showLabels { get; set; }

        [Parameter("Show account currency", DefaultValue = true)]
        public bool showCurrency { get; set; }

        [Parameter("Show base currency", DefaultValue = true)]
        public bool showBaseCurrency { get; set; }

        [Parameter("Look Back", DefaultValue = 40, MinValue = 0)]
        public int lookBack { get; set; }

        [Parameter("minVolume:PF ratio ($)", DefaultValue = 0.1, MinValue = 0)]
        public double profitfactor { get; set; }

        [Parameter("Max Equity Drawdown %", DefaultValue = 10, MinValue = 1)]
        public double EquityLoss { get; set; }

        protected override void Initialize()
        {
            Positions.Opened += delegate (PositionOpenedEventArgs args) { Update(); };
            Positions.Closed += delegate (PositionClosedEventArgs args) { Update(); };
            Positions.Modified += delegate (PositionModifiedEventArgs args) { Update(); };
        }

        public override void Calculate(int index)
        {
            if (!IsLastBar)
            {
                return;
            }
            else
            {
                Update();
            }
        }
        public void Update()
        {
            double buy_volume = 0, sell_volume = 0, total_volume = 0;
            double buy_ord_vol = 0, sell_ord_vol = 0, total_ord_vol = 0;
            double buy_profit = 0, sell_profit = 0, total_profit = 0;
            double buy_count = 0, sell_count = 0, total_count = 0;
            double buy_order = 0, sell_order = 0, total_order = 0;
            double pfBUY = 0, pfSELL = 0;
            var minvolume = Symbol.VolumeInUnitsMin;

            foreach (var p in Positions)
            {
                if (p.SymbolName != Symbol.Name)
                {
                    continue;
                }
                if (p.TradeType == TradeType.Buy)
                {
                    buy_volume += p.VolumeInUnits;
                    buy_count++;
                    buy_profit += p.NetProfit;
                }
                else
                {
                    sell_volume += p.VolumeInUnits;
                    sell_count++;
                    sell_profit += p.NetProfit;
                }
                total_volume = buy_volume - sell_volume;
                total_count = buy_count + sell_count;
                total_profit = buy_profit + sell_profit;
                total_order = buy_order + sell_order;
                pfBUY = (buy_volume / minvolume) * profitfactor;
                pfSELL = (sell_volume / minvolume) * profitfactor;
            }

            foreach (var o in PendingOrders)
            {
                if (o.SymbolName != Symbol.Name)
                {
                    continue;
                }
                if (o.TradeType == TradeType.Buy)
                {
                    buy_ord_vol += o.VolumeInUnits;
                    buy_order++;
                }
                else
                {
                    sell_ord_vol += o.VolumeInUnits;
                    sell_order++;
                }
                total_ord_vol = buy_ord_vol - sell_ord_vol;
                total_order = buy_order + sell_order;
            }

            StringBuilder s = new StringBuilder();

            if (showBalance)
            {
                if (showLabels)
                    s.Append("Balance: ");
                s.AppendFormat("{0:N2}", Account.Balance);
                if (showCurrency)
                {
                    s.Append(" ");
                    s.Append(Account.Asset.Name);
                }
                s.AppendLine();
            }

            if (showEquity)
            {
                if (showLabels)
                    s.Append("Equity: ");
                s.AppendFormat("{0:N2}", Account.Equity);
                if (showCurrency)
                {
                    s.Append(" ");
                    s.Append(Account.Asset.Name);
                }
                s.AppendLine();
            }

            if (showBuySellAmount)
            {
                var spread = Math.Round(Symbol.Spread / Symbol.PipSize, 1);
                if (showLabels)
                    s.Append("Spread: ");
                s.AppendFormat("{0:N1}", spread);
                s.AppendLine();

                if (showLabels)
                    s.Append("Buy Volume: ");
                s.AppendFormat("{0:N0}", buy_volume);
                if (showBaseCurrency)
                {
                    s.Append(" ");
                    s.Append(Symbol.Name.Substring(0, 3));
                }
                s.AppendLine();

                if (showLabels)
                    s.Append("Sell Volune: ");
                s.AppendFormat("{0:N0}", sell_volume);
                if (showBaseCurrency)
                {
                    s.Append(" ");
                    s.Append(Symbol.Name.Substring(0, 3));
                }
                s.AppendLine();

                if (showLabels)
                    s.Append("Total Volune: ");
                s.AppendFormat("{0:+#,###;-#,###;0}", total_volume);
                s.AppendLine();

                if (showLabels)
                    s.Append("Order Volume: ");
                s.AppendFormat("{0:+#,###;-#,###;0}", total_ord_vol);
                s.AppendLine();
            }

            if (showBuySellCount)
            {
                if (showLabels)
                    s.Append("Buy Position: ");
                s.AppendFormat("{0:N0}", buy_count);
                s.AppendLine();

                if (showLabels)
                    s.Append("Sell Position: ");
                s.AppendFormat("{0:N0}", sell_count);
                s.AppendLine();

                if (showLabels)
                    s.Append("Total Position: ");
                s.AppendFormat("{0:N0}", total_count);
                s.AppendLine();

                if (showLabels)
                    s.Append("Buy Order: ");
                s.AppendFormat("{0:N0}", buy_order);
                s.AppendLine();

                if (showLabels)
                    s.Append("Sell Order: ");
                s.AppendFormat("{0:N0}", sell_order);
                s.AppendLine();

                if (showLabels)
                    s.Append("Total Order: ");
                s.AppendFormat("{0:N0}", total_order);
                s.AppendLine();
            }

            if (showTotalAmount)
            {
                if (showLabels)
                    s.Append("Buy Profit: ");
                s.AppendFormat("{0:+#,###;-#,###;0}", buy_profit);
                if (showCurrency)
                {
                    s.Append(" ");
                    s.Append(Account.Asset.Name);
                }
                s.AppendLine();

                if (showLabels)
                    s.Append("Sell Profit: ");
                s.AppendFormat("{0:+#,###;-#,###;0}", sell_profit);
                if (showCurrency)
                {
                    s.Append(" ");
                    s.Append(Account.Asset.Name);
                }
                s.AppendLine();

                if (showLabels)
                    s.Append("Total Profit: ");
                s.AppendFormat("{0:+#,###;-#,###;0}", total_profit);
                if (showCurrency)
                {
                    s.Append(" ");
                    s.Append(Account.Asset.Name);
                }
                s.AppendLine();
            }

            if (showTotalCount)
            {
                var averageBuyFromCurrent = Math.Round((CalculateAveragePositionPrice(TradeType.Buy) - Symbol.Bid) / Symbol.PipSize, 1);
                var averageSellFromCurrent = Math.Round((Symbol.Ask - CalculateAveragePositionPrice(TradeType.Sell)) / Symbol.PipSize, 1);
                if (showLabels)
                    s.Append("Buy Target Away: ");
                s.AppendFormat("{0:N0}", averageBuyFromCurrent);
                s.AppendLine();

                if (showLabels)
                    s.Append("Sell Target Away: ");
                s.AppendFormat("{0:N0}", averageSellFromCurrent);
                s.AppendLine();
            }

            if (showPipCost)
            {
                if (showLabels)
                    s.Append("PIP Cost: ");
                s.AppendFormat("{0:N3}", total_volume * Symbol.PipValue);
                if (showCurrency)
                {
                    s.Append(" ");
                    s.Append(Account.Asset.Name);
                }
                s.AppendLine();

                if (showLabels)
                    s.Append("BuyProfitF: ");
                s.AppendFormat("{0:+#,###;-#,###;0}", pfBUY);
                if (showCurrency)
                {
                    s.Append(" ");
                    s.Append(Account.Asset.Name);
                }
                s.AppendLine();

                if (showLabels)
                    s.Append("SellProfitF: ");
                s.AppendFormat("{0:+#,###;-#,###;0}", pfSELL);
                if (showCurrency)
                {
                    s.Append(" ");
                    s.Append(Account.Asset.Name);
                }
                s.AppendLine();
            }

            if (showMarginLevel)
            {
                if (showLabels)
                    s.Append("Margin Level: ");
                if (Account.MarginLevel == null)
                {
                    s.Append("-");
                }
                else
                {
                    s.AppendFormat("{0:N2}", Account.MarginLevel);
                    s.Append("%");
                }
                s.AppendLine();
            }

            VerticalAlignment posv;
            HorizontalAlignment posh;
            switch (corner)
            {
                case 1:
                    posv = VerticalAlignment.Top;
                    posh = HorizontalAlignment.Left;
                    break;
                case 2:
                    posv = VerticalAlignment.Top;
                    posh = HorizontalAlignment.Center;
                    break;
                case 3:
                    posv = VerticalAlignment.Top;
                    posh = HorizontalAlignment.Right;
                    break;
                case 4:
                    posv = VerticalAlignment.Bottom;
                    posh = HorizontalAlignment.Right;
                    break;
                case 5:
                    posv = VerticalAlignment.Bottom;
                    posh = HorizontalAlignment.Center;
                    break;
                case 6:
                    posv = VerticalAlignment.Bottom;
                    posh = HorizontalAlignment.Left;
                    break;
                default:
                    posv = VerticalAlignment.Top;
                    posh = HorizontalAlignment.Left;
                    break;
            }
            Chart.DrawStaticText("showInfo", s.ToString(), posv, posh, Color.White);
        }
        private double CalculateAveragePositionPrice(TradeType tradeType)
        {
            double result = 0;
            double averagePrice = 0;
            long count = 0;

            foreach (var p in Positions)
            {
                if (p.SymbolName == Symbol.Name)
                {
                    if (p.TradeType == tradeType)
                    {
                        averagePrice += p.EntryPrice * p.VolumeInUnits;
                        count += p.Volume;
                    }
                }
            }
            if (averagePrice > 0 && count > 0)
                result = Math.Round(averagePrice / count, Symbol.Digits);
            return result;
        }
    }
}

Thanks and Regards

R. Vadivelan


velu130486
14 Sep 2022, 14:09

RE: RE:

Hello Xammo,

I tried your code in my Cbot, but it still not worked. It still create same number of new positions when multiple positions are closed.

By the way is there any reason for keeping int_count by default as 100

Thanks and Regards

R. Vadivelan

velu130486 said:

Thank you Xammo for your reply. I will try your code and update here if my problem is solved.

Thanks and Regards

R. Vadivelan

Xammo said:

Hi Vadivelan

I'm no pro so don't take the following too seriously just thought it might help you with an idea to get to where you want to be although you probably already realise you need to think things through more about your strategy as you work things out usually two more problems/challenges turn up!

I just had a quick go at coding something up and initially thought a flag would do the job but what about a countdown timer?

It all depends what timeframe you are working on - for example if 10 trades close all at once (even if you use ClosePositionAsync they won't all close at exactly the same millisecond) how long do you want to wait after the one trade has executed to be 'in the clear' to open another trade?

If a bunch of 10 trades closed between 12:00:00 -> 12:00:16 and another closed at 12:01:00 do you want to open a trade at 12:00:00 and 12:01:00 or do you consider them to be closing at the same time - depends on your timeframe kind a thing...

Basically what is the 'wait time' between determining a 'bunch of trades closing at the same time' and a 'series of trades closing one after the other in fairly close succession that you want a new trade to be executed each time'?

Anyway here you go - not tested/could well be issues depending on how you enter trades etc./just quickfire code probably doesn't confirm to coding etiquette/hopefully gives you some ideas and of course best of luck!

 

using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter("Count", DefaultValue = 100)]
        public int Param_int_Count { get; set; }

        private int int_Count;

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

        protected override void OnTick() //change to OnBar if you want to count down bars
        {
            if (int_Count > 0)
            {
                --int_Count;
            }
        }

        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            var pos = args.Position;
            var sym = pos.SymbolName;
            var close = lowBar[sym].ClosePrices.LastValue;
            double vmacur = vma[sym].Result.LastValue;
            double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;

            if (close > vmacur && int_Count == 0)
            {
                ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0);
            }
            else
            {
                ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0);
            }

            int_Count = Param_int_Count;
        }

        protected override void OnStop()
        {
            Positions.Closed -= PositionsOnClosed;
        }
    }
}

 

 

 


velu130486
12 Sep 2022, 13:52

RE:

Thank you Xammo for your reply. I will try your code and update here if my problem is solved.

Thanks and Regards

R. Vadivelan

Xammo said:

Hi Vadivelan

I'm no pro so don't take the following too seriously just thought it might help you with an idea to get to where you want to be although you probably already realise you need to think things through more about your strategy as you work things out usually two more problems/challenges turn up!

I just had a quick go at coding something up and initially thought a flag would do the job but what about a countdown timer?

It all depends what timeframe you are working on - for example if 10 trades close all at once (even if you use ClosePositionAsync they won't all close at exactly the same millisecond) how long do you want to wait after the one trade has executed to be 'in the clear' to open another trade?

If a bunch of 10 trades closed between 12:00:00 -> 12:00:16 and another closed at 12:01:00 do you want to open a trade at 12:00:00 and 12:01:00 or do you consider them to be closing at the same time - depends on your timeframe kind a thing...

Basically what is the 'wait time' between determining a 'bunch of trades closing at the same time' and a 'series of trades closing one after the other in fairly close succession that you want a new trade to be executed each time'?

Anyway here you go - not tested/could well be issues depending on how you enter trades etc./just quickfire code probably doesn't confirm to coding etiquette/hopefully gives you some ideas and of course best of luck!

 

using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter("Count", DefaultValue = 100)]
        public int Param_int_Count { get; set; }

        private int int_Count;

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

        protected override void OnTick() //change to OnBar if you want to count down bars
        {
            if (int_Count > 0)
            {
                --int_Count;
            }
        }

        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            var pos = args.Position;
            var sym = pos.SymbolName;
            var close = lowBar[sym].ClosePrices.LastValue;
            double vmacur = vma[sym].Result.LastValue;
            double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;

            if (close > vmacur && int_Count == 0)
            {
                ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0);
            }
            else
            {
                ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0);
            }

            int_Count = Param_int_Count;
        }

        protected override void OnStop()
        {
            Positions.Closed -= PositionsOnClosed;
        }
    }
}

 

 


velu130486
12 Sep 2022, 10:27 ( Updated at: 21 Dec 2023, 09:22 )

RE:

Hi Panagiotis,

Sorry for not explain clearly. I am using the Average method to close the positions. As you can see from the below picture multiple positions are closed at the same time for the same symbol. with the above code same number of new positions are created, however my requirement is to open only 1 new position for the symbol

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

I am not sure what kind of help you need. If you are looking for suggestions on what to do, then you can set a flag and raise when the first position is opened. Then you can check that flag for subsequent executions and decide accordingly.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


velu130486
12 Sep 2022, 09:34

RE:

Hello Team,

Could you please help on this topic.

Thanks and Regards

R. Vadivelan

velu130486 said:

Dear All,

I am using the Position on Closed event in my bot and it works fine. However my concern is if multiple positions are closed for a same symbol at a same tine, same number of positions are newly executed. However my requirement is to create only 1 position for each symbol.

        private void PositionsOnClosed(PositionClosedEventArgs args)
        {
            var pos = args.Position;
            var sym = pos.SymbolName;
            var close = lowBar[sym].ClosePrices.LastValue;
            double vmacur = vma[sym].Result.LastValue;
            double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
            if (close > vmacur)
                ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0);
            else
                ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0);
        }

Please help me to fix this issue

Thanks and Regards

R. Vadivelan

 


velu130486
08 Sep 2022, 13:09

RE:

Hi Panagiotis,

Actually my bot is multisymbol bot, so If I remove the library I will have problems in the coding. So I send the Library files and indicator files to your telegram. Could you please assist me to fix it there.

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

I can't build your project because I am missing references. Can you please simplify it and remove FeatureFXlib?

Panagiotis 

Join us on Telegram and Facebook

 


velu130486
08 Sep 2022, 12:39

RE:

Hi Panagiotis,

I followed your instruction, and copy paste the same code, but still I get the same error. Please help me to fix this issue

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using FeatureFXlib;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.IO;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class Test : Robot
    {
        [Parameter("MID", Group = "TIMEFRAME")]
        public TimeFrame midtf { get; set; }
        [Parameter("XAUUSD", Group = "METALS", DefaultValue = false)]
        public bool XAUUSD { get; set; }
        [Parameter("XAUEUR", Group = "METALS", DefaultValue = false)]
        public bool XAUEUR { get; set; }
        [Parameter("XAGUSD", Group = "METALS", DefaultValue = false)]
        public bool XAGUSD { get; set; }
        [Parameter("XAGEUR", Group = "METALS", DefaultValue = false)]
        public bool XAGEUR { get; set; }
        [Parameter("XPTUSD", Group = "METALS", DefaultValue = false)]
        public bool XPTUSD { get; set; }
        [Parameter("XPDUSD", Group = "METALS", DefaultValue = false)]
        public bool XPDUSD { get; set; }
        FeatureFX API = new FeatureFX();
        BarFX bar = new BarFX();
        Dictionary<string, Bars> midBar = new Dictionary<string, Bars>();
        Dictionary<string, ExponentialMovingAverage> ema = new Dictionary<string, ExponentialMovingAverage>();
        Dictionary<string, VariableMovingAverageMT> vma = new Dictionary<string, VariableMovingAverageMT>();

        protected override void OnStart()
        {
            bar.glob = MarketData;
            bar.AddCustomListMetals(XAUUSD, XAUEUR, XAGUSD, XAGEUR, XPTUSD, XPDUSD);
            foreach (var sym in bar.customList)
            {
                midBar.Add(sym, bar.@get(midtf, sym));
                ema.Add(sym, Indicators.ExponentialMovingAverage(midBar[sym].ClosePrices, 20));
                vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(6, TimeFrame.Hour));
            }
        }
        protected override void OnTick()
        {
            try
            {
                createnew();
            }
            catch
            {
                Print("On_Tick() is showing error");
            }
        }
        void createnew()
        {
            foreach (var sym in bar.customList)
            {
                var close = midBar[sym].ClosePrices.LastValue;
                double vmacur = vma[sym].Result.LastValue;
                if (close > vmacur)
                {
                    Print("BUY");
                }
                if (close < vmacur)
                {
                    Print("SELL");
                }
            }
        }
    }
}

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

It should look like this

vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(14, TimeFrame.Daily));

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


velu130486
08 Sep 2022, 09:55

RE:

Hi Panagiotis,

Thanks for your reply, but I have the same code in my file as below and I don't know how to fix this issues

ema.Add(sym, Indicators.ExponentialMovingAverage(midBar[sym].ClosePrices, 20));
vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(midBar[sym].ClosePrices, 6));

midbar[sym].ClosePrices is my timeframe parameter. Please help me to fix this if something is wrong.

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

You are missing the timeframe parameter here

 vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(midBar[sym].ClosePrices, 6));

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


velu130486
07 Sep 2022, 10:55

RE:

Hi Panagiotis,

Thanks for your support. Yes I got all the Position ID as per my requirement.

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

The code below works fine for me

          foreach (var pos in Positions.Where(p => Positions.Count(ps => ps.Comment == "PID" + p.Id.ToString()) == 0 && p.Comment == null))
            Print(pos.Id);

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


velu130486
07 Sep 2022, 08:58

RE:

Hi Panagiotis,

Yes I tried your suggestion, as below but it print all the open position ID. However my request is to get the position ID for which hedging position is not yet available

 private void unique()
  {
  foreach (var pos in Positions.Where(p => Positions.Count(ps => ps.Comment == p.Id.ToString()) == 0))
  Print(pos.Id);
  }

I request your support on this,. Please let me know If I had done something wrong

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

Did you try my suggestion?

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


velu130486
07 Sep 2022, 07:26

RE:

Hi Panagiotis,

Thanks for your reply and sorry for not making it clear. I explain the thing to be done as below

Assume that have 2 position opened

PID10001

PID10002

I am creating the hedging order based on certain pips loss, so hedging order is created as below

PID10003  ---------------> Hedging order so in comment I have "PID100001" original position ID

Now I want to compare all 3 positions and eliminate original and hedging order to close the remaining position based on condition

In the above case I need to close PID10002.

Please help me how to do this in a proper way

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

I am still not sure about your requirements but you can try this

 foreach (var pos in Positions.Where(p => Positions.Count(ps => ps.Comment == p.Id.ToString()) == 0))

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


velu130486
05 Sep 2022, 16:55 ( Updated at: 21 Dec 2023, 09:22 )

RE:

Hi Panagiotis,

Since it is not possible to edit the comments, could you please help me to filter the position which position ID is not available in Comments.

As you can see from the above picture I have position ID and comments column so I want to filter the position for which Position ID is not in comments, yellow highlighted position to do some action.

 foreach (var pos in positionsCopy)
            {
				// if position comment is empty then skip it
				if (string.IsNullOrWhiteSpace(pos.Comment)) continue;
				
				var commentSplit = pos.Comment.Split('PID');
				if (commentSplit.Length < 2) continue;
				var originalPositionIdString = commentSplit[1];
				
				long originalPositionId;
				
				if (!long.TryParse(originalPositionIdString, out originalPositionId)) continue;
				
				var originalPosition = Positions.FirstOrDefault(position => position.Id == originalPositionId);
				
				if (originalPosition == null) continue;
				
				// Now you have the original position on originalPosition variable
            }

Earlier I got support from this forum for the above code however it is not working fine. So could you please help me to filter the positions comment is blank and also position ID is not existing in other positions?

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

It is not possible because you cannot know the position id before it is executed.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


velu130486
05 Sep 2022, 13:42

RE:

Hi Panagiotis,

I understand the comments can't be edited, thats why it is possible to add the position ID in comments while executing the order itself via Cbot like label.

Or Please help me to find the positions which Position ID and Comment is matching, because I have a Cbot which creates opposite order (with Position ID in comments) after certain condition. Now I want to close the positions except the 2 positions which position ID and comments are matching.

Note : I am not a developer, last time I got support from this forum for creating the opposite orders. Now I want to filter out the positions in Cbot.

Thanks and Regards,

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

It is not possible to edit position comments at the moment.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


velu130486
26 Aug 2022, 09:19

RE:

PanagiotisCharalampous said:

Hi Vadivelan,

Unfortunaltely the code you sent references some external libraries therefore we won't be able to build it. If you have paid for this cBot, then the first thing you should do is to contact the developer.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

Hi Panagiotis,

Thanks for the reply. I have the library files with me. With that is it possible to fix it. Yes I had paid lot of money, however the developer is not responding.

Can I share the library files and Cbot source code to your Telegram.

Please support to fix this error

Regards

R. Vadivelan


velu130486
12 Jul 2022, 03:49

RE:

Hi Panagiotis,

This Bot was working fine in Ctrader 4.1. I got this error after update to 4.3.8. Now I can't contact the previous developer, so before passing this to new developer could you please help me to identify which section is causing the error because I already invested a lot of money for this bot. As I understood the error is coming from Alert feature, I am ok to run the bot even with alert facility. Please help me to fix this.

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi there,

The components that throw the exceptions are not part of cTrader. You either need to contact the original developer or pass the complete solution to another developer to fix the problem.

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


velu130486
11 Jul 2022, 06:52 ( Updated at: 21 Dec 2023, 09:22 )

RE:

Dear All.

Could you please help me to solve this problem, since I can't use my CBOT after the Ctrader update.

Thanks and Regards

R. Vadivelan

velu130486 said:

Dear All,

Till yesterday I was using IC Market Ctrader 4.1 and my Cbot was working fine. Today I updated to Spotware CTrader 4.3.8 but after that I can't lod my Cbot and it is showing the below error.

So I tried to build the bot in .Net 4, I got the below error

Also I got the above error when I tried to build in both .Net 4 and .Net 6.

I am not a developer, and I had developed this Cbot with help of a another person and I could not reach that person.

So please help me to solve this problem. I posted the Cbot code as below

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

using FeatureFXlib;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.IO;
using System.Windows.Forms;
using cAlgo.API.Alert;
using cAlgo.API.Alert.Utility;
using WMPLib;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class vadivelanZonev10 : Robot
    {
        [Parameter("Remove Olverlapping", Group = "FEATURE", DefaultValue = true)]
        public bool overlapping { get; set; }
        [Parameter("Sound Alert", Group = "FEATURE", DefaultValue = true)]
        public bool soundalert { get; set; }

        //-----------------CUSTOM PARAMETERS
        FeatureFX API = new FeatureFX();
        BarFX bar = new BarFX();
        Thread thread;
        //Form1 form = new Form1();
        //DataGridView table;

        ControlBase panel;
        int timeCount = 0;
        int alertCount = 0;
        int signalCount = 0;

        protected override void OnStart()
        {
            playDesktopAudio("FXaudio", "swiftly.mp3");
            bar.glob = MarketData;
            //table = form.dataGridView1;

            API.drawPanelButton("Execute", Chart, panel, IndicatorStart, VerticalAlignment.Bottom, cAlgo.API.HorizontalAlignment.Right);
            Chart.DrawIcon("start", ChartIconType.Circle, Bars.OpenTimes.LastValue, Bars.ClosePrices.LastValue, Color.White);
        }

        WMPLib.WindowsMediaPlayer player = new WMPLib.WindowsMediaPlayer();
        ChartRectangle drawRectangle(string id, DateTime t1, double y1, DateTime t2, double y2, Color clr)
        {
            var rec = Chart.DrawRectangle(id, t1, y1, t2, y2, clr);
            rec.Color = Color.FromArgb(80, clr.R, clr.G, clr.B);
            rec.IsFilled = true;
            return rec;
        }
        public void playDesktopAudio(string FolderName, string FileName)
        {
            var windowsFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            var path = Path.Combine(windowsFolder, FolderName, FileName);
            //cAlgo
            //Notifications.PlaySound(path);
            //System
            player.URL = path;
            player.controls.play();
        }
        void soundAlert()
        {
            if (soundalert)
                if (alertCount != timeCount)
                {
                    alertCount = timeCount;
                    playDesktopAudio("FXaudio", "swiftly.mp3");
                }
        }     
    }
}

Thanks and Regards

R. Vadivelan

 


velu130486
27 Oct 2021, 13:13

RE:

Thanks Ahmad for your immediate support and it is very much appreciated.

I will try to work around based on your coding.

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

The original position ID is on the comment of opposite position, so you can match them by using the opposite position comment and the original position ID.

To get original position ID from opposite position you can split its comment with "_", the second value will be ID, then parse the ID with long.Parse and then you can compare it with original position ID for matching.

            foreach (var pos in positionsCopy)
            {
				// if position comment is empty then skip it
				if (string.IsNullOrWhiteSpace(pos.Comment)) continue;
				
				var commentSplit = pos.Comment.Split('_');
				
				if (commentSplit.Length < 2) continue;
				
				var originalPositionIdString = commentSplit[1];
				
				long originalPositionId;
				
				if (!long.TryParse(originalPositionIdString, out originalPositionId)) continue;
				
				var originalPosition = Positions.FirstOrDefault(position => position.Id == originalPositionId);
				
				if (originalPosition == null) continue;
				
				// Now you have the original position on originalPosition variable
            }

 

 


velu130486
27 Oct 2021, 09:24 ( Updated at: 27 Oct 2021, 10:28 )

RE:

Hi Ahmad,

Sorry I made the mistake in ATR Calculation, after fixed it your code works fine. Thanks for your support.

Since you said earlier we can't modify the comment after the position is opened, how to match the original position and opposite position.

For ex in original position comment is blank, whereus the opposite position we have comment "Opposite_XX", How to match these 2 positions.

Another question is Once the opposite position is created for, I would like to modify the position to increase or decrease volume to maintain the proper hedging.

 

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

The code I posted opens an opposite position for each of your bot positions based on given condition.

What do you mean by lots of positions? do you want to set a maximum position number?

If you can tell us what exactly you want to implement on your cBot then I will be able to help you.

 


velu130486
26 Oct 2021, 09:58 ( Updated at: 21 Dec 2023, 09:22 )

RE:

Hi Ahmad,

Thanks for your quick reply and I try your code in backtest but still lot of positions are opened as below picture.

Could you please help to fix it.

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

You should use OnTick not OnBar, and the issue with your code is that you are opening multiple opposite positions for a single position, try this:

using System;
using System.Linq;
using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        protected override void OnTick()
        {
            CreateOpposite();
        }

        private void CreateOpposite()
        {
            var positionsCopy = Positions.ToArray();

            foreach (var pos in positionsCopy)
            {
                var comment = string.Format("Opposite_{0}", pos.Id);

                if (Positions.Any(position => string.Equals(position.Comment, comment, StringComparison.OrdinalIgnoreCase)))
                {
                    continue;
                }

                var sym = pos.SymbolName;
                var type = pos.TradeType;
                var cmd = pos.Comment;
                var ov = pos.VolumeInUnits;
                double atr = ATR[sym].Result.LastValue;

                if (type == TradeType.Buy && pos.Pips <= -5 * atr)
                {
                    ExecuteMarketOrder(TradeType.Sell, sym, ov, "EA", 0, 0, comment);
                }
                if (type == TradeType.Sell && pos.Pips <= -5 * atr)
                {
                    ExecuteMarketOrder(TradeType.Buy, sym, ov, "EA", 0, 0, comment);
                }
            }
        }
    }
}

I use comment to prevent opening multiple opposite positions for a single position, each position will have only one opposite position.

 


velu130486
25 Oct 2021, 10:22

RE: RE: RE:

Thanks Ahmad for your reply. I will try to play with position labels. By the way is there any possibility to change the Position label or comment once the position is opened. I am ok to do the modification manually also.

Thanks and Regards,

R. Vadivelan.

amusleh said:

velu130486 said:

Hi Ahmad,

Thanks for your reply. Actually my request is to double the volume on every 4th position count not based on time.

Because sometimes my bot create more than 4 - 6 positions within a hour depends on moving average signal. So the volume is increased on each and every position which I would like to control it, so I would like to increase the volume only on 4,8,12,16 position for both buy and sell positions etc.,

Thanks and Regards

R. Vadivelan

amusleh said:

Hi,

You can use timer, set the interval to 4 hours and double the volume whenever the timer elapsed:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.EasternStandardTime, AccessRights = AccessRights.None)]
    public class HighVolumeHours : Robot
    {
        private double _volume;

        protected override void OnStart()
        {
            // Here we set the initial volume to symbol minimum volume
            _volume = Symbol.VolumeInUnitsMin;

            // Here we start the timer and we set the interval to 4 hours
            Timer.Start(TimeSpan.FromHours(4));
        }

        protected override void OnTimer()
        {
            // double the volume whenever OnTimer is called
            _volume *= 2;

            // Stop the timer if we reached the symbol maximum volume
            if (_volume >= Symbol.VolumeInUnitsMax)
            {
                _volume = Symbol.VolumeInUnitsMax;

                Timer.Stop();
            }
        }
    }
}

 

 

Hi,

You can do that by using position label to differentiate your cBot positions from other positions, then use Positions collection to count the number of your cBot open positions.

Then you can multiply the number of positions to volume or any other number you want to, for example if your cBot had 4 open positions you can multiply the volume by 2.