コミュニティユーザーの要求に応じて,設計基準として多種多様な双等線戦略を希望します. この時期は多種多様な双等線戦略を実現します. 解説は戦略コードに書かれ,理解しやすく,学習に便利です. より多くのプログラム化,定量化取引を新しい同学に迅速に導入します.
双均線戦略の論理は単純である.つまり,2つの均線である. 一つの参数周期が小さい均線 (快線),一方の参数周期が大きい均線 (慢線). 2つの線が金叉 (快線が下からゆっくり走る) を多買いし,2つの線が死叉 (快線が上からゆっくり走る) を空売りする.均線は,我々はEMA均線を使用する.
策略が複数種に設計される限り,各種パラメータは異なる可能性がある (異なる種は異なる均線パラメータを使用する),したがって,
参数はこのような文字列形式で設計され,各参数にコマの間隔がある. 策略が実行開始時に,これらの文字列を解析する. 各種 (取引対) にマッチする実行ロジック. 策略轮
戦略設計はシンプルで,入門学習に適しています.
// 函数作用:取消当前交易对的所有挂单
function cancelAll(e) {
while (true) {
var orders = _C(e.GetOrders)
if (orders.length == 0) {
break
} else {
for (var i = 0 ; i < orders.length ; i++) {
e.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
}
Sleep(500)
}
}
// 函数作用:计算实时收益盈亏
function getProfit(account, initAccount, lastPrices) {
// account为当前账户信息,initAccount为初始账户信息,lastPrices为当前所有品种的最新价格
var sum = 0
_.each(account, function(val, key) {
// 遍历当前所有资产,计算除了USDT以外的资产币差,以及金额差
if (key != "USDT" && typeof(initAccount[key]) == "number" && lastPrices[key + "_USDT"]) {
sum += (account[key] - initAccount[key]) * lastPrices[key + "_USDT"]
}
})
// 返回根据当前价格计算得出的资产盈亏
return account["USDT"] - initAccount["USDT"] + sum
}
// 函数作用:生成图表配置
function createChartConfig(symbol, ema1Period, ema2Period) {
// symbol为交易对,ema1Period为第一根EMA均线周期,ema2Period为第二根EMA均线周期
var chart = {
__isStock: true,
extension: {
layout: 'single',
height: 600,
},
title : { text : symbol},
xAxis: { type: 'datetime'},
series : [
{
type: 'candlestick', // K线数据系列
name: symbol,
id: symbol,
data: []
}, {
type: 'line', // EMA数据系列
name: symbol + ',EMA1:' + ema1Period,
data: [],
}, {
type: 'line', // EMA数据系列
name: symbol + ',EMA2:' + ema2Period,
data: []
}
]
}
return chart
}
function main() {
// 重置所有数据
if (isReset) {
_G(null) // 清空所有持久化记录的数据
LogReset(1) // 清空所有日志
LogProfitReset() // 清空所有收益日志
LogVacuum() // 释放实盘数据库占用的资源
Log("重置所有数据", "#FF0000") // 打印信息
}
// 解析参数
var arrSymbols = symbols.split(",") // 逗号分割交易品种字符串
var arrEma1Periods = ema1Periods.split(",") // 分割第一根EMA均线的参数字符串
var arrEma2Periods = ema2Periods.split(",") // 分割第二根EMA均线的参数字符串
var arrAmounts = orderAmounts.split(",") // 分割每个品种的下单量
var account = {} // 用于记录当前资产信息的变量
var initAccount = {} // 用于记录最初资产信息的变量
var currTradeMsg = {} // 用于记录当前BAR是否交易的变量
var lastPrices = {} // 用于记录监控的品种最新价格的变量
var lastBarTime = {} // 用于记录最近一根BAR的时间的变量,用于画图时BAR的更新判断
var arrChartConfig = [] // 用于记录图表配置信息,用于画图
if (_G("currTradeMsg")) { // 例如重启时,恢复currTradeMsg数据
currTradeMsg = _G("currTradeMsg")
Log("恢复记录", currTradeMsg)
}
// 初始化account
_.each(arrSymbols, function(symbol, index) {
exchange.SetCurrency(symbol)
var arrCurrencyName = symbol.split("_")
var baseCurrency = arrCurrencyName[0]
var quoteCurrency = arrCurrencyName[1]
if (quoteCurrency != "USDT") {
throw "only support quoteCurrency: USDT"
}
if (!account[baseCurrency] || !account[quoteCurrency]) {
cancelAll(exchange)
var acc = _C(exchange.GetAccount)
account[baseCurrency] = acc.Stocks
account[quoteCurrency] = acc.Balance
}
// 初始化图表相关的数据
lastBarTime[symbol] = 0
arrChartConfig.push(createChartConfig(symbol, arrEma1Periods[index], arrEma2Periods[index]))
})
if (_G("initAccount")) {
initAccount = _G("initAccount")
Log("恢复初始账户记录", initAccount)
} else {
// 用当前资产信息,初始化initAccount变量
_.each(account, function(val, key) {
initAccount[key] = val
})
}
Log("account:", account, "initAccount:", initAccount) // 打印资产信息
// 初始化图表对象
var chart = Chart(arrChartConfig)
// 图表重置
chart.reset()
// 策略主循环逻辑
while (true) {
// 遍历所有品种,逐个执行双均线逻辑
_.each(arrSymbols, function(symbol, index) {
exchange.SetCurrency(symbol) // 切换交易对为symbol字符串记录的交易对
var arrCurrencyName = symbol.split("_") // 以“_”符号分割交易对
var baseCurrency = arrCurrencyName[0] // 交易币的字符串
var quoteCurrency = arrCurrencyName[1] // 计价币的字符串
// 根据index索引,获取当前交易对的EMA均线参数
var ema1Period = parseFloat(arrEma1Periods[index])
var ema2Period = parseFloat(arrEma2Periods[index])
var amount = parseFloat(arrAmounts[index])
// 获取当前交易对的K线数据
var r = exchange.GetRecords()
if (!r || r.length < Math.max(ema1Period, ema2Period)) { // K线长度不足时直接返回
Sleep(1000)
return
}
var currBarTime = r[r.length - 1].Time // 记录当前BAR时间戳
lastPrices[symbol] = r[r.length - 1].Close // 记录当前最新价格
var ema1 = TA.EMA(r, ema1Period) // 计算EMA指标
var ema2 = TA.EMA(r, ema2Period) // 计算EMA指标
if (ema1.length < 3 || ema2.length < 3) { // EMA指标数组长度过短,直接返回
Sleep(1000)
return
}
var ema1Last2 = ema1[ema1.length - 2] // 倒数第二BAR上的EMA
var ema1Last3 = ema1[ema1.length - 3] // 倒数第三BAR上的EMA
var ema2Last2 = ema2[ema2.length - 2]
var ema2Last3 = ema2[ema2.length - 3]
// 写入图表数据
var klineIndex = index + 2 * index
// 遍历K线数据
for (var i = 0 ; i < r.length ; i++) {
if (r[i].Time == lastBarTime[symbol]) { // 画图,更新当前BAR以及指标
// 更新
chart.add(klineIndex, [r[i].Time, r[i].Open, r[i].High, r[i].Low, r[i].Close], -1)
chart.add(klineIndex + 1, [r[i].Time, ema1[i]], -1)
chart.add(klineIndex + 2, [r[i].Time, ema2[i]], -1)
} else if (r[i].Time > lastBarTime[symbol]) { // 画图,添加BAR以及指标
// 添加
lastBarTime[symbol] = r[i].Time // 更新时间戳
chart.add(klineIndex, [r[i].Time, r[i].Open, r[i].High, r[i].Low, r[i].Close])
chart.add(klineIndex + 1, [r[i].Time, ema1[i]])
chart.add(klineIndex + 2, [r[i].Time, ema2[i]])
}
}
if (ema1Last3 < ema2Last3 && ema1Last2 > ema2Last2 && currTradeMsg[symbol] != currBarTime) {
// 金叉
var depth = exchange.GetDepth() // 获取当前订单薄深度数据
var price = depth.Asks[Math.min(takeLevel, depth.Asks.length)].Price // 取第10档价格,吃单
if (depth && price * amount <= account[quoteCurrency]) { // 获取深度数据正常,有足够资产下单
exchange.Buy(price, amount, ema1Last3, ema2Last3, ema1Last2, ema2Last2) // 下单买入
cancelAll(exchange) // 取消所有挂单
var acc = _C(exchange.GetAccount) // 获取账户资产信息
if (acc.Stocks != account[baseCurrency]) { // 检测账户资产发生变动
account[baseCurrency] = acc.Stocks // 更新资产
account[quoteCurrency] = acc.Balance // 更新资产
currTradeMsg[symbol] = currBarTime // 记录当前BAR已经交易
_G("currTradeMsg", currTradeMsg) // 持久化记录
var profit = getProfit(account, initAccount, lastPrices) // 计算收益
if (profit) {
LogProfit(profit, account, initAccount) // 打印收益
}
}
}
} else if (ema1Last3 > ema2Last3 && ema1Last2 < ema2Last2 && currTradeMsg[symbol] != currBarTime) {
// 死叉
var depth = exchange.GetDepth()
var price = depth.Bids[Math.min(takeLevel, depth.Bids.length)].Price
if (depth && amount <= account[baseCurrency]) {
exchange.Sell(price, amount, ema1Last3, ema2Last3, ema1Last2, ema2Last2)
cancelAll(exchange)
var acc = _C(exchange.GetAccount)
if (acc.Stocks != account[baseCurrency]) {
account[baseCurrency] = acc.Stocks
account[quoteCurrency] = acc.Balance
currTradeMsg[symbol] = currBarTime
_G("currTradeMsg", currTradeMsg)
var profit = getProfit(account, initAccount, lastPrices)
if (profit) {
LogProfit(profit, account, initAccount)
}
}
}
}
Sleep(1000)
})
// 状态栏表格变量
var tbl = {
type : "table",
title : "账户信息",
cols : [],
rows : []
}
// 将数据写入状态栏表格结构
tbl.cols.push("--")
tbl.rows.push(["初始"])
tbl.rows.push(["当前"])
_.each(account, function(val, key) {
if (typeof(initAccount[key]) == "number") {
tbl.cols.push(key)
tbl.rows[0].push(initAccount[key]) // 初始
tbl.rows[1].push(val) // 当前
}
})
// 显示状态栏表格
LogStatus(_D(), "\n", "profit:", getProfit(account, initAccount, lastPrices), "\n", "`" + JSON.stringify(tbl) + "`")
}
}
ETH,LTC,ETCは均線金
模擬ディスクのテストもできます.
戦略のソースコード:https://www.fmz.com/strategy/333783
戦略は,テストの復習,戦略設計の学習,実用盤の慎重な使用のためにのみ使用されます.
Mr.Huang. 2
Mr.Huang. 2
Mr.Huang. 1
軽い雲ありがとうございました!
wanghehe711@qq.comありがとう! ありがとう! 新人研究中ですが,実体テストではエラーが表示されました:GetOrders: Invalid ContractType これは管理の問題ですか?
発明者 量化 - 微かな夢ありがとうございました.
発明者 量化 - 微かな夢プログラミングを学ぶという戦略の例です. プログラミングを学ぶという戦略の例です.
wanghehe711@qq.com長期期貨に変えられるのか? 難しいです. 変えられるなら,試してみます.
発明者 量化 - 微かな夢この戦略は,先物ではなく現物戦略です.