StrategyQuant
Q AI AssistantAlgoCloudQuantAnalyzerQuantDataManager
Free CourseCompany
BlogDocumentationForumContact us
BlogMarketplace
Log in
Create free account

Product

  • Pricing & licenses
  • Learn
  • Marketplace
  • Start free trial

Legal

  • Terms of Service
  • Privacy Policy
  • Cookies

Contact

[email protected]

Company

StrategyQuant s.r.o.

Korunní 2569/108, Vinohrady, 101 00 Praha 10, Czech Republic, EU

IČ: 04000498

DIČ: CZ04000498

Social

  • Legal Notice | PROCESSING AND PROTECTION OF PERSONAL DATA

    Past performance is no guarantee of future success. All information should be viewed as educational only

    UNITED STATES Disclaimer required by Government - Commodity Futures Trading Commission informs: Futures and options trading have great potential rewards, but also great potential risk. You must be aware of the risks and be willing to accept them in order to invest in the futures and options markets. Don't trade with money you can't afford to lose. This is neither a solicitation nor an offer to buy/sell futures, shares or options on the same. No representation is being made that any account will or is likely to realise profits or losses similar to those discussed in this document. The past performance of any trading system or methodology is not necessarily indicative of future results.

    CFTC RULE 4.41 - HYPOTHETICAL OR SIMULATED PERFORMANCE RESULTS HAVE CERTAIN LIMITATIONS. UNLIKE A RECORD OF ACTUAL PERFORMANCE, SIMULATED RESULTS DO NOT REPRESENT ACTUAL TRADING. ALSO, SINCE THE TRADES WERE NOT EXECUTED, THE RESULTS MAY HAVE OFFSET THE IMPACT, IF ANY, OF CERTAIN MARKET FACTORS, SUCH AS LACK OF LIQUIDITY. SIMULATED TRADING PROGRAMMES IN GENERAL ARE ALSO SUBJECT TO THE FACT THAT THEY ARE DESIGNED WITH THE BENEFIT OF HINDSIGHT. NO REPRESENTATION IS BEING MADE THAT ANY ACCOUNT WILL OR IS LIKELY TO REALISE PROFITS OR LOSSES SIMILAR TO THOSE SHOWN.

    NO REPRESENTATION IS BEING MADE THAT ANY ACCOUNT WILL, OR IS LIKELY TO, REALISE PROFITS OR LOSSES SIMILAR TO THOSE DISCUSSED WITHIN THIS SITE. IF YOU DECIDE TO INVEST REAL MONEY, ALL TRADING DECISIONS IN THE FINANCIAL MARKETS SHOULD BE YOUR OWN.

    © StrategyQuant 2026

    Powered by Klaudie.ai

    Back to marketplaceDIGITAL

    Biggest MAE on multiple trades

    StrategyQuantPlugins
    Biggest MAE on multiple trades

    Calculates the worst combined maximum adverse excursion when multiple positions are open at the same time, helping you quantify drawdowns in basket entry strategies.

    Biggest MAE - useful for analyzing strategies with single or multiple orders.


    Multiple Orders vs Single Order

    It is more efficient to spread risk across a basket of orders rather than a single order. Multiple entry positions provide more flexibility without requiring precise single-entry positioning.

    When opening multiple orders simultaneously in the same direction, calculate the total MAE of all open positions. If positions are in opposite directions (hedging), subtract the MFE of opposite positions from the larger MAE to get the global MAE.


    Four Snippets

    BiggestMAEallTrade - Biggest MAE for one contract, normalized per contract for accurate results even if strategy increases contract size during backtesting.

    package SQ.Columns.Databanks;
    import com.strategyquant.lib.L;
    import com.strategyquant.lib.SQUtils;
    import com.strategyquant.lib.SettingsMap;
    import com.strategyquant.tradinglib.*;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.*;
    import java.lang.*;  
    // Mode in France by Emmanuel Evrard for the StrategyQuantX Community :)
    public class BiggestMAEallTrade extends DatabankColumn 
    {
        public BiggestMAEallTrade() 
        {
            super(L.tsq("Biggest Multiple MAE"), DatabankColumn.Decimal2PL, ValueTypes.Minimize, 0, 0, 100);
            setWidth(140);
            setTooltip(L.tsq("Biggest Multiple MAE - is the worst Maximum Adverse Excursion of all trades open at once"));
        }
        //------------------------------------------------------------------------
        @Override
        public double compute(SQStats stats, StatsTypeCombination combination, OrdersList ordersList, SettingsMap settings, SQStats statsLong, SQStats statsShort) throws Exception 
        {
            double worstMAE = -Double.MAX_VALUE;
            Date date = new Date();
            Date dateTemp = new Date();
            double Total1 = 0;
            double Size1 = 0;
            for(int i = 0; i<ordersList.size(); i++) 
            {
                Order order = ordersList.get(i);
                dateTemp = new Date(order.CloseTime);
                Size1 = order.Size;
                if (Size1 == 0) { Size1 = 0.01; }
                if (dateTemp.equals(date))
                {
                    Total1 += order.MAE;
                }
                else
                {
                    date = new Date(order.CloseTime);
                    Total1 = order.MAE;
                }
                if((Total1 / Size1)  > worstMAE) 
                {
                    worstMAE = (Total1/order.Size);
                }
            }
            return -1*worstMAE;
        }
    }
    

    BiggestMAEallTradePct - Biggest MAE as percentage of account balance. Shows if strategy uses adequate risk relative to account (e.g., comparing against 5% max daily loss).

    package SQ.Columns.Databanks;
    import com.strategyquant.lib.L;
    import com.strategyquant.lib.SQUtils;
    import com.strategyquant.lib.SettingsMap;
    import com.strategyquant.tradinglib.*;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.*;
    import java.lang.*;  
    // Mode in France by Emmanuel Evrard for the StrategyQuantX Community :)
    public class BiggestMAEallTradePct extends DatabankColumn 
    {
        public BiggestMAEallTradePct() 
        {
            super(L.tsq("Biggest Multiple MAE %"), DatabankColumn.Decimal2Pct, ValueTypes.Minimize, 0, 0, 100);
            setWidth(70);
            setTooltip(L.tsq("Biggest Multiple MAE % - is the worst Maximum Adverse Excursion of all trades open at once compared to AccountBalance"));
        }
        @Override
        public double compute(SQStats stats, StatsTypeCombination combination, OrdersList ordersList, SettingsMap settings, SQStats statsLong, SQStats statsShort) throws Exception 
        {
            double worstMAE = -Double.MAX_VALUE;
            Date date = new Date();
            Date dateTemp = new Date();
            double Total1 = 0;
            double Total2 = 0;
            for(int i = 0; i<ordersList.size(); i++) 
            {
                Order order = ordersList.get(i);
                dateTemp = new Date(order.CloseTime);
                if (dateTemp.equals(date))
                {
                    Total1 += order.MAE;
                }
                else
                {
                    date = new Date(order.CloseTime);
                    Total1 = order.MAE;
                }
                Total2 = SQUtils.safeDivide(Total1, order.AccountBalance - order.PL) * 100.0;
                if(Total2  > worstMAE) 
                {
                    worstMAE = Total2;
                }
            }
            return -1*worstMAE;
        }
    }
    

    BiggestMAEallHedgingTrade & BiggestMAEallHedgingTradePct - For hedged positions in opposite directions. Takes larger MAE and subtracts opposite direction MFE. Works when opposite trades are open during the larger MAE.

    package SQ.Columns.Databanks;
    import com.strategyquant.lib.L;
    import com.strategyquant.lib.SQUtils;
    import com.strategyquant.lib.SettingsMap;
    import com.strategyquant.tradinglib.*;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.*;
    import java.lang.*;  
    // Mode in France by Emmanuel Evrard for the StrategyQuantX Community :)
    public class BiggestMAEallHedgingTrade extends DatabankColumn 
    {
        public BiggestMAEallHedgingTrade() 
        {
            super(L.tsq("Biggest Multiple Hedging MAE"), DatabankColumn.Decimal2PL, ValueTypes.Minimize, 0, 0, 100);
            setWidth(140);
            setTooltip(L.tsq("Biggest Multiple Hedging MAE - is the worst Maximum Adverse Excursion of all trades open at once"));
        }
        //------------------------------------------------------------------------
        @Override
        public double compute(SQStats stats, StatsTypeCombination combination, OrdersList ordersList, SettingsMap settings, SQStats statsLong, SQStats statsShort) throws Exception 
        {
            double worstMAE1= -Double.MAX_VALUE;
            double worstMAE2 = -Double.MAX_VALUE;
            double BesttMFE1= -Double.MAX_VALUE;
            Date date = new Date();
            Date dateTemp = new Date();
            double Total1 = 0;
            double Size1 = 0;
            int direction = 0;
            for(int i = 0; i < ordersList.size(); i++) 
            {
                Order order = ordersList.get(i);
                dateTemp = new Date(order.CloseTime);
                Size1 = order.Size;
                direction=order.getDirection();
                if (direction == 1)     								// Bullish positions
                {
                    if (Size1 == 0) { Size1 = 0.01; }
                    if (dateTemp.equals(date))
                    {
                        Total1 += order.MAE;
                    }
                    else
                    {
                        date = new Date(order.CloseTime);
                        Total1 = order.MAE;
                    }
                    if((Total1 / Size1)  > worstMAE1) 
                    {
                        worstMAE1 = (Total1/order.Size);
                    }
                }
            }
            Total1 = 0;
            for(int i = 0; i < ordersList.size(); i++) 
            {
                Order order = ordersList.get(i);
                dateTemp = new Date(order.CloseTime);
                Size1 = order.Size;
                direction=order.getDirection();
                if (direction == -1)     								// Bearish positions
                {
                    if (Size1 == 0) { Size1 = 0.01; }
                    if (dateTemp.equals(date))
                    {
                        Total1 += order.MAE;
                    }
                    else
                    {
                        date = new Date(order.CloseTime);
                        Total1 = order.MAE;
                    }
                    if((Total1 / Size1)  > worstMAE2) 
                    {
                        worstMAE2 = (Total1/order.Size);
                    }
                }
            }
            if (worstMAE1 >= worstMAE2)
            {
                Total1 = 0;
                for(int i = 0; i < ordersList.size(); i++) 
                {
                    Order order = ordersList.get(i);
                    dateTemp = new Date(order.CloseTime);
                    Size1 = order.Size;
                    direction=order.getDirection();
                    if (direction == -1)     								// Bearish positions
                    {
                        if (Size1 == 0) { Size1 = 0.01; }
                        if (dateTemp.equals(date))
                        {
                            Total1 += order.MFE;
                        }
                        else
                        {
                            date = new Date(order.CloseTime);
                            Total1 = order.MFE;
                        }
                        if((Total1 / Size1)  > BesttMFE1) 
                        {
                            BesttMFE1 = (Total1/order.Size);
                        }
                    }
                }
                return -1*(worstMAE1 - BesttMFE1);
            }
            else if (worstMAE2 > worstMAE1)
            {
                Total1 = 0;
                for(int i = 0; i < ordersList.size(); i++) 
                {
                    Order order = ordersList.get(i);
                    dateTemp = new Date(order.CloseTime);
                    Size1 = order.Size;
                    direction=order.getDirection();
                    if (direction == 1)     								// Bullish positions
                    {
                        if (Size1 == 0) { Size1 = 0.01; }
                        if (dateTemp.equals(date))
                        {
                            Total1 += order.MFE;
                        }
                        else
                        {
                            date = new Date(order.CloseTime);
                            Total1 = order.MFE;
                        }
                        if((Total1 / Size1)  > BesttMFE1) 
                        {
                            BesttMFE1 = (Total1/order.Size);
                        }
                    }
                }
                return -1*(worstMAE2 - BesttMFE1);
            }
            return 0;
        }
    }
    
    package SQ.Columns.Databanks;
    import com.strategyquant.lib.L;
    import com.strategyquant.lib.SQUtils;
    import com.strategyquant.lib.SettingsMap;
    import com.strategyquant.tradinglib.*;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.*;
    import java.lang.*;  
    // Mode in France by Emmanuel Evrard for the StrategyQuantX Community :)
    public class BiggestMAEallHedgingTradePct extends DatabankColumn 
    {
        public BiggestMAEallHedgingTradePct() 
        {
            super(L.tsq("Biggest Multiple Hedging MAE %"), DatabankColumn.Decimal2Pct, ValueTypes.Minimize, 0, 0, 100);
            setWidth(100);
            setTooltip(L.tsq("Biggest Multiple Hedging MAE % - is the worst Maximum Adverse Excursion of all trades open at once compared to AccountBalance"));
        }
        @Override
        public double compute(SQStats stats, StatsTypeCombination combination, OrdersList ordersList, SettingsMap settings, SQStats statsLong, SQStats statsShort) throws Exception 
        {
            double worstMAE1= -Double.MAX_VALUE;
            double worstMAE2 = -Double.MAX_VALUE;
            double BesttMFE1= -Double.MAX_VALUE;
            Date date = new Date();
            Date dateTemp = new Date();
            double Total1 = 0;
            double Total2 = 0;
            int direction = 0;
            for(int i = 0; i<ordersList.size(); i++) 
            {
                Order order = ordersList.get(i);
                dateTemp = new Date(order.CloseTime);
                direction=order.getDirection();
                if (direction == 1)      								// Bullish position
                {
                    if (dateTemp.equals(date))
                    {
                        Total1 += order.MAE;
                    }
                    else
                    {
                        date = new Date(order.CloseTime);
                        Total1 = order.MAE;
                    }
                    Total2 = SQUtils.safeDivide(Total1, order.AccountBalance - order.PL) * 100.0;
                    if(Total2  > worstMAE1) 
                    {
                        worstMAE1 = Total2;
                    }
                }
            }
            Total1 = 0;
            for(int i = 0; i<ordersList.size(); i++) 
            {
                Order order = ordersList.get(i);
                dateTemp = new Date(order.CloseTime);
                direction=order.getDirection();
                if (direction == -1)      								// Bearish position
                {
                    if (dateTemp.equals(date))
                    {
                        Total1 += order.MAE;
                    }
                    else
                    {
                        date = new Date(order.CloseTime);
                        Total1 = order.MAE;
                    }
                    Total2 = SQUtils.safeDivide(Total1, order.AccountBalance - order.PL) * 100.0;
                    if(Total2  > worstMAE2) 
                    {
                        worstMAE2 = Total2;
                    }
                }
            }
            if (worstMAE1 >= worstMAE2)
            {
                Total1 = 0;
                for(int i = 0; i<ordersList.size(); i++) 
                {
                    Order order = ordersList.get(i);
                    dateTemp = new Date(order.CloseTime);
                    direction=order.getDirection();
                    if (direction == -1)      								// Bearish position
                    {
                        if (dateTemp.equals(date))
                        {
                            Total1 += order.MFE;
                        }
                        else
                        {
                            date = new Date(order.CloseTime);
                            Total1 = order.MFE;
                        }
                        Total2 = SQUtils.safeDivide(Total1, order.AccountBalance - order.PL) * 100.0;
                        if(Total2  > BesttMFE1) 
                        {
                            BesttMFE1 = Total2;
                        }
                    }
                }
                return -1*(worstMAE1 - BesttMFE1);
            }
            else if (worstMAE2 > worstMAE1)
            {
                Total1 = 0;
                for(int i = 0; i<ordersList.size(); i++) 
                {
                    Order order = ordersList.get(i);
                    dateTemp = new Date(order.CloseTime);
                    direction=order.getDirection();
                    if (direction == 1)      								// Bullish position
                    {
                        if (dateTemp.equals(date))
                        {
                            Total1 += order.MFE;
                        }
                        else
                        {
                            date = new Date(order.CloseTime);
                            Total1 = order.MFE;
                        }
                        Total2 = SQUtils.safeDivide(Total1, order.AccountBalance - order.PL) * 100.0;
                        if(Total2  > BesttMFE1) 
                        {
                            BesttMFE1 = Total2;
                        }
                    }
                }
                return -1*(worstMAE2 - BesttMFE1);
            }
            return 0;
        }
    }
    
    Past performance is no guarantee of future success. All information should be viewed as educational only UNITED STATES Disclaimer required by Government - Commodity Futures Trading Commission informs: Futures and options trading have great potential rewards, but also great potential risk. You must be aware of the risks and be willing to accept them in order to invest in the futures and options markets. Don't trade with money you can't afford to lose. This is neither a solicitation nor an offer to buy/sell futures, shares or options on the same. No representation is being made that any account will or is likely to realise profits or losses similar to those discussed in this document. The past performance of any trading system or methodology is not necessarily indicative of future results. CFTC RULE 4.41 - HYPOTHETICAL OR SIMULATED PERFORMANCE RESULTS HAVE CERTAIN LIMITATIONS. UNLIKE A RECORD OF ACTUAL PERFORMANCE, SIMULATED RESULTS DO NOT REPRESENT ACTUAL TRADING. ALSO, SINCE THE TRADES WERE NOT EXECUTED, THE RESULTS MAY HAVE OFFSET THE IMPACT, IF ANY, OF CERTAIN MARKET FACTORS, SUCH AS LACK OF LIQUIDITY. SIMULATED TRADING PROGRAMMES IN GENERAL ARE ALSO SUBJECT TO THE FACT THAT THEY ARE DESIGNED WITH THE BENEFIT OF HINDSIGHT. NO REPRESENTATION IS BEING MADE THAT ANY ACCOUNT WILL OR IS LIKELY TO REALISE PROFITS OR LOSSES SIMILAR TO THOSE SHOWN. NO REPRESENTATION IS BEING MADE THAT ANY ACCOUNT WILL, OR IS LIKELY TO, REALISE PROFITS OR LOSSES SIMILAR TO THOSE DISCUSSED WITHIN THIS SITE. IF YOU DECIDE TO INVEST REAL MONEY, ALL TRADING DECISIONS IN THE FINANCIAL MARKETS SHOULD BE YOUR OWN.
    Free

    Files

    • Snippet-BiggestMAEonmultipletrades.sqm14 KBLocked

    Download unlocks after purchase or with an active tier.

    Details
    Version1.0.0
    PublishedOctober 19, 2026
    Last updatedNovember 2, 2026
    AppSQ
    TypeSnippet
    AuthorEmmanuel
    App version145.3058
    Codebase categoryDatabank / Filter