4. 1. 2023

5 3

Return / Max Drawdown (Max Intraday Drawdown or Trade Drawdown)


Sometimes the calculated Drawdown does not reflect the Maximum Drawdown we could have and which would trigger a margin call. I get many strategies with great Ret/DD ratio. But when I look at the strategies I can see that some of them have much bigger Max Intraday Drawdown (= Maximum Adverse Excursion). See picture.
This new code chooses the greater Drawdown (Max Intraday Drawdown or Trade Drawdown).

I hope there are no mistakes !

package SQ.Columns.Databanks;

import com.strategyquant.lib.*;
import com.strategyquant.datalib.*;
import com.strategyquant.tradinglib.*;

//created by Fabien 17/12/2022

public class ProfitMaxDD extends DatabankColumn {
    
    public ProfitMaxDD() {
        super("Profit/MaxDD", 
          DatabankColumn.Decimal2, // value display format
          ValueTypes.Maximize, // whether value should be maximized / minimized / approximated to a value   
          0, // target value if approximation was chosen  
          0, // average minimum of this value
          100); // average maximum of this value
        
    setWidth(80); // defaultcolumn width in pixels
    
        setTooltip("NetProfit/ Max Intraday or Trade DD Ratio");  
    setDependencies("NetProfit", "MaxIntradayDrawdown", "Drawdown");
    /* If this new column is dependent on some other columns that have to vbe computed first, put them here.
       Make sure you don't creat circular dependency, such as A depends on B and B depends on A.
       Columns (=stats values) are identified by the name of class)
    */
    //setDependencies("DrawdownPct", "NumberOfTrades");
    }
  
  //------------------------------------------------------------------------


    @Override
    public double compute(SQStats stats, StatsTypeCombination combination, OrdersList ordersList, SettingsMap settings, SQStats statsLong, SQStats statsShort) throws Exception {
    
    double netProfit = stats.getDouble("NetProfit");
    double maxIntradayDrawdown = stats.getDouble("MaxIntradayDrawdown");
    double DD = Math.abs(stats.getDouble("Drawdown"));
    double MaxDD = Math.max(maxIntradayDrawdown, DD);

        return round2( SQUtils.safeDivide(netProfit, MaxDD));
    }	
}

 

Subscribe
Notify of
3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Emmanuel
15. 1. 2023 8:57 am

Thank you Fabien !

Angel Talavera
24. 8. 2024 9:20 am

How can I know the maximum daily open loss of a system that could adapt this code?

Patrick Stettler
29. 4. 2025 9:49 pm

Thank you for this code, much appreciated.

I still struggle with the issue that Fabien described above. I get many great strategies with great Ret/DD ratios. But from a Maximum Adverse Execution MAE point of view many of them are useless (as margin calls would have killed the strategy).

Can the SQX-team please include MAE/MFE metrics in the Ranking filters?