Skip to content

Conversation

@d3x0r
Copy link

@d3x0r d3x0r commented Mar 11, 2021

d3x0r added 8 commits January 12, 2021 09:23
…_ENABLE_COLUMN_METADATA, sqlite3_column_table_alias returns the alias specified in the query.
…ed; Add sqlite3_column_table_alias returns the alias of the table the column belongs to, which was specified in the prepared statement.
@d3x0r d3x0r marked this pull request as ready for review March 11, 2021 05:34
@justinclift
Copy link

justinclift commented Mar 11, 2021

Not super sure, but this probably won't get merged from here.

Saying that because this is just a mirror of the actual repo, and the SQLite Bug report page says to report bugs via their public forum.

That being said, SQLite is Open Source, not Open Contribution, so the SQLite authors would need to re-implement any changes. 🤷

@d3x0r
Copy link
Author

d3x0r commented Nov 16, 2021

The first message associated with the PR was a Sqlite Forum link.... so that was already done.
That's interesting about 'open source, but not open contribution' how about 'open fix your non-functionality' ?
I'm going to keep quietly keeping this in sync... (although I might have to close this specific PR - it seems to represent changes that https://github.com/d3x0r/sqlite/tree/sqlite3_column_table_alias doesn't actually have against master. ) same branch; I started to open a new PR, but realized this one should just update...
This gives a way to get a standard diff which could be used with patch ....

@justinclift
Copy link

As a thought, is this something that you could turn into a SQLite extension instead?

That way, it could be directly hosted in one of the SQLite extension repositories (there seem to be a few now), and people would probably find it easier. 😄

@Atiqjokhio
Copy link

           

     Cross-EA Risk Synchronization: Implementing a Centralized SQLite Database for Portfolio Protection()

Icon for article

## 1. Introduction to Portfolio Synchronization ()

In the modern era of algorithmic trading, managing multiple trading accounts across different MetaTrader5 terminals has become a standard practice for professional traders and hedge funds. However, the biggest challenge lies in data consistency. When an Expert Advisor (EA) executes a trade on one terminal, how does the rest of the ecosystem stay informed in real-time? This article explores a robust solution: using a centralized SQLite database to synchronize portfolio data.

Traditional methods of communication between terminals, such as Global Variables or local CSV files, often fall short when dealing with high-frequency data or complex relational structures. SQLite provides a serverless, zero-configuration database engine that allows for structured data storage, ensuring that every trade, modification, and balance update is logged and accessible by any authorized terminal in the network.


## 2. Why SQLite is the Best Choice ()

   

MQL5 provides native support for SQLite, making it an incredibly efficient tool for developers. The primary advantages include:

Zero Configuration: Unlike SQL Server or MySQL, SQLite does not require a separate server process. The entire database is stored in a single file on your hard drive.


Speed: It is optimized for local read/write operations, which is crucial for trading environments where milliseconds matter.

ACID Compliance: It ensures that database transactions are processed reliably, preventing data corruption during sudden system crashes or power failures.

Portability: The database file can be easily moved or backed up, making it ideal for traders who use Virtual Private Servers (VPS).

## 3. Designing the Database Schema ()


Before writing any MQL5 code, we must define how our data will be organized. A centralized portfolio database typically requires at least three main tables:

Accounts Table: To store account numbers, broker names, and leverage settings.

Icon for article

Trades Table: To log every open position, including ticket numbers, entry prices, and stop-loss levels.

History Table: To keep a record of closed trades for performance analysis.

By using structured tables, we can perform complex SQL queries, such as calculating the total exposure across all accounts for a specific currency pair (e.g., EURUSD) with a single command.


## 4. The Synchronization Logic: Step-by-Step ()

The core of our system is a "Synchronization Engine" built within an Expert Advisor. The logic follows a continuous loop:

Step A: Data Extraction

The EA uses the Position Get Double and Position Get Integer functions to scan the current terminal's state. It gathers information such as the current profit, swap, and volume for every open position.

Step B: Writing to the Centralized Database

Once the data is gathered, the EA opens a connection to the shared SQLite file. It uses the DatabaseExecute function to run "INSERT" or "UPDATE" queries. This ensures that the centralized file always reflects the most recent state of the local terminal.

Step C: Cross-Terminal Reading

