第四章 使用功能
我们接着要将前面章节讨论过的代码,转换成可重复使用的功能。如此可帮我们省去大量的工作,将精力放在交易系统上,而非交易机制上。
建立功能背后的想法是建立可进行非常具体任务的代码区块。代码应该灵活到足以在各种交易情况下都能重复使用。所有外部变量或计算都需要传递给功能。功能可位于包含文件或链接库的外部,因此不可假设所有必要值都会以其他方式提供给功能使用。为保持一致性,目前为止已用之所有外部变量,我们都会保持相同的名称。我们在这些变量前加“arg”(自变量)来表示其为功能自变量,以示区别。
定仓位大小功能
我们以仓位大小计算开始,如先前章节的定义:

第一行是我们的功能声明,我们称此功能为CalCLotSize()。在验证仓位大小这一章节中我们来比较其中代码,而DynamicLotSize、EquityPercent、StopLoss以及FixedLotSize现在都是功能自变量。这些名称的外部变量仍然在我们的程序中,只是把它们当作自变量转移至功能罢了。
功能的自变量在程序中以粗体显示。除了我们现在使用的自变量之外,代码和之前的仓位计算代码是完全相同。我们在功能结尾加了return(返回)语句,这会把LotSize值传回至调用功能。
功能本身会位于程序档案的某处,在start()和init()功能的外部,或放在外部的包含档内。在后者的情况下,程序上端的#include语句会包含此文件供程序使用。
这里有如何在代码中使用此功能的说明。首先,我们列出会用于仓位大小设定的外部变量列表:

如何调用该功能的说明如下,此行代码位于start()功能内部:

外部变量会作为自变量传给该功能。该功能在计算仓位大小后,把值储存在LotSize变量中。请注意:此变量不同于CalcLotSize()功能内部的LotSize变量,虽然两者都是功能变量,且即使名称相同,但实则却为不同的变量。
仓位验证功能
我们继续仓位验证代码。此为个别功能,如决定用替代方式计算仓位大小。无论采用哪种方式确定仓位大小,你在使用它来传递给下单功能之前,都会想先行验证:

就此功能,我们会把CalcLotSize()当作自变量使用,以传递变量与算出的仓位大小。自变量argLotSize接着就会被处理并返回至调用的功能。
下单功能
现在该把市价买单功能组合起来了。我们先前审查过的下单功能和代码之间会有若干差异。例如,我们不会在下单功能中平仓,而是单独处理平仓。我们会在第五章建立平仓功能。
我们也会计算和修改下单功能外的停损价与获利价。由于计算停损价的方式有多种,我们得让下单功能尽可能保持灵活,而非使其局限于既定的计算停损方式。交易单修改代码已被移至个别的功能。
我们会使用OrderSend()在目前的市场下买单。如未下单,我们会执行错误处理代码。无论如何,我们都会把单号返回给调用功能,如未下单的话就返回“-1”。
我们用自变量argSymbol指定交易单符号,而非仅用目前的图表符号。如此一来,如决定要在另一个符号下单,就能轻易进行了。与其用预定义的Bid和Ask变量,不如用有MODE_ASK和MODE_BID参数的MarketInfo()功能来为特定符号获取买卖价。
我们还为交易单说明(order comment)指定了默认值。自变量argComment有默认值“Buy Order”(买单)。此自变量如无指定值,会使用默认值。我们会假设仓位大小和滑价在调用此功能之前已计算并验证过:

在OrderSend()功能中,需要注意的是,我们已用有MODE_ASK参数的MarketInfo()功能来代替预定义的Ask变量。这会获取以argSymbol表示的目前商品符号的目前卖价。
如未顺利下单,就会执行错误处理程序;否则,单票将返回至调用功能。如未下单的话会返回“-1”。附录D有市价卖单的完整下单功能源代码。
设定挂单
欲设挂单,我们需要就挂单价以及交易单到期时间传递参数。该功能会新增argPendingPrice和argExpiration自变量。我们会假设挂单价、停损价与获利价在调用此功能之前都已计算和验证过。设挂单功能时也会一并设停损与获利,无须单独的交易单修改功能。
以下为挂单交易的停损买单源代码:


请注意:我们已为argExpiration指定了默认值“0”。如未使用挂单到期时间,而想用默认的交易单说明,调用功能时可省略argExpiration和aigComment自变量。下面的例子为下无到期时间与默认交易单说明的停损买单“Buy Stop Order”源代码:

我们已在错误处理功能中将挂单价加进了日志,如有指定到期时间也一并加上。TimeToStr()功能会转换datetime变量的字符串格式。
此功能与开停损卖单、限价买单及限价卖单的功能相同。唯一的区别是,OrderSend()功能交易单类型参数作了相应的改变。你可同时检视附录D中所有设挂单交易的功能。
平仓功能
最后,让我们建立单一交易单的平仓功能。我们会用第四章总结部分的代码。在第五章,我们会探讨多张同类型交易单之平仓方式,这种平仓方式更简单。然而,若只需平一张交易单,此功能也没问题。
以下是平仓功能源代码:


对于ClosePrice变量,我们用MarketInfo()获取以argSymbol表示之商品目前的卖价。我们分别为平仓票和滑价使用功能自变量argCloseTicket和argSlippage。如未顺利平仓,我们执行错误处理区块,就会将单号和目前卖价打印至日志。
卖单平仓代码与平仓代码几乎一模一样,除了以买价作为ClosePrice变量。可在附录D中检视市价卖单平仓功能源代码。
挂单平仓功能
以下为单张挂单的平仓功能源代码,对所有挂单类型都适用,无论买单或卖单:
