FarhadCrab6-mini
Download scriptProfessional Logic Overview: FarhadCrab6
This document provides a non-technical explanation of the automated trading logic contained within the FarhadCrab6 script. The script is designed to manage trades automatically by monitoring market trends, price levels, and specific mathematical indicators.
1. Risk Management & Safety Mechanisms
The script includes several "safety valves" designed to protect the account from significant losses:
- Profit and Loss Limits: It monitors the account's total equity against the initial deposit. If the account reaches a pre-defined profit target (Maximum Yield) or suffers a specific percentage of loss (Maximum Loss), the script is programmed to automatically close all open positions.
- Margin Monitoring: Before opening any new trades, the script checks if there is enough "Free Margin" (available funds). If the account lacks sufficient funds, it will halt trading to prevent errors.
- Trailing Stops: For active trades, the script uses a "Trailing Stop" mechanism. This means that as a trade moves into profit, the stop-loss level moves forward automatically to "lock in" some of those gains while allowing the trade room to continue growing.
2. Market Analysis Logic
The script evaluates the market using three primary layers of analysis:
- Trend Identification: It uses a Long-Term Moving Average (MA) to determine the general direction of the price. If the price is above this average, it views the market as an uptrend; if below, it views it as a downtrend.
- Overbought/Oversold Detection: The script looks for "exhaustion" points—situations where the price has moved too far in one direction and might be due for a reversal. It uses two specific indicators (DeMarker and RSI) to identify these zones.
- Volatility Context: It monitors market volatility (via an ADX indicator). Depending on whether the market is trending strongly or moving sideways, it adjusts how much profit it aims to capture.
3. Trading Strategy Execution
The script follows a structured set of rules to enter and manage trades:
Entry Rules (Buy/Sell)
- Standard Entries: A Buy signal is generated when specific indicators suggest the market is "oversold" (the price has dropped too far), while a Sell signal appears when the market is "overbought."
- Hedge Logic: The script contains specialized logic to open "Hedge" positions. This occurs when it detects a specific trend reversal or a discrepancy in price movement, allowing it to balance open positions with new ones in the opposite direction.
Dynamic Lot Sizing
Rather than always trading the same amount, the script calculates the size of each trade (Lot Size) based on the current account balance. It dynamically adjusts these sizes to ensure that the volume of trades remains proportional to the available capital.
Take Profit & Stop Loss Logic
- Variable Targets: The goal for profit varies based on market conditions. In stable, trending markets, it seeks a standard target; in "sideways" (choppy) markets, it switches to a different profit goal (the
prvalue). - Automated Adjustments: While the user can set a hard Stop Loss, the script primarily relies on its Trailing Stop and Take Profit logic to manage the lifecycle of a trade from entry to exit.
//+------------------------------------------------------------------+
//| FarhadCrab6.mq4 |
//| Copyright © 2007, Farhad Farshad |
//| http://www.fxperz.com
//| farhadfarshad11@yahoo.com
//| ***** PLEASE NOTE *****
//| This EA best works on EURUSD 1M TimeFrame.
//| If you get money from this EA please donate some to poor people of your country.
//+-----------------------------------------------------------------+
#property copyright "Copyright © 2007, Farhad Farshad"
#property link "http://www.fxperz.com"
#include <stdlib.mqh>
extern double maxLoss = 100; // Maximum Loss that you can bear in percent
extern double maxYield = 0.1; // a number between 0 to 100 (not more than 10 is recommended)
extern double lTakeProfit = 300; // recomended no more than 20
extern double sTakeProfit = 300; // recomended no more than 20
extern double takeProfit = 300; // recomended no more than 20
extern double pr = 300; //take profit in sideway markets.
extern double stopLoss = 0; //
extern int magicEA = 124; // Magic EA identifier. Allows for several co-existing EA with different input values
extern double lTrailingStop = 15; // trail stop in points
extern double sTrailingStop = 15; // trail stop in points
extern color clOpenBuy = Blue; //Different colors for different positions
extern color clCloseBuy = Aqua; //Different colors for different positions
extern color clOpenSell = Red; //Different colors for different positions
extern color clCloseSell = Violet; //Different colors for different positions
extern color clModiBuy = Blue; //Different colors for different positions
extern color clModiSell = Red; //Different colors for different positions
extern int Slippage = 3;
extern string nameEA = "FarhadCrab6.mq4";// To "easy read" which EA place an specific order and remember me forever :)
double maLongCurrent, maShortCurrent, maLongPrevious, maShortPrevious, faRSICurrent, deMark;
double realTP, realSL, faMiddle, faHighest, faLowest, closeCurrent,faCloseM5, closeCurrentD, closePreviousD;
int cnt, ticket;
bool isBuying = false, isSelling = false, isBuyClosing = false, isSellClosing = false;
double initialDeposit; //First of All Specify your initial Deposit.
double lLots , sLots;// you can change the lot but be aware of margin. Its better to trade with 1/4 of your capital.
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start() {
/*
*/
initialDeposit=AccountBalance();
//System Stoploss based on LongTerm Moving Average (Fibo 55 day MA)
//StopLoss For Buy Positions (Optional)
//if ((maLongCurrent>closeCurrentD) && (maLongPrevious<closePreviousD) && (maLongCurrent>highCurrentH1)) {
if ((AccountEquity()>(initialDeposit+((maxYield/100)*initialDeposit)))
|| (AccountBalance()-AccountEquity()>((maxLoss/100)*initialDeposit))
//|| ((maLongCurrent>closeCurrentD) && (maLongPrevious<closePreviousD) && (maLongCurrent>highCurrentH1))
){
CloseBuyPositions();
//return(0);
}
//StopLoss For Sell Positions (Optional)
//if ((maLongCurrent<closeCurrentD) && (maLongPrevious>closePreviousD) && (maLongCurrent<lowCurrentH1)) {
if ((AccountEquity()>(initialDeposit+((maxYield/100)*initialDeposit)))
|| (AccountBalance()-AccountEquity()>((maxLoss/100)*initialDeposit))
//|| ((maLongCurrent<closeCurrentD) && (maLongPrevious>closePreviousD) && (maLongCurrent<lowCurrentH1))
){
CloseSellPositions();
return(0);
}
double overbought,oversold;
if (maLongCurrent>closeCurrentD) //downtrend
{
oversold = 0.15;
overbought = 0.85;
}
if (maLongCurrent<closeCurrentD) //uptrend
{
oversold = 0.15;
overbought = 0.85;
}
// Check for invalid bars and takeprofit
if(Bars < 200) {
Print("Not enough bars for this strategy - ", nameEA);
return(0);
}
calculateIndicators(); // Calculate indicators' value
//Check for TakeProfit Conditions
if(lTakeProfit<1){
Print("TakeProfit less than 1 on this EA with Magic -", magicEA );
return(0);
}
if(sTakeProfit<1){
Print("TakeProfit less than 1 on this EA with Magic -", magicEA);
return(0);
}
//Introducing new expressions
double deMark = iDeMarker(NULL,PERIOD_M1,9,0);
double previousdeMark = iDeMarker(NULL,PERIOD_M1,9,1);
double rsi = iRSI(NULL,PERIOD_M1,9,PRICE_CLOSE,0);
double n;
if ((AccountEquity()-AccountBalance()==0) || (AccountEquity()-AccountBalance()>-((OrderLots())*500)))
n = 0;
else
n = 1;
if (OrdersTotal()>n)
{
return(0);
}
int bnt;
for(bnt=0;bnt<OrdersTotal();bnt++)
{
OrderSelect (bnt, SELECT_BY_POS);
if (TimeCurrent()-OrderOpenTime()<500) {
//if((OrdersTotal()>1)){
return(0);
}
}
//Check Margin Requirement
if(AccountFreeMargin()<0){
Print("We have no money. Free Margin = ", AccountFreeMargin());
return(0);
}
//Buy Condition
if ((!takeBuyPositions()) && (n == 0) ){
if (
(deMark<oversold)
//&& (previousdeMark < deMark)
&& (rsi < 30)
// && ((maLongCurrent<closeCurrentD))
)
{
OpenBuy();
return(0);
}
}
if ((!takeBuyPositions()) && (n == 1) ){
if (
(deMark<0.30)
&& (previousdeMark < deMark)
&& (OrderType()==OP_SELL)
)
{
hedgeOpenBuy();
return(0);
}
}
//Sell Condition
if ((!takeSellPositions()) && (n == 0)){
if (
(deMark>overbought)
//&& (previousdeMark > deMark)
&& (rsi > 70)
// && ((maLongCurrent>closeCurrentD))
)
{
OpenSell();
return(0);
}
}
if ((!takeSellPositions()) && (n == 1)){
if (
(deMark>0.70)
&& (previousdeMark > deMark)
&& (OrderType()==OP_BUY)
)
{
hedgeOpenSell();
return(0);
}
}
//Trailing Expressions
TrailingPositionsBuy(lTrailingStop);
TrailingPositionsSell(sTrailingStop);
return (0);
}
//Number of Buy Positions
bool takeBuyPositions() {
for (int i=0; i<OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==Symbol() && OrderMagicNumber() == magicEA) {
return(0);
}
}
}
return(0);
}
//Number of Sell Positions
bool takeSellPositions() {
for (int i=0; i<OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==Symbol() && OrderMagicNumber() == magicEA) {
return(0);
}
}
}
return(0);
}
void TrailingPositionsBuy(int trailingStop) {
for (int i=0; i<OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==Symbol() && OrderMagicNumber() == magicEA) {
if (OrderType()==OP_BUY) {
if (Bid-OrderOpenPrice()>trailingStop*Point) {
if (OrderStopLoss()<Bid-trailingStop*Point)
ModifyStopLoss(Bid-trailingStop*Point);
}
}
}
}
}
}
void TrailingPositionsSell(int trailingStop) {
for (int i=0; i<OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==Symbol() && OrderMagicNumber() == magicEA) {
if (OrderType()==OP_SELL) {
if (OrderOpenPrice()-Ask>trailingStop*Point) {
if (OrderStopLoss()>Ask+trailingStop*Point ||
OrderStopLoss()==0)
ModifyStopLoss(Ask+trailingStop*Point);
}
}
}
}
}
}
void ModifyStopLoss(double ldStopLoss) {
bool fm;
fm = OrderModify(OrderTicket(),OrderOpenPrice
(),ldStopLoss,OrderTakeProfit(),0,CLR_NONE);
}
void OpenBuy() {
double ldLot, ldStop, ldTake;
string lsComm;
ldLot = GetSizeLot();
ldStop = GetStopLossBuy();
ldTake = GetTakeProfitBuy();
lsComm = GetCommentForOrder();
if ((AccountEquity()-AccountBalance()==0) || (AccountEquity()-AccountBalance()>-((OrderLots())*500)))
lLots = NormalizeDouble((MathRound((AccountBalance()-500)/1000)/10),1)/10;
else
lLots = NormalizeDouble((MathRound((AccountBalance()-500)/1000)/5),1)/10;
OrderSend(Symbol(),OP_BUY,lLots,Ask,Slippage,ldStop,ldTake,nameEA,magicEA,0,clOpenBuy);
}
void OpenSell() {
double ldLot, ldStop, ldTake;
string lsComm;
ldLot = GetSizeLot();
ldStop = GetStopLossSell();
ldTake = GetTakeProfitSell();
lsComm = GetCommentForOrder();
if ((AccountEquity()-AccountBalance()==0) || (AccountEquity()-AccountBalance()>-((OrderLots())*500)))
sLots = NormalizeDouble((MathRound((AccountBalance()-500)/1000)/10),1)/10;
else
sLots = NormalizeDouble((MathRound((AccountBalance()-500)/1000)/5),1)/10;
OrderSend(Symbol(),OP_SELL,sLots,Bid,Slippage,ldStop,ldTake,nameEA,magicEA,0,clOpenSell);
}
void hedgeOpenBuy() {
double ldLot, ldStop, ldTake;
string lsComm;
ldLot = GetSizeLot();
ldStop = GetStopLossBuy();
ldTake = GetTakeProfitBuy();
lsComm = GetCommentForOrder();
//if ((AccountEquity()-AccountBalance()==0) || (AccountEquity()-AccountBalance()>-(MathSqrt(OrderLots())*500)))
//lLots = 0.2; //MathRound(AccountBalance()/4000);
//else
lLots = NormalizeDouble((MathRound((AccountBalance()-500)/1000)/5),1)/10;
OrderSend(Symbol(),OP_BUY,lLots,Ask,Slippage,Ask-60*Point,ldTake,nameEA,magicEA,0,clOpenBuy);
}
void hedgeOpenSell() {
double ldLot, ldStop, ldTake;
string lsComm;
ldLot = GetSizeLot();
ldStop = GetStopLossSell();
ldTake = GetTakeProfitSell();
lsComm = GetCommentForOrder();
// if ((AccountEquity()-AccountBalance()==0) || (AccountEquity()-AccountBalance()>-(MathSqrt(OrderLots())*500)))
//sLots = 0.2; //MathRound(AccountBalance()/4000);
// else
sLots = NormalizeDouble((MathRound((AccountBalance()-500)/1000)/5),1)/10;
OrderSend(Symbol(),OP_SELL,sLots,Bid,Slippage,Bid+60*Point,ldTake,nameEA,magicEA,0,clOpenSell);
}
string GetCommentForOrder() { return(nameEA); }
double GetSizeLot() { return(lLots); }
double GetTakeProfitBuy() { if (iADX(NULL,0,14,PRICE_MEDIAN,MODE_MAIN,0)<25) return(Ask+lTakeProfit*Point); else return(Ask+pr*Point); }
double GetTakeProfitSell() { if (iADX(NULL,0,14,PRICE_MEDIAN,MODE_MAIN,0)<25) return(Bid-sTakeProfit*Point); else return (Bid-pr*Point);}
double GetStopLossBuy() { if (stopLoss==0) return(0); else return(Ask - stopLoss*Point);}
double GetStopLossSell() { if (stopLoss==0) return(0); else return(Bid + stopLoss*Point);}
void calculateIndicators() {
// Calculate indicators' value
closeCurrentD = iClose(NULL,PERIOD_M1,0); //Close Price Current for D1 TimeFrame
closePreviousD = iClose(NULL,PERIOD_M1,1); //Close Price Previous for D1 TimeFrame
maLongCurrent = iMA(NULL,PERIOD_M1,55,1,MODE_SMMA,PRICE_TYPICAL,0); //Current Long Term Moving Average
maLongPrevious = iMA(NULL,PERIOD_M1,55,1,MODE_SMMA,PRICE_TYPICAL,1); //Previous Long Term Moving Average
// Check for BUY, SELL, and CLOSE signal
isBuying = false;
isSelling = false;
isBuyClosing = false;
isSellClosing = false;
}
void CloseBuyPositions(){
for (int i=0; i<OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==Symbol() && OrderMagicNumber() == magicEA) {
if (OrderType()==OP_BUY) OrderClose(OrderTicket(),lLots,Bid,Slippage);
}
}
}
}
void CloseSellPositions(){
for (int i=0; i<OrdersTotal(); i++) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderSymbol()==Symbol() && OrderMagicNumber() == magicEA) {
if (OrderType()==OP_SELL) OrderClose(OrderTicket(),sLots,Ask,Slippage);
}
}
}
}
Profitability Reports
Expected payoff
Average expected payoff across the available backtests for each symbol.
Comments