EA 中的每日亏损上限:自营交易公司要求做对的四个决定

10 十月 2026, 10:24
Bohdan Klok
0
4

每日亏损上限听起来像一行代码:"如果今天的亏损超过 X%,就停止。"实际上它包含四个决定,每一个都会改变上限触发的时机。自营交易公司(prop firm)让这些决定变得无法回避:只要突破一次每日上限,账户就没了,不管策略在当月其余时间表现如何。下面介绍上限通常如何计算、简单实现在哪里出错,以及我在自己的 EA 中使用的代码。

1. "今天"是什么?

是交易服务器的一天,而不是您电脑的一天:TimeCurrent() 就是 MetaTrader 到处显示的时钟。自营交易公司在其服务器或某个固定时区的午夜重置上限——请确认您的公司用的是哪一个;如果不是服务器的午夜,就需要平移重置时间。服务器日的开始很简单:

datetime now = TimeCurrent();
datetime day = now - now % 86400;       // 00:00 server time

2. 相对于什么的亏损?

相对于当天开始时的余额。许多自营交易公司取那一刻余额和净值中较高的一个,所以更严格的选择才是安全的:如果您带着 300 的浮动盈利过夜,这部分盈利就属于基数,把它亏回去也算亏损。

double base = MathMax(AccountInfoDouble(ACCOUNT_BALANCE), AccountInfoDouble(ACCOUNT_EQUITY));

3. 亏损怎么衡量?

按净值,而不是按已平仓交易。只看已平仓交易的上限,会让一笔持仓远远超过它:自营公司的监控看得到浮动亏损,您的代码却看不到。所以检查要在每个报价时进行:

if(AccountInfoDouble(ACCOUNT_EQUITY) <= base * (1.0 - limitPercent / 100.0))
   stopped = true;      // close the positions, open nothing until the next day

并且针对整个账户。每个 EA 各自的上限适合您自己的风险控制,但自营公司把所有持仓加在一起算。如果程序的多个副本在多个图表上运行,它们看到的是同一个账户净值,并各自平掉自己的持仓。

4. 重启后还剩什么?

这正是简单实现总会出错的地方。基数保存在变量里;终端在 14:00 重启(更新、VPS 重启、修改参数);程序重新开始,把上午亏损之后的当前余额当作"当天开始",于是又允许一个完整的上限。当天的状态必须保存在程序之外。终端的全局变量正是为此而设:

string key = StringFormat("DL_%I64d_%I64u_%s_", AccountInfoInteger(ACCOUNT_LOGIN), magic, _Symbol);
if(GlobalVariableCheck(key + "day") && (datetime)GlobalVariableGet(key + "day") == day)
  {
   base    = GlobalVariableGet(key + "base");       // the real start of the day
   stopped = GlobalVariableGet(key + "stop") != 0.0;
  }
else
  {
   GlobalVariableSet(key + "day", (double)day);      // a new day: remember it
   GlobalVariableSet(key + "base", base);
   GlobalVariableSet(key + "stop", 0.0);
  }

终端会在最后一次访问后保留全局变量四周,并写入磁盘,因此它们能挺过重启、重新编译和参数修改。

重要的小细节

  • 平仓并停止:上限触发时,平掉本程序的持仓,并在第二天之前拒绝所有新信号。要在用户看得到的地方报告(图表面板上的一行、弹出提醒、推送通知),而不只是写在日志里。
  • 平仓可能失败:市场休市、价格变动、服务器繁忙。要重试,但不要每个报价都试:在交易时段开放期间每秒一次就够了。
  • 在策略测试器中,全局变量属于测试代理,而且测试不会中途重启:那里用内存中的状态就够了。
  • 百分比要低于自营公司的上限。每笔风险 1% 时,3% 的每日上限就是三笔止损;如果公司的上限是 5%,把您自己的上限设为 4%,因为价格可能跳空越过您的止损。

产品中

从 1.09 版本起,Indicator Signal Trader Kb 正好具备这些:"Daily loss limit" 参数,默认关闭,以服务器日开始时余额与净值中较高者为基数、针对整个账户计算,重启后仍然保留,触发时面板上显示红色一行。在策略测试器中,上限设为 0.5%、每笔风险 1%,在 GBPUSD 2022-2026 年间触发了 372 次,而且触发后的同一天没有再开过任何一笔仓——这正是每日上限唯一必须保证的事情。