Ulcer index bug

Ulcer index itself is one-directional but the direction is specified in the SQX version therefore this does appear to be symmetrical:

LongEntrySignal = UlcerIndex(Main chart, Down UI, UlcerIndexiPeriod1)[1]   is rising;

ShortEntrySignal = UlcerIndex(Main chart, UP UI, UlcerIndexiPeriod1)[1]   is rising;



But for some other reasons, the strategy does not act symmetrically until I remove ulcer and only ulcer from the equation therefore the problem is ulcers internal calculations

LongEntrySignal = (UlcerIndex(Main chart, Down UI, UlcerIndexiPeriod1)[1]   is rising
   or  True);

ShortEntrySignal = (UlcerIndex(Main chart, UP UI, UlcerIndexiPeriod1)[1]   is rising
   or  True);



I'm guessing this below should do it (but I can't easily check my work because SQX reverts changes when I recompile and I don't feel like tediously reconstructing all the rules in algowizard making a clone of ulcer)
...
if(Mode == 1){ // UP UI=1

highestCalculator.onBarUpdate(Input.Close.get(0), CurrentBar); 
double hc = highestCalculator.getHighestValue();
double dd =  100d*((Input.Close.get(0))-hc)/hc;
ddBuffer.set(0,dd);
double sum =0;

for(int k = 0;k<Period;k++){
sum = sum + Math.pow(ddBuffer.get(k),2);
}

double uI = SQUtils.round(Math.sqrt((sum/Period)),4);

Value.set(0,uI);
}
else if(Mode == 2){ // Down UI=2

lowestCalculator.onBarUpdate(Input.Close.get(0), CurrentBar); 
double lc = lowestCalculator.getLowestValue(); 
double dd =  100d*(lc-(Input.Close.get(0)))/lc;
ddBuffer.set(0,dd);
double sum =0;


...
Or maybe it should be this:

double dd =  100d*(lc/(lc-(Input.Close.get(0))));
something like that.

Attachments
ulcer-ruled-out.sqx
(1001.88 KiB)
bugged-ulcer.sqx
(769.17 KiB)
  • Votes +4
  • Project StrategyQuant X
  • Type Bug
  • Status Fixed
  • Priority Normal

History

b
#1

bentra

21.07.2022 18:56

Task created

b
#2

bentra

21.07.2022 18:58
Voted for this task.
b
#3

bentra

25.07.2022 16:31
I'm pretty sure you can't do 1/price to reverse price like that, it changes ratios. Why not 2/price or 100/price or 0.1/price? Each one would get different results depending on how you use the price. You could try price * -1 to flip the price around though...


h
#4

hruyak41287

29.07.2022 13:43
Voted for this task.
E
#5

Emmanuel

06.08.2022 15:33
Voted for this task.
CG
#6

Chris G

19.09.2022 20:12
Voted for this task.
b
#7

bentra

22.09.2022 10:03
To give context, the current code looks like this:


if(Mode == 1){ // UP UI=1
                
                highestCalculator.onBarUpdate(Input.Close.get(0), CurrentBar); 
                double hc = highestCalculator.getHighestValue();        
                double dd =  100d*((Input.Close.get(0))-hc)/hc;
                ddBuffer.set(0,dd);
                double sum =0;
                
                    for(int k = 0;k<Period;k++){
                        sum = sum + Math.pow(ddBuffer.get(k),2);
                        }
                    
                    double uI = SQUtils.round(Math.sqrt((sum/Period)),4);
                    
                    Value.set(0,uI);    
            }
            else if(Mode == 2){ // Down UI=2
            
                lowestCalculator.onBarUpdate(Input.Close.get(0), CurrentBar); 
                double lc = 1/lowestCalculator.getLowestValue(); 
                double dd =  100d*((1/Input.Close.get(0))-lc)/lc;               
                ddBuffer.set(0,dd);
                double sum =0;
                
                    for(int k = 0;k<Period;k++){
                        sum = sum + Math.pow(ddBuffer.get(k),2);
                        }
                
                    double uI = SQUtils.round(Math.sqrt((sum/Period)),4);
                    
                    Value.set(0,uI);                            
            }       



b
#8

bentra

22.09.2022 18:26

Attachment Strategy 10615021-ulcerclone.sqx added

Attachment SQExtension-ulcerclone.sxp added

Strategy 10615021-ulcerclone.sqx
(128.95 KiB)
SQExtension-ulcerclone.sxp
(1.80 KiB)
OK I couldn't resist fixing this for you. It turns out we don't need "1/"  nor do we need to reverse the equation since we are just taking the difference between close and the max close (and then dividing it by max) and then doing math pow on it so this is fine:

            if(Mode == 1){ // UP UI=1
                
                highestCalculator.onBarUpdate(Input.Close.get(0), CurrentBar); 
                double hc = highestCalculator.getHighestValue();        
                double dd =  100d*((Input.Close.get(0))-hc)/hc;
                ddBuffer.set(0,dd);
                double sum =0;
                
                    for(int k = 0;k<Period;k++){
                        sum = sum + Math.pow(ddBuffer.get(k),2);
                        }
                    
                    double uI = SQUtils.round(Math.sqrt((sum/Period)),4);
                    
                    Value.set(0,uI);    
            }
            else if(Mode == 2){ // Down UI=2
            
                lowestCalculator.onBarUpdate(Input.Close.get(0), CurrentBar); 
                double lc = lowestCalculator.getLowestValue(); 
                double dd =  100d*((Input.Close.get(0))-lc)/lc;     
                ddBuffer.set(0,dd);
                double sum =0;
                
                    for(int k = 0;k<Period;k++){
                        sum = sum + Math.pow(ddBuffer.get(k),2);
                        }
                
                    double uI = SQUtils.round(Math.sqrt((sum/Period)),4);
                    
                    Value.set(0,uI);                            
            }       



Trades Symmetry 98%

MF
#9

Mark Fric

10.11.2022 11:36

Status changed from New to Fixed

thank you, I'll be using your fix.

Votes: +4

Drop files to upload

or

choose files

Max size: 5MB

Not allowed: exe, msi, application, reg, php, js, htaccess, htpasswd, gitignore

...
Wait please