How do I set an alarm to sound and e-mail at the same time?

Request for help.
How to write an alertif so that it can simultaneously send an alert to defined e-mails and hear an audible alert.
Entering type 1 for buy causes only the first line of alertif to work (in this case, sending an email without a sound)
and entering a different type causes repeated alerts with the same date / time.

AlertIf(Buy, "EMAIL", "Alert Buy", 1 );
AlertIf(Buy, "SOUND C:\\Windows\\Media\\muzyka\\SALSATRONIC.WAV"  , "Alert Buy wazny", 1 );

Read the manual. As documented in the MANUAL
http://www.amibroker.com/guide/h_alerts.html

Alertif function implements internal logic in the form of finite state machine that prevents repeated signals of the same type from occuring

Your code has SAME TYPE (1) specified as parameter and for this reason repeated alert of same type is silenced.

Again as explicitly stated in manual: AFL Function Reference - ALERTIF

IMPORTANT: AlertIf is not mindless function, it contains internal logic (aka. finite state machine). For full understanding how AlertIf function works and how to use it, you need to read Tutorial: Using formula-based alerts.

So in AlertIf calls you should use different type (third argument) OR different than default flags (again manual AFL Function Reference - ALERTIF) OR use SendEmail function to directly send email AFL Function Reference - SENDEMAIL OR use PlaySound function AFL Function Reference - PLAYSOUND

if( LastValue( Buy ) )
{
   // mindless sending of emails and playing sound each time formula is executed 
   // and Buy signal is present on last bar
   // (that is NOT what AlertIf is meant to do)
   SendEmail("subject", "message");
   PlaySound("C:\\Windows\\Media\\muzyka\\SALSATRONIC.WAV");
}

Can I have a type other than 1 in alertif, e.g. 5?
And will the alertif then function properly, using the internal logic of finite states?

AlertIf(Buy, "EMAIL", "Alert Buy", 1 );
AlertIf(Buy, "SOUND C:\\Windows\\Media\\muzyka\\MARSHALL_AQUICCI-SALSATRONIC.WAV"  , "Alert Buy wazny", 5 );

When switching type from 1 to 5, it generates a lot of email.
How to write the code so that there is 1 e-mail and 1 signal to one event from the minute candle.

image

Re-read (possibly several times) what I wrote previously, including all references to the Users' Manual. All the information needed is ALREADY there.

The User manual says (as I already wrote in previous reply):

Alertif function implements internal logic in the form of finite state machine that prevents repeated signals of the SAME type from occuring

Now you are getting repeated signals BECAUSE you are using different type. You wanted TWO alerts from same event (buy). TWO is more than one. TWO is repetition.
Either you use SAME type and mechanism that PREVENTS repeated alerts (so you can only have ONE non-repeated alert). Or you don't use this mechanism and you get repeated alerts.

You can't have a cake and eat it too.

I also gave you solution to this "paradox". As I wrote previously, you can use AlertIf() for email and PlaySound for sound. That way you would have non-repeated alert and repeated sound. You could also suppress repeated sound if you use static variables. Lots of such examples can be found on the forum. USE SEARCH.

@Zbigniew please see this solution here if it works for you.

@deepuanant - it is better to refer to the original source, not the copy

2 Likes

@Tomasz my bad I missed on the earlier thread the static variable part and didn't notice the same thanks for highlighting the same.

here is the revised code for @Zbigniew reference.

// https://forum.amibroker.com/t/how-do-i-set-an-alarm-to-sound-and-e-mail-at-the-same-time/28013/2
// https://www.amibroker.com/kb/index.php?s=Status%28%22lastbarend%22%29%3B //

lastBartime = Status( "lastbarend" );
varName = Name() + "_lastdt";
recordedTimestamp = Nz( StaticVarGet( varName ) );
Newbar = lastBarTime != recordedTimestamp;

if( LastValue( Buy ) && Newbar ) // Buy Condition True on New Bar
{
    StaticVarSet( varName, lastBartime );
    AlertIf( Buy, "EMAIL", "Alert Buy", 1 );
    AlertIf( Buy, "SOUND C:\\Windows\\Media\\muzyka\\MARSHALL_AQUICCI-SALSATRONIC.WAV"  , "Alert Buy wazny", 5 );
}

As I explained already in the other post, this LastValue(Buy) is NOT needed and NOT present in original Knowledge Base Article. Now you have doubled the same condition (AlertIF(Buy) already contains "if( Buy )" logic). Again, correct code is in the original KB article, not on forum: AmiBroker Knowledge Base ยป How to execute part of the formula only when new bar is added

This code starts the music every time the timestamp changes, i.e. a new minute starts.
I did a lot of rehearsals and I have run out of ideas.
None of the conditions entered in the code worked as expected. In your example when starting Playsound, the code is to know whether it should run on buy or sell condition. I read the instructions over and over again and found no answer.
If it is so obvious, please help me, because for me it is not simple and obvious.

AlertIf(Buy, "EMAIL", "Alert Buy", 1 );
AlertIf(Sell, "EMAIL" , "Alert Sell", 2 );
lastBartime = LastValue( DateTime() );
varName = Name() + "_lastdt";
recordedTimestamp = Nz( StaticVarGet( varName ) );
if( lastBarTime != recordedTimestamp )
{
    StaticVarSet( varName, lastBartime );
    IIf(Sell,  PlaySound("C:\\Windows\\Media\\muzyka\\MARSHALL_AQUICCI-SALSATRONIC.WAV"), Null);
    IIf(Buy,  PlaySound("C:\\Windows\\Media\\muzyka\\MARSHALL_AQUICCI-SALSATRONIC.WAV"), Null);
    //PlaySound("C:\\Windows\\Media\\muzyka\\MARSHALL_AQUICCI-SALSATRONIC.WAV");
    //if( LastValue( Sell ) ) {    PlaySound("C:\\Windows\\Media\\muzyka\\MARSHALL_AQUICCI-SALSATRONIC.WAV"); }
    //if( LastValue( Buy ) ) {    PlaySound("C:\\Windows\\Media\\muzyka\\MARSHALL_AQUICCI-SALSATRONIC.WAV"); }
}

Your use of IIF function is incorrect, see "Basic mistakes" in the guide: Common Coding mistakes

You should be using if() statement instead. I gave you correct code EARLIER in this very thread: How do I set an alarm to sound and e-mail at the same time? - #2 by Tomasz

Is this a properly written code?

AlertIf(Buy, "EMAIL", "Alert Buy", 1 );
AlertIf(Sell, "EMAIL" , "Alert Sell", 2 );
lastBartime = LastValue( DateTime() );
varName = Name() + "_lastdt";
recordedTimestamp = Nz( StaticVarGet( varName ) );
if( lastBarTime != recordedTimestamp )
{
    StaticVarSet( varName, lastBartime );
if( LastValue( Buy ) )
{
   PlaySound("SOUND C:\\Windows\\Media\\muzyka\\MARSHALL_AQUICCI-SALSATRONIC.WAV");
}
}

Yes it is correct code.

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.