Technical Logic Overview: Starter Script
This document provides a non-technical explanation of the logic contained within the provided MetaTrader script. The script is an automated trading system (Expert Advisor) designed to manage trades based on specific technical indicators, risk management rules, and historical performance analysis.
1. Core Trading Philosophy
The script operates on a "signal-based" strategy. It monitors three specific mathematical indicators to determine market direction and then executes trades automatically when certain conditions align. It also includes a dynamic "Position Sizing" logic that adjusts the amount of money invested based on past successes and failures.
2. Key Components and Indicators
The script uses three primary tools to "read" the market:
- Laguerre Oscillator: Used primarily to identify the current momentum and trend direction.
- Moving Average (MA): A smoothed average of price over a set period (default is 120) used to determine the general trajectory of the market (upward or downward).
- CCI (Commodity Channel Index): Used to measure the strength of price movement relative to its historical average, helping to identify "overbought" or "oversold" conditions.
3. Entry Logic (How it opens trades)
The script will only open a new trade if there are no existing positions currently open for the specific currency pair. It looks for two distinct scenarios:
Buy Orders (Long Positions)
A purchase is triggered when all four of these conditions are met simultaneously:
- Laguerre Indicator: Is at or below zero (suggesting a potential bottom or reversal).
- Moving Average: The current value is higher than the previous value (indicating an upward trend).
- CCI Indicator: Is below -5 (indicating the market might be "oversold").
- Availability: No other "Sell" positions are currently active.
Sell Orders (Short Positions)
A sale is triggered when all four of these conditions are met simultaneously:
- Laguerre Indicator: Is at or above 1 (suggesting a potential peak or reversal).
- Moving Average: The current value is lower than the previous value (indicating a downward trend).
- CCI Indicator: Is above 5 (indicating the market might be "overbought").
- Availability: No other "Buy" positions are currently active.
4. Exit Logic (How it closes trades)
The script monitors active trades constantly and will close them based on two main triggers:
Momentum Reversal
- For Buy Positions: If the Laguerre indicator rises above 0.9, the script assumes the upward momentum is exhausted and closes the trade.
- For Sell Positions: If the Laguerre indicator falls below 0.1, the script assumes the downward momentum is exhausted and closes the trade.
Stop Loss (Risk Protection)
The script includes a safety feature where a trade will be automatically closed if the price moves against the position by a predefined number of points (the Stop variable). This acts as a "circuit breaker" to prevent significant losses in a single trade.
5. Intelligent Risk Management
A standout feature of this script is its Dynamic Lot Calculation. Instead of always trading the same amount, it analyzes your trading history:
- Risk Awareness: It calculates the lot size based on a percentage of your "Free Margin" (available funds).
- Loss Correction: If the script detects a string of recent losses without a break, it automatically reduces the trade size to preserve capital.
- Success Adjustment: If the script detects a string of wins, it can adjust the lot size accordingly based on the
IncreaseFactor. - Minimum Safety: The script ensures that even after reductions, the trade size never falls below a minimum of 0.1 lots to ensure the account remains active.
//+------------------------------------------------------------------+
//| Starter.mq4 |
//| Copyright © 2005, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
#define MAGICMA 20050610
extern double Lots = 1;
extern double MaximumRisk = 0.03;
extern double DecreaseFactor = 3;
extern double IncreaseFactor = 3;
//extern double Lots = 4;
extern double Stop = 10;
extern double MAPeriod=120;
double spread=1.5;
//+-- extern double JuiceLevel = 0.0005;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Calculate optimal lot size |
//+------------------------------------------------------------------+
double LotsOptimized()
{
double lot=Lots;
int orders=HistoryTotal(); // history orders total
int losses=0; // number of losses orders without a break
int wines=0; // number of wines orders without a break
int i;
//---- select lot size
lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000,1);
//---- calcuulate number of losses orders without a break
if(DecreaseFactor>0)
{
for(i=orders-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
//----
if(OrderProfit()>0) break;
if(OrderProfit()<0) losses++;
}
if(losses>1) lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
}
if((IncreaseFactor>0) && (losses<1))
{
for(i=orders-1;i>=0;i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) { Print("Error in history!"); break; }
if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;
//----
if(OrderProfit()<0) break;
if(OrderProfit()>0) wines++;
}
if(wines>1) lot=NormalizeDouble(lot-lot*wines/IncreaseFactor,1);
}
//---- return lot size
if(lot<0.1) lot=0.1;
// lot=1;
return(lot);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
double Laguerre;
double Alpha;
double MA, MAprevious;
//+-- double Juice;
int cnt, ticket, total;
Laguerre=iCustom(NULL, 0, "Laguerre", 0, 0);
Alpha=iCCI(NULL, 0, 14, PRICE_CLOSE, 0);
MA=iMA(NULL,0,MAPeriod,0,MODE_EMA,PRICE_MEDIAN,0);
MAprevious=iMA(NULL,0,MAPeriod,0,MODE_EMA,PRICE_MEDIAN,1);
//+-- Juice=iCustom(NULL,0,"Juice",0,0);
total=OrdersTotal();
bool est_s=true;
bool est_b=true;
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if((OrderType()==OP_SELL) && (OrderSymbol()==Symbol())) est_s=false;
if((OrderType()==OP_BUY) && (OrderSymbol()==Symbol())) est_b=false;
}
// if(total<1)
{
// no opened orders identified
if(AccountFreeMargin()<(1000*Lots))
{
Print("We have no money. Free Margin = ", AccountFreeMargin());
return(0);
}
// check for long position (BUY) possibility
if((Laguerre<=0) && (MA>MAprevious) && (Alpha<-5) && est_b) //+-- && Juice>JuiceLevel)
{
ticket=OrderSend(Symbol(),OP_BUY,LotsOptimized(),Ask,3,0,0,"starter",16384,0,Green);
}
// check for short position (SELL) possibility
if((Laguerre>=1) && (MA<MAprevious) && (Alpha>5) && est_s) //+-- && Juice>JuiceLevel)
{
ticket=OrderSend(Symbol(),OP_SELL,LotsOptimized(),Bid,3,0,0,"starter",16384,0,Red);
}
}
// it is important to enter the market correctly,
// but it is more important to exit it correctly...
for(cnt=0;cnt<total;cnt++)
{
OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
if(OrderType()<=OP_SELL && // check for opened position
OrderSymbol()==Symbol()) // check for symbol
{
if(OrderType()==OP_BUY) // long position is opened
{
// should it be closed?
if(Laguerre>0.9)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
return(0); // exit
}
// check for stop
if(Stop>0)
{
if(Bid-OrderOpenPrice()>Point*Stop)
{
OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
return(0);
}
}
}
else // go to short position
{
// should it be closed?
if(Laguerre<0.1)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
return(0); // exit
}
// check for stop
if(Stop>0)
{
if(OrderOpenPrice()-Ask>Point*Stop)
{
OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
return(0);
}
}
}
}
}
return(0);
}
// the end.
Comments