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

第一行是我们的功能声明,我们称此功能为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和argComment自变量。下面的例子为下无到期时间与默认交易单说明的停损买单"Buy Stop Order"源代码:

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


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

