Hello, I started using the ProOrder system 1 week or so ago and I’m trying to build a simple script which will analyze price movements and buy or sell according to price reaction on key levels (past supports and resistances), for now the idea is to make it very basic then refine it, but I already have a hard time making the basic version start, when doing so PRT tells me (I tried to translate it the best I can since it wasn’t originally wrote in english) :
ParseError at [row,col]:[1,241]
Message: XML document structures must start and finish within the same entity
This message isn’t really clear and makes it hard to debug the error, is there any way to access a more verbose debugger to track the issue?
Anyway here is the code :
//INITIALISATION
IF init = Undefined THEN
init = 1
$priceLv[0] = 1.25050
$priceLv[1] = 1.24908
$priceLv[2] = 1.24846
$priceLv[3] = 1.24612
$priceLv[4] = 1.24548
$priceLv[5] = 1.24414
$priceLv[6] = -1.00000
FOR x = 0 TO 6 DO
$priceMem[x] = 0
$priceLimHigh[x] = $priceLv[x] + 2*PipSize
$priceLimLow[x] = $priceLv[x] - 2*PipSize
NEXT
ENDIF
// -------- PROCESSING
FOR x = 0 TO 6 DO
// -------- Price Movements Init
//If price CROSSES OVER -> upward trend
IF close CROSSES OVER $priceLv[x] AND $priceMem[x] = 0 THEN
$priceMem[x] = 1
ENDIF
//if price CROSSES UNDER -> downward trend
IF close CROSSES UNDER $priceLv[x] AND $priceMem[x] = 0 THEN
$priceMem[x] = -1
ENDIF
//If price CROSSES OVER High Limit -> next time price crosses this levels, trend will be downward
IF $priceMem[x] = 1 AND NOT LongOnMarket THEN
IF close CROSSES OVER $priceLimHigh[x] THEN
$priceMem[x] = -1
ENDIF
ENDIF
//If price CROSSES UNDER Low Limit -> next time price crosses this levels, trend will be upward
IF $priceMem[x] = -1 AND NOT ShortOnMarket THEN
IF close CROSSES UNDER $priceLimLow[x] THEN
$priceMem[x] = 1
ENDIF
ENDIF
// -------- Passing order
IF $priceMem[x] = 1 AND close > $priceLimLow[x] AND close < $priceLimHigh[x] AND close[1] < open[1] THEN
BUY 1 CONTRACT AT MARKET
ENDIF
IF $priceMem[x] = -1 AND close > $priceLimLow[x] AND close < $priceLimHigh[x] AND close[1] > open[1] THEN
SELLSHORT 1 CONTRACT AT MARKET
ENDIF
// -------- Closing order
IF LongOnMarket AND $priceMem[x] = 1 AND close > close[1] THEN
SELL AT MARKET
ENDIF
IF ShortOnMarket AND $priceMem[x] = -1 AND close < close[1] THEN
EXITSHORT AT MARKET
ENDIF
NEXT
I tried to target the error and it looks like this is this following part that is causing the error :
//Si prix CROSSES OVER -> mouvement de fond haussier
IF close CROSSES OVER $priceLv[x] AND $priceMem[x] = 0 THEN
$priceMem[x] = 1
ENDIF
//Si prix CROSSES UNDER -> mouvement de fond baissier
IF close CROSSES UNDER $priceLv[x] AND $priceMem[x] = 0 THEN
$priceMem[x] = -1
ENDIF
//Si prix CROSSES OVER limite Haute -> la prochaine fois que le prix reviendra sur la ligne de prix, considérer mvmt comme baissier
IF $priceMem[x] = 1 AND NOT LongOnMarket THEN
IF close CROSSES OVER $priceLimHigh[x] THEN
$priceMem[x] = -1
ENDIF
ENDIF
Any idea about what I could have done wrong ?
Thanks
Hi,
Such a message generally is an indication that the PRT parser chokes on conditional stuff inside your code, which it tries to be intelligent about (predict what variables are going to be used downstream so they don’t need to be explicitly defined by you, the coder). Generally you can’t help it going wrong, as in all cases I run into it, it’s just a PRT bug. Easy example :
GraphOn = 1 // Debug Mode.
If GraphOn then // Debug Mode ?
Graph OnMarket // 0 or 1
endif
This may go wrong depending on unknown internal situations, and the solution is to remove (comment out) that If GraphOn and adjacent Endif.
In your situation the For loop including the Sell and ExitShort commands, look sufficiently suspicious to me to avoid. So notice that your conditions would allow to trigger several of either, and the choking is on. You could cover for this technically wrong setup by means of tracking that one of the commands has been executed already (thus, formally you will be off market in the next call of the bar/code) so you won’t execute a next which would overrule the previous. In your case you’re thus not only overruling a former Sell with a Sell, but you will also overrule a former Sell with an ExitShort. And vise versa.
Try it out quickly by means of looping one time only (not 7 times (0 to 6)) and comment out the ExitShort (or Sell).
Heads up, because what you do seems nice. 🙂
Peter
Deleted as I proved myself wrong! 😉
Thanks for the heads up!
I tried multiple things :
- Doing only one looping and commenting out everything except one BUY command
- Breaking out of the loop when one the Buy, Sell, SellShort, ExitShort command is called
- Putting
NOT OnLongMarket AND NOT OnShortMarket in the conditions so multiples commands aren’t called during the same looping
- Putting every conditions in his own loop and Breaking out of it as soon as the condition is met
But to no avail for now.
As I said the error disappears when I comment out this part within the loop:
// -------- Price Movement Initialization
//If price CROSSES OVER -> background upward trend
IF close CROSSES OVER $priceLv[x] AND $priceMem[x] = 0 THEN
$priceMem[x] = 1
ENDIF
//If price CROSSES UNDER -> background downward trend
IF close CROSSES UNDER $priceLv[x] AND $priceMem[x] = 0 THEN
$priceMem[x] = -1
ENDIF
//If price CROSSES OVER High Limit -> next time price crosses this levels, trend will be downward
IF $priceMem[x] = 1 AND NOT LongOnMarket THEN
IF close CROSSES OVER $priceLimHigh[x] THEN
$priceMem[x] = -1
ENDIF
ENDIF
//If price CROSSES UNDER Low Limit -> next time price crosses this levels, trend will be upward
IF $priceMem[x] = -1 AND NOT ShortOnMarket THEN
IF close CROSSES UNDER $priceLimLow[x] THEN
$priceMem[x] = 1
ENDIF
ENDIF
So maybe the choking is happening during the modification of the variables in those conditions? Would it be possible according to your knowledge?
Anyway I’m going to keep fiddling with it
Looks like it is the expressions like
IF close CROSSES OVER $priceLv[x]
that are causing the error
IF $priceMem[x] = 1 AND NOT LongOnMarket THEN
IF close CROSSES OVER $priceLimHigh[x] THEN
$priceMem[x] = -1
ENDIF
ENDIF
Maye you can concentrate on the part above;
So you’re inside of an If conditioned by an array variable which you set within that If ( $PriceMem[x] ).
Normally this can be done of course, but arrays could be too much of a tweak for PRT itself to have thought of this situation.
priceMemHlp = $priceMem[x]
IF $priceMem[x] = 1 AND NOT LongOnMarket THEN
IF close CROSSES OVER $priceLimHigh[x] THEN
priceMemHlp = -1
ENDIF
ENDIF
$priceMem[x] = priceMemHlp
Untested of course so I hope I have the logic right.
Because this is so often about “structures”, also think of this setup which is more common to PRT coding/coders :
Condition1 = close CROSSES OVER $priceLimHigh[x]
...
If Condition1 then
...
I wouldn’t do it like that by nature, but still it is a means, and it avoids more “structure” as such for the “parser”.
Do you receive the error during Optimization (iterating over Optimization Variables) ? or do you receive the error when the backtest tries to show the Stats of the result ?
When you don’t recognize “Optimization” as such, you would not be able to tell, unless without the error the result is there 50 times faster. I hope this is clear ?
Just in case it is new to you, Optimization makes use of the form with at the bottom of it what you see below.
Thanks, I tried that too but it didn’t change the result.
In fact I think the error only comes from the fact that I’m using “CROSSES OVER/UNDER” for a curve (the price) in relation to a single price, the documentation stipulates that CROSSES OVER/UNDER is to be used to compare 2 curves, so maybe that’s just it unless it is supposed to also work the way I did it…
It’s not possible to use CROSSES OVER/UNDER with arrays as they are NOT historicized, i.e. $myElement[N] will only retain the current value, as it’s not possible to access the value retained the prior candle. Whenever you change it, the previous value is lost.
CROSSES means comparing the previous valus with the current one. Since only the current one is available, those instructions cannot be used. If you know what element is to be compared, I suggest to assign its value to a variable, provided you know what element of the array is the one to be tested:
.
.
IF close CROSSES OVER MyVariable THEN
.
ENDIF
.
.
myVariable = $myElement[5]
this will work, as I only want to test element 1:
IF BarIndex = 0 THEN
$myArray[1] = 0
$myArray[2] = 0
$myArray[3] = 0
ENDIF
IF OnMarket THEN
SELL AT Market
ENDIF
$myArray[1] = $myArray[2]
$myArray[2] = $myArray[3]
$myArray[3] = close
x = $myArray[1]
Sma = average[20,0](close)
//IF $myArray[1] CROSSES OVER Sma THEN // ERROR
IF x CROSSES OVER Sma THEN
BUY AT Market
ENDIF
Alright, it makes sense now.
I just ended up using open < value AND close > value instead