Problem with pending order Stop Loss - only integers
Problem with pending order Stop Loss - only integers
24 Nov 2014, 17:31
Hi :)
I am a coding rookie so please be gentle.
I am manually trading and what I try to code is a Bot which is creating a pending stop order with with the following settings (for a sell order) SL 1 pip above the last candlestick, Entry 1 pip below, TP some pips away, (will move it manually afterwards).
Entry and TP are working fine so far. My problem is the SL. In the example picture below I calculated a SL = 3.5 but my order manager is putting the SL 4 pips away from the entry point (1.5 pip above last CS instead of 1 pip). Since I am scalping these 0.5 pips mean something to me.
I wonder why this is happening. First I thougth maybe it needs an exact pip/pipette value so I rounded the number, but nothing changed. What I recognized is that the separator on the actual SL is a . and the separator in the log box is a ,
Is it possible to put the SL on an exact price like 1.24175 instead of having to calculate the pips from the entry point which is a poor roundabout way?
Next step is auto calculating the position size which is another reason why I need an exact SL.
Thank you for your help!
Moe
double previousHigh = MarketSeries.High.Last(1); Print("High: {0}", previousHigh); double previousLow = MarketSeries.Low.Last(1); Print("Low: {0}", previousLow); double Stop_Loss = ((previousHigh + 0.0001) - (previousLow - 0.0001)) * 10000; Print("Stoploss: {0}", Stop_Loss); double Stop_Loss_rounded = Math.Round(Stop_Loss, 1); Print("Stoploss rounded: {0}", Stop_Loss_rounded); PlaceStopOrder(TradeType.Sell, Symbol, 1000, (previousLow - 0.0001), "mySample_cBot", Stop_Loss_rounded, 7, null, "Second");
Replies
AlexanderRC
26 Nov 2014, 12:36
I have experienced this problem too, but implemented a workaround to change TP and SL to exact prices in a callback and forgot to report that. Essentially, ExecuteMarketOrder[Async] and friends have take profit and stop loss parameters of the double type, but rounded to integers.
@AlexanderRC
zumzum
27 Nov 2014, 12:34
RE:
AlexanderRC said:
I have experienced this problem too, but implemented a workaround to change TP and SL to exact prices in a callback and forgot to report that. Essentially, ExecuteMarketOrder[Async] and friends have take profit and stop loss parameters of the double type, but rounded to integers.
Hi Alexander,
would you mind to share your workaround?
My workaround is to draw a line at the SL price I desire and then move the SL by hand to the target price. Currently I'm manually scalping so it's not to bad (but still far away from reasonable coding).
Correct me if I am wrong but I think when it comes to automatic scalping cTrader is kind of useless if you want to use pending orders. If you go for just say ~3 net pips you just don't want to pay an extra 0.5 pips when your stoploss is hit, especially with higher lot sizes.
Sorry we only offer integers please pay another 100EUR... yea sure ;)
Then you don't need to care about spread anymore, it's doubled this way anyway.
When I get to a point where I want to go for automatic trading I got to change to another platform, maybe Ninjatrader since it is using C# too (or mayne even consider MT4).
I don't get why there is onyl "Stop loss in pips" and not also "Stop loss price" it's circuitous in many situations. Same situation with crosshair and integers only.
Don't get me wrong overall I like cTrader but it really has it teething troubles.
This needs a Hotfix.
@zumzum
deansi
02 Dec 2014, 03:40
zumzum another workaround thats possible to implement in a cbot is to have both the server set SL rounded up to nearest pip, and a cbot implemented SL that is the exact target SL you want that checks on every tick.
So you would set the server SL to a rounded up value of your target (eg real target SL is 3.5pips, set server to 4.0 pips) as backup safety, then you use an OnTick() method to keep checking if the market has reached or passed your real target SL of 3.5pips and close the trade the tick it finds the price has. The only thing you need is to have a price version of your stop loss for this on tick methed, not quantity of pips like the server way of setting the SL.
In addition this workaround requires that the computer and cbot are running and internet connectivity ok, in case of a problem your server set SL (in this example of 4.0pips) if hit, will only cost you 0.5pips more if your system wasnt connected for some reason or if the market volatility was too fast, all good reasons to have BOTH stop losses in place just in case.
If youre getting more slippage than expected due to the delay between your computer and the trade server, or you just want to be able to turn your computer off but the SL still hold up, you could put this system on a vps, for about £25 per month, or some brokers give you this service free if you have enough balance or volume turn over per month.
Let me know if you have trouble coding.
@deansi
AlexanderRC
02 Dec 2014, 12:46
( Updated at: 21 Dec 2023, 09:20 )
RE: RE:
zumzum said:
Hi Alexander,would you mind to share your workaround?
Here is an example
using cAlgo.API; using cAlgo.API.Internals; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class FractionalPips : Robot { [Parameter(DefaultValue = 10.3, MinValue = 0.1)] public double TakeProfitPips { get; set; } [Parameter(DefaultValue = 10.3, MinValue = 0.1)] public double StopLossPips { get; set; } protected override void OnStart() { Positions.Opened += Positions_Opened; ExecuteMarketOrderAsync(TradeType.Sell, Symbol, 1000, "MyRobot"); } void Positions_Opened(PositionOpenedEventArgs obj) { var p = obj.Position; if (p.Label == "MyRobot") { ModifyPositionAsync(p, p.EntryPrice + Symbol.PipSize * StopLossPips, p.EntryPrice - Symbol.PipSize * TakeProfitPips); } } } }
@AlexanderRC
deansi
03 Dec 2014, 17:34
Now that Ive researched it again, It was bugging me too so I figured it out, Not sure why spotware support didnt just mention this, instead of saying an exact SL is a limitation. The only limitation is the initial entering of the order, but modifying it gives you the option of any exact SL and TP you want
Alexanders example should do a good job.
A slight variant to that which works if you dont want to use the Async order and Async modify position types, and to add a bit more explanation below:
double SLinPips = 3.7; double TPinPips = 5.5; ExecuteMarketOrder(TradeType.Sell, Symbol, vol, label, SLinPips, TPinPips, slip); // For a Sell Entry var pos1 = LastResult.Position; //get most recent position if (pos1.TradeType == TradeType.Sell) //make sure its the right direction, for SL TP direction to be right { double SL = pos1.EntryPrice + SLinPips * Symbol.PipSize; //get the positions actual entry price add SL double TP = pos1.EntryPrice - TPinPips * Symbol.PipSize; ModifyPosition(pos1, SL, TP); // change the SL and TP }
So to explain what going on in this example the ExecuteMarketOrder will enter the order with the SL and TP but rounded to whole pips first, then when the order is filled it will continue on to the code below it, where the SL and TP are reinstated, but this time to the exact 3.7pips and 5.5pips.
You would obviously need another similar one below your buy trades with the appropriate logic of trade type and SL being below the entryprice and TP above etc
@deansi
Spotware
25 Nov 2014, 12:34
It is a current limitation, we plan to allow decimal pip values in the future.
@Spotware