- ago
Hi,
I’m sending alerts to my email (in my strategy) using the SendEmail function. It works when I run the backtest, but I am getting no emails when I activate the strategy in the Strategy Monitor. Any reason why? The strategy is running and producing signals. It is also setup to auto-place.
Thanks!
0
471
16 Replies

Reply

Bookmark

Sort
- ago
#1
Hi,

We don't know. Can you copy/paste the Execute() block with the logic and the SendEmail code?
0
- ago
#2
Here is the code...

I also have a SendEmail in the Initialize function.

CODE:
      public override void Execute(BarHistory bars, int idx)       {          // FIRST TRADING DAY OF WEEK LOGIC          if (TodayIsFirstSessionOfTheWeek(bars, bars.DateTimes[idx]))          {             // Ensure Filter Pre/Post Market Data is checked!             if (!HasOpenPosition(bars, PositionType.Long))             {                int firstBarToday = idx - bars.IntradayBarNumber(idx);                if (bars.DateTimes[firstBarToday].TimeOfDay == ts0930) // the first bar was the premarket bar ending at 0930                {                   if (idx > firstBarToday)                   {                      _limit = bars.Open[firstBarToday + 1] * 0.99;                   }                   else                   {                      // use the close of the last premarket bar                      _limit = bars.Close[firstBarToday] * 0.99;                   }                }                else                {                   // the first bar was not a premarket bar                   _limit = bars.Open[firstBarToday] * 0.99;                }                //if (idx == bars.Count - 1)                //{                   string msg = "PlaceTrade Buy Limit @ " + bars.DateTimes[idx].Date.ToLongDateString() + " " + bars.DateTimes[idx].TimeOfDay.ToString() +                      " limit price = " + _limit.ToString()                      + " idx = " + idx.ToString()                      + " bars.Count = " + bars.Count.ToString();                   SendMsg("Wealth-Lab 8", msg);                //}                PlaceTrade(bars, TransactionType.Buy, OrderType.Limit, _limit);                return;             }             SetBackgroundColor(bars, idx, WLColor.FromArgb(40, WLColor.Red));             return;          }          else          {             SetBackgroundColor(bars, idx, WLColor.FromArgb(40, WLColor.Red));             // Ensure Filter Pre/Post Market Data is checked!             if (HasOpenPosition(bars, PositionType.Long))             {                SetBackgroundColor(bars, idx, WLColor.FromArgb(40, WLColor.Orange));                target = LastOpenPosition.EntryPrice;                pct_profit_or_loss = LastOpenPosition.ProfitPctAsOf(idx);                target = LastOpenPosition.EntryPrice;                if (pct_profit_or_loss > -0.5)                {                   //WriteToDebugLog("Parameter 1 = " + Parameters[1].AsDouble.ToString());                   //target *= 1 + (Parameters[1].AsDouble / 100.0);                   target *= 1.03;                   //if (idx == bars.Count - 1)                   //{                      string msg = "PlaceTrade Sell Limit @ " + bars.DateTimes[idx].Date.ToShortDateTimeString() + " " + bars.DateTimes[idx].TimeOfDay.ToString() + " target price = " + target.ToString()                      + " idx = " + idx.ToString()                      + " bars.Count = " + bars.Count.ToString();                      SendMsg("Wealth-Lab 8", msg);                   //}                   PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, target);                }                // Sell TQQQ if the loss < 15 percent (temporarily changed it zero to force a trade)                else if (pct_profit_or_loss < -16.0)                {                   //if (idx == bars.Count - 1)                   //{                      string msg = "PlaceTrade Sell Limit @ " + bars.DateTimes[idx].Date.ToShortDateTimeString() + " " + bars.DateTimes[idx].TimeOfDay.ToString()                                  + " bars.Close[idx] = " + bars.Close[idx].ToString()                                  +" idx = " + idx.ToString()                                  +" bars.Count = " + bars.Count.ToString();                      SendMsg("Wealth-Lab 8 ALERT", msg);                   //}                   PlaceTrade(bars, TransactionType.Sell, OrderType.Limit, bars.Close[idx]);                }                if (pct_profit_or_loss < -5.0)                {                   //if (idx == bars.Count - 1)                   //{                      string msg = "Loss so far < -5.0 @ " + bars.DateTimes[idx].Date.ToShortDateTimeString() + " " + bars.DateTimes[idx].TimeOfDay.ToString()                               + " pct_loss = " + pct_profit_or_loss.ToString()                               +" idx = " + idx.ToString()                               +" bars.Count = " + bars.Count.ToString();                      SendMsg("Wealth-Lab 8 ALERT", msg);                   //}                }             }          }       }
0
- ago
#3
Thanks. By chance there's an error message in the log (Tools > Event Log)?
0
Cone8
 ( 23.73% )
- ago
#4
What does SendMsg() do?
0
- ago
#5
There are no errors shown in the log. It's connected to TDA.

CODE:
      public override void Initialize(BarHistory bars)       {          PlotStopsAndLimits(3);          SendMsg("Wealth-Lab 8", "Initialize RunAnyDayStrategy @ " + DateTime.Now.ToLongTimeString() + " - bars.Count = " + bars.Count.ToString());       }       public void SendMsg(string subject, string msg)       {          int port = 587;          SendEmail("from-email@outlook.com", "smtp-mail.outlook.com", "from-email@outlook.com", "my-password",             port, "toemail-address", subject, msg);       }

0
Cone8
 ( 23.73% )
- ago
#6
Turn off Live Positions in the Trading Preferences if you want to evaluate a backtest in the Strategy Monitor.
0
- ago
#7
For the strategy monitor, I’ll add more code to skip all bars except the last one because I need a live position.

I see how to detect the execution mode.

I’m wondering, what does this have to do with the email problem?

Thank you all for your help!

It’s much appreciated.

Mike
0
Cone8
 ( 23.73% )
- ago
#8
It's a problem because your conditions to send the email depend on the pct_profit_or_loss of hypothetical positions, which don't exist in the Live Position context.

What you should [probably] be doing is looping through Backtester.Orders in BacktestComplete() to process all the signals. That way you could get all the signals in probably one or two emails.
0
- ago
#9
Ok. Thank you Cone.

Mike
0
Cone8
 ( 23.73% )
- ago
#10
Try this for a signal emailer.. you can add the usings, pop that method in to your script, and enter your email credentials where required.
CODE:
// Add these - using System.Linq; using System.Text; public override void BacktestComplete()       {          StringBuilder sb = new System.Text.StringBuilder();          sb.AppendLine("Signal Count = " + Backtester.Orders.Count.ToString()).AppendLine().AppendLine("Exits ------------- Type\tPrice\tWeight\t\tValue");          string fmt = "{0,-6}{1,-6}{2,-8}{3,-8}{4,-8:N2}{5,-8:N4}{6}";          List<Transaction> sells = Backtester.Orders.Where(x => x.IsExit).OrderBy(w => w.Weight).ToList();          for (int n = sells.Count - 1; n >= 0; n--)          {             Transaction t = sells[n];             double tradevalue = t.Bars.LastValue * t.Quantity;             string signal = String.Format(fmt, t.TransactionType, t.Quantity, t.Bars.Symbol, t.OrderType, t.OrderPrice, t.Weight, tradevalue.ToString("C2", System.Globalization.CultureInfo.CurrentCulture));             sb.AppendLine(signal);          }          sb.AppendLine().AppendLine("Entries ----------- Type\tPrice\tWeight\t\tValue");          List<Transaction> buys = Backtester.Orders.Where(x => x.IsEntry).OrderBy(w => w.Weight).ToList();          for (int n = buys.Count - 1; n >= 0; n--)          {             Transaction t = buys[n];             double tradevalue = t.Bars.LastValue * t.Quantity;             string signal = String.Format(fmt, t.TransactionType, t.Quantity, t.Bars.Symbol, t.OrderType, t.OrderPrice, t.Weight, tradevalue.ToString("C2", System.Globalization.CultureInfo.CurrentCulture));             sb.AppendLine(signal);          }          string messageSubject = StrategyName + " Signals: " + Backtester.Orders.Count.ToString();          string messageText = sb.ToString();          string mailaccount = "user@mail.com";          string toAccount = "user@gmail.com";          string smtpServer = "smtp.gmail.com";          string pw = "*******";          int port = 465;       // for Gmail, port can be 587 (TLS) or 465 (SSL)          //signals to debug          WriteToDebugLog(messageText, false);                       if (!pw.Contains("****"))      //did you enter a real password?                SendEmail(mailaccount, smtpServer, mailaccount, pw, port, toAccount, messageSubject, messageText);                 }
0
- ago
#11
Thank you. I'm giving it a try. It needs "using System.Collections.Generic;" too.
1
- ago
#12
I'm still not getting any emails. It doesn't matter if Live Positions is checked or not.
0
Cone8
 ( 23.73% )
- ago
#13
Are you using gmail?
Because unless you're a Google Workspace customer, it's no longer possible to send email using just a name and password from "less secure apps" (like WealthLab) even if that option is enabled.
1
Cone8
 ( 23.73% )
- ago
#14
Actually, I just tried and haven't been able to make it work either. It seems like the mail client is set up correctly - at least it's not reporting an error when sending.

Has anyone else had success with SendEmail recently?
0
- ago
#15
I’m using outlook.com to send it to a gmail address. It worked for me earlier today. I’m not sure what happened.
0
- ago
#16
Consider 1) reviewing possible recent changes to the platform and/or 2) using an application-specific password in your C# code .
1

Reply

Bookmark

Sort