Saturday, January 25, 2025

Managing Trading Risks by Knowing Calendar Events That Affect Market Volatility

 

Introduction to Trading Risks

In Forex and other financial markets, risk management is one of the most critical aspects of successful trading. One key element in effective risk management is understanding and anticipating market volatility, which can be influenced by a variety of factors, most notably economic events. These events are often scheduled in advance and can cause significant price fluctuations, potentially wiping out your trading account if you're not careful.

Understanding how to monitor and react to these events is crucial in mitigating the risks associated with Forex trading. A solid understanding of market volatility and economic events, along with a reliable way to access and interpret relevant data, can help traders make informed decisions and adjust their positions accordingly to minimize risk.

How Economic Events Affect Forex Market Volatility

Economic events, often announced by government agencies or major financial organizations, can have a significant impact on currency pairs and, by extension, the Forex market. These events include reports like GDP releases, interest rate decisions, employment reports, and inflation data. The market can react strongly to such data releases, causing large price swings and, in some cases, triggering slippage or even stopping out positions.

Some events are more impactful than others. For example:

  • Level 1 Events (Low Impact): These events typically cause minor volatility. Currency pairs might move slightly, but these events usually have a minimal effect on the market.
  • Level 2 Events (Medium Impact): These events can cause moderate volatility. A strong miss in forecasted data can lead to noticeable fluctuations in exchange rates.
  • Level 3 Events (High Impact): These are the most volatile events, often moving the market significantly. Examples include central bank interest rate decisions or employment data releases.

Traders who are not aware of the timing of such events, or fail to account for their potential market impact, risk losing substantial portions of their capital. This is where knowing how to access and interpret economic calendars becomes vital.

The Risk of Trading Without Awareness of Economic Events

If you're unaware of upcoming economic events, you might find yourself caught in a volatile market just as a high-impact report is released. Here's an example scenario to illustrate the risk:

  1. Uninformed Trading: A trader decides to open a position on the EUR/USD pair. They're comfortable with their analysis and open the trade, not realizing that a U.S. Non-Farm Payrolls (NFP) report is set to be released in a few hours.
  2. High-Impact Event: The NFP report shows unexpected data, causing the U.S. dollar to strengthen significantly against the euro. The trader's position quickly moves into negative territory.
  3. Wiped Out Funds: Due to the high volatility caused by the NFP release, the trader’s stop-loss is skipped, or worse, their position is margin-called, resulting in a significant loss of capital.

In such cases, market volatility can easily wipe out a trader's deposited funds, especially if leverage is used.

Example: Economic Calendar Events and Volatility

To protect against such risks, traders should track upcoming economic events and adjust their strategies accordingly. This can be done by monitoring economic calendars that list all scheduled events, including their level of impact (Low, Medium, or High).

One of the best ways to stay informed is by using APIs that provide real-time data on these events. By integrating such APIs into your trading systems, you can automate the process of monitoring economic events.

Example Python Program: Economic Events Viewer

Below is an example Python program that fetches high-impact economic calendar events and displays them in a table format. This program helps you visualize events that may influence your trading decisions.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import sys
import requests
from datetime import datetime, timedelta
from PyQt6.QtWidgets import QApplication, QWidget, QTableWidget, QTableWidgetItem, QVBoxLayout, QPushButton, QComboBox
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QHeaderView

