This shows the value of including error reporting alerts in the code.c1borg » Tue Mar 05, 2019 8:48 am wrote:I have this repeating error no idea if its a bug.
Could be my mistake and im certainly not proficient enough as a coder to spot this yet, however I will attempt to figure it out.2019.03.05 09:19:18.332 TDesk Trading Partner EAz XAUUSD,H1: Alert: Sell stop: Lots 0.01: Price 0.6802: Bid 0.6795600000000001: TP 0.0: SL 0.0
2019.03.05 09:19:18.320 TDesk Trading Partner EAz XAUUSD,H1: NZDUSD TDesk Trading Partner EAz OP_SELLSTOP order send failed with error(130): invalid stops
Analysis so far, I have 1 NZDUSD trade active and no pending trades. I am also using the new Rolling Grid feature set to enabled and so I tried to disable that feature but it still happens. Im also using the feature on another demo with no issues. My observation is It seems to be attempting to place the trade above the current one, is that a clue.
Edit......
Ok tracked it down to the setting UseAtrForGrid which I have set to true with the default settings seems to be causing the problem.
I need to adjust my ATR settings any recommendations?
- UseGridTrading=true
TypeOfGrid=0
GridSize=3
DistanceBetweenTradesPips=125
UseAtrForGrid=true
GridAtrTimeFrame=1440
GridAtrPeriod=20
GridAtrDivisor=5.0
The Bid price is a variable of the double type, so it has 8 decimal points. Crapql4 sometimes replaces the final 0 with a 1. See the value of the order price being sent - 0.6795600000000001. That has happened here and so the order generates the invalid stop error.
Desky needs to know the bid, ask and no of decimal points (known as "Digits) for each individual pair so there is a function that reads these at the start of many functions by calling void GetBasics(string symbol). Here it is as it now is in V3 in post 1:
Code: Select all
void GetBasics(string symbol)
{
//Sets up bid, ask, digits, factor for the passed pair
digits = (int)MarketInfo(symbol, MODE_DIGITS);
bid = NormalizeDouble(MarketInfo(symbol, MODE_BID), digits);
ask = NormalizeDouble(MarketInfo(symbol, MODE_ASK), digits);
factor = GetPipFactor(symbol);
longSwap = MarketInfo(symbol, MODE_SWAPLONG);
shortSwap = MarketInfo(symbol, MODE_SWAPSHORT);
}//End void GetBasics(string symbol)
bid = NormalizeDouble(MarketInfo(symbol, MODE_BID), digits);
NormalizeDouble forces the variable to hold only the value of the digits after the decimal point, so removing the chance of the eighth having the erroneous 1 added. If you go to the function in your current version, you will see that this is missing. I also had to slightly rearrange the order so that 'digits' is correctly populated.
Copy the code here over the top of the code in 2z. Look a few lines down to the top of bool LookForTradingOpportunities(string symbol, int pairIndex, int type). You will see this code:
GetBasics(symbol);
This ensures that Desky is working with up to date values.
The void OnTimer() event holds the iteration through our list of trading pairs. Find it with a search for:
for (int pairIndex = 0; pairIndex < ArraySize(TDeskSymbols); pairIndex++)
Three lines above this you will see: string symbol = "";
pairIndex is assigned the place in our trade pair list. 'symbol' is assigned the pair symbol such as GBPUSD. These are then passed to every subsequent called function e.g. DoHedging(symbol, pairIndex);
So, if you want to add your own functions define them like this:
void MyFunction((string symbol, int pairIndex)
{
GetBasics(symbol);
Rest of function;
}
Then call it from where ever is appropriate:
MyFunction(symbol, pairIndex);
You pass symbol and pairIndex around whenever you call a new function. pairIndex is not always needed but I have taken lately to passing it around anyhow, so it can be passed from function to function. Suppose you have defined two functions and the second is called from within the first:
void MyFunction((string symbol, int pairIndex)
{
GetBasics(symbol);
double priceToSend = MySecondFunction(symbol, pairIndex);
}
double MySecondFunction((string symbol, int pairIndex)
{
GetBasics(symbol);
double price = bid;
return (price);
}
The void DoHedging(string symbol, int pairIndex) function calls two sub-functions, so have a look to see a real example.