Okay, when I run this script over 2020 YTD with EOD t6 data, we get some weirdness starting in March. findCall() and findPut() are failing to find a contract. The code may have a bug in how it selects the option.

Code
CONTRACT* findCall(int Expiry,var Premium)
{
	for(i=0; i<50; i++) {
		if(!contract(CALL,Expiry,Price+0.5*i)) return 0;
		if(between(ContractBid,0.1,Premium)) return ThisContract;
	}
	return 0;
}

This call exits when contract(CALL,Expiry,Price+0.5*i) fails instead of searching through the remaining strike prices.

I tried contractFind() though I have a similar issue with not finding contracts after 02-24. Here is the script with my debug printfs.

Code
// OptionsSimple.c

// Quite simple options trading system 
// WITHOUT ROLL 

// https://financial-hacker.com/algorithmic-options-trading-part-3/


// Even simpler options trading system 
#include <contract.c>

#define EXPIRY_DAYS	2		// default 6*7
#define PREMIUM		2.0		// default 2.0

int i;
var Price;

CONTRACT* findCall(int Expiry,var Premium)
{
	for(i=0; i<100; i++) {
		if(!contractFind(CALL,Expiry,Price+1.0*i,2,Price,Price+50))
		{
			printf("\nbeo: !contractFind(CALL,... Strike=%.02f,2,...) Premium %.02f.", Price-1.0*i, Premium);
			return 0;
		}
		if(between(ContractBid,0.1,Premium))
		{
			printf("\nbeo: between(ContractBid %.02f,0.1,Premium %.02f)", ContractBid, Premium);
			return ThisContract;
		}
	}
	return 0;
}

CONTRACT* findPut(int Expiry,var Premium)
{
	for(i=0; i<100; i++) {
		if(!contractFind(PUT,Expiry,Price-1.0*i,2,Price-50, Price)) 
		{
			printf("\nbeo: !contractFind(PUT,... Strike=%.02f,2,...) Premium %.02f.", Price-1.0*i, Premium);
			return 0;
		}
		if(between(ContractBid,0.1,Premium)) 
		{
			printf("\nbeo: between(ContractBid %.02f,0.1,Premium %.02f)", ContractBid, Premium);
			return ThisContract;
		}
	}
	return 0;
}

void run() 
{
	StartDate = 20200101;
	EndDate = 20200403;
	BarPeriod = 1440;
	BarZone = ET;
	BarOffset = 15*60+20; // trade at 15:20 ET
	LookBack = 1;
	set(PLOTNOW);
	set(PRELOAD|LOGFILE);

	assetList("AssetsIB");
	asset("SPY"); // unadjusted!
	Multiplier = 100;

// load today's contract chain
	Price = priceClose();
	contractUpdate("SPY",0,CALL|PUT);

// all expired? enter new options
	if(!NumOpenShort) { 
		CONTRACT *Call = findCall(EXPIRY_DAYS,PREMIUM); 
		CONTRACT *Put = findPut(EXPIRY_DAYS,PREMIUM); 		
		if(Call && Put) {
			MarginCost = 0.5*(0.15*Price-min(Call->fStrike-Price,Price-Put->fStrike));
			contract(Call); enterShort();
			contract(Put); enterShort();
		}
		else if (Call)
		{
			printf("\nbeo: found Call, no Put. %.02fC for %.02f$\n", Call->fStrike, Price);
		}
		else if (Put)
		{
			printf("\nbeo: found Put, no Call. %.02fC for %.02f$\n", Put->fStrike, Price);
		}
		else
		{
			printf("\nbeo: no call or put. Price %.02f$\n", Price);
		}
	}
	else
	{
		// printf("\nbeo: NumOpenShort does not exist. Price %.02f$\n", Price);
	}
}