Interesting question. Building on comments by glSglS It appears that HoldForm is treated specially by (conversion to) TraditionalForm, whereas a normal hold attribute does not prevent reordering. This is not exactly surprising considering that formatting rules do not directly respect hold attributes. (See Returning an unevaluated expression with values substituted inReturning an unevaluated expression with values substituted in)
Here is a concise example:
{HoldForm[b + a^2], Defer[b + a^2], HoldComplete[b + a^2]} // TraditionalForm Note that neither Defer nor HoldComplete prevent this reordering. So while MakeBoxes has HoldAllComplete this is insufficient to preserve order.
Further, Box form is itself vulnerable to reordering by TraditionalForm:
MakeBoxes[b + a^2] % // TraditionalForm // DisplayForm RowBox[{"b", "+", SuperscriptBox["a", "2"]}]
a^2 + b
Note that the RowBox is in the correct order but the second line still alters its order.
One finds that HoldForm becomes a TagBox upon box conversion. Interestingly it seems that an arbitrary TagBox also prevents this reordering:
TagBox[RowBox[{"b", "+", SuperscriptBox["a", "2"]}], foo] // TraditionalForm // DisplayForm b + a^2
MakeBoxes[Annotation[b + a^2]] % // TraditionalForm // DisplayForm TagBox[RowBox[{b, +, SuperscriptBox[a, 2]}], #1 &]
b + a^2
In any case it seems that including HoldForm is the simplest solution. Here is an alternative formulation using Collect for your consideration:
MakeBoxes[mypoly[poly_, var_], TraditionalForm] := ToBoxes @ Collect[poly, var, # &, HoldForm[+##] ~Reverse~ {2} &] 