financial_news_bot / examples /ema_strategy_example.py
Dmitry Beresnev
add a draft for monitoring, ema crossover strategy, etc
dbd43f7
"""
EMA 50/200 Crossover Strategy - Usage Examples
Demonstrates the Golden Cross / Death Cross trading strategy.
"""
import pandas as pd
import yfinance as yf
from src.core.trading.ema_crossover_strategy import EMACrossoverStrategy
def example_1_basic_usage():
"""Example 1: Basic EMA crossover analysis."""
print("\n=== Example 1: Basic EMA Crossover ===\n")
# Initialize strategy
strategy = EMACrossoverStrategy(
fast_ema=50,
slow_ema=200,
use_volume_filter=True,
use_adx_filter=True
)
# Download data
ticker = "AAPL"
data = yf.download(ticker, period="2y", progress=False)
# Generate signals
signals = strategy.generate_signals(data, ticker=ticker)
# Display recent signals
print(f"Analysis for {ticker}:")
print(f" Current Price: ${signals['Close'].iloc[-1]:.2f}")
print(f" EMA 50: ${signals['EMA_Fast'].iloc[-1]:.2f}")
print(f" EMA 200: ${signals['EMA_Slow'].iloc[-1]:.2f}")
print(f" Position: {strategy.get_current_position(signals)}")
# Find recent crossovers
golden_crosses = signals[signals['Golden_Cross']].tail(3)
death_crosses = signals[signals['Death_Cross']].tail(3)
if not golden_crosses.empty:
print(f"\nRecent Golden Crosses:")
for date, row in golden_crosses.iterrows():
print(f" {date.date()}: ${row['Close']:.2f}")
if not death_crosses.empty:
print(f"\nRecent Death Crosses:")
for date, row in death_crosses.iterrows():
print(f" {date.date()}: ${row['Close']:.2f}")
def example_2_market_scan():
"""Example 2: Scan market for signals."""
print("\n=== Example 2: Market Scan ===\n")
# Initialize strategy
strategy = EMACrossoverStrategy()
# Define tickers to scan
tickers = [
"AAPL", "MSFT", "GOOGL", "AMZN", "NVDA",
"TSLA", "META", "AMD", "NFLX", "DIS"
]
# Data loader function
def load_data(ticker, period):
return yf.download(ticker, period=period, progress=False)
# Scan market
print("Scanning market for EMA crossover signals...\n")
results = strategy.scan_market(tickers, load_data, period="1y")
if not results.empty:
print(f"\nFound {len(results)} signals:\n")
print(results.to_string(index=False))
else:
print("\nNo signals found.")
def example_3_custom_parameters():
"""Example 3: Custom EMA parameters."""
print("\n=== Example 3: Custom EMA 20/50 ===\n")
# Faster crossover (20/50 instead of 50/200)
strategy = EMACrossoverStrategy(
fast_ema=20,
slow_ema=50,
atr_multiplier_sl=1.5, # Tighter stop
atr_multiplier_tp=3.0, # Closer target
adx_threshold=25, # Stronger trend required
use_volume_filter=True,
use_adx_filter=True
)
print(strategy.get_strategy_description())
# Test on volatile stock
ticker = "NVDA"
data = yf.download(ticker, period="6mo", progress=False)
signals = strategy.generate_signals(data, ticker=ticker)
print(f"\nAnalysis for {ticker}:")
print(f" Current Position: {strategy.get_current_position(signals)}")
print(f" ADX: {signals['ADX'].iloc[-1]:.1f}")
print(f" Volume Ratio: {signals['Volume_Ratio'].iloc[-1]:.2f}x")
def example_4_signal_details():
"""Example 4: Detailed signal analysis."""
print("\n=== Example 4: Signal Details ===\n")
strategy = EMACrossoverStrategy()
ticker = "TSLA"
data = yf.download(ticker, period="1y", progress=False)
signals = strategy.generate_signals(data, ticker=ticker)
# Find most recent signal
recent_long = signals[signals['Signal_Long']].tail(1)
recent_short = signals[signals['Signal_Short']].tail(1)
if not recent_long.empty:
row = recent_long.iloc[0]
print(f"Most Recent LONG Signal for {ticker}:")
print(f" Date: {recent_long.index[0].date()}")
print(f" Price: ${row['Close']:.2f}")
print(f" Stop Loss: ${row['Stop_Loss_Long']:.2f} ({((row['Stop_Loss_Long']/row['Close']-1)*100):.1f}%)")
print(f" Take Profit: ${row['Take_Profit_Long']:.2f} ({((row['Take_Profit_Long']/row['Close']-1)*100):.1f}%)")
print(f" R:R Ratio: {row['RR_Ratio']:.1f}:1")
print(f" ADX: {row['ADX']:.1f}")
print(f" Volume: {row['Volume_Ratio']:.2f}x average")
if not recent_short.empty:
row = recent_short.iloc[0]
print(f"\nMost Recent SHORT Signal for {ticker}:")
print(f" Date: {recent_short.index[0].date()}")
print(f" Price: ${row['Close']:.2f}")
print(f" Stop Loss: ${row['Stop_Loss_Short']:.2f}")
print(f" Take Profit: ${row['Take_Profit_Short']:.2f}")
print(f" R:R Ratio: {row['RR_Ratio']:.1f}:1")
def example_5_backtest_simulation():
"""Example 5: Simple backtest simulation."""
print("\n=== Example 5: Backtest Simulation ===\n")
strategy = EMACrossoverStrategy()
ticker = "SPY"
data = yf.download(ticker, period="5y", progress=False)
signals = strategy.generate_signals(data, ticker=ticker)
# Extract trades
long_signals = signals[signals['Signal_Long']]
short_signals = signals[signals['Signal_Short']]
print(f"Backtest Results for {ticker} (5 years):")
print(f" Total LONG signals: {len(long_signals)}")
print(f" Total SHORT signals: {len(short_signals)}")
# Calculate simple stats
if len(long_signals) > 0:
avg_adx = long_signals['ADX'].mean()
avg_vol_ratio = long_signals['Volume_Ratio'].mean()
print(f"\nLONG Signal Statistics:")
print(f" Average ADX: {avg_adx:.1f}")
print(f" Average Volume Ratio: {avg_vol_ratio:.2f}x")
# Show signal distribution by year
all_signals = pd.concat([long_signals, short_signals])
if not all_signals.empty:
signals_by_year = all_signals.groupby(all_signals.index.year).size()
print(f"\nSignals by Year:")
for year, count in signals_by_year.items():
print(f" {year}: {count} signals")
def example_6_no_filters():
"""Example 6: Pure EMA crossover (no filters)."""
print("\n=== Example 6: Pure EMA Crossover (No Filters) ===\n")
# Disable all filters
strategy = EMACrossoverStrategy(
use_volume_filter=False,
use_adx_filter=False
)
ticker = "AAPL"
data = yf.download(ticker, period="2y", progress=False)
signals = strategy.generate_signals(data, ticker=ticker)
# Count signals
total_long = signals['Golden_Cross'].sum()
total_short = signals['Death_Cross'].sum()
print(f"Pure EMA Crossover for {ticker}:")
print(f" Golden Crosses: {total_long}")
print(f" Death Crosses: {total_short}")
print(f" Current Position: {strategy.get_current_position(signals)}")
def main():
"""Run all examples."""
examples = [
example_1_basic_usage,
example_2_market_scan,
example_3_custom_parameters,
example_4_signal_details,
example_5_backtest_simulation,
example_6_no_filters,
]
for example in examples:
try:
example()
except Exception as e:
print(f"\n✗ Example failed: {e}")
import traceback
traceback.print_exc()
print("\n" + "=" * 70)
if __name__ == "__main__":
# Run single example
# example_1_basic_usage()
# Or run all examples
main()