Citation: 4A_54/2021 E. A

A.a. La société B.________ SA (ci-après: la banque, ou B.________), sise à... (VD), est active dans le trading en ligne; elle ne fournit aucun conseil en investissement, ni service de gestion de fortune. Cette banque permet à sa clientèle d'effectuer en ligne des transactions boursières ainsi que des opérations de négoce sur devises (transactions Forex). Pour ce faire, elle a sa propre plateforme informatique intitulée P.________. Le Forex est le marché sur lequel les devises convertibles sont échangées l'une contre l'autre à des taux de change variant en permanence. Il n'existe pas une place unique d'échange, si bien que le traitement d'une paire de devises donnée (par exemple la paire EUR/CHF) peut s'opérer de manière électronique sur la plateforme de tout acteur du marché offrant ce service. L'acteur en question examine les prix proposés par les fournisseurs de liquidités et choisit le taux qu'il entend proposer à ses clients. Le client décide sur cette base de passer un ordre d'achat ou de vente. Le prix auquel une paire de devises est échangée à un moment donné peut donc différer selon la plateforme utilisée. Les transactions Forex sont hautement spéculatives. La banque conseille à ses clients de réduire les risques de pertes en recourant notamment aux ordres " stop-loss ". Ce type d'ordre tend à l'achat ou à la vente de devises sitôt atteint le taux spécifié par le client (cf. au surplus consid. 5.3). A.b. Le 6 septembre 2011, la Banque Nationale Suisse (ci-après: la BNS) a instauré un taux plancher de CHF 1.20 pour EUR 1.00 afin de répondre aux préoccupations croissantes liées à la hausse du franc suisse. A.c. A.________ (ci-après: le client) dispose d'une certaine expérience dans le domaine financier. Le 3 septembre 2014, il a ouvert un compte trading auprès de B.________. Il a commencé dès le lendemain à effectuer des transactions Forex sur la paire EUR/CHF au moyen de la plateforme P.________. L'accès à celle-ci ne peut se faire sans que l'utilisateur ait accepté un contrat dénommé "e-forex". Ce contrat-cadre contient notamment les clauses suivantes: "4.7 (...) (...) v) Vous reconnaissez et acceptez que B.________ n'a aucune obligation d'offrir des cours à tout moment. Dans le cas où B.________ n'offrirait pas de cours pendant une certaine période, vous ne pourrez pas ouvrir ou liquider une position par le biais de la Plateforme e-forex et vos ordres ne seront pas exécutés. (...) 4.13 Acceptation des risques (...) iv) Vous reconnaissez et acceptez que dans certaines conditions de marché, il sera difficile, voire impossible d'exécuter des ordres à un prix déterminé ou de liquider certaines positions, d'estimer un prix juste ou acceptable et d'estimer l'exposition au risque. Cela peut notamment arriver lorsque le marché est illiquide ou lors d'une défaillance de système électronique ou de télécommunications ou dans un cas de force majeure. Le fait de placer un ordre de type " stop-loss " ne garantit pas nécessairement une limitation du risque car, dans certaines conditions de marché, votre ordre ne pourra pas être exécuté. B.________ ne peut pas garantir qu'un ordre d'achat ou de vente sera exécuté au prix limite que vous avez fixé. Ainsi, les opérations de liquidation visant à exclure ou à limiter les risques résultant de transactions sur instruments financiers, qu'elles soient effectuées par vous-même ou par B.________, peuvent ne pas être réalisables ou l'être uniquement à un prix très défavorable. (...) " A.d. Dès le 22 octobre 2014, le client s'est construit une position consistant en l'achat de 2'000'000 EUR/CHF au cours de 1.204119. Le 8 janvier 2015, il a donné un ordre " stop-loss " au cours de 1.194. A.e. Le 15 janvier 2015, la BNS a annoncé à 10 h 30 qu'elle abandonnait le taux plancher. Les marchés ont été pris par surprise; s'en est suivi un vent de panique. Le franc suisse s'est fortement apprécié par rapport à l'euro dès 10 heures 30 minutes 48-49 secondes; dès ce moment, les cotations traitables sur le marché interbancaire sont devenues inexistantes ("illiquidité" du marché). A 10:41:03, la banque a suspendu le négoce sur la paire de devises EUR/CHF pour le reprendre à 11:35:32. Comme prévu par le contrat e-forex, la position du client a été liquidée automatiquement à 11:35, entre la 33ème et la 35ème seconde, à des cours nettement inférieurs (entre 1.03989 et 1.04390) à celui auquel elle avait été acquise (1.204119). A la suite de cette opération, et en considération des actifs disponibles, le compte du client affichait un solde négatif de CHF 287'641.95. La banque en a exigé le paiement - en vain. A.f. Le 24 septembre 2015, la société F.________ SA a rédigé un rapport concernant les événements du 15 janvier 2015, à la demande de la banque. Cette fiduciaire a constaté que selon la chronologie fournie par sa mandante, quelques secondes seulement après l'annonce de la BNS, soit à 10:30:50, la plupart des fournisseurs de liquidités n'offraient plus de cours pour la paire EUR/CHF et ne donnaient que des cours indicatifs. L'analyse des cotations transmises par les fournisseurs de liquidités confirmait la diminution considérable de la liquidité du marché après l'annonce de la BNS; la situation ne s'était normalisée qu'à compter de 11:45. La fiduciaire n'a trouvé aucune trace d'un traitement inéquitable des clients.