Topics
Replies
PanagiotisCharalampous
31 May 2019, 09:28
Hi kanapon,
Yes that is correct, sorry for the typo :)
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
30 May 2019, 14:23
Hi aerich48,
We had a look at this and it seems that at the time you sent the message above you were already logged in, this is why you did not receive a response. Can you please check your implementation? If you already have sessions established then you need to log out first before you can login again.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
30 May 2019, 14:08
Hi ramonsgarcia,
Thanks for posting in our forum. The MACD Histogram is plotting the MACD line find in MACD Crossover as a histogram and not the Histofram line of the MACD Crossover.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
30 May 2019, 11:59
Hi aerich48,
The fact that the nearest proxy is changing in cTrader should not affect your connectivity with other proxies. If it is possible please send us at community@spotware.com the exact message that received an empty response with its timestamp and the proxy to which it was sent so that we can investigate what happened.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
30 May 2019, 11:50
Hi Accelerate,
Backtesting data is created from the broker's price feed. Since brokers have different price feeds, you cannot expect that the backtesting data will match. If you still believe there is an issue, please contact your broker.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
30 May 2019, 09:37
Hi nelson.pmf.sc,
Try the below
if (Positions.Count(x => x.Label == "EUR/USD C") < 20)
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
30 May 2019, 09:32
Hi nmaxcom,
Can you post the cBot code and explain your calim that "an equity drawdown that never happened"?
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
29 May 2019, 17:43
Hi francescoxio,
Thanks for posting in our forum. To delete your account you need to contact ICMarkets.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
29 May 2019, 11:52
Hi kanapon,
Can you try the cBot below and let me know if this is what you need?
// //+------------------------------------------------------------------+ //| Smart Grid | //| Copyright 2014, MD SAIF | //| http://www.facebook.com/cls.fx | //+------------------------------------------------------------------+ //-Grid trader cBot based on Bar-Time & Trend. For range market & 15 minute TimeFrame is best. using System; using cAlgo.API; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class SmartGrid : Robot { private bool _accountIsOutOfMoney; private int _openTradeResult; private readonly string Label = "SmartGrid2"; private DateTime _lastBuyTradeTime; private DateTime _lastSellTradeTime; [Parameter("Buy", DefaultValue = true)] public bool Buy { get; set; } [Parameter("Sell", DefaultValue = true)] public bool Sell { get; set; } [Parameter("Pip Step", DefaultValue = 10, MinValue = 1)] public int PipStep { get; set; } [Parameter("First Volume", DefaultValue = 1000, MinValue = 1000, Step = 1000)] public int FirstVolume { get; set; } [Parameter("Volume Exponent", DefaultValue = 1.0, MinValue = 0.1, MaxValue = 5.0)] public double VolumeExponent { get; set; } [Parameter("Max Spread", DefaultValue = 3.0)] public double MaxSpread { get; set; } [Parameter("Average TP", DefaultValue = 3, MinValue = 1)] public int AverageTakeProfit { get; set; } private double CurrentSpread { get { return (Symbol.Ask - Symbol.Bid) / Symbol.PipSize; } } protected override void OnStart() { } protected override void OnTick() { if (CountOfTradesOfType(TradeType.Buy) > 0) AdjustBuyPositionTakeProfits(CalculateAveragePositionPrice(TradeType.Buy), AverageTakeProfit); if (CountOfTradesOfType(TradeType.Sell) > 0) AdjustSellPositionTakeProfits(CalculateAveragePositionPrice(TradeType.Sell), AverageTakeProfit); if (CurrentSpread <= MaxSpread && !_accountIsOutOfMoney) ProcessTrades(); if (!this.IsBacktesting) DisplayStatusOnChart(); } protected override void OnError(Error error) { if (error.Code == ErrorCode.NoMoney) { _accountIsOutOfMoney = true; Print("opening stopped because: not enough money"); } } protected override void OnBar() { RefreshData(); } protected override void OnStop() { // ChartObjects.RemoveAllObjects(); Chart.RemoveAllObjects(); } private void ProcessTrades() { if (Buy && CountOfTradesOfType(TradeType.Buy) == 0 && MarketSeries.Close.Last(1) > MarketSeries.Close.Last(2)) { _openTradeResult = OrderSend(TradeType.Buy, LimitVolume(FirstVolume)); if (_openTradeResult > 0) _lastBuyTradeTime = MarketSeries.OpenTime.Last(0); else Print("First BUY openning error at: ", Symbol.Ask, "Error Type: ", LastResult.Error); } if (Sell && CountOfTradesOfType(TradeType.Sell) == 0 && MarketSeries.Close.Last(2) > MarketSeries.Close.Last(1)) { _openTradeResult = OrderSend(TradeType.Sell, LimitVolume(FirstVolume)); if (_openTradeResult > 0) _lastSellTradeTime = MarketSeries.OpenTime.Last(0); else Print("First SELL opening error at: ", Symbol.Bid, "Error Type: ", LastResult.Error); } if (CountOfTradesOfType(TradeType.Buy) > 0 && Buy) { if (Math.Round(Symbol.Ask, Symbol.Digits) < Math.Round(FindLowestPositionPrice(TradeType.Buy) - PipStep * Symbol.PipSize, Symbol.Digits) && _lastBuyTradeTime != MarketSeries.OpenTime.Last(0)) { var calculatedVolume = CalculateVolume(TradeType.Buy); _openTradeResult = OrderSend(TradeType.Buy, LimitVolume(calculatedVolume)); if (_openTradeResult > 0) _lastBuyTradeTime = MarketSeries.OpenTime.Last(0); else Print("Next BUY opening error at: ", Symbol.Ask, "Error Type: ", LastResult.Error); } } if (CountOfTradesOfType(TradeType.Sell) > 0 && Buy) { if (Math.Round(Symbol.Bid, Symbol.Digits) > Math.Round(FindHighestPositionPrice(TradeType.Sell) + PipStep * Symbol.PipSize, Symbol.Digits) && _lastSellTradeTime != MarketSeries.OpenTime.Last(0)) { var calculatedVolume = CalculateVolume(TradeType.Sell); _openTradeResult = OrderSend(TradeType.Sell, LimitVolume(calculatedVolume)); if (_openTradeResult > 0) _lastSellTradeTime = MarketSeries.OpenTime.Last(0); else Print("Next SELL opening error at: ", Symbol.Bid, "Error Type: ", LastResult.Error); } } } private int OrderSend(TradeType tradeType, double volumeToUse) { var returnResult = 0; if (volumeToUse > 0) { var result = ExecuteMarketOrder(tradeType, Symbol, volumeToUse, Label, 0, 0, 0, "smart_grid"); if (result.IsSuccessful) { Print(tradeType, "Opened at: ", result.Position.EntryPrice); returnResult = 1; } else Print(tradeType, "Openning Error: ", result.Error); } else Print("Volume calculation error: Calculated Volume is: ", volumeToUse); return returnResult; } private void AdjustBuyPositionTakeProfits(double averageBuyPositionPrice, int averageTakeProfit) { foreach (var buyPosition in Positions) { if (buyPosition.Label == Label && buyPosition.SymbolCode == Symbol.Code) { if (buyPosition.TradeType == TradeType.Buy) { double? calculatedTakeProfit = Math.Round(averageBuyPositionPrice + averageTakeProfit * Symbol.PipSize, Symbol.Digits); if (buyPosition.TakeProfit != calculatedTakeProfit) ModifyPosition(buyPosition, buyPosition.StopLoss, calculatedTakeProfit); } } } } private void AdjustSellPositionTakeProfits(double averageSellPositionPrice, int averageTakeProfit) { foreach (var sellPosition in Positions) { if (sellPosition.Label == Label && sellPosition.SymbolCode == Symbol.Code) { if (sellPosition.TradeType == TradeType.Sell) { double? calculatedTakeProfit = Math.Round(averageSellPositionPrice - averageTakeProfit * Symbol.PipSize, Symbol.Digits); if (sellPosition.TakeProfit != calculatedTakeProfit) ModifyPosition(sellPosition, sellPosition.StopLoss, calculatedTakeProfit); } } } } private void DisplayStatusOnChart() { if (CountOfTradesOfType(TradeType.Buy) > 1) { var y = CalculateAveragePositionPrice(TradeType.Buy); // ChartObjects.DrawHorizontalLine("bpoint", y, Colors.Yellow, 2, LineStyle.Dots); Chart.DrawHorizontalLine("bpoint", y, Color.Yellow, 2, LineStyle.Dots); } else //ChartObjects.RemoveObject("bpoint"); Chart.RemoveObject("bpoint"); if (CountOfTradesOfType(TradeType.Sell) > 1) { var z = CalculateAveragePositionPrice(TradeType.Sell); //ChartObjects.DrawHorizontalLine("spoint", z, Colors.HotPink, 2, LineStyle.Dots); Chart.DrawHorizontalLine("spoint", z, Color.HotPink, 2, LineStyle.Dots); } else //ChartObjects.RemoveObject("spoint"); Chart.RemoveObject("spoint"); //ChartObjects.DrawText("pan", GenerateStatusText(), StaticPosition.TopLeft, Colors.Tomato); Chart.DrawStaticText("pan", GenerateStatusText(), VerticalAlignment.Top, HorizontalAlignment.Left, Color.Tomato); } private string GenerateStatusText() { var statusText = ""; var buyPositions = ""; var sellPositions = ""; var spread = ""; var buyDistance = ""; var sellDistance = ""; spread = "\nSpread = " + Math.Round(CurrentSpread, 1); buyPositions = "\nBuy Positions = " + CountOfTradesOfType(TradeType.Buy); sellPositions = "\nSell Positions = " + CountOfTradesOfType(TradeType.Sell); if (CountOfTradesOfType(TradeType.Buy) > 0) { var averageBuyFromCurrent = Math.Round((CalculateAveragePositionPrice(TradeType.Buy) - Symbol.Bid) / Symbol.PipSize, 1); buyDistance = "\nBuy Target Away = " + averageBuyFromCurrent; } if (CountOfTradesOfType(TradeType.Sell) > 0) { var averageSellFromCurrent = Math.Round((Symbol.Ask - CalculateAveragePositionPrice(TradeType.Sell)) / Symbol.PipSize, 1); sellDistance = "\nSell Target Away = " + averageSellFromCurrent; } if (CurrentSpread > MaxSpread) statusText = "MAX SPREAD EXCEED"; else statusText = "Smart Grid" + buyPositions + spread + sellPositions + buyDistance + sellDistance; return (statusText); } private int CountOfTradesOfType(TradeType tradeType) { var tradeCount = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) tradeCount++; } } return tradeCount; } private double CalculateAveragePositionPrice(TradeType tradeType) { double result = 0; double averagePrice = 0; double count = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) { averagePrice += position.EntryPrice * position.VolumeInUnits; count += position.VolumeInUnits; } } } if (averagePrice > 0 && count > 0) result = Math.Round(averagePrice / count, Symbol.Digits); return result; } private double FindLowestPositionPrice(TradeType tradeType) { double lowestPrice = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) { if (lowestPrice == 0) { lowestPrice = position.EntryPrice; continue; } if (position.EntryPrice < lowestPrice) lowestPrice = position.EntryPrice; } } } return lowestPrice; } private double FindHighestPositionPrice(TradeType tradeType) { double highestPrice = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) { if (highestPrice == 0) { highestPrice = position.EntryPrice; continue; } if (position.EntryPrice > highestPrice) highestPrice = position.EntryPrice; } } } return highestPrice; } private double FindPriceOfMostRecentPositionId(TradeType tradeType) { double price = 0; var highestPositionId = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) { if (highestPositionId == 0 || highestPositionId > position.Id) { price = position.EntryPrice; highestPositionId = position.Id; } } } } return price; } private double GetMostRecentPositionVolume(TradeType tradeType) { double mostRecentVolume = 0; var highestPositionId = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType) { if (highestPositionId == 0 || highestPositionId > position.Id) { mostRecentVolume = position.VolumeInUnits; highestPositionId = position.Id; } } } } return mostRecentVolume; } private int CountNumberOfPositionsOfType(TradeType tradeType) { var mostRecentPrice = FindPriceOfMostRecentPositionId(tradeType); var numberOfPositionsOfType = 0; foreach (var position in Positions) { if (position.Label == Label && position.SymbolCode == Symbol.Code) { if (position.TradeType == tradeType && tradeType == TradeType.Buy) { if (Math.Round(position.EntryPrice, Symbol.Digits) <= Math.Round(mostRecentPrice, Symbol.Digits)) numberOfPositionsOfType++; } if (position.TradeType == tradeType && tradeType == TradeType.Sell) { if (Math.Round(position.EntryPrice, Symbol.Digits) >= Math.Round(mostRecentPrice, Symbol.Digits)) numberOfPositionsOfType++; } } } return (numberOfPositionsOfType); } private double CalculateVolume(TradeType tradeType) { var numberOfPositions = CountNumberOfPositionsOfType(tradeType); var mostRecentVolume = GetMostRecentPositionVolume(tradeType); var calculatedVolume = Symbol.NormalizeVolumeInUnits(mostRecentVolume * Math.Pow(VolumeExponent, numberOfPositions)); return (calculatedVolume); } private double LimitVolume(double volumeIn) { var symbolVolumeMin = Symbol.VolumeInUnitsMin; var symbolVolumeMax = Symbol.VolumeInUnitsMax; var result = volumeIn; if (result < symbolVolumeMin) result = symbolVolumeMin; if (result > symbolVolumeMax) result = symbolVolumeMax; return (result); } } }
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
29 May 2019, 10:50
Hi kanapon,
Thanks for posting in our forum. It seems that this parameter affects only the placement of the first order. If there are positions opened, then it is ignored.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
29 May 2019, 09:43
Hi maustofx,
Thank you for posting in our forum. This functionality is by design. Objects are saved for the chart, not for the timeframe for the symbol.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
29 May 2019, 09:38
Hi Alex,
See below an example for using the Daily timeframe
using System; using cAlgo.API; using cAlgo.API.Internals; using cAlgo.API.Indicators; using cAlgo.Indicators; namespace cAlgo { [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class ActiveAreas : Indicator { public Color _textColor; [Parameter("High Color", DefaultValue = "DarkOrange")] public string ColorH { get; set; } [Parameter("Low Color", DefaultValue = "Orange")] public string ColorL { get; set; } [Parameter("Low Lookback", DefaultValue = "0")] public int Low { get; set; } [Parameter("High Lookback", DefaultValue = "2")] public int High { get; set; } //[Output("Line")] //public IndicatorDataSeries Result { get; set; } protected override void Initialize() { // Initialize and create nested indicators } public override void Calculate(int index) { // Draw the text on the last bar high. var series = MarketData.GetSeries(TimeFrame.Daily); var highPrice = series.High.Last(High); var lowPrice = series.Low.Last(Low); Chart.DrawHorizontalLine("Active Area High", highPrice, ColorH, 2, LineStyle.Solid); Chart.DrawHorizontalLine("Active Area Low", lowPrice, ColorL, 2, LineStyle.Solid); } } }
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
29 May 2019, 09:32
Hi Ariel,
Thanks for positng in our forum. We are currently rolling out v3.5 to brokers. 3.6 will come after that.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
28 May 2019, 17:42
Hi nantonakumac,
Thanks for sharing your feedback with us about cTrtader Mobile. Please note that the issue with the Ichimoku indicator will be fixed in an upcoming update. Regarding the indicators, we would like to assure you that new features and functionalities will be constantly added with new updates on a frequent basis.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
28 May 2019, 16:32
Hi Zobad,
This time you introduced tag 1 which I don't know where you found :) Did you check the Rules of Engagement?
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
28 May 2019, 15:18
Hi Zobad,
The previous messages you posted were logon messages. In your order message I can already see an issue with tag 59. 0 is not a valid value. Symbol is also wrong. It should be an integer. I would advise you to have a look at the Rules of Engagement to check what are the valid values for each tag.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
28 May 2019, 14:38
Hi Zohad,
I do not see any problems in the messages. Can you tell us what is the issue?
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
28 May 2019, 10:38
Hi zobad.mahmood,
Thanks for posting in our forum. Your message ddes not seem to be a correct logon message. See an example of a logon message below
8=FIX.4.4|9=126|35=A|49=theBroker.12345|56=CSERVER|34=1|52=20170117- 08:03:04|57=TRADE|50=any_string|98=0|108=30|141=Y|553=12345|554=passw0rd!|10=131|
You can find more information here.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
28 May 2019, 09:55
Hi calgodemo,
Thanks for posting in our forum. It would be easier for us to help you if you shared your indicator's code.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
31 May 2019, 09:41
Hi Max,
This is not multithreading but event criven programming. Both OnPositionsClosed and OnTick are event which do not depend on each other. My approach would be to trigger the order only when all the positions of the group have closed. However without the cBot code we cannot provide specific guidance as we can only make assumptions about it.
Best Regards,
Panagiotis
@PanagiotisCharalampous