You can use aggregate functions in ORDER BY:
SELECT shops.id AS shopid -- No need to use MAX(...) here
FROM shops
LEFT JOIN expiration ON shops.id=expiration.shopid
GROUP BY shopid
ORDER BY
MAX(shops.grade) DESC,
MIN(expiration.startdate) ASC,
MAX(expiration.enddate) DESC,
shops.id