Need help in generating a score on bullish indicator

Hi everyone!
I am trying to put a score for every green/bullish on my indicator namely, MA20, MA50 and MA200.
I am getting a score if the value is not null but, if it is null, I am getting a blank score.
Any help would be appreciated.
Thank you!

//
// Code is not originally mine
// Credits goes to the original uploader/coder
//
i=0;

//Longterm Bullish or Bearish
Bull = C > MA(C,200);
Bear= C < MA(C,200);
IIf(Bull,i+1,i);
lt_status=    WriteIf(Bull, "Bullish", WriteIf(Bear, "Bearish", "Neutral"));
lt_Col=IIf(Bull, colorGreen, IIf(bear, colorRed, colorLightGrey));

//Midterm Bullish or Bearish
mBull = C > MA(C,50);
mBear= C < MA(C,50);
IIf(mBull,i+1,i);
mt_status=    WriteIf(mBull, "Bullish", WriteIf(mBear, "Bearish", "Neutral"));
mt_Col=IIf(mBull, colorGreen, IIf(mbear, colorRed, colorLightGrey));

//Shortterm Bullish or Bearish
sBull = C > MA(C,20);
sBear= C < MA(C,20);
IIf(sBull,i+1,i);
st_status=    WriteIf(sBull, "Bullish", WriteIf(sBear, "Bearish", "Neutral"));
st_Col=IIf(sBull, colorGreen, IIf(sbear, colorRed, colorLightGrey));

TrendScore= 
IIf(Bull,1,0)+
IIf(mBull,1,0)+
IIf(sBull,1,0);

Filter = 1;

AddTextColumn(st_status, "Short-term", 1, colorWhite, st_Col);
AddTextColumn(mt_status, "Medium-term", 1, colorWhite, mt_Col);
AddTextColumn(lt_status, "Long-term", 1, colorWhite, lt_Col);
AddColumn(TrendScore,"Score",1.0);

Please find below a screenshot of how it looks like.

Capture

Hi All!
I have already fixed my problem. Please find below my final code.
Please do not hesitate to reply if you would like to improve my code or make it short.
Thank you!

//
// Code is not originally mine
// Credits goes to the original uploader/coder
//
i=0;

//Longterm Bullish or Bearish
Bull = C > MA(C,200);
Bear = C < MA(C,200);
lt_False = IsNull(MA(C,200)) AND Bull;
lt_True = Bull;
IIf(lt_False OR lt_True,i+1,i);
lt_status=    WriteIf(Bull, "Bullish", WriteIf(Bear, "Bearish", "Neutral"));
lt_Col=IIf(Bull, colorGreen, IIf(bear, colorRed, colorLightGrey));

//Midterm Bullish or Bearish
mBull = C > MA(C,50);
mBear= C < MA(C,50);
mt_False = IsNull(MA(C,50)) AND mBull;
mt_True = mBull;
IIf(mt_False OR mt_True,i+1,i);
mt_status=    WriteIf(mBull, "Bullish", WriteIf(mBear, "Bearish", "Neutral"));
mt_Col=IIf(mBull, colorGreen, IIf(mbear, colorRed, colorLightGrey));

//Shortterm Bullish or Bearish
sBull = C > MA(C,20);
sBear= C < MA(C,20);
st_False = IsNull(MA(C,20)) AND sBull;
st_True = sBull;
IIf(st_False OR st_True,i+1,i);
st_status=    WriteIf(sBull, "Bullish", WriteIf(sBear, "Bearish", "Neutral"));
st_Col=IIf(sBull, colorGreen, IIf(sbear, colorRed, colorLightGrey));

TrendScore= 
IIf(lt_False OR lt_True,1,0)+
IIf(mt_False OR mt_True,1,0)+
IIf(st_False OR st_True,1,0);

Filter = 1;

AddTextColumn(st_status, "Short-term", 1, colorWhite, st_Col);
AddTextColumn(mt_status, "Medium-term", 1, colorWhite, mt_Col);
AddTextColumn(lt_status, "Long-term", 1, colorWhite, lt_Col);
AddColumn(TrendScore,"Score",1.0);

Dear @Tomasz,

I had read certain internal operations of AB, regarding variables, in the forum but didn't find the post
but it was something like this, the reason why AB is so fast and memory efficient
so,

a = C;
b = C;
d = C;

//is equivalent to 
a = b= d= C;
// As in a common address space is used for all 3 variables.

only something an operation like a++ would copy to a new memory address space.

In this code below, is MA computed thrice ?

Bull = C > MA(C,200);
Bear = C < MA(C,200);
lt_False = IsNull(MA(C,200)) AND Bull;

// Would this be faster ?
MA200 = MA(C,200);

and then use variable subsequently or does the AFL implicitly optimize such type of code?

2 Likes

To replace Null all you need is Nz function.
(As aside it is good coding practice to store multiple same calls to variable-> see ma... because then it is called just once)


// Code is not originally mine
// Credits goes to the original uploader/coder
/// some corrections at:
/// @link https://forum.amibroker.com/t/need-help-in-generating-a-score-on-bullish-indicator/8484/5
//
//Longterm Bullish or Bearish
ma1 = MA(C,200);
Bull = C > ma1;
Bear = C < ma1;
lt_status=    WriteIf(Bull, "Bullish", WriteIf(Bear, "Bearish", "Neutral"));
lt_Col=IIf(Bull, colorGreen, IIf(bear, colorRed, colorLightGrey));

