昨晚跑一个欧美M15的均值回归策略,用Python调MT5的接口,结果initialize()直接返回False,连终端都没握上手。我第一反应是代码写错了,改了半天参数,最后发现是MT5终端本身的一个设置没打开。这事儿让我想起之前一个汇友,他折腾了三天,最后发现是API版本和终端build号对不上。所以今天不聊行情,就聊聊这个连接问题到底出在哪儿。
先说一个我踩过的坑。当时我装的是MetaTrader5 pip包,版本是5.0.45,终端是券商官网下的最新版,build 4260。按说应该没问题,但initialize()就是失败。后来查了日志,发现终端里有个选项叫“允许算法交易”,默认是关的。这个选项不在“工具-选项-智能交易”里,而是在终端右上角那个“算法交易”按钮上,必须点亮成绿色。很多人以为EA能跑就行,但Python接口走的是另一条通道,这个按钮不亮,Python连不上。这个坑我踩了两次,第二次是换了VPS之后,忘了在新终端上开这个按钮。
再一个常见问题是API版本和终端build不匹配。MetaTrader5这个pip包更新挺频繁的,但终端build更新更快。比如你pip install的是5.0.45,它要求终端build至少是3800如果你券商给的终端是老版本,比如build 3200,那initialize()就会返回False,而且错误码是-10003,意思是“终端不支持”。这时候要么升级终端,要么降级pip包。我一般建议直接去MetaQuotes官网下最新终端,别用券商定制版,定制版往往锁了build号。
还有一个隐蔽的问题:VPS上的多终端冲突。我有次在VPS上同时开了两个MT5终端,一个跑黄金,一个跑镑美,Python脚本只连其中一个。结果initialize()有时候成功有时候失败。后来发现是path参数没指定清楚。MT5的Python接口默认会找第一个打开的终端,如果你开了多个,它可能连到错误的那个。解决办法是在initialize()里显式传入终端路径,比如:
这样它就只认这个路径下的终端,不会乱连。另外,如果你用的是MT5对冲账户,还要注意margin_mode参数,默认是净持仓模式,对冲账户要改成mt5.ACCOUNT_MARGIN_MODE_RETAIL_HEDGING,否则下单会报错。
再说一个Python端的坑。有些人用Anaconda环境,里面预装了老版本的MetaTrader5包,你pip install新版本之后,import的还是老版本。这时候要在命令行里跑pip show MetaTrader5确认版本,如果不对,用pip install --upgrade --force-reinstall MetaTrader5强制重装。我有个朋友就是因为这个,折腾了一晚上,最后发现是环境里有两个版本。
最后说下排查顺序。如果你也遇到连不上的问题,按这个顺序来:
我现在的习惯是,每次换VPS或者重装终端,先跑一个最小测试脚本,就三行:import MetaTrader5 as mt5,print(mt5.initialize()),print(mt5.last_error())。如果返回True和(1, 'Success'),再跑策略。这样能省很多时间。
你们有没有遇到过initialize()返回True但后面下单失败的情况?我最近碰到一个,怀疑是symbol_select没调用,想听听大家的排查思路。
补充一个小细节:那个按钮点亮后最好重启一下终端再跑initialize(),我昨晚就是没重启,白白多折腾了十几分钟。
先说一个我踩过的坑。当时我装的是MetaTrader5 pip包,版本是5.0.45,终端是券商官网下的最新版,build 4260。按说应该没问题,但initialize()就是失败。后来查了日志,发现终端里有个选项叫“允许算法交易”,默认是关的。这个选项不在“工具-选项-智能交易”里,而是在终端右上角那个“算法交易”按钮上,必须点亮成绿色。很多人以为EA能跑就行,但Python接口走的是另一条通道,这个按钮不亮,Python连不上。这个坑我踩了两次,第二次是换了VPS之后,忘了在新终端上开这个按钮。
再一个常见问题是API版本和终端build不匹配。MetaTrader5这个pip包更新挺频繁的,但终端build更新更快。比如你pip install的是5.0.45,它要求终端build至少是3800如果你券商给的终端是老版本,比如build 3200,那initialize()就会返回False,而且错误码是-10003,意思是“终端不支持”。这时候要么升级终端,要么降级pip包。我一般建议直接去MetaQuotes官网下最新终端,别用券商定制版,定制版往往锁了build号。
还有一个隐蔽的问题:VPS上的多终端冲突。我有次在VPS上同时开了两个MT5终端,一个跑黄金,一个跑镑美,Python脚本只连其中一个。结果initialize()有时候成功有时候失败。后来发现是path参数没指定清楚。MT5的Python接口默认会找第一个打开的终端,如果你开了多个,它可能连到错误的那个。解决办法是在initialize()里显式传入终端路径,比如:
- terminal_path = "C:/Program Files/MetaTrader 5/terminal64.exe"
- mt5.initialize(path=terminal_path)
这样它就只认这个路径下的终端,不会乱连。另外,如果你用的是MT5对冲账户,还要注意margin_mode参数,默认是净持仓模式,对冲账户要改成mt5.ACCOUNT_MARGIN_MODE_RETAIL_HEDGING,否则下单会报错。
再说一个Python端的坑。有些人用Anaconda环境,里面预装了老版本的MetaTrader5包,你pip install新版本之后,import的还是老版本。这时候要在命令行里跑pip show MetaTrader5确认版本,如果不对,用pip install --upgrade --force-reinstall MetaTrader5强制重装。我有个朋友就是因为这个,折腾了一晚上,最后发现是环境里有两个版本。
最后说下排查顺序。如果你也遇到连不上的问题,按这个顺序来:
- 检查终端右上角“算法交易”按钮是否点亮
- 确认终端build号,在“帮助-关于”里看,要大于3800
- 确认pip包版本,用pip show MetaTrader5看
- 如果开了多个终端,initialize()里指定path
- VPS上检查防火墙是否拦了终端和Python的通信端口
我现在的习惯是,每次换VPS或者重装终端,先跑一个最小测试脚本,就三行:import MetaTrader5 as mt5,print(mt5.initialize()),print(mt5.last_error())。如果返回True和(1, 'Success'),再跑策略。这样能省很多时间。
你们有没有遇到过initialize()返回True但后面下单失败的情况?我最近碰到一个,怀疑是symbol_select没调用,想听听大家的排查思路。
补充一个小细节:那个按钮点亮后最好重启一下终端再跑initialize(),我昨晚就是没重启,白白多折腾了十几分钟。
