AccountSentry
Download scriptAccountSentry Logic Overview
AccountSentry is a safety management tool designed to act as an automated "guardian" for your trading account. Rather than executing trades itself, its primary function is to monitor your account's health in real-time and intervene automatically if certain risk thresholds are breached. It essentially provides a safety net to protect your capital from significant unforeseen losses or extreme market volatility.
Core Functionality
1. Dynamic Equity Protection (Trailing Stop) One of the script’s primary features is its ability to "lock in" progress. It monitors your account balance and can establish a trailing protection level. As your account balance grows, the system updates this protection threshold. If the current value of your account (equity) falls below this high-water mark, the script triggers an emergency protocol to protect what you have earned.
2. Automated Emergency Shutdown If the safety thresholds mentioned above are hit—specifically if the equity drops to the protection level—the script is designed to take immediate action. It will automatically close all open positions and pending orders across the account and switch to a "HALTED" status. This prevents further losses from occurring during a sudden market downturn or a technical error.
3. Continuous Risk Monitoring The script constantly scans several key performance indicators (KPIs) to keep you informed of your risk exposure:
- Margin Levels: It tracks the percentage of your account used as collateral. If your margin level drops too low (indicating high risk), it records these lows to help you understand your risk limits.
- Floating Profit and Loss: It monitors the real-time gains and losses of your active trades, keeping track of your maximum floating profit and maximum floating loss.
- Order Limits: It keeps a record of the total number of open orders to ensure you are not over-leveraging your account beyond your intended capacity.
4. Real-Time Dashboard To keep the user informed, the script provides a live visual update directly on the trading terminal. This dashboard displays critical information at a glance, including:
- Current status (Running vs. Halted).
- Account balance and equity figures.
- Current margin levels and maximum used margins.
- Total number of open orders.
- Historical "highs" and "lows" for your floating profit, loss, and equity levels.
Summary for the User
Think of AccountSentry as a "circuit breaker" for your trading account. It works in the background to observe your portfolio's health. If the market moves against you in a way that threatens your capital beyond your pre-defined safety parameters, it closes your positions automatically to preserve your remaining balance, while simultaneously providing you with a clear, real-time summary of your risk metrics.
//+------------------------------------------------------------------+
//| AccountSentry.mq4 |
//| Copyright © 2008, David E. Fulton |
//| http://www.defulton.com/forex|
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, David E. Fulton"
#property link "http://www.defulton.com/forex"
//*******************************************************
extern string version= "AccountSentry V1.0"; //*
extern string ContactMe="david@defulton.com"; //*
extern string Build = "Build 014"; //*
extern string BuildDate="-- 19 December 2008 --"; //*
//*******************************************************
double MaxAccountMargin = 0.0;
double MaxFloatingLoss = 0.0;
double MinMarginLevel = 0.0;
double AccountMarginLevel = 0.0;
double AccountCurrentBalance;
bool ContinueOpening=true;
string Status="";
int nTickCount;
int deinit() {
return(0);
}
int init() {
if (AccountMargin() > 0) // eleminate zero divide error
MinMarginLevel = AccountEquity() / AccountMargin() * 100;
if (!GlobalVariableCheck("GV_AccountBeginningBalance"))
GlobalVariableSet("GV_AccountBeginningBalance",0.0);
if (!GlobalVariableCheck("GV_AccountEquityProtection"))
GlobalVariableSet("GV_AccountEquityProtection",0.0);
if (!GlobalVariableCheck("GV_TrailingEquityProtection"))
GlobalVariableSet("GV_TrailingEquityProtection",0.0);
if (!GlobalVariableCheck("GV_CloseAllAndHalt"))
GlobalVariableSet("GV_CloseAllAndHalt",0.0);
if (!GlobalVariableCheck("GV_MarginLevel"))
GlobalVariableSet("GV_MarginLevel",0.0);
if (!GlobalVariableCheck("GV_MaxAccountMargin"))
GlobalVariableSet("GV_MaxAccountMargin",0.0);
if (!GlobalVariableCheck("GV_MaxFloatingLoss"))
GlobalVariableSet("GV_MaxFloatingLoss",0.0);
if (!GlobalVariableCheck("GV_MaxFloatingProfit"))
GlobalVariableSet("GV_MaxFloatingProfit",0.0);
if (!GlobalVariableCheck("GV_MaxOpenOrders"))
GlobalVariableSet("GV_MaxOpenOrders",0.0);
if (!GlobalVariableCheck("GV_MinMarginLevel"))
GlobalVariableSet("GV_MinMarginLevel",0.0);
if (!GlobalVariableCheck("GV_MinEquityLevel"))
GlobalVariableSet("GV_MinEquityLevel",0.0);
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start() {
nTickCount++;
GlobalVariableSet("GV_AccountCurrentBalance",AccountBalance());
// Account equity protection
if (AccountEquity() <= GlobalVariableGet("GV_TrailingEquityProtection")) {
ContinueOpening=False;
GlobalVariableSet("GV_CloseAllAndHalt",1.0);
CloseAll();
Status="HALTED";
DisplayComments();
return(0);
} else {
GlobalVariableSet("GV_CloseAllAndHalt",0.0);
ContinueOpening=true;
}
if (GlobalVariableGet("GV_AccountCurrentBalance") > GlobalVariableGet("GV_AccountBeginningBalance")) {
GlobalVariableSet("GV_TrailingEquityProtection",GlobalVariableGet("GV_AccountEquityProtection") +
GlobalVariableGet("GV_AccountCurrentBalance") - GlobalVariableGet("GV_AccountBeginningBalance"));
} else {
GlobalVariableSet("GV_AccountCurrentBalance",AccountBalance());
GlobalVariableSet("GV_TrailingEquityProtection",GlobalVariableGet("GV_AccountEquityProtection"));
}
if (AccountMargin() > 0) { // eleminate zero divide error
AccountMarginLevel = AccountEquity() / AccountMargin() * 100;
}
if (GlobalVariableGet("GV_MinMarginLevel") == 0) {
GlobalVariableSet("GV_MinMarginLevel",AccountMarginLevel);
}
if (AccountMarginLevel < GlobalVariableGet("GV_MinMarginLevel")) {
GlobalVariableSet("GV_MinMarginLevel",AccountMarginLevel); //update minimum margin level
}
if (AccountMargin() > GlobalVariableGet("GV_MaxAccountMargin")) {
MaxAccountMargin = AccountMargin();
GlobalVariableSet("GV_MaxAccountMargin",AccountMargin()); //update GV_MaxAccountMargin
}
if (AccountProfit() > GlobalVariableGet("GV_MaxFloatingProfit")) {
GlobalVariableSet("GV_MaxFloatingProfit",AccountProfit());
}
if (GlobalVariableGet("GV_MinEquityLevel") == 0) {
GlobalVariableSet("GV_MinEquityLevel",AccountEquity());
} else {
if (AccountEquity() < GlobalVariableGet("GV_MinEquityLevel"))
GlobalVariableSet("GV_MinEquityLevel",AccountEquity());
}
if (AccountProfit() < MaxFloatingLoss) {
MaxFloatingLoss = AccountProfit();
GlobalVariableSet("GV_MaxFloatingLoss",MaxFloatingLoss); //update GV_MaxFloatingLoss
}
if (OrdersTotal() > GlobalVariableGet("GV_MaxOpenOrders")) {
GlobalVariableSet("GV_MaxOpenOrders",OrdersTotal()); //update GV_MaxOpenOrders
}
if (ContinueOpening>0) {
Status="RUNNING";
} else {
Status="HALTED";
}
if (!IsTesting()) {
DisplayComments();
}
return(0);
}
void DisplayComments() {
Comment("\n",version," ",Build,
"\n",
"\nTick=",nTickCount,
"\nCurrent Terminal Status=",Status,
"\nAccount Leverage=1:",AccountLeverage(),
"\n",
"\nBeginning Account Balance=",GlobalVariableGet("GV_AccountBeginningBalance"),
"\nCurrent Account Balance=",GlobalVariableGet("GV_AccountCurrentBalance"),
"\nTrailing Equity Stop Loss=",GlobalVariableGet("GV_TrailingEquityProtection"),
"\n",
"\nCurrent AccountEquity=",AccountEquity(),
"\nCurrent AccountMargin=",AccountMargin(),
"\nCurrent Account Margin Level=",MathRound(AccountMarginLevel),"%",
"\nCurrent Open Orders=",OrdersTotal(),
"\n",
"\nMinumum Equity Level=",GlobalVariableGet("GV_MinEquityLevel"),
"\nMaximum Floating Profit=",GlobalVariableGet("GV_MaxFloatingProfit"),
"\nMaximum Floating Loss=",GlobalVariableGet("GV_MaxFloatingLoss"),
"\nMaximum Account Margin=",GlobalVariableGet("GV_MaxAccountMargin"),
"\nMinimum Margin Level=",MathRound(GlobalVariableGet("GV_MinMarginLevel")),"%",
"\nMaximum Open Orders=",GlobalVariableGet("GV_MaxOpenOrders"));
}
//+------------------------------------------------------------------+
//| Close all orders |
//+------------------------------------------------------------------+
void CloseAll() {
for (int i=0;i<5;i++) {
int total_trades=OrdersTotal();
for (int j=0;j<total_trades;j++) {
while (!IsTradeAllowed()) { // wait if trade context is busy
}
if (OrderSelect(j,SELECT_BY_POS,MODE_TRADES)) {
int order_type=OrderType();
double order_openprice=OrderOpenPrice();
int order_ticket=OrderTicket();
double order_volume=OrderLots();
string order_symbol=OrderSymbol();
//close pending orders
if (order_type>=OP_BUYLIMIT) OrderDelete(order_ticket,CLR_NONE);
//close sell orders
if (order_type==OP_SELL) OrderClose(order_ticket,order_volume,
MarketInfo(order_symbol,MODE_ASK),3,CLR_NONE);
//close buy orders
if (order_type==OP_BUY) OrderClose(order_ticket,order_volume,
MarketInfo(order_symbol,MODE_BID),3,CLR_NONE);
}
}
}
total_trades=OrdersTotal();
return(0);
}
//+------------------------------------------------------------------+
Comments