class EconomicEventsWindow(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('Economic Events')
        self.setGeometry(100, 100, 900, 400)

        self.table = QTableWidget(self)
        self.table.setColumnCount(5)
        self.table.setHorizontalHeaderLabels(['Date', 'Name', 'Previous', 'Forecast', 'Actual'])

        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.horizontalHeader().setSectionResizeMode(0, QHeaderView.ResizeMode.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.Stretch)
        self.table.horizontalHeader().setSectionResizeMode(4, QHeaderView.ResizeMode.Stretch)

        layout = QVBoxLayout()

        self.filter_combobox = QComboBox(self)
        self.filter_combobox.addItem("All Levels")
        self.filter_combobox.addItem("Level 1")
        self.filter_combobox.addItem("Level 2")
        self.filter_combobox.addItem("Level 3")
        layout.addWidget(self.filter_combobox)

        self.button = QPushButton("Fetch Economic Data", self)
        self.button.clicked.connect(self.fetch_data)
        layout.addWidget(self.button)

        layout.addWidget(self.table)

        self.setLayout(layout)

    def fetch_data(self):
        url = "https://investing11.p.rapidapi.com/get_economic_calendar"
        querystring = {"time_interval": "this_week", "country": "US"}
        headers = {
            "x-rapidapi-host": "investing11.p.rapidapi.com",
            "x-rapidapi-key": "your_api_key_here"
        }

        response = requests.get(url, headers=headers, params=querystring)

        if response.status_code == 200:
            try:
                data = response.json()
                if "data" in data and data["data"]:
                    self.table.setRowCount(0)
                    selected_filter = self.filter_combobox.currentText()

                    for event in data["data"]:
                        event_importance = event["importance"]
                        if selected_filter == "All Levels" or (selected_filter == f"Level {event_importance}"):
                            timestamp = event['timestamp']
                            utc_time = datetime.utcfromtimestamp(timestamp)
                            pst_time = utc_time + timedelta(hours=8)
                            human_readable_time = pst_time.strftime('%Y-%m-%d %H:%M:%S')

                            name = event['name']
                            previous = event['previous']
                            forecast = event['forecast']
                            actual = event.get('actual', 'N/A')

                            row_position = self.table.rowCount()
                            self.table.insertRow(row_position)
                            self.table.setItem(row_position, 0, QTableWidgetItem(human_readable_time))
                            self.table.setItem(row_position, 1, QTableWidgetItem(name))
                            self.table.setItem(row_position, 2, QTableWidgetItem(previous))
                            self.table.setItem(row_position, 3, QTableWidgetItem(forecast))
                            self.table.setItem(row_position, 4, QTableWidgetItem(actual))
            except ValueError:
                print("Error parsing the response.")
        else:
            print(f"Error: {response.status_code}")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = EconomicEventsWindow()
    window.show()
    sys.exit(app.exec())

Key Features of the Program:

  1. Event Filtering: The program allows filtering by the importance level (Level 1, Level 2, Level 3, or all).
  2. Real-Time Data: Fetches data for economic events from an API that gives real-time data on event schedules.
  3. Human Readable Date and Time: Converts the event timestamps to local Philippine Standard Time (PST) for easy understanding.

Risk Management Strategy: Recommended Position Sizing

Once you have access to high-impact event data, it’s important to manage your positions wisely. Here are a few general recommendations for position sizing:

  1. Avoid Overexposure: Never risk more than 1-2% of your total capital on a single trade. This ensures that one losing trade does not wipe out your account.

  2. Adjust Stop-Losses: Consider widening your stop-loss before major high-impact events, as price movements during these periods can be more volatile than usual.

  3. Use Lower Leverage: High leverage increases the risk of significant loss. For volatile events, consider using lower leverage to reduce the chance of a margin call.

  4. Reduce Position Size: When major news is about to be released, reduce your position size to ensure that the risk exposure is minimized.

Conclusion

Managing trading risk in the Forex market requires awareness of the events that drive market volatility. By using tools like economic calendars and understanding their potential impact on the market, traders can adjust their positions accordingly. Combining these tools with sound risk management practices (such as using appropriate leverage, adjusting position sizes, and setting stop-loss orders) can help traders protect their funds and increase their chances of long-term profitability.

Stay informed, be strategic, and use your resources wisely to manage risk and protect your capital.

Tuesday, January 14, 2025

Identifying Support and Resistance Levels in Stock Trading Using Python

 Stock trading is as much an art as it is a science, requiring careful analysis of historical data to predict future movements. Among the most critical tools in a trader's arsenal are support and resistance levels, which help in identifying key price points where stocks might reverse or break out. This blog post walks you through a Python program that uses the yfinance library to plot these levels for a stock and explains their importance in trading.


Why Identify Support and Resistance Levels?

Support represents a price level where demand is strong enough to halt or reverse a stock's downward trend. Traders expect the price to "bounce" back up when it reaches this level.

Resistance, on the other hand, is a price level where selling pressure prevents the stock from rising further, often leading to a downward reversal.

These levels are crucial for several reasons:

  1. Better Decision-Making: They help traders decide when to enter or exit trades.
  2. Minimized Risks: Stop-loss and take-profit levels can be strategically set around these points.
  3. Trend Analysis: Support and resistance levels confirm existing trends or signal potential reversals.
  4. Breakout Detection: A breach of these levels often indicates significant price movements.

The Python Program

This program fetches historical stock data for the past three months using yfinance, identifies support and resistance levels, and plots the results for visual clarity.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import yfinance as yf
import matplotlib.pyplot as plt
from datetime import datetime, timedelta

# Define the stock ticker and date range
ticker = "AAPL"
end_date = datetime.now()
start_date = end_date - timedelta(days=90)  # Last 3 months

# Download historical data
data = yf.download(ticker, start=start_date, end=end_date, progress=False)

# Extract the closing prices
data['Close'] = data['Adj Close']
close_prices = data['Close']

# Identify support and resistance levels
def find_support_resistance(prices, window=5):
    """
    Find support and resistance levels in price data.

    Parameters:
    - prices: pandas.Series of prices
    - window: Look-back window to identify local min/max

    Returns:
    - support: List of tuples with (date, price)
    - resistance: List of tuples with (date, price)
    """
    support = []
    resistance = []

    for i in range(window, len(prices) - window):
        is_support = prices[i] == min(prices[i-window:i+window+1])
        is_resistance = prices[i] == max(prices[i-window:i+window+1])

        if is_support:
            support.append((prices.index[i], prices[i]))
        if is_resistance:
            resistance.append((prices.index[i], prices[i]))

    return support, resistance

# Find support and resistance levels
support, resistance = find_support_resistance(close_prices)

# Print support and resistance levels
print("Support Levels:")
for date, price in support:
    print(f"Date: {date}, Price: {price}")

print("\nResistance Levels:")
for date, price in resistance:
    print(f"Date: {date}, Price: {price}")

# Plotting
plt.figure(figsize=(14, 7))
plt.plot(data.index, close_prices, label="Close Price", color="blue", linewidth=2)

# Mark support and resistance levels
if support:
    support_dates, support_prices = zip(*support)
    plt.scatter(support_dates, support_prices, color="green", label="Support", marker="^", alpha=0.8, s=100)
if resistance:
    resistance_dates, resistance_prices = zip(*resistance)
    plt.scatter(resistance_dates, resistance_prices, color="red", label="Resistance", marker="v", alpha=0.8, s=100)

# Formatting the plot
plt.title(f"Support and Resistance Levels for {ticker} (Last 3 Months)", fontsize=16)
plt.xlabel("Date", fontsize=14)
plt.ylabel("Price", fontsize=14)
plt.xticks(rotation=45)
plt.legend(fontsize=12)
plt.grid(True)
plt.tight_layout()
plt.show()

How It Works

  1. Data Collection:
    • The program uses yfinance to fetch Apple’s (AAPL) stock data for the last three months.
  2. Support and Resistance Detection:
    • A sliding window technique identifies local minima (support) and maxima (resistance) over a 5-day look-back period.
  3. Visualization:
    • The program plots the stock’s closing prices, marking support levels with green triangles (^) and resistance levels with red triangles (v).

Output

Console

The program prints the dates and prices of all identified support and resistance levels, making it easy to analyze historical behavior:

1
2
3
4
5
6
7
Support Levels:
Date: 2024-10-12 00:00:00, Price: 149.50
Date: 2024-11-02 00:00:00, Price: 152.30

Resistance Levels:
Date: 2024-10-18 00:00:00, Price: 160.75
Date: 2024-11-10 00:00:00, Price: 165.00

Plot

A chart showing the stock’s closing price over the last three months, with support and resistance levels highlighted.




Why This Matters

Identifying support and resistance levels empowers traders to make informed decisions. For instance:

  • If a stock approaches a strong support level, it might signal a buying opportunity.
  • Conversely, if it nears resistance, selling may be prudent to lock in profits.

Furthermore, a breakout above resistance or below support often signifies the start of a new trend, enabling traders to capitalize on significant price movements.


Conclusion

Support and resistance levels are indispensable tools in stock trading. By using Python and yfinance, traders can automate their analysis, saving time and making more objective decisions. Whether you're a beginner or an experienced trader, understanding and leveraging these levels can help improve your trading strategies.

Monday, December 9, 2024

Trading the Bollinger Band Breakout Strategy with AAPL

 The Bollinger Band breakout strategy is a classic approach to capturing market trends and momentum using a statistical representation of price volatility. In this blog post, we implement and simulate this strategy using Python and MetaTrader 5, applying it to historical data for AAPL (Apple Inc.) from April 2024 to the present.

Overview of the Bollinger Band Breakout Strategy

Bollinger Bands consist of three lines:

  • SMA (Simple Moving Average): The middle band, representing the average price over a specific period.
  • Upper Band: Two standard deviations above the SMA.
  • Lower Band: Two standard deviations below the SMA.

The strategy uses these bands to identify breakout opportunities:

  • Buy Signal: When the price remains near the upper band for two consecutive days.
  • Sell Signal: When the price remains near the lower band for two consecutive days.
  • Exit Criteria: Exit a trade:
    • Within four days if a profit is realized.
    • After four days if a loss exceeds 50 cents.
    • Do not exit on the first day even if the loss is 50 cents or more.

Simulation Rules and Implementation

  1. Trade Setup:
    • Start with an initial balance of $10,000.
    • Each trade involves a fixed investment of $1.
  2. Entry and Exit Points:
    • Trades are placed after consecutive signals near the upper or lower band.
    • Exit trades within the defined criteria, accounting for both profit and loss conditions.
  3. Performance Tracking:
    • The program calculates and records the profit or loss of each trade.
    • It computes the final balance after simulating the entire historical dataset.

Python Implementation

Below is a concise description of the program:

  1. Data Retrieval: Historical price data for AAPL is fetched using MetaTrader 5.
  2. Bollinger Band Calculation: The bands are computed using a 20-day SMA and standard deviation.
  3. Trade Simulation: The program simulates trades based on the Bollinger Band breakout strategy, tracking performance over time.
  4. Visualization: The results are plotted to illustrate trades on the price chart.

Key Results

The program evaluates the performance of this strategy over the given period. Each trade entry and exit point, along with its profit or loss, is displayed. Here's an example of the output:

1
2
3
4
5
6
Initial Balance: 10000.00 USD
Final Balance: 10032.75 USD

Trade Results:
Buy | Entry: 185.43 | Exit: 186.89 | Profit: 1.46 USD | Entry Date: 2024-01-31 | Exit Date: 2024-02-02
Sell | Entry: 183.21 | Exit: 182.71 | Profit: 0.50 USD | Entry Date: 2024-02-10 | Exit Date: 2024-02-14

Actual result:
With the trading rules implemented, The current balance was 10046.60 USD. if I adjust the trade amount from $1 to $5, I still get 10233.00 USD!

Chart Visualization

The chart includes:

  • Price movements with Bollinger Bands (upper, lower, and middle).
  • Entry and exit points for each trade marked on the chart.

Here’s an example of what the visualization looks like:

  • Blue Line: Closing prices.
  • Green Line: Upper Band.
  • Red Line: Lower Band.
  • Orange Line: SMA (Middle Band).
  • Trade Points: Green dots for Buy entries and red dots for Sell entries, with exit points marked as crosses.



Insights

This simulation demonstrates how the Bollinger Band breakout strategy can be used to identify potential trading opportunities. While the strategy does not guarantee profits, it offers a systematic approach to trend-following and momentum trading.


Next Steps

You can further refine this strategy by:

  1. Adjusting the Bollinger Band parameters (e.g., SMA length or standard deviation multiplier).
  2. Incorporating additional indicators for confirmation.
  3. Exploring advanced position-sizing methods to optimize returns.
Here is the complete program listing:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import MetaTrader5 as mt5
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime

# Initialize and connect to MetaTrader 5
account = nnnn  # Replace with your account number
password = "xxxx"  # Replace with your password
server = "MetaQuotes-Demo"  # Replace with your server

# Simulated starting balance
initial_balance = 10000  # Starting balance in USD
trade_amount = 1  # Trade size in USD
current_balance = initial_balance

if not mt5.initialize(login=account, password=password, server=server):
    print(f"Failed to initialize MT5: {mt5.last_error()}")
    quit()

# Symbol and timeframe
SYMBOL = "AAPL"
TIMEFRAME = mt5.TIMEFRAME_D1  # Daily timeframe

# Get historical data from 2024/04/01 to present
start_date = datetime(2024, 4, 1)
end_date = datetime.now()

rates = mt5.copy_rates_range(SYMBOL, TIMEFRAME, start_date, end_date)
if rates is None:
    print(f"Failed to retrieve data for {SYMBOL}")
    mt5.shutdown()
    quit()

# Convert to DataFrame
data = pd.DataFrame(rates)
data['time'] = pd.to_datetime(data['time'], unit='s')
data.set_index('time', inplace=True)

# Calculate Bollinger Bands
window = 20  # 20-day moving average
data['SMA'] = data['close'].rolling(window=window).mean()
data['STD'] = data['close'].rolling(window=window).std()
data['Upper Band'] = data['SMA'] + 2 * data['STD']
data['Lower Band'] = data['SMA'] - 2 * data['STD']

# Identify proximity to Bollinger Bands
threshold = 0.15  # Define "near" as within 1% of the band
data['Near Upper Band'] = abs(data['close'] - data['Upper Band']) / data['Upper Band'] < threshold
data['Near Lower Band'] = abs(data['close'] - data['Lower Band']) / data['Lower Band'] < threshold

# Simulate trades
open_trade = None  # Track the current open trade
trade_results = []  # Store trade outcomes

for i in range(len(data)):
    row = data.iloc[i]
    if open_trade is None:
        # Check for entry signals
        if (
            row['Near Upper Band']
            and data.iloc[i - 1]['Near Upper Band']
        ):
            open_trade = {
                'type': 'Buy',
                'entry_price': row['close'],
                'entry_date': row.name,
                'days_held': 0
            }
        elif (
            row['Near Lower Band']
            and data.iloc[i - 1]['Near Lower Band']
        ):
            open_trade = {
                'type': 'Sell',
                'entry_price': row['close'],
                'entry_date': row.name,
                'days_held': 0
            }
    else:
        # Update trade duration
        open_trade['days_held'] += 1

        # Calculate profit/loss
        if open_trade['type'] == 'Buy':
            profit = trade_amount * ((row['close'] - open_trade['entry_price']) )
        else:  # Sell trade
            profit = trade_amount * ((open_trade['entry_price'] - row['close']))

        # Check exit conditions
        if profit > 0 and open_trade['days_held'] <= 4:
            # Exit with profit within 4 days
            current_balance += profit
            trade_results.append({
                'type': open_trade['type'],
                'entry_price': open_trade['entry_price'],
                'exit_price': row['close'],
                'profit': profit,
                'entry_date': open_trade['entry_date'],
                'exit_date': row.name
            })
            open_trade = None
        elif open_trade['days_held'] > 3 and profit <= -0.5:
            # Exit if loss exceeds 50 cents after 4 days
            current_balance += profit
            trade_results.append({
                'type': open_trade['type'],
                'entry_price': open_trade['entry_price'],
                'exit_price': row['close'],
                'profit': profit,
                'entry_date': open_trade['entry_date'],
                'exit_date': row.name
            })
            open_trade = None

# Display trade results
print(f"Initial Balance: {initial_balance:.2f} USD")
print(f"Final Balance: {current_balance:.2f} USD")
print("\nTrade Results:")
for trade in trade_results:
    print(f"{trade['type']} | Entry: {trade['entry_price']:.2f} | Exit: {trade['exit_price']:.2f} | "
          f"Profit: {trade['profit']:.2f} USD | "
          f"Entry Date: {trade['entry_date']} | Exit Date: {trade['exit_date']}")

# Plot the chart with trades
plt.figure(figsize=(15, 8))
plt.plot(data.index, data['close'], label="Close Price", color="blue")
plt.plot(data.index, data['Upper Band'], label="Upper Band", color="green", alpha=0.5)
plt.plot(data.index, data['Lower Band'], label="Lower Band", color="red", alpha=0.5)
plt.plot(data.index, data['SMA'], label="Middle Band (SMA)", color="orange")

# Plot trade entry/exit points
for trade in trade_results:
    color = "green" if trade['type'] == 'Buy' else "red"
    marker = "o" if trade['type'] == 'Buy' else "x"
    plt.scatter(trade['entry_date'], trade['entry_price'], color="green", marker="o", zorder=5)
    plt.scatter(trade['exit_date'], trade['exit_price'], color="red", marker="x", zorder=5)

# Add a single entry and exit symbol to the legend
plt.scatter([], [], color="green", marker="o", label="Entry")
plt.scatter([], [], color="red", marker="x", label="Exit")

# Plot settings
plt.title(f"Bollinger Bands Strategy Simulation with Trade Rules")
plt.xlabel("Date")
plt.ylabel("Price")
plt.legend(loc="best")
plt.grid(True)

# Display the chart
plt.show()
# Shutdown MT5
mt5.shutdown()

Monday, December 2, 2024

Python Script to Connect to MetaTrader 5, Retrieve Ticker Info, Historical Data, and Run a Trading Bot

 In this blog post, we’ll explore a Python script that connects to MetaTrader 5 (MT5), retrieves ticker information, historical data, and executes trades with a simple trading bot. This example script demonstrates the power of MT5's Python API, offering a blend of real-time trading and data analysis, which is essential for developing automated trading systems.

Prerequisites

Before we dive into the code, make sure you have the following:

  1. MetaTrader 5 Installed: MT5 should be installed on your system.
  2. MetaTrader 5 Python API (MetaTrader5 module): You can install it via pip: pip install MetaTrader5
  3. A Demo Account on MetaTrader 5: This is required for trading simulations.
  4. Pandas Library: To handle the historical data in a DataFrame.

Script Breakdown

1. Initialize the MT5 Connection

To begin with, we need to establish a connection with MetaTrader 5. The script initializes the connection using login credentials, password, and the server name. If the connection fails, the script prints the error and exits.

2. Account Information and Symbol Selection

Next, the script retrieves and prints the account balance. It then checks if the specified symbol (in this case, TSLA) is available on the selected server. If the symbol is not available, the script shuts down the connection.

3. Retrieving Current Price

The script then retrieves the current price of the symbol. This information is essential for calculating the lot size for our trade request.

4. Trade Execution

Now that we have the current price, the script calculates the lot size based on the amount we wish to invest. The symbol_info.volume_min and symbol_info.volume_step are used to ensure that the lot size conforms to the broker’s requirements. A buy order is then created and sent.

5. Retrieving Historical Data

The script retrieves historical data for the given symbol within a defined date range. The data is then converted into a Pandas DataFrame, which allows for easy manipulation and analysis.

6. Shutdown MT5 Connection

Finally, after completing the data retrieval and trade, the script shuts down the MetaTrader 5 connection.

How This Script Works

  • Initialize Connection: Establishes a connection to MT5 with your demo account credentials.
  • Retrieve Ticker Info: Fetches the current price of the TSLA stock.
  • Calculate Lot Size: Based on the current price and the desired investment, the script calculates the appropriate lot size for the trade.
  • Execute Trade: A buy order for TSLA is placed with a specified lot size and price.
  • Historical Data Retrieval: It fetches daily historical data from 2022 to the present.
  • Shutdown: Cleanly shuts down the connection to MT5.
Bonus:

1. Run MT5 Without GUI (Headless Mode)

By default, when you run MetaTrader 5, the application window opens. However, you can prevent this window from opening by using a special configuration or by running MT5 in a detached or background mode.

To run MetaTrader 5 in headless mode:

  • MetaTrader 5 on Windows: You can start MT5 in headless mode by running the terminal with specific command-line arguments. The MT5 terminal itself does not need to be visible for the API (Python) to connect and interact with it.

Steps:

  1. Launch MT5 in Headless Mode:

    • Windows: You can start the MetaTrader 5 terminal with the -silent argument in the command line to suppress the GUI. Command: terminal.exe -silent

    • Connecting from Python: Once the terminal is running in the background (in headless mode), your Python script can connect to the MetaTrader 5 application just like it would in normal mode, and it will not open the MT5 application window.

Conclusion

This Python script provides a solid foundation for interacting with MetaTrader 5. It allows you to execute trades, retrieve real-time ticker information, and analyze historical market data using the MT5 Python API. You can expand this framework to include more advanced trading strategies, risk management features, and data analysis tools, making it a versatile tool for developing automated trading systems.

By combining Python's power with MetaTrader 5's trading capabilities, you open the door to fully automated trading, where your algorithm can handle trading decisions in real time. Happy coding, and may your trades be profitable!


Here is the complete program listing:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
import MetaTrader5 as mt5
import time
import pandas as pd
from datetime import datetime

# Account details
account = nnn #your username
password = "xxx"#password
server = "MetaQuotes-Demo" #server

SYMBOL = "TSLA"
AMOUNT = 1
start_date = datetime(2022, 1, 1)  # Start date for data
end_date = datetime.now()  # End date is the current date

# Initialize MetaTrader 5
if not mt5.initialize(login=account, password=password, server=server):
    print(f"Failed to initialize MetaTrader 5: {mt5.last_error()}")
    quit()

# Check account information
account_info = mt5.account_info()
if account_info:
    print(f"Account balance: {account_info.balance} USD")
else:
    print(f"Failed to retrieve account info: {mt5.last_error()}")
    mt5.shutdown()
    quit()

# Check and select symbol
if not mt5.symbol_select(SYMBOL, True):
    print(f"Symbol {SYMBOL} not available or not selected.")
    mt5.shutdown()
    quit()

# Get symbol info
symbol_info = mt5.symbol_info(SYMBOL)
if not symbol_info:
    print(f"Failed to retrieve symbol info for {SYMBOL}")
    mt5.shutdown()
    quit()

# Get current price
tick = mt5.symbol_info_tick(SYMBOL)
if not tick:
    print(f"Failed to get price info for {SYMBOL}")
    mt5.shutdown()
    quit()

price = tick.ask

# Calculate lot size
lot_size = max(symbol_info.volume_min, round((AMOUNT / price) / symbol_info.volume_step) * symbol_info.volume_step)

# Create trade request
trade_request = {
    "action": mt5.TRADE_ACTION_DEAL,
    "symbol": SYMBOL,
    "volume": lot_size,
    "type": mt5.ORDER_TYPE_BUY,
    "price": price,
    "deviation": 20,
#    "magic": 123456,
    "comment": "Buy TSLA $500 trade",
    "type_time": mt5.ORDER_TIME_GTC,
    "type_filling": mt5.ORDER_FILLING_FOK,  # Changed to IOC
}

# Optional: Wait for 1 second before sending the order
time.sleep(1)

# Send trade request
result = mt5.order_send(trade_request)

# Check trade result
if result.retcode == mt5.TRADE_RETCODE_DONE:
    print(f"Trade executed successfully. Ticket={result.order}")
else:
    print(f"Trade execution failed. Retcode={result.retcode}")
    print(f"Error details: {mt5.last_error()}")


# Retrieve historical data for the specified date range
rates = mt5.copy_rates_range(SYMBOL, mt5.TIMEFRAME_D1, start_date, end_date)

# Check if data was retrieved
if rates is None:
    print(f"Failed to retrieve data for {symbol}")
    mt5.shutdown()
    quit()

# Convert the data to a pandas DataFrame
data = pd.DataFrame(rates)

# Convert timestamps to datetime
data['time'] = pd.to_datetime(data['time'], unit='s')

# Set the time column as the index
data.set_index('time', inplace=True)

# Print the first few rows of the data
print(data.head())
# Shutdown MT5
mt5.shutdown()




Sunday, November 19, 2023

Building a Stock Screener in Python to Identify MACD Equals Signal Opportunities

 Introduction:

Stock screeners are invaluable tools for investors looking to identify potential trading opportunities. In this article, we'll explore how to create a simple yet effective stock screener in Python using financial data from Yahoo Finance. Specifically, we'll focus on scanning for stocks where the MACD (Moving Average Convergence Divergence) equals the Signal line within the last 24 hours. Check out my related article about MACD Trading Strategy(Making some modifications on my article "How I will trade using MACD as indicator").


Prerequisites:

Before diving into the code, make sure you have the required libraries installed. You can install them using:

pip install pandas yahoo_fin yfinance


The Python Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import pandas as pd
from yahoo_fin import stock_info as si
import yfinance as yf
import datetime


# Fetch the list of Nasdaq tickers
df2 = pd.DataFrame(si.tickers_nasdaq())

# Set the date range for the stock data
end_date = datetime.datetime.today().strftime('%Y-%m-%d')
start_date = (datetime.datetime.today() - datetime.timedelta(days=1)).strftime('%Y-%m-%d')

# Loop through each stock ticker
for ticker in df2[0]:
    try:
        # Download stock data from Yahoo Finance
        data = yf.download(ticker, start=start_date, end=end_date, interval='1m')
        
        # Calculate MACD and Signal line
        # Calculate MACD
        data['ema_12'] = data['Close'].ewm(span=12, adjust=False).mean()
        data['ema_26'] = data['Close'].ewm(span=26, adjust=False).mean()
        data['macd'] = data['ema_12'] - data['ema_26']
        data['signal'] = data['macd'].ewm(span=9, adjust=False).mean()
        # Delete rows where macd and signal both equal 0
        data = data[(data['macd'] != 0) & (data['signal'] != 0)]
        # Check if there is an instance where MACD equals Signal
        if any(data['macd'] == data['signal']):
            print(f"Opportunity found for {ticker}: MACD equals Signal")
    except:
        pass  # Handle exceptions, e.g., delisted stocks or connection issues

Understanding the Code:

1. Fetching Tickers: We use the si.tickers_nasdaq() function from the yahoo_fin library to get a list of Nasdaq stock tickers. 
2. Downloading Stock Data: For each ticker, we use yfinance to download historical stock data for the last 24 hours with a 1-minute interval.
3. Calculating MACD and Signal:
    • data['ema_12'] = data['Close'].ewm(span=12, adjust=False).mean(): This line calculates the 12-period Exponential Moving Average (EMA) of the closing prices. It uses the ewm method in pandas, which stands for exponentially weighted moving average. The span parameter defines the window size, and adjust=False means that equal weights are assigned to all values in the window.
    • data['ema_26'] = data['Close'].ewm(span=26, adjust=False).mean(): Similar to the first line, this calculates the 26-period EMA of the closing prices.
    • data['macd'] = data['ema_12'] - data['ema_26']: This line computes the MACD line by subtracting the 26-period EMA from the 12-period EMA. The MACD line represents the difference between these two moving averages.
    • data['signal'] = data['macd'].ewm(span=9, adjust=False).mean(): Here, the code calculates the 9-period EMA of the MACD line, creating the signal line. The signal line is often used to generate buy or sell signals when it crosses the MACD line.
              4.Identifying Opportunities: We check if there is any instance where the MACD equals the Signal line. If found, we print a message indicating a potential trading opportunity.

              Conclusion:

              By building this simple stock screener in Python, you can quickly identify stocks exhibiting MACD equals Signal patterns. However, it's crucial to conduct further analysis and consider other factors before making any trading decisions. Additionally, remember to handle exceptions gracefully to ensure the robustness of your stock screener.

              This is just one of several scenarios, for complete details check the related article on my patreon.

              Sunday, June 4, 2023

              Evaluating Profitability and Accuracy in Stock Price Prediction using Random Forest Regression

              Introduction:

              Stock price prediction plays a crucial role in investment decision-making. In this article, we explore the application of Random Forest Regression to predict stock prices and evaluate the resulting profitability and accuracy. We focus on the stock of Apple Inc. (AAPL) and analyze historical data over the past six months.


              Step 1: Retrieving Historical Data:

              We start by retrieving historical stock price data using the Yahoo Finance API. The data consists of daily closing prices, which will serve as our primary feature for prediction.


              Step 2: Preparing Features and Target Variable:

              To train our Random Forest Regressor model, we prepare the feature variable (X) as the closing price and the target variable (y) as the shifted closing price for the following day.


              Step 3: Training the Random Forest Regressor:

              We train the Random Forest Regressor model with 100 estimators, a maximum depth of 10, and a minimum number of samples required to be a leaf node set to 2.


              Step 4: Predicting Close Prices:

              Using the trained model, we predict the close prices for the past six months, excluding the last data point, which we use for evaluation purposes.


              Step 5: Analyzing Signals, Accuracy, and Profitability:

              We analyze the predicted signals generated by the Random Forest model and compare them with the actual close prices. We count the number of correct and wrong signals to calculate the accuracy rating. Additionally, we compute the profitability by placing trades based on the signals and calculating the profit made by exiting the trade on the following day.


              Step 6: Plotting Actual and Predicted Close Prices:

              We visualize the actual and predicted close prices over the past six months using a line chart. This provides a visual representation of the model's performance.


              Results and Discussion:

              Upon analyzing the signals, we obtain the accuracy rating and total profit made. The accuracy rating reflects the percentage of correct signals generated by the model. Furthermore, the profitability is calculated by considering the difference in prices between consecutive days and multiplying it by the investment amount ($1 in this case).


              In our evaluation, we observed a certain level of accuracy and profit generated by the model. However, it is important to note that this analysis is based on historical data and simplified assumptions. Achieving high accuracy and profitability in real-world trading involves various factors, including market conditions, transaction costs, and risk management.


              Improving Accuracy:

              To improve the accuracy of stock price prediction, consider the following strategies:

              1. Feature Engineering: Explore additional features such as volume, technical indicators, and news sentiment to enhance the predictive power of the model.
              2. Model Tuning: Experiment with different hyperparameters of the Random Forest Regressor, such as the number of estimators, maximum depth, and minimum samples per leaf, to find the optimal configuration for improved accuracy.
              3. Ensemble Methods: Consider using ensemble techniques, such as combining multiple models or incorporating other algorithms like Gradient Boosting or LSTM, to leverage diverse predictions and potentially enhance accuracy.
              4. Cross-Validation: Implement cross-validation techniques to evaluate the model's performance on multiple folds of data and ensure its robustness and generalization.

              Conclusion:

              The application of Random Forest Regression for stock price prediction demonstrates potential profitability and accuracy. By analyzing signals, calculating accuracy, and evaluating profit, we gain insights into the model's performance. However, it is crucial to remember that investing in the stock market involves risks, and the accuracy of predictions may vary under different market conditions. Continued research, exploration of additional features, and fine-tuning of the model are necessary for further improvements in accuracy. It is advisable to consult with financial experts and consider multiple factors before making investment decisions.

              Here is the sample Python code used in this article:

               1
               2
               3
               4
               5
               6
               7
               8
               9
              10
              11
              12
              13
              14
              15
              16
              17
              18
              19
              20
              21
              22
              23
              24
              25
              26
              27
              28
              29
              30
              31
              32
              33
              34
              35
              36
              37
              38
              39
              40
              41
              42
              43
              44
              45
              46
              47
              48
              49
              50
              51
              52
              53
              54
              55
              56
              57
              58
              59
              60
              61
              62
              63
              64
              65
              import yfinance as yf
              import pandas as pd
              import numpy as np
              from datetime import datetime, timedelta
              from sklearn.ensemble import RandomForestRegressor
              import matplotlib.pyplot as plt
              
              # Step 1: Retrieve historical data
              ticker = "AAPL"  # Ticker symbol for Apple Inc.
              end_date = datetime.today().strftime('%Y-%m-%d')
              start_date = (datetime.today() - timedelta(days=6*30)).strftime('%Y-%m-%d')
              data = yf.download(ticker, start=start_date, end=end_date)
              
              # Step 2: Prepare features and target variable
              data['Close_shifted'] = data['Close'].shift(-1)
              data = data.dropna()
              
              X = data[['Close']]
              y = data['Close_shifted']
              
              # Step 3: Train the Random Forest Regressor
              model = RandomForestRegressor(n_estimators=100, max_depth=10, min_samples_leaf=2)
              model.fit(X, y)
              
              # Step 4: Predict close price for the past 6 months
              predicted_prices = model.predict(X[:-1])  # Exclude the last data point from prediction
              
              # Step 5: Analyze the signals and calculate accuracy and profit
              correct_signals = 0
              wrong_signals = 0
              total_profit = 0
              
              for i in range(len(predicted_prices)):
                  if predicted_prices[i] > data['Close'].iloc[i]:
                      if data['Close'].iloc[i+1] > data['Close'].iloc[i]:
                          correct_signals += 1
                      else:
                          wrong_signals += 1
                  elif predicted_prices[i] < data['Close'].iloc[i]:
                      if data['Close'].iloc[i+1] < data['Close'].iloc[i]:
                          correct_signals += 1
                      else:
                          wrong_signals += 1
              
                  # Calculate profit
                  if predicted_prices[i] > data['Close'].iloc[i]:
                      daily_profit = (data['Close'].iloc[i+1] - data['Close'].iloc[i]) / data['Close'].iloc[i]
                      total_profit += daily_profit
              
              accuracy = correct_signals / (correct_signals + wrong_signals) * 100
              print("Correct Signals:", correct_signals)
              print("Wrong Signals:", wrong_signals)
              print("Accuracy Rating:", accuracy, "%")
              print("Total Profit:", total_profit)
              
              # Step 6: Plot actual and predicted close prices
              plt.figure(figsize=(10, 6))
              plt.plot(data.index[:-1], data['Close'][:-1], label='Actual Close Price')  # Exclude the last data point
              plt.plot(data.index[:-1], predicted_prices, label='Predicted Close Price')  # Exclude the last data point
              plt.xlabel('Date')
              plt.ylabel('Close Price')
              plt.title('Actual vs Predicted Close Price')
              plt.legend()
              plt.xticks(rotation=45)
              plt.show()
              


              Evaluation results after running the program:

              And here is the generated chart:



              Managing Trading Risks by Knowing Calendar Events That Affect Market Volatility

                Introduction to Trading Risks In Forex and other financial markets, risk management is one of the most critical aspects of successful trad...