Hello everyone,

I stumbled upon Concretum and their promised market beating strategy with a Sharpe Ratio of 1.33 and tried to recreate it on Zorro right away, however my results were vastly different.

I mostly used chat GPT to recreate it as well as some zorro functions that I know are needed but I am still not sure that it is coded properly to match the functions, including the VWAP which seems to be an aggregate of the whole daily price and volume. any code feedback would be highly appreciated, here's the link for their strategy if anyone is interested in seeing how it works Concretum Strategy

Code
 /// Concretum Intraday SPY strategy ///
/// Based on https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4824172 ///

var UpperBoundary;
var LowerBoundary;

function calculateNoiseArea() {
   int Lookback = 14;
   int i; 
   int BarsPerDay = 13; 
   var volatilityMultiplier = 1.; 
   var OpenPrice = priceOpen(0);
   var SumMove = 0;

   for(i = 1; i <= Lookback; i++) {
      var PreviousOpen = priceOpen(i * BarsPerDay); 
      var PreviousClose = priceClose(i * BarsPerDay - (BarsPerDay - 1)); 
      var Move = abs(PreviousClose / PreviousOpen - 1);
      SumMove += Move;
   }

   var AvgMove = SumMove / Lookback;

   UpperBoundary = OpenPrice * (1 + volatilityMultiplier * AvgMove);
   LowerBoundary = OpenPrice * (1 - volatilityMultiplier * AvgMove);

   var PreviousClose = priceClose(1); 
   if(OpenPrice > PreviousClose) {
      UpperBoundary += (OpenPrice - PreviousClose);
   } else {
      LowerBoundary -= (PreviousClose - OpenPrice);
   }
}

void run() {
   Verbose = 3;
   NumCores = -2; 
   set(PLOTNOW|LOGFILE|TESTNOW);
   setf(PlotMode, PL_DIFF);
   StartDate = 2011;
   EndDate = 2023;
   LookBack = 14 * 13 + 1;
   BarPeriod = 1;  
   // BarZone = EST;
   StartMarket = 0930;  // Start of market hours
   EndMarket = 1600;    // End of market hours
   Capital = Margin = 10000;
	BarMode = BR_NOSHIFT+BR_SLEEP; // Only calculate and trade during market hours 
   asset("SPY");
   MaxLong = MaxShort = -1;
   
   vars Prices = series(priceClose());
   vars Volumes = series(marketVol());
   var VWAP = VWAV(Prices, Volumes, 14); 

   calculateNoiseArea();

   if(crossOver(Prices, UpperBoundary))  
      enterLong();
   
   if(crossUnder(Prices, LowerBoundary)) 
      enterShort();
   
   if(TradeIsLong && (Prices[0] < UpperBoundary || crossUnder(Prices, VWAP)))
      exitLong();

   if(TradeIsShort && (Prices[0] > LowerBoundary || crossOver(Prices, VWAP)))
      exitShort();

   if(tod() == 1530){ 
      exitShort();
      exitLong();
   }

   // Plot the indicators
   plot("VWAP", VWAP, LINE, PURPLE);
   plot("Upper Boundary", UpperBoundary, LINE, BLUE);
   plot("Lower Boundary", LowerBoundary, LINE, YELLOW);
   plot("MarketVol", marketVol(), BARS|NEW, BLUE);
}

Attached Files
Last edited by juanex; 08/19/24 01:30.