marketRangePips Question
marketRangePips Question
20 Jan 2018, 19:37
Hey guys
My question is, can marketRangePips work only one way?
My cbots use the TP:SL (Take Profit vs Stop Loss) ration to atleast 2:1, so my TP is usually twice as big as SL.
So, can the marketRangePips be separated to movements UP and movements DOWN? On the example below I would like marketRangePips to be 700 for movements up and 350 for movements down (just identical to TP and SL)
ExecuteMarketOrder(TradeType.Buy, Symbol, volume, "Buy1", 350, 700, marketRangePips);
Replies
irmscher9
22 Jan 2018, 12:53
( Updated at: 21 Dec 2023, 09:20 )
Ok.
I was actually looking for solution to this:
As you can see there's a fracture (if I said it correctly) all of a sudden and thus ignoring my Stop Loss and drawing down my whole account. So I thought Market Range would help to avoid these.
@irmscher9
PanagiotisCharalampous
22 Jan 2018, 14:13
Hi irmscher9,
If you send us the cBot code and the backtesting parameters, maybe we can check out why the stop loss is ignored.
Best Regards,
Panagiotis
@PanagiotisCharalampous
irmscher9
22 Jan 2018, 14:57
Here is the bot. It's not about the bot actually. You will get the same problem with ANY bot when those fractures happen, usually after the weekends and holidays. I actually program my bots not to trade on Fridays after 20:00 pm and Mondays before 4:00 am and it's kinda a solution but this fracture above happened on 13th of April 2017 which is Thursday, then there are 2 bars which are dated by 16th which is Sunday and it's weird. Well, may be Bank holiday or something.
So the thing is, I can program my bot NOT to trade and close all existing trades on Firidays after 20.00pm, but how do I do with the rest which are not weekends? That's why I tought marketRangePips might help.
Here's the bot:
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 NewcBot : Robot { //--TODO: //-- 1. Chaikin Volotility, if above 500 - don't trade for X amount of time. [Parameter("Source")] public DataSeries SourceSeries { get; set; } [Parameter("Lot Size", DefaultValue = 1)] public double lot { get; set; } private MarketSeries m30; private RelativeStrengthIndex _rsi; private MacdHistogram _mcd; private CommodityChannelIndex _cci; private DonchianChannel _dnc; private BollingerBands _blb; private DirectionalMovementSystem _dms; private ExponentialMovingAverage _ema14; private ExponentialMovingAverage _ema21; private ExponentialMovingAverage _ema30; private ExponentialMovingAverage _ema100; private ExponentialMovingAverage _ema150; public double haOpen; public double haClose; public double candle; public double candle1; public double candle2; public double candle3; public double candle4; public double upShadow; public double upShadow1; public double upShadow2; public double upShadow3; public double upShadow4; public double downShadow; public double downShadow1; public double downShadow2; public double downShadow3; public double downShadow4; public double HeikenC; public double HeikenC2; public double haOpen_30m; public double candle_30m; public int buyPeriods; public int sellPeriods; public int fractal65; public int fractal35; public int buyMode; public int sellMode; public int noBuyMode; public int noSellMode; public bool BUYcond; public bool SELLcond; public double BUYprice; public double SELLprice; public double A; public double HeikenCinit; public long volume; protected override void OnStart() { Positions.Closed += OnPositionsClosed; m30 = MarketData.GetSeries(TimeFrame.Minute30); volume = Symbol.QuantityToVolume(lot); _rsi = Indicators.RelativeStrengthIndex(SourceSeries, 21); _mcd = Indicators.MacdHistogram(70, 35, 15); _cci = Indicators.CommodityChannelIndex(20); _dnc = Indicators.DonchianChannel(20); _blb = Indicators.BollingerBands(SourceSeries, 20, 2, MovingAverageType.Simple); _dms = Indicators.DirectionalMovementSystem(14); _ema14 = Indicators.ExponentialMovingAverage(SourceSeries, 14); _ema21 = Indicators.ExponentialMovingAverage(SourceSeries, 21); _ema30 = Indicators.ExponentialMovingAverage(SourceSeries, 30); _ema100 = Indicators.ExponentialMovingAverage(SourceSeries, 90); _ema150 = Indicators.ExponentialMovingAverage(SourceSeries, 170); haClose = 0; haOpen = 0; candle = 0; candle1 = 0; candle2 = 0; candle3 = 0; candle4 = 0; upShadow = 0; upShadow1 = 0; upShadow2 = 0; upShadow3 = 0; upShadow4 = 0; downShadow = 0; downShadow1 = 0; downShadow2 = 0; downShadow3 = 0; downShadow4 = 0; HeikenC = 0; HeikenC2 = 0; haOpen_30m = 0; candle_30m = 0; buyPeriods = 0; sellPeriods = 0; fractal65 = 0; fractal35 = 0; noBuyMode = 0; noSellMode = 0; BUYprice = 0; SELLprice = 0; BUYcond = false; SELLcond = false; } protected override void OnTick() { //-- var positionBUY1 = Positions.Find("Buy1"); var positionSELL1 = Positions.Find("Sell1"); //----- Fractals if (_rsi.Result.Last(2) <= 49 && _rsi.Result.Last(2) > 31 && MarketSeries.Low.Last(1) > MarketSeries.Low.Last(2) && MarketSeries.Low.Last(2) > MarketSeries.Low.Last(3) && MarketSeries.Low.Last(3) < MarketSeries.Low.Last(4) && MarketSeries.Low.Last(4) < MarketSeries.Low.Last(5)) { fractal35 = 25; } //-- _rsi.Result.Last(2) < 67 && if (_rsi.Result.Last(2) >= 51 && _rsi.Result.Last(2) < 69 && MarketSeries.High.Last(1) < MarketSeries.High.Last(2) && MarketSeries.High.Last(2) < MarketSeries.High.Last(3) && MarketSeries.High.Last(3) > MarketSeries.High.Last(4) && MarketSeries.High.Last(4) > MarketSeries.High.Last(5)) { fractal65 = 25; //Print("haClose = ", haClose); } //-- Cancelling fractal if (_rsi.Result.LastValue > 70) { fractal65 = 0; } if (_rsi.Result.LastValue < 30) { fractal35 = 0; } //-- noBuy noSell if (Server.Time.DayOfWeek == DayOfWeek.Friday && Server.Time.Hour == 21) { noBuyMode = 7; noSellMode = 7; } //-- current price double ask = Math.Round(Symbol.Ask, 5); double bid = Math.Round(Symbol.Bid, 5); double current_price = (ask + bid) / 2; //-- Coefficients and differences double rsiC = _rsi.Result.Last(0) - _rsi.Result.Last(1); //-- bools bool cci450_17 = _cci.Result.Maximum(17) >= 450; bool cciM450_17 = _cci.Result.Minimum(17) <= -450; bool cci300_5 = _cci.Result.Maximum(5) > 300; bool cciM300_5 = _cci.Result.Minimum(5) < -300; bool rsi25_30 = _rsi.Result.Minimum(30) <= 25; bool rsi75_30 = _rsi.Result.Maximum(30) >= 75; bool rsi30_10 = _rsi.Result.Minimum(10) < 30; bool rsi70_10 = _rsi.Result.Maximum(10) > 70; bool rsi33_5 = _rsi.Result.Minimum(10) < 30; bool rsi67_5 = _rsi.Result.Maximum(10) > 70; //-- double opn = MarketSeries.Open.LastValue; double cls = MarketSeries.Close.LastValue; //----- dmsC double dmsD0 = _dms.DIPlus.Last(0) - _dms.DIMinus.Last(0); double dmsD1 = _dms.DIPlus.Last(1) - _dms.DIMinus.Last(1); double dmsC = dmsD0 - dmsD1; //-- HeikenC2 = (candle + candle1 + candle2) / 30; if (current_price > _blb.Top.LastValue) { A = (current_price - _blb.Top.LastValue) * 1000; } if (current_price < _blb.Bottom.LastValue) { A = (current_price - _blb.Bottom.LastValue) * 1000; } double trend = (_ema21.Result.LastValue - _ema30.Result.LastValue) * 1000; if (_rsi.Result.LastValue < 39) { buyMode = 25; } if (_rsi.Result.LastValue > 60 && buyMode > 0) { buyMode = 0; } //-- && HeikenC > -17 if (buyMode > 0 && HeikenC > -5 && current_price < _dnc.Middle.LastValue && cciM300_5 == false && noBuyMode == 0 && positionBUY1 == null && positionSELL1 == null) { ExecuteMarketOrder(TradeType.Buy, Symbol, volume, "Buy1", 500, 750, 750); buyPeriods = 0; buyMode = 0; //Print("A = ", A); Print("HeikenCinit = ", HeikenCinit); Print("HeikenC = ", HeikenC); //Print("C1 = ", C1); //Print("C2 = ", C2); Print("________________"); } //-- && HeikenC < 17 if (_rsi.Result.LastValue > 70 && positionBUY1 == null && positionSELL1 == null) { //ExecuteMarketOrder(TradeType.Sell, Symbol, 1, "Sell1", 50, 75); //sellPeriods = 0; //Print("A = ", A); //Print("HeikenC = ", HeikenC); } //-- Closing positions if (positionBUY1 != null) { //--0 if (buyPeriods > 1 && (Server.Time.DayOfWeek == DayOfWeek.Friday || Server.Time.DayOfWeek == DayOfWeek.Saturday) && Server.Time.Hour >= 20) { //ClosePosition(positionBUY1); } //--1 if (buyPeriods > 20 && MarketSeries.High.Last(2) > _ema100.Result.LastValue && MarketSeries.High.Last(2) < _ema150.Result.LastValue && MarketSeries.High.Last(0) < MarketSeries.High.Last(1) && MarketSeries.High.Last(1) < MarketSeries.High.Last(2) && MarketSeries.High.Last(2) > MarketSeries.High.Last(3) && MarketSeries.High.Last(3) > MarketSeries.High.Last(4)) { //ClosePosition(positionBUY1); //Print("fractal BUY1 close"); } //--2 if (buyPeriods > 10 && positionBUY1.Pips > 30 && _cci.Result.HasCrossedBelow(330, 0)) { //ClosePosition(positionBUY1); //Print("cci330 BUY1 close"); } } if (positionSELL1 != null && rsiC < 7) { //--0 if (sellPeriods > 20 && positionSELL1.Pips >= 20 && _cci.Result.HasCrossedAbove(-150, 0)) { //ClosePosition(positionSELL1); } //--1 if (sellPeriods > 20 && MarketSeries.Low.Last(2) < _ema100.Result.LastValue && MarketSeries.Low.Last(2) > _ema150.Result.LastValue && MarketSeries.Low.Last(0) > MarketSeries.Low.Last(1) && MarketSeries.Low.Last(1) > MarketSeries.Low.Last(2) && MarketSeries.Low.Last(2) < MarketSeries.Low.Last(3) && MarketSeries.Low.Last(3) < MarketSeries.Low.Last(4)) { //ClosePosition(positionSELL1); //Print("fractal SELL1 close"); } //--2 if (sellPeriods > 10 && positionSELL1.Pips > 30 && _cci.Result.HasCrossedAbove(-330, 0)) { //ClosePosition(positionSELL1); //Print("cci330 BSELL1 close"); } } } protected override void OnBar() { //-- positions //-- find positions var positionBUY1 = Positions.Find("Buy1"); var positionSELL1 = Positions.Find("Sell1"); var positionBUY1a = Positions.Find("Buy1a"); var positionSELL1a = Positions.Find("Sell1a"); var positionBUY2 = Positions.Find("Buy2"); var positionSELL2 = Positions.Find("Sell2"); //-- buy && sell periods if (positionBUY1 != null) { buyPeriods++; } if (positionSELL1 != null) { sellPeriods++; } //-- Countdowners if (fractal35 > 0) { fractal35--; } if (fractal65 > 0) { fractal65--; } //-- BuyMode if (buyMode > 0) { buyMode--; } if (sellMode > 0) { sellMode--; } //-- NoBuyMode if (noBuyMode > 0) { noBuyMode--; } if (noSellMode > 0) { noSellMode--; } //-- HeikenC & HeikenAshi if (candle1 != candle) { if (candle1 != 0) { candle4 = candle3; candle3 = candle2; candle2 = candle1; candle1 = candle; } else { candle1 = candle; } } if (upShadow1 != upShadow) { if (upShadow1 != 0) { upShadow4 = upShadow3; upShadow3 = upShadow2; upShadow2 = upShadow1; upShadow1 = upShadow; } else { upShadow1 = upShadow; } } if (downShadow1 != downShadow) { if (downShadow != 0) { downShadow4 = downShadow3; downShadow3 = downShadow2; downShadow2 = downShadow1; downShadow1 = downShadow; } else { downShadow1 = downShadow; } } //-- Heiken Ashi 30m double open2_30m = m30.Open.Last(2); double high2_30m = m30.High.Last(2); double low2_30m = m30.Low.Last(2); double close2_30m = m30.Close.Last(2); double open1_30m = m30.Open.Last(1); double high1_30m = m30.High.Last(1); double low1_30m = m30.Low.Last(1); double close1_30m = m30.Close.Last(1); double haClose1_30m = (open2_30m + high2_30m + low2_30m + close2_30m) / 4; double haClose_30m = (open1_30m + high1_30m + low1_30m + close1_30m) / 4; if (haOpen_30m > 0) haOpen_30m = (haOpen_30m + haClose1_30m) / 2; else haOpen_30m = (open1_30m + close1_30m) / 2; candle_30m = (haOpen_30m - haClose_30m) * -100; //-- Heiken Ashi local double open2 = MarketSeries.Open.Last(2); double high2 = MarketSeries.High.Last(2); double low2 = MarketSeries.Low.Last(2); double close2 = MarketSeries.Close.Last(2); double open1 = MarketSeries.Open.Last(1); double high1 = MarketSeries.High.Last(1); double low1 = MarketSeries.Low.Last(1); double close1 = MarketSeries.Close.Last(1); double haClose1 = (open2 + high2 + low2 + close2) / 4; haClose = (open1 + high1 + low1 + close1) / 4; if (haOpen > 0) { haOpen = (haOpen + haClose1) / 2; //haOpen1 = (haOpen1 + haClose2) / 2; } if (haOpen == 0) { haOpen = (open1 + close1) / 2; //haOpen1 = (open2 + close2) / 2; } double haHigh = Math.Max(Math.Max(high1, haOpen), haClose); double haLow = Math.Min(Math.Min(low1, haOpen), haClose); if (candle >= 0) { upShadow = (haHigh - haClose) * 10000; downShadow = (haOpen - haLow) * -10000; } if (candle < 0) { upShadow = (haHigh - haOpen) * 10000; downShadow = (haClose - haLow) * -10000; } //candle0 = (haOpen0 - haClose1) * -10000; candle = (haOpen - haClose) * -10000; //-- New HeikenC 20 and -20 critical values if (candle4 != 0) { double zero = candle + upShadow + downShadow; double one = candle1 + upShadow1 + downShadow1; double two = candle2 + upShadow2 + downShadow2; double three = candle3 + upShadow3 + downShadow3; double four = candle4 + upShadow4 + downShadow4; double multiplier = (four + three) / (two + one + zero); double C1 = MarketSeries.Close.Last(1) - MarketSeries.Open.Last(1); double C2 = MarketSeries.Close.Last(2) - MarketSeries.Open.Last(2); HeikenCinit = (zero + one + two + three + four) / 50000; HeikenC = ((zero + one + two + three + four) / 50000) + C1 * 1.25 + C2 * 0.75; //Print("HeikenCinit = ", HeikenCinit); //Print("HeikenC = ", HeikenC); //Print("C1 = ", C1); //Print("C2 = ", C2); //Print("________________"); //HeikenC = ((candle + upShadow + downShadow) + (candle1 + upShadow1 + downShadow1) + (candle2 + upShadow2 + downShadow2) + (candle3 + upShadow3 + downShadow3) + (candle4 + upShadow4 + downShadow4)) / 5000; //HeikenC = ((candle + upShadow + downShadow) + (candle1 + upShadow1 + downShadow1) + (candle2 + upShadow2 + downShadow2)) / 30000; } //Print("candle = ", candle); //Print("candle1 = ", candle1); //Print("candle2 = ", candle2); //Print("candle3 = ", candle3); //Print("candle4 = ", candle4); //Print("________________"); //Print("HeikenC = ", HeikenC); } private void OnPositionsClosed(PositionClosedEventArgs args) { var position = args.Position; if (position.Label == "Buy1") { noBuyMode = 5; Print("noBuyMode = ", noBuyMode); } if (position.Label == "Sell1") { } } protected override void OnStop() { // Put your deinitialization logic here } } }
I'm testing it on TickMode between 28/03/2016 and present day.
Thanks :)
@irmscher9
PanagiotisCharalampous
22 Jan 2018, 15:35
Hi irmscher9,
It seems to be an issue with backtesting data. The point that creates this issue does not seem very reasonable. Did you try to contact your broker to check it?
Best Regards,
Panagiotis
@PanagiotisCharalampous
irmscher9
22 Jan 2018, 15:39
Yes, they said you should use MarketRange at your cAlgo. Should I contact them again? what should I say then? Are use sure this one is not a real slippage?
@irmscher9
PanagiotisCharalampous
23 Jan 2018, 17:47
Hi irmscher,
We resolved the issue. There was a discrepancy in the backtesting data which we fixed. Please clear your cached tick data (you can find them in \AppData\Roaming\IC Markets cAlgo\BacktestingCache\Ticks\UK100) and run the backtesting again.
Best Regards,
Panagiotis
@PanagiotisCharalampous
irmscher9
23 Jan 2018, 20:08
Hey Panagiotis thanks for prompt reply :)
Do I delete the whole UK100 folder then?
@irmscher9
PanagiotisCharalampous
24 Jan 2018, 09:17
Hi irmscher9,
Yes you can delete the entire folder.
Best Regards,
Panagiotis
@PanagiotisCharalampous
irmscher9
30 Jan 2018, 13:34
Hey, I have similar issue with USDCHF on 25DEC 2015 (screenshot):
https://1drv.ms/i/s!AvJJop5QTya740_K6VN79zfJw4Go
@irmscher9
PanagiotisCharalampous
30 Jan 2018, 15:55
Hi irmscher9,
Can you please post the image in the forum? I do not have access to it anymore.
Best Regards,
Panagiotis
@PanagiotisCharalampous
irmscher9
30 Jan 2018, 16:10
( Updated at: 21 Dec 2023, 09:20 )
Oops, wait, the wrong one. Here's the right one:
@irmscher9
PanagiotisCharalampous
30 Jan 2018, 16:12
Hi again,
I don't think this is the one. This is for USDJPY and it is for other dates.
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
30 Jan 2018, 16:12
Ok thanks, didn't see your second post
@PanagiotisCharalampous
PanagiotisCharalampous
30 Jan 2018, 16:22
Hi irmscher9,
It seems that the discrepancies are on Christmas day when usually markets are closed. Unfortunately this is not so obvious as the previous case to intervene ourserves, therefore you should contact IC Markets and let them know to check their historical data. Then if there is a problem they should contact us with instructions on how to resolve this issue.
Best Regards,
Panagiotis
@PanagiotisCharalampous
irmscher9
22 Feb 2018, 12:51
Ok, I got in touch with ICMarkets, and here's what they told me:
Andrey Kurnikovs Friday at 14:48 Hi I have an issue with USD CHF backtesting data I have contacted the cTrader CTDN.com 02:38:01 pm they said I should better get in touch with my broker regarding this here it is: https://1drv.ms/i/s!AvJJop5QTya752oATrHxHUw6_DCz (this is a one drive link) (Microsoft one drive shared) and 02:39:08 pm /guides/images/4b4095a6867d0a0da688d9980e647bf865fa3b84.png both cases ignore stop loss If something like that happened in real trading mode, my whole account would be depleted for nothing... Is this a bug or a real backtesting data? If yes, then how to avoid this. Why the positions ignore Stop Losses. Thanks
We apologize for the delay to respond your email. Kindly inform that we have checked your query and screenshots, however, it is not clear which stop losses that were "ignored" you are referring to . The screenshot you have provided is referring the USDCHF chart dated January 15, 2015 which is when there was a huge flash crash on CHF currency . You may find many economical articles in this regard e.g. https://www.forbes.com/sites/deanpopplewell/2015/01/15/flash-crash-ensues-after-swiss-drop-euro-cap/#137788666359 . You may take a look at this article https://www.financemagnates.com/forex/brokers/ic-markets-covering-90-client-negative-losses-swiss-franc-volatility/ informing what actions ICMarkets took to assist clients with the losses they have encountered. I hope it clarifies your query. Should you not hesitate to contact us if you require any further information.
Ok. All my positions on this bot have 60pips Stop Loss. As you can see it works on this position: https://1drv.ms/u/s!AvJJop5QTya76VVTV6sJA6uzm_OW But completely ignored on the following: https://1drv.ms/u/s!AvJJop5QTya76VTz3uozzPv87SSU On top of that, somehow, a number of positions have been opened resulting in a 4,500x4 loss (you can see that on both screenshots on the bottom of the screen)
Dear Andrey, That is expected movement on such uncommon market conditions as during CHF crash. Unfortunately, we are not able to assist with your backtesting program. If you have any recent live account trade inquiries , we will be happy to investigate, however, we are not able to conduct investigation on your cbot tests. Apologize for the inconvenience.
@irmscher9
irmscher9
22 Feb 2018, 12:54
I don't get it, what kind of market conditions can explain the ignoring of Stop Loss...
Any ideas? Is there anything can be done about it?
@irmscher9
PanagiotisCharalampous
22 Feb 2018, 13:02
Hi irmscher9,
Stop Loss is executed as a market order. Therefore slippage is expected, especially when a market is crashing against you. Practically there isn't anything you can do. You cannot sell an asset at a price you want if there is nobody willing to buy it at that price.
Best Regards,
Panagiotis
@PanagiotisCharalampous
irmscher9
27 Feb 2018, 13:59
Yes, OK.
But why does the bot open 4 positions simutenously when it really not supposed to (screenshot):
https://1drv.ms/u/s!AvJJop5QTya76VVTV6sJA6uzm_OW
@irmscher9
PanagiotisCharalampous
22 Jan 2018, 11:13
Hi irmscher9,
Probably you have misunderstood what market range does. Market range specifes the amount of pips that you accept the price to move against you when closing a deal. If the calculated VWAP for the deal exceeds the market range, then it will be either executed partially, only for the liquidity available within the market rage or not executed at all. So there is actually one direction every time, up for buy orders and down for sell orders. Market range affects only the market order and not TP and SL. TP is a limit order therefore market range is not applicable (it can also be interpreted as market range of 0) and SL is a stop order in which you will accept any market range since you need to stop losses and close the entire position.
Let me know if the above clarifies things for you.
Best Regards,
Panagiotis
@PanagiotisCharalampous