I have script to download daily data either from Yahoo Finance or other exchange website. This can be done with AmiQuote as well. After each update, I use this AFL script to scan for missing data.
// Must set range to "1 recent bar(s)"
// Scan latest date
EnableScript("JScript");
<%
function Scan_latest_date(){
AmiBroker = new ActiveXObject("Broker.Application");
var bar_count, stock_count, date_num, latest_date_num, latest_date_str, oDate;
stocks = AmiBroker.Stocks;
stock_count = stocks.Count;
latest_date_num = 20200101;
for (i=51; i<75; i++) {
stock_quote = stocks(i).Quotations;
bar_count = stock_quote.count;
oDate = new Date( stock_quote(bar_count-1).Date );
date_num = oDate.getFullYear()*10000 + (oDate.getMonth()+1)*100 + oDate.getDate();
if (date_num > latest_date_num) {
latest_date_num = date_num;
if ((oDate.getMonth()+1) < 10) {
mth_str = "0" + (oDate.getMonth()+1);
} else {
mth_str = (oDate.getMonth()+1);
}
if (Number(oDate.getDate()) < 10) {
day_str = "0" + oDate.getDate();
} else {
day_str = oDate.getDate();
}
latest_date_str = oDate.getFullYear() + "-" + mth_str + "-" + day_str;
}
}
return latest_date_str;
}
%>
if ( status("stocknum") == 0 ) { //Set the latest date for the first time in exploration
script = GetScriptObject();
latest_date_str = script.Scan_latest_date();
StaticVarSetText("missing_datetime",latest_date_str);
fh = fopen("C:\\Users\\....\\missing_data.txt", "w",shared=True); \\replace .... with your file output dir
} else {
fh = fopen("C:\\Users\\....\\missing_data.txt", "a",shared=True); \\replace .... with your file output dir
}
Sort_key = ParamList("Date Selection:","Auto Scan|Manual Input",defaultval=0);
yr = Param("Year",2021,2020,2030,1);
mth = Param("Month",1,1,12,1);
dy = Param("Day",1,1,31,1);
if (Sort_key == "Auto Scan") {
ymd = StaticVarGetText("missing_datetime");}
else {
ymd= NumToStr(yr,1.0,False) + "-" + NumToStr(mth,1.0) + "-" + NumToStr(dy,1.0); }
Date_time = DateTime();
Date_num = DateNum();
if (StrRight(Name(),2) == "_D") {
Filter = 0; // Skip ticker symbol with "_D"
if (fh) fclose(fh);
} else {
if (IsNull(Lookup(BarIndex(),_DT(ymd),0))) {
Filter = 1;
if (fh)
{
if (StrLeft(Name(),1) != "^") {
fputs( Name() + "\n" , fh );
}
fclose(fh);
}
else { //if fh is null, do fopen until fh is not null
do
fh = fopen("C:\\Users\\....\\missing_data.txt", "a",shared=True); \\replace .... with your file output dir
while (!fh);
if (StrLeft(Name(),1) != "^") {
fputs( Name() + "\n" , fh );
}
fclose(fh);
}
}
//if (Lookup(BarIndex(),_DT(ymd),0) == Null) Filter = 1; // This does not work. Why ?
else {
Filter = 0;
if (fh) fclose(fh);
}
}
SetOption("NoDefaultColumns",True);
AddTextColumn(Name(),"Ticker");
I use Nasdaq stock split to check for stock split.
Stock Splits Calendar | Nasdaq
For new tickers and delisted, I use this.
Stock Screener | Nasdaq
For delisted stocks, I add "_D" to the tickers as I notice after sometimes delisted tickers will be reused. Otherwise, it will mess up your database if you intend to keep delisted stocks in your database. If a ticker is having missing data, then it may not worth tracking as it is not worth investing.