mql5/Include/Example1/CTradeSignal.mqh
SoloTradeOfficial f20bb89655 new files added
2025-08-30 11:40:16 +00:00

252 lines
No EOL
9.4 KiB
MQL5

//+------------------------------------------------------------------+
//| CTradeSignal.mqh |
//| Copyright 2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "SoloTrade Official, Solomon"
#property link "https://www.mql5.com/en/users/SoloTradeOfficial"
#property version "1.00"
#property description "THE WORLD MOST INTELLIGENT FOREX AI/ALGO BOTS EVER IN"
"HUMAN HISTORY OF FINTECH, BY SOLOMON ESHUN"
"\nTrading Bots in MQL5"
// Scope Resolution Operator `::`
// --- DECLARATION ---
// This part is like the public menu. It tells us WHAT the class can do.
class CTradeSignal {
private:
string m_symbol;
int m_magic_number;
public:
// Constructor declaration
CTradeSignal(string symbol, int magic_number);
// Method declaration
void CheckSignal();
};
// --- DEFINITION / IMPLEMENTATION ---
// This part is the kitchen. It's HOW the work gets done.
// Because this code is outside the class { } block, we MUST use ::
// Definition for the constructor
CTradeSignal::CTradeSignal(string symbol, int magic_number) {
m_symbol = symbol;
m_magic_number = magic_number;
Print("Trade Signal object created for ", m_symbol);
}
// Definition for the CheckSignal method
void CTradeSignal::CheckSignal() {
// Some complex logic to check for a trade signal...
Print("Checking for a signal on ", m_symbol, " with magic number ", m_magic_number);
}
//+------------------------------------------------------------------+
// NOTES BELOW
//You are asking fantastic questions that get to the heart of Object-Oriented Programming (OOP) design. Let's break down both of these concepts.
//
//---
//
//### Part 1: The Scope Resolution Operator (`::`)
//
//This is a syntax tool, a way of giving the compiler an exact address for a piece of code.
//
//**The Core Idea:** The `::` operator tells the compiler, "The function I am defining on the left of the `::` belongs to the class I am naming on the right." It resolves the *scope* of the function.
//
//**Analogy: The Office Building**
//
//Imagine you have a large office building (your entire program). The building has several departments: Sales, Marketing, and Engineering (these are your classes).
//
//Each department has a manager named "John."
//
//* `Sales::John`
//* `Marketing::John`
//* `Engineering::John`
//
//If you just shout "John!", nobody knows who you're talking about. You need to be specific. The `::` is how you specify which "department" (class) the "person" (function) belongs to.
//
//So, `Car::Car(...)` means "I am defining the `Car` constructor that belongs to the `Car` class."
//
//#### Why Do We Need This?
//
//The main reason is for **code organization**. It's considered very good practice to separate a class's *declaration* from its *definition (or implementation)*.
//
//1. **The Declaration (The "What"):** This goes in a header file (e.g., `Car.mqh`). It's like the table of contents for your class. It tells the world what the class is named and what public functions it has, but not *how* they work.
//
//2. **The Definition (The "How"):** This can go in the same file (usually below the declaration) or a separate `.cpp` file in larger projects. This is where you write the actual code for each function. Because this code is now *outside* the `class { ... }` block, you must use the scope resolution operator (`::`) to tell the compiler which class each function belongs to.
//
//#### MQL5 Example:
//
//Let's see this in action with a `CTradeSignal` class.
//
//**File: `CTradeSignal.mqh`**
//
//```mql5
//// --- DECLARATION ---
//// This part is like the public menu. It tells us WHAT the class can do.
//
//class CTradeSignal
//{
//private:
// string m_symbol;
// int m_magic_number;
//
//public:
// // Constructor declaration
// CTradeSignal(string symbol, int magic_number);
//
// // Method declaration
// void CheckSignal();
//};
//
//
//// --- DEFINITION / IMPLEMENTATION ---
//// This part is the kitchen. It's HOW the work gets done.
//// Because this code is outside the class { } block, we MUST use ::
//
//// Definition for the constructor
//CTradeSignal::CTradeSignal(string symbol, int magic_number)
//{
// m_symbol = symbol;
// m_magic_number = magic_number;
// Print("Trade Signal object created for ", m_symbol);
//}
//
//// Definition for the CheckSignal method
//void CTradeSignal::CheckSignal()
//{
// // Some complex logic to check for a trade signal...
// Print("Checking for a signal on ", m_symbol, " with magic number ", m_magic_number);
//}
//```
//
//By separating the "what" from the "how," your class declaration at the top becomes very clean and easy to read, while the complex logic is neatly organized below.
//
//---
//
//### Part 2: Composition ("Has-A" Relationship)
//
//This is a powerful design pattern. You've already learned about Inheritance, which creates an "Is-A" relationship (`A CMACrossoverSignal` **is a** `CSignal`).
//
//**Composition creates a "Has-A" relationship.**
//
//**The Core Idea:** Instead of a class inheriting features, it is *composed* of other objects. It holds other objects inside it as member variables.
//
//**Analogy: The Car (Again!)**
//
//A `Car` is a perfect example of composition.
//
//* A `Car` **is not** an `Engine`.
//* A `Car` **is not** a `Wheel`.
//* Instead, a `Car` **has an** `Engine`.
//* A `Car` **has** four `Wheels`.
//* A `Car` **has a** `Transmission`.
//
//The `Car` class coordinates the work of all its component parts. When you press the accelerator in the `Car`, the `Car` object tells its `Engine` object to increase RPMs, which in turn tells the `Transmission` object to engage a gear, which tells the `Wheel` objects to turn.
//
//#### MQL5 Example: An Expert Advisor Composed of Parts
//
//Let's model an EA. An EA might be composed of a signal generator, a risk manager, and a trade executor.
//
//**Step 1: Define the "Part" Classes**
//
//We'll use the `CRiskManager` from our Abstraction example and a simplified `CTradeExecutor`.
//
//```mql5
//// (Assuming CRiskManager class is defined as in the previous example)
//
//class CTradeExecutor
//{
//public:
// void ExecuteBuy(string symbol, double lots)
// {
// Print("EXECUTOR: Placing BUY order for ", lots, " lots on ", symbol);
// // Real MQL5 OrderSend() logic would go here
// }
//};
//```
//
//**Step 2: Define the "Whole" Class using Composition**
//
//The `CExpertAdvisor` class will *contain* objects of the other classes as member variables.
//
//```mql5
//// Include the files for the parts
//#include "CRiskManager.mqh"
//#include "CTradeExecutor.mqh"
//// (Assuming CTradeSignal from above is also available)
//
//class CExpertAdvisor
//{
//private:
// // --- COMPOSITION HAPPENS HERE ---
// // The EA "has-a" signal, a risk manager, and an executor.
// CTradeSignal m_signal;
// CRiskManager m_risk_manager;
// CTradeExecutor m_trade_executor;
//
//public:
// // The EA's constructor initializes its component parts
// CExpertAdvisor(string symbol, int magic_number) : m_signal(symbol, magic_number),
// m_risk_manager(1.0, 5), // 1% risk, 5 trades max
// m_trade_executor()
// {
// Print("Expert Advisor object created and ready.");
// }
//
// // The EA's main logic function
// void OnTick()
// {
// // The EA delegates work to its parts.
// // 1. It asks its signal component for a signal.
// // m_signal.CheckSignal(); // Pretend this returns a trade direction
//
// ENUM_TRADE_DIRECTION tradeDirection = GetSignalFromSomewhere(); // Fake signal
//
// if (tradeDirection != TRADE_DIRECTION_NONE)
// {
// // 2. It asks its risk manager component if a trade is allowed.
// if (m_risk_manager.isTradeAllowed(30.0)) // 30 pips SL
// {
// // 3. If everything is OK, it tells its trade executor to place the trade.
// m_trade_executor.ExecuteBuy(_Symbol, 0.1);
// }
// }
// }
//
// // Fake function for demonstration
// ENUM_TRADE_DIRECTION GetSignalFromSomewhere() { return TRADE_DIRECTION_BUY; }
//};```
//
//**Step 3: Using the Composed Object**
//
//```mql5
//// In your main .mq5 file
//
//#include "CExpertAdvisor.mqh"
//
//// Create the main EA object
//CExpertAdvisor MyEA("EURUSD", 12345);
//
//// The main OnTick function simply delegates all work to our EA object.
//void OnTick()
//{
// MyEA.OnTick();
//}
//```
//
//### Summary: Composition vs. Inheritance
//
//| Feature | Inheritance ("Is-A") | Composition ("Has-A") |
//| :--- | :--- | :--- |
//| **Relationship** | A derived class is a specialized version of its base class. | An object is built from other, independent objects. |
//| **Flexibility** | Static. The relationship is fixed when you compile the code. | Highly flexible. You can often change the "parts" at runtime. |
//| **Coupling** | Tightly coupled. A change in the base class can break all derived classes. | Loosely coupled. The "whole" only cares about the public interface of its "parts". |
//| **When to Use** | When you can say "Type B is a type of Type A". (A `Toyota` is a `Car`). | When you can say "Type A has a Type B". (A `Car` has an `Engine`). |
//
//Generally, modern programming advice is to **"prefer composition over inheritance."** It leads to more flexible, scalable, and maintainable code, just like you saw with the `CExpertAdvisor` example.