- Square
- TradingView策略信号下单机器人-币安版
TradingView策略信号下单机器人-币安版
Author:
高频量化, Date: 2022-08-19 16:38:43
Tags:
/*
- 交互命令字符串格式
action:amount
action: buy , sell , long , short , cover_long , cover_short, spk , bpk
- 交易所类型
eType变量取值: 0 spot , 1 futures
- TV文档链接
https://www.tradingview.com/pine-script-docs/en/v4/Quickstart_guide.html
https://cn.tradingview.com/chart/8xfTuX7F/
- TV webhook 发送请求
https://www.fmz.com/api/v1?access_key=xxx&secret_key=yyyy&method=CommandRobot&args=[186515,"action:amount"]
- 引用类库
引用数字货币交易类库
*/
// 参数
//var IsMarketOrder = true
var QuotePrecision = 3
var BasePrecision = 3
// 期货参数
var Ct = "swap"
//exchange.SetContractType("swap") // 设置为永续合约
//exchange.SetCurrency("BTC_USDT")
// 全局变量
var BUY = "buy"
var SELL = "sell"
var LONG = "long"
var SHORT = "short"
var COVER_LONG = "cover_long"
var COVER_SHORT = "cover_short"
var SPK = "spk"
var BPK = "bpk"
//------------------- 添加
const accountInformation = { //账号信息
type: 'table',
title: '账号信息',
cols: ['初始余额', '钱包余额 ', '保证金余额', '可用保证金', '已用保证金', '总收益', '收益率'], //列表头
rows: null //列表数组
};
const binanceFundingRate = { //持仓单数组
type: 'table',
title: '币安U本位持仓单',
cols: ['交易对', '交易方向 ', '开仓量', '开仓价格', '持仓价值', '杠杆', '占用保证金', '持仓盈利'], //列表头
rows: null //列表数组
};
initialPrincipalUsdt = null //初始本金/usdt
revenueUsdt = 0 //曲线
//--------------------------------------
//账号信息
//--------------------------------------
function accountInformationfunction() {
exchange.SetContractType("swap"); // 设置为永续合约 swap / quarter/
var Currency = exchange.GetCurrency()
exchange.SetCurrency(Currency) //切换产品访问的是U本位的账号信息
var account = _C(exchange.GetAccount)
_CDelay(2000 * 60)
if (!account) {
Log("没有获取资产")
return
}
if (initialPrincipalUsdt==null ) {
initialPrincipalUsdt = account.Info.totalWalletBalance //获取加载的时候,净值记录为开始余额
_G("initialPrincipalUsdt", initialPrincipalUsdt) //获取保存的数据
if (initialPrincipalUsdt == 0) {
Log("USDT合约中没有资产")
return
}
}
/*API
"totalInitialMargin": "0.00000000", // 以USD计价的所需起始保证金总额
"totalMaintMargin": "0.00000000", // 以USD计价的维持保证金总额
"totalWalletBalance": "126.72469206", // 以USD计价的账户总余额
"totalUnrealizedProfit": "0.00000000", // 以USD计价的持仓未实现盈亏总额
"totalMarginBalance": "126.72469206", // 以USD计价的保证金总余额
"totalPositionInitialMargin": "0.00000000", // 以USD计价的持仓所需起始保证金(基于最新标记价格)
"totalOpenOrderInitialMargin": "0.00000000", // 以USD计价的当前挂单所需起始保证金(基于最新标记价格)
"totalCrossWalletBalance": "126.72469206", // 以USD计价的全仓账户余额
"totalCrossUnPnl": "0.00000000", // 以USD计价的全仓持仓未实现盈亏总额
"availableBalance": "126.72469206", // 以USD计价的可用余额
"maxWithdrawAmount": "126.72469206" // 以USD计价的最大可转出余额
*/
InitialBalance = Number(initialPrincipalUsdt)
WalletBalance = account.Info.totalWalletBalance
marginBalance = account.Info.totalCrossWalletBalance
FreeMargin = account.Info.availableBalance
UsedMargin = account.Info.totalMaintMargin
TotalRevenue = Number(WalletBalance) - Number(InitialBalance)
Yield1 = TotalRevenue / InitialBalance
yield1 = Number(Yield1)
Yield = (yield1 * 100).toFixed(2) + "%"
//封装在数组中
revenueUsdt = Number(TotalRevenue)
accountInformation.rows = [] //置空
//'初始余额', '钱包余额 ', '保证金余额', '可用保证金', '已用保证金', '总收益', '收益率'
accountInformation.rows[0] = [InitialBalance, WalletBalance, marginBalance, FreeMargin, UsedMargin, TotalRevenue, Yield]
}
//--------------------------------------
//持仓单数组
//--------------------------------------
function binanceFundingRatefunction() { //持仓单数组
binanceFundingRate.rows = []
exchange.SetContractType("swap"); // 设置为永续合约,注意币本位和USDT本位都存在永续
var y = 0 //判断没有改产品也可以
for (var i = 0; i < exchanges.length; i++) {
exchange.SetCurrency(exchanges[i].GetCurrency()) //切换产品
//-------------------------------------------------------
var position = _C(exchange.GetPosition) //获取账号持仓情况
// Log("position", position)
_CDelay(1000 * 2 * 60)
//币本位不一样的跨期合约放在一个数组。永续与之不一样
if (position) {
for (var iii = 0; iii < position.length; iii++) {
if (exchange.GetContractType() == position[iii].ContractType) { //为什么要判断,因为跨期合约的持仓,都放在一起了
binanceFundingRate.rows[y] = [position[iii].Info.symbol, position[iii].Type == 0 ? "BUY" : "SELL", position[iii].Amount,
position[iii].Price, position[iii].Amount * position[iii].Price,
position[iii].MarginLevel, position[iii].Margin, position[iii].Profit
]
y++
}
}
}
}
}
//--------------------------------------
//主函数
//--------------------------------------
function main() {
// 清空日志,如不需要,可以删除
//LogReset(1)
// 设置精度
exchange.SetPrecision(QuotePrecision, BasePrecision)
// 识别期货还是现货
var eType = 0
var eName = exchange.GetName() //交易所名称 如:Futures_Binance
var patt = /Futures_/
if (patt.test(eName)) { //判断是否带有Futures_ 期货交易的话设置合约为永续 Ct = "swap"
Log("添加的交易所为期货交易所:", eName, "#FF0000")
eType = 1
if (Ct == "") {
throw "Ct 合约设置为空"
} else {
Log(exchange.SetContractType(Ct), "设置合约:", Ct, "#FF0000")
}
} else {
Log("添加的交易所为现货交易所:", eName, "#32CD32")
}
//测试持仓函数
var position3 = exchange.GetPosition()
if (position3.length == 0) {
Log("机器人首次启动,正在对交易所进行全面检查", "#33CD33")
Log(exchange.GetLabel(), "账户信息初始化完成:交易所没有持仓单子,一切正常", "#0000FF")
Log("机器人已就绪! !等待信号! !", "#0000FF")
}
if (position3.length > 0) {
Log("机器人首次启动,正在对交易所进行全面检查", "#33CD33")
Log(exchange.GetLabel(), "账户信息初始化完成:交易所检查异常,有单子持仓, 请确认! ! !,", "持有仓位种类", position3.length, "(种)", "持仓数量:", position3[0].Amount, "(张/币)", "持仓方向:", position3[0].Type, "(0代表多单/1代表空单)", "#0000FF")
Log("机器人已就绪! ! 等待信号中! ! !", "#0000FF")
}
var lastMsg = ""
var position = _C(exchange.GetPosition)
var acc = _C(exchange.GetAccount)
//LogProfit(acc.Balance)
//LogProfit(acc.Balance, '&')
//LogProfit(acc.Stocks)
//var acc = exchange.GetAccount
Log(acc);
var count = 0 //记录循环次数
if(initialPrincipalUsdt==null){
initialPrincipalUsdt = _G("initialPrincipalUsdt") //获取保存的数据
}
while (true) {
var cmd = GetCommand()
if (!cmd) {
//Log("没有接收到cmd命令:", cmd, "#FF0000")
//continue
}
if (cmd) {
// 检测交互命令
Log("接收到来自TradingView的警报信号", cmd, "#32CD32")
Log("开始执行本次信号循环处理!", "#32CD32")
lastMsg = "命令:" + cmd + "时间:" + _D()
var arr = cmd.split(":")
if (arr.length != 2) {
Log("cmd信息有误:", cmd, "(请确认开仓或平仓的命令是否正确)", "#FF0000")
continue
}
var action = arr[0]
var amount = parseFloat(arr[1])
//var amount = 0.01 //等号后面合约张数的数量
//Log(action, amount)
//Log("电报群共享的为FMZ第一版本的机器人代码,仅供学习用,如需完美对接电报群里播报信号的TradingView策略或想要更多优质TV策略的请联系群主18664029094", "#0000FF")
//Log("微信 tian-qi-666 或电报群 //t.me/tq16889 或Bilbil视频上搜索:收益14500%策略详细使用方法或500U账户如何用复利下单全自动交易", "#FF0000")
//Log("TradingView策略如何对接到发明者(FMZ)量化机器人的?发明者如何依据TV的信号对币安或OKEX等交易所进行全自动开仓平仓做单的? ", "#0000FF")
//现货处理逻辑
if (eType == 0) {
if (action == BUY) {
var buyInfo = IsMarketOrder ? exchange.Buy(-1, amount) : $.Buy(amount)
Log("buyInfo:", buyInfo)
} else if (action == SELL) {
var sellInfo = IsMarketOrder ? exchange.Sell(-1, amount) : $.Sell(amount)
Log("sellInfo:", sellInfo)
} else {
Log("现货交易所不支持!", "#FF0000")
}
//期货处理逻辑
} else if (eType == 1) {
var tradeInfo = null
var ticker = _C(exchange.GetTicker)
if (action == LONG) {
Log("开多:", amount, "#32CD32")
//如果发过来的是long:0.01指令,那就平空,同时执行开多命令
//exchange.SetDirection("closesell")
//var tradeInfo1 = IsMarketOrder ? exchange.Buy(-1, amount) : exchange.Buy(ticker.Sell, amount)
//exchange.SetDirection("buy")
//var tradeInfo2 = IsMarketOrder ? exchange.Buy(-1, amount) : exchange.Buy(ticker.Sell, amount)
//tradeInfo = [tradeInfo1, tradeInfo2]
exchange.SetDirection("buy")
tradeInfo = IsMarketOrder ? exchange.Buy(-1, amount) : exchange.Buy(ticker.Sell, amount)
Log("本次信号处理完毕!!! 等待接受新的信号!!!", "#0000FF")
} else if (action == SHORT) {
Log("开空:", amount, "#32CD32")
//如果发过来的是short:0.01指令,那就平多,同时执行做空命令
//exchange.SetDirection("closebuy")
//var tradeInfo1 = IsMarketOrder ? exchange.Sell(-1, amount) : exchange.Sell(ticker.Buy, amount)
//exchange.SetDirection("sell")
//var tradeInfo2 = IsMarketOrder ? exchange.Sell(-1, amount) : exchange.Sell(ticker.Buy, amount)
//tradeInfo = [tradeInfo1, tradeInfo2]
exchange.SetDirection("sell")
tradeInfo = IsMarketOrder ? exchange.Sell(-1, amount) : exchange.Sell(ticker.Buy, amount)
Log("本次信号处理完毕!!! 等待接受新的信号!!!", "#0000FF")
} else if (action == COVER_LONG) {
Log("平多单:", amount, "#32CD32")
//增加是否有持仓情况判断
// 依次取回数据获取的结果
var account = _C(exchange.GetAccount)
if (!ticker || !account) {
Log(exchange.GetLabel(), ":获取交易数据异常,先不下单,跳过。", "@")
continue
}
// 获取持仓情况
var position = exchange.GetPosition()
// if (position_size != 0)
// Log(exchanges[i].GetLabel(), "的持仓数量为:", position_size)
if (position.length == 0) {
Log(exchange.GetLabel(), ":没有持仓,不做平仓.")
Log("本次信号处理完毕!!! 等待接受新的信号!!!", "#0000FF")
continue
}
//如果发过来的是cover_long:2指令,那就平多,同时平空
//exchange.SetDirection("closebuy")
//var tradeInfo1 = IsMarketOrder ? exchange.Sell(-1, amount) : exchange.Sell(ticker.Buy, amount)
//exchange.SetDirection("closesell")
//var tradeInfo2 = IsMarketOrder ? exchange.Buy(-1, amount) : exchange.Buy(ticker.Sell, amount)
//tradeInfo = [tradeInfo1, tradeInfo2]
exchange.SetDirection("closebuy")
tradeInfo = IsMarketOrder ? exchange.Sell(-1, amount) : exchange.Sell(ticker.Buy, amount)
Log("本次信号处理完毕!!! 等待接受新的信号!!!", "#0000FF")
} else if (action == COVER_SHORT) {
Log("平空单:", amount, "#32CD32")
//增加是否有持仓情况判断
// 依次取回数据获取的结果
var account1 = _C(exchange.GetAccount)
if (!ticker || !account1) {
Log(exchange.GetLabel(), ":获取交易数据异常,先不下单,跳过。", "@")
continue
}
// 获取持仓情况
var position1 = exchange.GetPosition()
// if (position_size != 0)
// Log(exchanges[i].GetLabel(), "的持仓数量为:", position_size)
if (position1.length == 0) {
Log(exchange.GetLabel(), ":没有持仓,不做平仓.")
Log("本次信号处理完毕!!! 等待接受新的信号!!!", "#0000FF")
continue
}
//如果发过来的是cover_short:0.01指令,那就平多,同时平空
//exchange.SetDirection("closebuy")
//var tradeInfo1 = IsMarketOrder ? exchange.Sell(-1, amount) : exchange.Sell(ticker.Buy, amount)
//exchange.SetDirection("closesell")
//var tradeInfo2 = IsMarketOrder ? exchange.Buy(-1, amount) : exchange.Buy(ticker.Sell, amount)
//tradeInfo = [tradeInfo1, tradeInfo2]
exchange.SetDirection("closesell")
tradeInfo = IsMarketOrder ? exchange.Buy(-1, amount) : exchange.Buy(ticker.Sell, amount)
Log("本次信号处理完毕!!! 等待接受新的信号!!!", "#0000FF")
} else if (action == SPK) { // 卖出平多仓,卖出开空仓
exchange.SetDirection("closebuy")
var tradeInfo1 = IsMarketOrder ? exchange.Sell(-1, amount) : exchange.Sell(ticker.Buy, amount)
exchange.SetDirection("sell")
var tradeInfo2 = IsMarketOrder ? exchange.Sell(-1, amount) : exchange.Sell(ticker.Buy, amount)
tradeInfo = [tradeInfo1, tradeInfo2]
} else if (action == BPK) { // 买入平空仓,买入开多仓
exchange.SetDirection("closesell")
var tradeInfo1 = IsMarketOrder ? exchange.Buy(-1, amount) : exchange.Buy(ticker.Sell, amount)
exchange.SetDirection("buy")
var tradeInfo2 = IsMarketOrder ? exchange.Buy(-1, amount) : exchange.Buy(ticker.Sell, amount)
tradeInfo = [tradeInfo1, tradeInfo2]
} else {
Log("期货交易所不支持!", "#FF0000")
}
if (tradeInfo) {
Log("tradeInfo:", tradeInfo)
}
} else {
throw "eType error, eType:" + eType
}
acc = _C(exchange.GetAccount)
}
/* //原来有
var tbl = {
type: "table",
title: "状态信息",
cols: ["数据"],
rows: []
}
tbl.rows.push([JSON.stringify(acc)])
LogStatus(_D(), eName, "上次接收到的命令:", lastMsg, "\n", "`" + JSON.stringify(tbl) + "`")
*/
if (count % 100 == 0) {
//展示持仓与挂单信息
// binanceOrderRate()
// FirmOfferIncome()
accountInformationfunction() //账号信息
binanceFundingRatefunction() //持仓单数组
//一小时才记录一次
if (count % 600 == 0) {
LogProfit(revenueUsdt, '&') //资金曲线
}
}
LogStatus("上次接收到的命令:", lastMsg, "\n",
'\n`' + JSON.stringify("最后更新时间:" + _D()) + '`\n' +
'\n`' + JSON.stringify([accountInformation]) + '`\n' +
'\n`' + JSON.stringify([binanceFundingRate]) + '`\n'
); //栏目框展示
count++
_G("initialPrincipalUsdt", initialPrincipalUsdt) //获取保存的数据
Sleep(1000)
}
}
More