交易信息大全
2026币圈信息集合

FMZ量化交易交易策略开发经验

欧意OKX  币安Binance  芝麻开门GATE

目前不清退的交易所推荐:

1、全球第二大交易所OKX欧意

国区邀请链接: https://www.promooboost.com/join/1837888   币种多,交易量大!

国际邀请链接:https://www.okx.com/join/1837888 注册简单,交易不需要实名,新用户能开合约,币种多,交易量大!

2、老牌交易所比特儿现改名叫芝麻开门 :https://www.gateport.business/share/XgRDAQ8

全球最大交易所币安,国区邀请链接:https://accounts.binance.com/zh-CN/register?ref=16003031  币安注册不了IP地址用香港,居住地选香港,认证照旧,邮箱推荐如gmail、outlook。支持币种多,交易安全!

买好币上KuCoinhttps://www.kucoin.com/r/af/1f7w3  CoinMarketCap前五的交易所,注册友好操简单快捷!

FMZ量化交易平台邀请链接:https://www.fmz.com/

本文旨在描述一些策略开发的经验,以及一些技巧,让读者快速掌握交易策略开发的重点。

当您在一些策略设计中遇到类似的细节时,您可以立即想出一个合理的解决方案。

我们以 FMZ Quant 平台为例进行说明、测试和实践。

我们将使用 JavaScript 的策略编程语言

对于交易对象,我们以区块链资产市场(BTC、ETH等)为对象

数据采集​​和处理

通常,根据策略逻辑的不同,可能会使用以下不同的接口来获取行情数据,大部分策略逻辑都是由行情数据驱动的(当然,有些策略是不关心价格数据的,比如固定投资策略)。

  • GetTicker:获取实时报价。
    一般用于快速获取当前最新价格,“买入1”价格,“卖出1”价格。
  • GetDepth:获取订单簿的订单深度。
    一般用于获取订单簿深度的每一层的价格和挂单的大小。用于对冲策略、做市策略等。
  • GetTrade:获取市场的最新交易记录。
    一般用于分析短时间内的市场行为,分析市场的微观变化。通常用于高频策略和算法策略。
  • GetRecords:获取市场K线数据。通常用于趋势跟踪策略和计算指标。

容错

在设计策略时,初学者通常会忽略各种错误,直观地认为策略中每个部分的结果都是成立的。但事实并非如此,在策略程序的运行中,在请求行情数据时,会遇到各种意想不到的情况。

例如,一些市场接口返回未执行的数据:

var depth = exchange.GetDepth()

// depth.Asks[0].Price < depth.Bids[0].Price "Selling 1" price is lower than "buying 1" price, this situation cannot exist on the market.
// Because the selling price is lower than the buying price, the order must have been executed.
// depth.Bids[n].Amount = 0 Order book buying list "nth" layer, order quantity is 0
// depth.Asks[m].Price = 0 Order book selling list "mth" layer, the order price is 0

或者直接 exchange.GetDepth() 返回一个空值。

这样奇怪的情况还有很多。因此,有必要处理这些可预见的问题。这样的处理方案称为容错处理。

处理故障的正常方法是丢弃数据并重新获取它。

例如:

function main () {
     while (true) {
         onTick()
         Sleep(500)
     }
}

function GetTicker () {
     while (true) {
         var ticker = exchange.GetTicker()
         if (ticker.Sell > ticker.Buy) { // Take the example of fault-tolerant processing that detects whether the "Selling 1" price is less than the "Buying 1" price.
                                               // Exclude this error, the current function returns "ticker".
             Return ticker
         }
         Sleep(500)
     }
}

function onTick () {
     var ticker = GetTicker() // Make sure the "ticker" you get doesn't exist the situation that "Selling 1" price is less than the "Buying 1" price.
     // ... specific strategy logic
}

类似的方法可以用于其他可预见的容错过程。

设计原则是永远不能使用错误的逻辑来驱动策略逻辑。

K线数据的使用

K线数据采集,调用:

var r = exchange.GetRecords()

得到的K线数据是一个数组,比如这样:

[
    {"Time":1562068800000,"Open":10000.7,"High":10208.9,"Low":9942.4,"Close":10058.8,"Volume":6281.887000000001},
    {"Time":1562072400000,"Open":10058.6,"High":10154.4,"Low":9914.5,"Close":9990.7,"Volume":4322.099},
    ...
    {"Time":1562079600000,"Open":10535.1,"High":10654.6,"Low":10383.6,"Close":10630.7,"Volume":5163.484000000004}
]

可以看到每个大括号{}包含时间、开盘价、最高价、最低价、收盘价和成交量。

这是一个K线吧。一般K线数据用于计算移动平均线、MACD等指标。

将K线数据作为参数(原材料数据)传递,然后设置指标参数来计算指标数据的函数,我们称之为指标函数。

FMZ Quant量化交易平台上有很多指标功能。

例如,我们计算移动平均线指标。根据传递的K线数据的周期,我们计算相应周期的移动平均线。

比如传K线数据(一根K线柱代表一天),计算日均线,同理,如果传均指标函数的K线数据是1小时周期,那么计算指标为 1 小时移动平均线。

通常我们在计算指标时经常会忽略一个问题。如果我要计算5日均线指标,那么我们首先准备好日K线数据:

var r = exchange.GetRecords(PERIOD_D1) // Pass parameters to the "GetRecords" function "PERIOD_D1" specifies the day K line to be acquired.
                                       // Specific function using method can be seen at: https://www.fmz.com/api#GetRecords

有了每日K线数据,我们就可以计算出均线指标。如果我们要计算 5 日均线,那么我们必须将指标函数的指标参数设置为 5。

var ma = TA.MA(r, 5) // "TA.MA()" is the indicator function used to calculate the moving average indicator. The first parameter sets the daily K-line data r just obtained.
                             // The second parameter is set to 5. The calculated 5-day moving average is the same as the other indicators.

我们忽略了一个潜在的问题。如果 K 线数据中的 K 线柱数少于 5 条,如何计算出有效的 5 日均线?

答案是你无能为力。

因为移动平均线指标是一定数量K线柱的收盘价的平均值。

6e9899bf1c18d37b9759

因此,在使用K线数据和指标函数计算指标数据之前,需要确定K线数据中K线柱的数量是否满足指标计算的条件(指标参数)。

所以在计算 5 日移动平均线之前,你必须先检查一下。完整代码如下:

function CalcMA () {
     var r = _C(exchange.GetRecords, PERIOD_D1) // _C() is a fault-tolerant function, the purpose is to avoid r being null, you can get more information at: https://www.fmz.com/api#_C
     if (r.length > 5) {
         Return TA.MA(r, 5) // Calculate the moving average data with the moving average indicator function "TA.MA", return it as a function return value.
     }

     Return false
}

function main () {
     var ma = CalcMA()
     Log(ma)
}

6e5029f18c426962e781

回测展示:

[null,null,null,null,4228.7,4402.9400000000005, ... ]

您可以看到计算出的 5 天移动平均线指标。前四个为空,因为K线条数少于5,无法计算平均值。当你到达第5个K线柱时,你可以计算它。

判断K线更新的技巧

我们在写策略的时候,经常会有这样的场景,比如策略需要在每个K线周期完成的时候处理一些操作,或者打印一些日志。

我们如何实现这些功能?对于没有编程经验的初学者来说,可能是个比较麻烦的问题。在这里,我们为您提供解决方案。

如何判断一个K线柱周期就完成了。我们可以从K线数据中的时间属性入手。每次拿到K线数据,我们都会判断这个K线数据的最后一个K线柱的时间属性是否发生变化。如果变了,说明有新的K线柱生成(证明新生成的K线柱的上一个K线柱周期已经完成),如果没有变化,说明没有新的K线柱-line bar 生成(当前最后一个 K 线 bar 周期尚未完成)。

所以我们需要一个变量来记录K线数据的最后一个K线柱的时间。

var r = exchange.GetRecords()
var lastTime = r[r.length - 1].Time // "lastTime" used to record the last K-line bar time.

在实践中,通常是这样的:

function main () {
     var lastTime = 0
     while (true) {
         var r = _C(exchange.GetRecords)
         if (r[r.length - 1].Time != lastTime) {
             Log ("New K-line bar generated")
             lastTime = r[r.length - 1].Time // Be sure to update "lastTime", this is crucial.

             // ... other processing logic
             // ...
         }

         Sleep(500)
     }
}

6e4b63a61104fbb1cf42

可以看到在回测中,K线周期设置为每天(exchange.GetRecords函数调用时未指定参数,根据回测设置的K线周期为默认参数)。每当新的 K 线柱出现时,它都会打印一个日志。

数值计算

  • 计算访问交易所界面所花费的时间

如果您想对策略访问交易所界面所需的时间进行一定的显示或控制,您可以使用以下代码:

function main () {
     while (true) {
         var beginTime = new Date().getTime()
         var ticker = exchange.GetTicker()
         var endTime = new Date().getTime()

         LogStatus(_D(), "GetTicker() function time-consuming:", endTime - beginTime, "millisecond")
         Sleep(1000)
     }
}

简单来说就是调用GetTicker函数后记录的时间戳减去调用前的时间戳,计算出所经历的毫秒数,也就是GetTicker函数从执行到返回所用的时间。

  • 使用“Math.min / Math.max”限制数值的上下限

例如,在下达卖单的过程中,卖单的金额不得大于账户中的币数。
因为如果它大于账户中可用的硬币数量,订单将导致错误。

我们这样控制它:

例如,我们计划卖空 0.2 个硬币。

var planAmount = 0.2
var account = _C(exchange.GetAccount)
var amount = Math.min(account.Stocks, planAmount)

这样可以确保下达的订单数量不会超过账户中可用的硬币数量。

同理,Math.max用于保证某个值的下限。

  • 这通常适用于什么样的场景?

一般情况下,正常交易所对某些交易对有最低发送订单限制。如果低于最低金额,订单将被拒绝。这也会导致程序失败。

假设BTC通常最小下单数量为0.01。

交易策略有时会导致小于 0.01 的订单数量,因此我们可以使用Math.max来确保最小订单数量。

  • 订单数量、价格精准控制

可以使用_N()函数或SetPrecision函数来控制精度。

SetPrecision()功能只需设置一次,订单数量和价格值的小数位数在系统中自动截断。

功能是对_N()某个值进行小数点截断(精度控制)。

例如:

var pi = _N(3.141592653, 2)
Log(pi)

pi的值被小数位截去,保留2位小数,即:3.14

有关详细信息,请参阅 API 文档。

一些逻辑设置

  • 定时,在一定时间内执行一些操作

可以利用这样的机制,利用时间戳检测的方法,确定当前时间戳减去上一次执行定时任务的时间戳,实时计算经过的时间。当经过的时间超过某个设置的时间长度时。之后,执行新的操作。

例如,用于固定投资策略。

var lastActTime = 0
var waitTime = 1000 * 60 * 60 * 12 // number of milliseconds a day
function main () {
     while (true) {
         var nowTime = new Date().getTime()
         if (nowTime - lastActTime > waitTime) {
             Log ("Execution Fixed")
             // ... specific fixed investment operation, buying operation.


             lastActTime = nowTime
         }

         Sleep(500)
     }
}

这是一个简单的例子。

  • 设计策略的自动恢复机制

使用FMZ量化_G()功能,退出保存功能,方便设计退出保存进度,重启自动恢复状态的策略。

var hold = {
     Price : 0,
     Amount : 0,
}

function main () {
     if (_G("hold")) {
         var ret = _G("hold")
         hold.price = ret.price
         hold.amount = ret.amount
         Log("restore hold:", hold)
     }

     var count = 1
     while (true) {
         // ... strategy logic
         // ... In the strategy operation, it is possible that when opening a position, then assign the position price of the open position to "hold.price", and the amount of open positions is assigned to "hold.amount" to record the position information.

         hold.price = count++ // simulate some values
         hold.amount = count/10 // Simulate some values

         Sleep(500)
     }
}

function onexit () { // Click the stop button on the robot to trigger the execution of this function. After the execution, the robot stops.
     _G("hold", hold)
     Log("save hold:", JSON.stringify(hold))
}

6e21184fccbecf239f63

可以看出,hold每次机器人停止时都会保存对象中的数据。每次重新启动数据时,读取数据并将其值hold恢复到停止前的状态。

当然,以上只是一个简单的例子。如果在实际交易策略中使用,应根据策略中需要恢复的关键数据(一般为账户信息、持仓、盈利值、交易方向等)进行设计。

此外,您还可以设置一些其他条件来恢复。

这些是制定交易策略的一些技巧,希望对初学者有所帮助!

动手实践训练是提高自己最快的方法!祝大家好运。

FMZ量化交易平台邀请链接:https://www.fmz.com/

全球最大交易所币安,国区邀请链接:https://accounts.binance.com/zh-CN/register?ref=16003031  币安注册不了IP地址用香港,居住地选香港,认证照旧,邮箱推荐如gmail、outlook。支持币种多,交易安全!

买好币上KuCoinhttps://www.kucoin.com/r/af/1f7w3  CoinMarketCap前五的交易所,注册友好操简单快捷!

目前不清退的交易所推荐:

1、全球第二大交易所OKX欧意,邀请链接:https://www.promooboost.com/join/1837888 注册简单,交易不需要实名,新用户能开合约,币种多,交易量大!。

2、老牌交易所比特儿现改名叫芝麻开门 :https://www.gateport.business/share/XgRDAQ8

买好币上币库:https://www.kucoin.com/r/1f7w3

火必所有用户现在可用了,但是要重新注册账号火币https://www.huobi.com

全球最大交易所币安

国区邀请链接: 支持86手机号码,网页直接注册。

赞(0)
未经允许不得转载:2026币圈信息集合 » FMZ量化交易交易策略开发经验