Type/to search
8
Follow
1361
Followers
Контракт цифровой валюты простой копировальный торговый робот
Discussions
Created 2021-04-07 21:30:05  Updated 2024-12-05 21:59:36
 11
 4627

img

Контракт цифровой валюты простой копировальный торговый робот

В предыдущих статьях мы реализовали простого копировального торгового робота. Сегодня мы реализуем контрактную версию простого копировального торгового робота.

Идеи дизайна

Существует большая разница между контрактной версией робота для копирования сделок и спотовой версией. Спотовая копировальная торговля может быть достигнута в основном путем мониторинга изменений в активах счета. Фьючерсная версия требует отслеживания изменений позиций на счетах.
Таким образом, ситуация во фьючерсной версии более сложная, поскольку фьючерсы имеют длинные позиции, короткие позиции и различные контракты. Эту серию деталей необходимо обработать. Основная идея — отслеживать изменения позиций.
Запустить действие копирования на основе изменения положения. Когда он был впервые разработан, планировалось обрабатывать как длинные, так и короткие позиции одновременно, но оказалось, что это будет очень сложно. После анализа проблемы было принято решение обрабатывать длинные и короткие позиции по отдельности.

Реализация стратегии

Параметры стратегии:

img

Поддерживается бэктестинг, и вы можете напрямую использовать настройки по умолчанию для бэктестинга наблюдений.

Исходный код стратегии:

javascript
/*backtest start: 2021-03-18 00:00:00 end: 2021-04-07 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"},{"eid":"Futures_OKCoin","currency":"BTC_USD"},{"eid":"Futures_OKCoin","currency":"BTC_USD"}] */ function test() { // 测试函数 var ts = new Date().getTime() if (ts % (1000 * 60 * 60 * 6) > 1000 * 60 * 60 * 5.5) { Sleep(1000 * 60 * 10) var nowPosAmount = getPosAmount(_C(exchange.GetPosition), refCt) var longPosAmount = nowPosAmount.long var shortPosAmount = nowPosAmount.short var x = Math.random() if (x > 0.7) { exchange.SetDirection("buy") exchange.Buy(-1, _N(Math.max(1, x * 10), 0), "参考账户测试开单#FF0000") } else if(x < 0.2) { exchange.SetDirection("sell") exchange.Sell(-1, _N(Math.max(1, x * 10), 0), "参考账户测试开单#FF0000") } else if(x >= 0.2 && x <= 0.5 && longPosAmount > 4) { exchange.SetDirection("closebuy") exchange.Sell(-1, longPosAmount, "参考账户测试平仓#FF0000") } else if(shortPosAmount > 4) { exchange.SetDirection("closesell") exchange.Buy(-1, _N(shortPosAmount / 2, 0), "参考账户测试平仓#FF0000") } } } function getPosAmount(pos, ct) { var longPosAmount = 0 var shortPosAmount = 0 _.each(pos, function(ele) { if (ele.ContractType == ct && ele.Type == PD_LONG) { longPosAmount = ele.Amount } else if (ele.ContractType == ct && ele.Type == PD_SHORT) { shortPosAmount = ele.Amount } }) return {long: longPosAmount, short: shortPosAmount} } function trade(e, ct, type, delta) { var nowPosAmount = getPosAmount(_C(e.GetPosition), ct) var nowAmount = type == PD_LONG ? nowPosAmount.long : nowPosAmount.short if (delta > 0) { // 开仓 var tradeFunc = type == PD_LONG ? e.Buy : e.Sell e.SetDirection(type == PD_LONG ? "buy" : "sell") tradeFunc(-1, delta) } else if (delta < 0) { // 平仓 var tradeFunc = type == PD_LONG ? e.Sell : e.Buy e.SetDirection(type == PD_LONG ? "closebuy" : "closesell") if (nowAmount <= 0) { Log("未检测到持仓") return } tradeFunc(-1, Math.min(nowAmount, Math.abs(delta))) } else { throw "错误" } } function main() { LogReset(1) if (exchanges.length < 2) { throw "没有跟单的交易所" } var exName = exchange.GetName() // 检测参考交易所 if (!exName.includes("Futures_")) { throw "仅支持期货跟单" } Log("开始监控", exName, "交易所", "#FF0000") // 检测跟单交易所 for (var i = 1 ; i < exchanges.length ; i++) { if (exchanges[i].GetName() != exName) { throw "跟单的期货交易所和参考交易所不同!" } } // 设置交易对、合约 _.each(exchanges, function(e) { if (!IsVirtual()) { e.SetCurrency(refCurrency) if (isSimulate) { if (e.GetName() == "Futures_OKCoin") { e.IO("simulate", true) } } } e.SetContractType(refCt) }) var initRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt) while(true) { if (IsVirtual()) { // 回测时才模拟 test() // 测试函数,模拟参考账户主动交易,触发跟单账户跟单 } Sleep(5000) var nowRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt) var tbl = { type : "table", title : "持仓", cols : ["名称", "标签", "多仓", "空仓", "账户资产(Stocks)", "账户资产(Balance)"], rows : [] } _.each(exchanges, function(e) { var pos = getPosAmount(_C(e.GetPosition), refCt) var acc = _C(e.GetAccount) tbl.rows.push([e.GetName(), e.GetLabel(), pos.long, pos.short, acc.Stocks, acc.Balance]) }) LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`") // 计算仓位变动量 var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short // 检测变动 if (longPosDelta == 0 && shortPosDelta == 0) { continue } else { // 检测到仓位变动 for (var i = 1 ; i < exchanges.length ; i++) { // 执行多头动作 if (longPosDelta != 0) { Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "执行多头跟单,变动量:", longPosDelta) trade(exchanges[i], refCt, PD_LONG, longPosDelta) } // 执行空头动作 if (shortPosDelta != 0) { Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "执行空头跟单,变动量:", shortPosDelta) trade(exchanges[i], refCt, PD_SHORT, shortPosDelta) } } } // 执行跟单操作后,更新 initRefPosAmount = nowRefPosAmount } }

тест

Поскольку OKEX может использовать диск моделирования OKEX после обновления интерфейса V5, для удобства тестирования я использовал два ключа API диска моделирования OKEX.

Первый добавленный объект обмена — это ссылочный обмен, а копировальный обмен будет следовать за этой учетной записью обмена.
На странице имитации торговли OKEX вручную разместите 3 квартальных контракта на монеты ETH на основе биржевого счета.

img

Видно, что реальный рынок фиксирует изменения в позициях счетов референтной биржи, а затем отслеживает операции.

img

Давайте попробуем закрыть две контрактные позиции, которые мы только что открыли. Позиции после закрытия выглядят так, как показано на рисунке:

img

Следите за операцией в реальном времени и закройте 2 контракта.

img

Эта стратегия разработана простым и понятным способом, без какой-либо оптимизации. Улучшение все еще должно касаться деталей, таких как обнаружение активов при выполнении заказов. Для простоты дизайна рыночные заказы используются для выполнения заказов . Стратегия предоставляет только идеи для обучения, а фактическая торговля будет оптимизирована в соответствии с потребностями.

Адрес стратегии: https://www.fmz.com/strategy/270012

Вы можете оставить сообщение.

Related Recommendations
Comment
All comments (11)

    2个不同的交易所不能对接么

    4 years ago

    可以实现的,改下代码就可以了。

    4 years ago

    具体改哪里能请教一下么,我现在用的bibox期货,想对接跟单别人的okx交易所的话,需要改哪里呢

    4 years ago

    因为交易所的合约规格可能不一样,可能要根据具体情况调整跟单的代码。

    4 years ago

    发明者什么时候能对接币赢合约期货啊?币安和欧意返手续费太少了,高频机器人,手续费太伤了

    4 years ago

    我用的bibox交易所,有百分之80的返佣,FMZ完美支持

    4 years ago

    这边评估下这个交易所,还没有交易所方面联系过我们。

    4 years ago

    希望有个币安usdt的跟单版本哈

    5 years ago

    希望有币安usdt永续合约版本,执行者的API?????

    5 years ago

    希望能有火币usdt永续合约版本的

    5 years ago

    很感谢你的分享,很值得学习。

    5 years ago
  • 1
iPhone Download
Forums
PINE Language
© 2015 - ∞ INVENTOR PTE LTD (SG)