//Midterm Bullish or Bearish
ma2 = MA(C,50);
mBull = C > ma2;
mBear= C < ma2;
mt_status=    WriteIf(mBull, "Bullish", WriteIf(mBear, "Bearish", "Neutral"));
mt_Col=IIf(mBull, colorGreen, IIf(mbear, colorRed, colorLightGrey));

//Shortterm Bullish or Bearish
ma3 = MA(C,20);
sBull = C > ma3;
sBear= C < ma3;
st_status=  WriteIf(sBull, "Bullish", WriteIf(sBear, "Bearish", "Neutral"));
st_Col=IIf(sBull, colorGreen, IIf(sbear, colorRed, colorLightGrey));

TrendScore= Nz(Bull,0) + Nz(mBull, 0) + Nz(sBull, 0);

Filter = 1;

AddTextColumn(st_status, "Short-term", 1, colorWhite, st_Col);
AddTextColumn(mt_status, "Medium-term", 1, colorWhite, mt_Col);
AddTextColumn(lt_status, "Long-term", 1, colorWhite, lt_Col);
AddColumn(TrendScore,"Score",1.0);

Besides this use of IIf function is wrong.

You should read coding mistakes section of help.
https://www.amibroker.com/guide/a_mistakes.html
as well as difference of IIf vs. if here

4 Likes

@travick it is very easy to check using Code Check & Profile:

Bull = C > MA(C,200);
Bear = C < MA(C,200);
lt_False = IsNull(MA(C,200)) AND Bull;

2


MA200 = MA(C,200);
Bull = C > MA200;
Bear = C < MA200;
lt_False = IsNull(MA200) AND Bull;

3

Summing up, if you intend to use the same average x times, you should once assign it's value to a variable and later use that variable instead of the MA.

6 Likes

Thanks @Milosz Very apt pointer to the "Code Check & profile" :smile:

I was looking for a post that I read and writing that post so probably missed a few things I wanted to add at that time.
Somethings are so obviously done out of habit that when confronted with that as a simple question, i'm confused.

Even my half re-written code of OP wasn't posted, @fxshrat has got that part done :+1:

2 Likes

I think you were searching for this post :slight_smile: :

3 Likes

Bingo, bookmarked it now.

Overall, AFL is very easy to relate with logically, if you are very influenced by C++.
On the other hand, other Wrapper languages in order to easy things out have softened the hardcore programming concept at lower levels :slight_smile:

1 Like

I have printed it out and it is hanging on my wall, so it wasn't difficult to find ....

Just joking :smiley::sweat_smile:

3 Likes

Thank you very much, fxshrat!
I've noted all your suggestions and I will make it a coding good practice.
The "Nz" function was really a spot on! I've been looking for this for ages!

Thank you, Milosz for pointing this out, I appreciate it a lot!

1 Like

Thank you, @travick for pointing this out... I really apprciate it!

Just trying to modified @fxshrat above code using VarSet, hope it’s correct.

//taken from @fxshrat diffferent code snippet
default_per = MxFromString( "[20;50;200]" );
Term_Name = "Short-term,Medium-term,Long-term";

Filter = 1;
for ( i = 1; i <= 3; i++ ) 
{
VarSet( "MA" + i, MA( C, default_per[i-1][0]));
VarSet( "Bull" + i, C > Varget("MA" + i));
VarSet( "Bear" + i, C < Varget("MA" + i));
VarSet( "Color" + i, IIf(Varget("Bull" + i), colorGreen, IIf(Varget("Bear" + i), colorRed, colorLightGrey)));
AddTextColumn(WriteIf(Varget("Bull" + i), "Bullish", WriteIf(Varget("Bear" + i), "Bearish", "Neutral")), StrExtract( Term_Name, i-1), 1, colorWhite, Varget("Color" + i));
}

TrendScore= Nz(Bull1,0) + Nz(Bull2, 0) + Nz(Bull3, 0);
AddColumn(TrendScore,"Score",1.0);
1 Like

@Fossil, here is modification without use of VarSet/VarGet

/// modified from @Fossil code snippet
/// @link https://forum.amibroker.com/t/need-help-in-generating-a-score-on-bullish-indicator/8484/13
/// @link https://forum.amibroker.com/t/need-help-in-generating-a-score-on-bullish-indicator/8484/14
default_per = MxFromString( "[20;50;200]" );
Term_Name = "Short-term,Medium-term,Long-term";

Filter = 1;

TrendScore = 0;
for ( i = 1; i <= 3; i++ ) 
{
	myma = MA( C, default_per[i-1][0]);
	upcond = C > myma;
	dncond = C < myma;

	color = IIf(upcond, colorGreen, IIf(dncond, colorRed, colorLightGrey));
	string_out = WriteIf(upcond, "Bullish", WriteIf(dncond, "Bearish", "Neutral"));
	AddTextColumn(string_out, StrExtract(Term_Name, i-1), 1, colorWhite, color);

	TrendScore += Nz(upcond);
}

AddColumn(TrendScore,"Score",1.0);
4 Likes

@Fossil and @fxshrat

Thank you! I love this short version!

1 Like