Sending email from Quantstrip
The send_email() function
send_email(subject,body,to,account=None)
There are two ways to integrate with the email functionality in Quantstrip, either using the send_email() function or using the email_manager object for more advanced options and formatting.
The send_email() function provides a simple interface for sending emails from your trading clients. It's part of the email management system that supports multiple email accounts and handles all SMTP configuration automatically.
Key Features
- Simple function call to send emails
- Automatic account selection (uses default if not specified)
- Support for multiple recipients
- HTML email support
- Built-in error handling and reporting
Parameters:
| Parameter | Type | Description |
|---|---|---|
subject |
str |
Email subject line |
body |
str |
Email body content (plain text or HTML) |
to |
str |
Recipient email address(es), comma-separated for multiple |
account |
str |
Optional account name to use. Uses default account if not specified |
Returns: tuple[bool, str] - (success status, message describing result)
Example:
from quantstrip import send_email
# Send with default account
success, msg = send_email(
subject="Trade Alert",
body="SPY position opened at $450",
to="trader@example.com"
)
if success:
print("Email sent successfully")
else:
print(f"Email failed: {msg}")
Multiple Recipients
You can send to multiple recipients by comma-separating email addresses.
Example:
# Send to multiple recipients
send_email(
subject="Daily Report",
body="Trading summary attached",
to="trader1@example.com,trader2@example.com,manager@example.com"
)
Using Specific Account
If you have multiple email accounts configured (e.g., one for alerts, one for reports), specify which to use with the account parameter.
Example:
# Send using specific account
send_email(
subject="URGENT: Stop Loss Hit",
body="Position closed at -2%",
to="trader@example.com",
account="Alerts" # Use the "Alerts" account
)
Error Handling
The function returns a tuple with success status and a descriptive message. Always check the result to handle failures gracefully.
Example:
success, msg = send_email(
subject="Trade Execution",
body="Filled 100 AAPL @ $150",
to="trader@example.com"
)
if not success:
# Handle the error
logger.error(f"Failed to send email: {msg}")
# Possible errors:
# - "Email account 'X' not found"
# - "No email accounts configured"
# - "Authentication failed - check username/password"
# - "Could not connect to SMTP server - check server/port"
Common Use Cases
Trade Alerts
# Alert on position entry
def on_entry(self, symbol, price, quantity):
send_email(
subject=f"Position Opened: {symbol}",
body=f"Bought {quantity} shares of {symbol} at ${price}",
to="trader@example.com"
)
Daily Reports
# Send end-of-day summary
def send_daily_report(self):
report = self.generate_report() # Your report logic
send_email(
subject=f"Daily Report - {datetime.now().strftime('%Y-%m-%d')}",
body=report,
to="trader@example.com,manager@example.com"
)
Error Notifications
# Alert on strategy errors
try:
self.execute_strategy()
except Exception as e:
send_email(
subject="Strategy Error!",
body=f"Error in {self.strategy_name}:\n{str(e)}",
to="trader@example.com",
account="Alerts" # Use high-priority account
)
Stop Loss Alerts
# Urgent notifications
def on_stop_loss(self, symbol, loss_amount):
send_email(
subject=f"STOP LOSS: {symbol}",
body=f"Stop loss triggered on {symbol}. Loss: ${loss_amount:.2f}",
to="trader@example.com",
account="Alerts"
)
Using the email_manager object
The email_manager object can be used directly for more advanced options like sending HTML formatted emails.
Sending HTML Emails
For HTML formatted emails, use the underlying email_manager.send() function with html=True.
Example:
from quantstrip import email_manager
html_body = """
<html>
<body>
<h2>Trade Summary</h2>
<p>Today's P&L: <span style="color:green">$1,234.56</span></p>
<ul>
<li>AAPL: +$500</li>
<li>MSFT: +$734.56</li>
</ul>
</body>
</html>
"""
success, msg = email_manager.send(
subject="Daily P&L Report",
body=html_body,
to="trader@example.com",
html=True
)
Configuration
Before using send_email(), you need to configure at least one email account in your settings. Email accounts are managed through the EmailManager class and stored in the settings system.
Account Setup
Email accounts are configured at: /config/Notification/Email Accounts/[AccountName]/
Each account requires:
| Field | Description |
|---|---|
smtp_server |
SMTP server address (e.g., smtp.gmail.com) |
smtp_port |
SMTP port (typically 587 for TLS) |
use_tls |
Whether to use TLS encryption (true/false) |
username |
SMTP username |
password |
SMTP password (stored securely) |
from_address |
Email address to send from |
from_name |
Display name for sender |
is_default |
Whether this is the default account (true/false) |
Provider Templates
The EmailManager includes templates for common providers:
- Gmail: smtp.gmail.com:587 (requires App Password)
- Outlook: smtp.office365.com:587
- Yahoo: smtp.mail.yahoo.com:587 (requires App Password)
- SendGrid: smtp.sendgrid.net:587
Use these templates when creating accounts programmatically.
Testing Configuration
Always test your email configuration before relying on it in production.
from email_manager import email_manager
# Test an account
success, msg = email_manager.test_account(
name="Default",
test_recipient="your.email@example.com"
)
if success:
print("Email configuration working!")
else:
print(f"Configuration problem: {msg}")
Best Practices
Batching Notifications
Instead of sending an email for every event, batch them together.
class NotificationBatcher:
def __init__(self, flush_interval_seconds=300):
self.messages = []
self.last_flush = datetime.now()
self.flush_interval = timedelta(seconds=flush_interval_seconds)
def add_message(self, message):
self.messages.append(f"[{datetime.now().strftime('%H:%M:%S')}] {message}")
# Auto-flush if interval passed
if datetime.now() - self.last_flush > self.flush_interval:
self.flush()
def flush(self):
if self.messages:
body = "\n".join(self.messages)
send_email(
subject=f"Trading Updates ({len(self.messages)} events)",
body=body,
to="trader@example.com"
)
self.messages.clear()
self.last_flush = datetime.now()
# Usage
batcher = NotificationBatcher(flush_interval_seconds=300) # 5 minutes
# Throughout trading day
batcher.add_message("Opened AAPL position")
batcher.add_message("Stop loss adjusted for MSFT")
# ... messages accumulate ...
# On shutdown or at regular intervals
batcher.flush()
Troubleshooting
Authentication Failed
Error: "Authentication failed - check username/password"
Connection Errors
Error: "Could not connect to SMTP server - check server/port"
Account Not Found
Error: "Email account 'X' not found"
email_manager.get_accounts() to list available accounts.
No Accounts Configured
Error: "No email accounts configured"
send_email().
Debugging
Enable detailed logging to troubleshoot email issues:
import logging
# Enable email manager debug logging
logging.getLogger('email_manager').setLevel(logging.DEBUG)
# Your code
success, msg = send_email("Test", "Body", "test@example.com")
print(f"Result: {success}, Message: {msg}")