Other terminals running the same synchronization EA will periodically "SELECT" data from the database. If Terminal A opens a trade, Terminal B will see that trade in the database within milliseconds and can adjust its own risk management logic accordingly.


##5.Handling Multi-Terminal Conflicts()

Icon for article

One common issue in centralized systems is "Database Locking." This happens when two terminals try to write to the same SQLite file at exactly the same time. To solve this, we implement a "Retry Logic" in MQL5. If the database returns a "BUSY" error, the EA will wait for a few microseconds and try again. This ensures that no data is lost even in a busy multi-account environment.


##6. Performance Optimization and Maintenance()

As the number of trades grows, the database file can become large. To maintain peak performance, we recommend:

Indexing: Create indexes on columns like "Ticket" and "AccountNumber" to speed up search queries.

Vacuuming: Regularly use the VACUUM command to defragment the database file and reduce its size.

Asynchronous Operations: While MQL5 is single-threaded, we can optimize our SQL queries to be as short as possible to avoid freezing the terminal's main thread.


##7. Future Improvements()

Implementing a centralized SQLite database transforms MetaTrader 5 from a standalone platform into a part of a powerful, interconnected trading ecosystem. It provides the transparency and data integrity required for professional portfolio management. In the future, this system can be expanded to include web-based dashboards or mobile notifications by connecting the SQLite database to external Python scripts or web APIs.

//+------------------------------------------------------------------+
//|                                     PortfolioSync_SQLite.mq5      |
//|                                  Copyright 2026, Trading Expert  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

// Global handle for the database
int db_handle = INVALID_HANDLE;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Open or create the centralized database file
   db_handle = DatabaseOpen("CentralPortfolio.db", DATABASE_OPEN_READWRITE | DATABASE_OPEN_CREATE | DATABASE_OPEN_COMMON);
  
   if(db_handle == INVALID_HANDLE)
   {
      Print("Error: Failed to open database. Code: ", GetLastError());
      return(INIT_FAILED);
   }

   // Create a table for account synchronization if it doesn't exist
   string query = "CREATE TABLE IF NOT EXISTS Portfolio (ID INTEGER PRIMARY KEY, Account INTEGER, Equity REAL, Profit REAL);";
   if(!DatabaseExecute(db_handle, query))
   {
      Print("Error creating table: ", GetLastError());
      DatabaseClose(db_handle);
      return(INIT_FAILED);
   }

   Print("Database initialized successfully.");
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   if(db_handle != INVALID_HANDLE)
   {
      DatabaseClose(db_handle);
      Print("Database connection closed.");
   }
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double equity = AccountInfoDouble(ACCOUNT_EQUITY);
   double profit = AccountInfoDouble(ACCOUNT_PROFIT);
   long account_id = AccountInfoInteger(ACCOUNT_LOGIN);

   // Update account info in the centralized database
   string query = StringFormat("INSERT OR REPLACE INTO Portfolio (ID, Account, Equity, Profit) VALUES (1, %lld, %f, %f);",
                               account_id, equity, profit);

   if(!DatabaseExecute(db_handle, query))
   {
      Print("Failed to update database: ", GetLastError());
   }
}

##8.Conclusion & References


References & Useful Links:


1. Official Documentation:

   - [MQL5 Programming Guide](https://www.mql5.com/en/docs)

   - [SQLite Documentation](https://sqlite.org/docs.html)

   - [MetaTrader 5 Help](https://www.metatrader5.com/en/help)


2. Related Articles on MQL5:

   - [Database Operations in MQL5](https://www.mql5.com/en/articles/1581)

   - [Expert Advisor Programming](https://www.mql5.com/en/articles/386)


3. External Resources:

   - [SQLite Tutorial](https://www.sqlitetutorial.net)

   - [Algorithmic Trading Strategies](https://www.invesotopedia.cm)


4. Tools:

   - [MetaTrader 5 Download](https://www.metatrader5.com/en/download)

   - [SQLite Browser](https://sqlitebrowser.org)


Code Repository:

- Complete source code: [GitHub Link](https://github.com/your-repo)


---

Article written for [MQL5 Community](https://www.mql5.com)




## 📝 NOTE TO EDITOR/MODERATOR:

Please ensure:

1. All external links above are clickable hyperlinks

2. Internal anchor links connect to respective sections

3. Section IDs: #section1, #section2, etc. are properly set


Thank you!










Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants