输入/搜索内容
欢迎使用优宽量化交易平台
编程语言
JavaScript
TypeScript
Python
C++
My语言(麦语言)
PINE语言
Blockly可视化
Workflow工作流
支持的协议
密钥安全性
实盘
策略库
托管者
部署托管者
一键租用托管者
手动部署托管者
托管者操作注意事项
全局指定IP地址
命令行版本托管者程序的参数
实盘数据迁移
托管者监控
交易所
策略编辑器
回测系统
策略入口函数
策略框架与API函数
模板类库
策略参数
交互控件
商品期货
期权交易
股票证券
C++策略编写说明
JavaScript策略编写说明
内置库
扩展API接口
MCP 服务
交易终端
数据探索
Alpha因子分析工具
调试工具
远程编辑
完整策略的导入与导出
多语言支持
实盘、策略分组
实盘展示
策略分享与出租
实盘消息推送
实盘报错、异常退出的常见原因
交易所特殊说明、兼容记录

在优宽量化交易平台,可以使用哪些编程语言实现我的策略?

支持的编程语言

优宽量化交易平台支持JavaScriptTypeScriptPythonC++PINEMy语言Blockly可视化以及Workflow工作流等多种方式编写和设计策略。

支持JavaScript语言,集成了以下JavaScript库:

程序异常报错、接口业务报错
JavaScript语言策略中,发生程序异常报错或接口业务报错时,错误日志将显示策略代码中发生错误的具体行号,便于策略调试与问题排查。

支持JavaScript异步编程特性:

  • setTimeout / clearTimeout

    javascript
    function main() { let symbol = "rb888" let delay = 10 let depth = exchange.GetDepth(symbol) let callback = function(e, id, msg) { Log(msg + ",撤销订单。") e.CancelOrder(id) } let ordersLen = 3 let arrTimerId = [] for (let i = 1 ; i <= ordersLen ; i++) { let orderId = exchange.CreateOrder(symbol, "buy", depth.Bids[i * 3].Price, i * 0.1) let timerId = setTimeout(callback, delay * 1000, exchange, orderId, `延迟${delay}秒`) Log("i:", i, ", timerId:", timerId) arrTimerId.push(timerId) } // clearTimeout let clearTimeoutIdx = 1 Log("clearTimeoutIdx:", clearTimeoutIdx, `, arrTimerId[clearTimeoutIdx]:`, arrTimerId[clearTimeoutIdx]) clearTimeout(arrTimerId[clearTimeoutIdx]) Sleep(60 * 1000) }
  • fetch
    fetch函数是HttpQuery函数的异步版本重载。

    使用await关键字以同步语法处理异步操作:

    javascript
    function main() { let url = "https://httpbin.org/get?test=123" const promiseBooks = new Promise(async function(resolve, reject) { Log("开始执行") let data = await fetch(url) Log("data.ok:", data.ok, ", data.text():", data.text()) if (data.ok) { Log("成功获取 data:", data) return resolve(data.text()) } else { return reject(new Error("data 无效")) } }) promiseBooks.then(function(ret) { Log("ret:", ret) }).catch(function(err) { Log("err.name:", err.name, "err.stack:", err.stack, "err.message:", err.message) }) }
  • 使用Promise.all并发执行多个异步网络请求:

    javascript
    async function main() { let symbols = ["test1", "test2", "test3"] // 等待请求耗时: 99 毫秒 let arr = [] let beginTs1 = new Date().getTime() for (let symbol of symbols) { let url = `https://httpbin.org/get?test=${symbol}` arr.push(fetch(url).then(function(resp) { if (resp.ok) { return {"symbol": symbol, "json": resp.json()} } else { throw "req failed" } })) } let endTs1 = new Date().getTime() let beginTs2 = new Date().getTime() const ret = await Promise.all(arr) for (let data of ret) { Log(data) } let endTs2 = new Date().getTime() Log("创建请求耗时:", endTs1 - beginTs1, "毫秒") Log("等待请求耗时:", endTs2 - beginTs2, "毫秒") LogStatus(_D(), ret) }
  • 使用Promise.race获取多个异步请求中最先resolvedrejected的结果:

    javascript
    async function getTicker(e) { return Promise.resolve().then(function() { let ret = e.GetTicker("rb888") return {"name": e.GetLabel(), "ret": ret} }) } async function main() { Log("begin") let arrPromise = [] for (let e of exchanges) { arrPromise.push(getTicker(e)) } let ret = await Promise.race(arrPromise) Log(ret) }
  • threading.Thread中使用setTimeout()函数:

    javascript
    function test() { Log("Test function started") // step 3. Test function started let timerId1 = setTimeout(function() { Log("Timeout callback executed after 5 seconds") // step 5. Timeout callback executed after 5 seconds }, 5000) Log("Test function completed") // step 4. Test function completed } function main() { Log("Main function started") // step 1. Main function started let t1 = threading.Thread(test) Log("Worker thread created successfully") // step 2. Worker thread created successfully t1.join() Log("Main function completed") // step 6. Main function completed }
  • 多线程并发获取ticker数据的异步处理示例:
    由于exchange.GetTicker()是同步阻塞操作,即使包装在Promise中,内部执行仍是同步的;JavaScript是单线程的,同步操作会阻塞事件循环;微任务队列中的回调函数仍然是串行执行的。

    javascript
    async function getTicker(symbol) { Log("getTicker symbol:", symbol) return Promise.resolve().then(function() { // 注意与fetch请求数据时的区别 let ret = exchange.GetTicker(symbol) Log(ret) return ret }) } async function main() { let symbols = ["rb888", "MA888", "i888"] let t1 = threading.Thread(async function(symbols, func) { let arrPromise = [] for (let symbol of symbols) { arrPromise.push(func(symbol)) } let ret = await Promise.all(arrPromise) Log("ret:", ret) }, symbols, getTicker) t1.join() }

支持TypeScript语言,在策略创建时仍设置为JavaScript策略,然后在策略代码开头写入// @ts-check或者点击策略编辑区域右上角的「TypeScript」按钮,即可切换到TypeScript。平台将自动识别代码为TypeScript,并为您提供相应的编译和类型检查支持:

  • 类型安全:TypeScript的静态类型检查功能可以帮助您在编写代码时发现潜在的错误,提高代码质量。
  • 代码自动补全:TypeScript的类型系统使得您在编写代码时能够更快地找到所需的属性和方法,提高开发效率。
  • 更清晰的代码结构:使用TypeScript,您可以更好地组织和维护代码,使其易于阅读和理解。
  • 强大的面向对象编程特性:TypeScript提供了接口、类、泛型等强大的面向对象编程特性,帮助您编写更加健壮、可重用的策略代码。

  • 设置Python策略程序使用的Python解释器
    使用Python编写的策略,在回测或实盘时,如果托管者所在系统环境同时安装了Python2和Python3,可以在策略开始的第一行设置策略运行时启动的Python版本。例如:#!python3#!python2,系统将自动查找相应的解释器。也可以指定绝对路径,例如:#!/usr/bin/python3

  • 基于Python的策略安全性
    在优宽量化交易平台上开发的策略,仅对优宽量化交易平台账户持有者可见。在优宽量化交易平台上可以实现策略代码的完全本地化,例如将策略封装成一个Python库,在策略代码中加载,从而实现策略代码本地化。

    Python代码的安全性:
    由于Python是开源且易于反编译的语言,如果策略非自用而是出租,担心策略泄露可以让策略运行在自己部署的托管者上,并以子账号或全托管管理的形式出租。

    Python策略代码加密:
    默认情况下,Python策略代码作者自用时不加密,租给他人使用时加密。在Python策略开头编写如下代码,可以指定自用或租出Python策略运行时是否加密策略代码。支持策略代码加密的Python版本为:Python 2.7版本、Python 3.5版本、Python 3.6版本。

    • 策略作者自己运行、通过注册码给他人使用时,均加密策略代码:
      使用代码#!python指定Python解释器版本,之后使用逗号,间隔,输入加密指令encrypt。如果不指定Python版本,可以直接添加#!encrypt

      python
      #!python,encrypt

      python
      #!encrypt
    • 策略作者自己运行、通过注册码给他人使用时均不加密策略代码:

      python
      #!python,not encrypted

      或者

      python
      #!not encrypted

    判断Python策略代码加密是否生效,使用代码os.getenv('__FMZ_ENV__'),返回字符串"encrypt"表示已经生效。仅在实盘有效,回测不会加密Python策略代码。

    python
    #!encrypt def main(): ret = os.getenv('__FMZ_ENV__') # 打印变量ret为字符串encrypt或者ret == "encrypt"为真,即代表加密生效 Log(ret, ret == "encrypt")
  • Python自定义模块导入功能
    FMZ平台支持在Python策略中导入自定义模块,实现代码的模块化开发和复用。

    例如,我们需要设计一个模块:mymath,将mymath.py保存为一个单独的文件。

    python
    # mymath.py - 保存为一个单独的文件 """ 简单的数学工具模块 """ def add(a, b): """加法""" return a + b

    部署模块文件,将mymath.py文件放置到托管者程序目录下的指定位置(storage目录中的文件夹名称是实盘Id,以实盘Id为123456为例):

    托管者程序目录/logs/storage/123456/mymath.py

    最后在FMZ平台上的Python策略中直接导入mymath模块。

    python
    import mymath def main(): Log("mymath.add(1, 2):", mymath.add(1, 2))

    Id为123456的实盘(策略实例)所绑定的策略中即可调用mymath模块中的方法。

平台支持C++编程语言,兼容C++ 11标准。C++策略需要预先编译后执行,在回测系统中,C++策略运行于专用的C++回测服务器;在实盘环境中,C++策略编译通过后基于托管者运行。

使用C++编程语言和C++ 11标准,您可以在优宽量化交易平台上开发高性能的交易策略。借助C++的现代特性,您能够构建灵活、可扩展的交易算法,实现自动化交易。

集成了以下C++库:

平台支持My语言(麦语言)编写和设计策略,兼容文华麦语言的大部分语法、指令和函数。My语言鼓励积木式编程,将复杂算法拆解为函数模块。通过简洁的语法、专用数据结构和强大的金融函数库,支持复杂金融逻辑的实现。以模块化方式构建应用,有效提升开发效率和代码可维护性。

My语言策略示例:基于平移布林通道的交易系统

mylang
M := 12; // 参数范围 1, 20 N := 3; // 参数范围 1, 10 SDEV := 2; // 参数范围 1, 10 P := 16; // 参数范围 1, 20 // 该策略为趋势跟踪交易策略,适用较大周期,如日线。 // 该模型仅用作模型开发案例,依此入市,风险自负。 //////////////////////////////////////////////////////// // 平移BOLL通道计算 MID:=MA(C,N); // 计算中轨 TMP:=STD(C,M)*SDEV; // 计算标准差 DISPTOP:=REF(MID,P)+TMP; // 平移BOLL通道上轨 DISPBOTTOM:=REF(MID,P)-TMP; // 平移BOLL通道下轨 // 系统入场 H>=DISPTOP,BPK; L<=DISPBOTTOM,SPK; AUTOFILTER;

平台支持并兼容Trading View的PINE语言脚本。PINE语言是一种轻量级但功能强大的策略编程语言,用于创建可进行回测和实盘交易的技术指标与策略。活跃的社区已创作了超过10万个PINE脚本。
用户可以轻松获取并应用各种技术分析工具和交易策略;能够借助社区脚本快速实现交易想法,无需从零开始编写代码,从而大幅缩短开发周期;帮助新手和资深交易员学习并理解不同的技术指标、策略和编程概念。

PINE语言策略示例:超级趋势策略

pine
strategy("supertrend", overlay=true) [supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod")) plot(direction < 0 ? supertrend : na, "Up direction", color = color.green, style=plot.style_linebr) plot(direction > 0 ? supertrend : na, "Down direction", color = color.red, style=plot.style_linebr) if direction < 0 if supertrend > supertrend[2] strategy.entry("entry long", strategy.long) else if strategy.position_size < 0 strategy.close_all() else if direction > 0 if supertrend < supertrend[3] strategy.entry("entry short", strategy.short) else if strategy.position_size > 0 strategy.close_all()

平台支持Blockly可视化编程方式。借助Blockly编辑器,用户可以通过拼接图形化代码块(类似积木)来表达编程概念,如变量、逻辑表达式、循环等。这种方式使编程过程无需关注繁琐的语法细节,而是直接按照编程逻辑进行操作。通过图形化代码块的组合,用户能够直观理解程序逻辑,快速实现策略构想。该功能特别适合初学者培养策略设计能力,帮助其快速掌握程序化交易和量化交易的基础知识。

平台支持以 Workflow 工作流方式编写策略。工作流是一种可视化的策略设计方式,通过节点连接和配置来构建交易逻辑,无需编写代码即可实现策略。

工作流特点

  • 可视化拖拽设计,所见即所得
  • 预置丰富的功能节点(数据获取、指标计算、条件判断、交易执行等)
  • 降低编程门槛,适合快速搭建和验证策略
  • 支持回测功能,可视化查看节点执行状态