Двухсторонняя контрактная торговая сетка v1.0.2

Автор:ветер, Дата: 2021-06-24 15:37:17
Тэги:Решетка

Двухсторонняя контрактная торговая сетка v1.0.2

Функции

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

  • Покупатели считают, что покупка слишком поздняя
  • Удвоение
  • Автоматическая оплата
  • Тенденция к открытой платформе (в разработке, платная версия)
  • Динамические изменения в количестве заказов (в разработке, платная версия)
  • Появление "Золотой вилки" (в разработке, платная версия)

Проверка данных

img

img

Удвоилось за полгода 2000 года. Получается, что выигрыш очевиден, и мы можем выдержать рост или падение.

Сохранение

Постоянная оптимизация



/*backtest
start: 2021-01-01 00:00:00
end: 2021-06-21 23:59:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","balance":2000}]
*/

// 首次买入
let FIRST_BUY = true;
// 已存在买涨订单
let MANY_BUYING = false;
// 已存在做空订单
let SHORT_BUYING = false;
// 买涨订单创建时间
let MANY_BUY_TIME = null;
// 做空订单创建时间
let SHORT_BUY_TIME = null;
// 买涨空仓时间
let MANY_EMPTY_STEP_TIME = null;
// 做空空仓时间
let SHORT_EMPTY_STEP_TIME = null;
// 校验空仓时间
let CHECK_TIME = null;

let QUANTITY = [0.001, 0.002, 0.004, 0.008, 0.016, 0.032, 0.064];
// 下次购买价格(多仓)
let MANY_NEXT_BUY_PRICE = 0;
// 下次购买价格(空仓)
let SHORT_NEXT_BUY_PRICE = 0;
// 当前仓位(多仓)
let MANY_STEP = 0;
// 当前仓位(空仓)
let SHORT_STEP = 0;
// 止盈比率
let PROFIT_RATIO = 1;
// 补仓比率
let DOUBLE_THROW_RATIO = 1.5;
// 卖出后下次购买金额下浮比率
let BUY_PRICE_RATIO = 1;
// 交易订单列表(多仓)
let MANY_ORDER_LIST = [];
// 交易订单列表(空仓)
let SHORT_ORDER_LIST = [];

function getManyQuantity() {
    if (MANY_STEP < QUANTITY.length) {
        return QUANTITY[MANY_STEP]
    }
    return QUANTITY[0]
}

function getShortQuantity() {
    if (SHORT_STEP < QUANTITY.length) {
        return QUANTITY[SHORT_STEP]
    }
    return QUANTITY[0]
}

function firstManyBuy(ticker) {
    if (MANY_BUYING) {
        return
    }
    exchange.SetDirection("buy")
    let orderId = exchange.Buy(ticker.Last, getManyQuantity())
    if (!orderId) {
        return
    }
    MANY_BUYING = true
    while (true) {
        exchange.SetDirection("buy") 
        let order = exchange.GetOrder(orderId)
        if (null === order) {
            continue
        }
        if (1 === order.Status || 2 === order.Status) {
            MANY_NEXT_BUY_PRICE = order.Price * ((100 - DOUBLE_THROW_RATIO) / 100)
            MANY_STEP = MANY_STEP + 1
            MANY_BUYING = false
            MANY_EMPTY_STEP_TIME = null
            let sellPrice = order.Price * ((100 + PROFIT_RATIO) / 100)
            MANY_ORDER_LIST.push({
                buyPrice: order.Price,
                sellPrice: sellPrice,
                quantity: order.Amount,
                isSell: false,
            })
            break
        }
    }
}

function firstShortBuy(ticker) {
    if (SHORT_BUYING) {
        return
    }
    exchange.SetDirection("sell")
    let orderId = exchange.Sell(ticker.Last, getShortQuantity())
    if (!orderId) {
        return
    }
    SHORT_BUYING = true
    while (true) {
        let order = exchange.GetOrder(orderId)
        if (null === order) {
            continue
        }
        if (1 === order.Status || 2 === order.Status) {
            SHORT_NEXT_BUY_PRICE = order.Price * ((100 + DOUBLE_THROW_RATIO) / 100)
            SHORT_STEP = SHORT_STEP + 1
            SHORT_BUYING = false
            SHORT_EMPTY_STEP_TIME = null
            let sellPrice = order.Price * ((100 - PROFIT_RATIO) / 100)
            SHORT_ORDER_LIST.push({
                buyPrice: order.Price,
                sellPrice: sellPrice,
                quantity: order.Amount,
                isSell: false,
            })
            break
        }
    }
}

function manyBuy(ticker) {
    if (MANY_BUYING) {
        return
    }
    Log('ticker: ' + ticker.Last + ' MANY_NEXT_BUY_PRICE: ' + MANY_NEXT_BUY_PRICE)
    if (ticker.Last > MANY_NEXT_BUY_PRICE) {
        return
    }
    exchange.SetDirection("buy")
    let orderId = exchange.Buy(ticker.Last, getManyQuantity())
    if (!orderId) {
        return
    }
    MANY_BUYING = true
    MANY_BUY_TIME = Unix()
    while (true) {
        let now = Unix()
        let order = exchange.GetOrder(orderId)
        let expire = MANY_BUY_TIME + (60 * 30)
        if (null === order) {
            continue
        }
        // 买入成功处理
        if (1 === order.Status || 2 === order.Status) {
            MANY_NEXT_BUY_PRICE = order.Price * ((100 - DOUBLE_THROW_RATIO) / 100)
            MANY_STEP = MANY_STEP + 1
            MANY_BUYING = false
            MANY_EMPTY_STEP_TIME = null
            let sellPrice = order.Price * ((100 + PROFIT_RATIO) / 100)
            MANY_ORDER_LIST.push({
                buyPrice: order.Price,
                sellPrice: sellPrice,
                quantity: order.Amount,
                isSell: false,
            })
            break
        }
        // 买入超时处理
        if (now >= expire) {
            exchange.CancelOrder(orderId)
            MANY_BUYING = false
            MANY_BUY_TIME = null
            MANY_NEXT_BUY_PRICE = ticker.Last * ((100 - DOUBLE_THROW_RATIO) / 100)
            return
        }
    }
}

function shortBuy(ticker) {
    if (SHORT_BUYING) {
        return
    }
    Log('ticker: ' + ticker.Last + ' SHORT_NEXT_BUY_PRICE: ' + SHORT_NEXT_BUY_PRICE)
    if (ticker.Last < SHORT_NEXT_BUY_PRICE) {
        return
    }
    exchange.SetDirection("sell")
    let orderId = exchange.Sell(ticker.Last, getShortQuantity())
    if (!orderId) {
        return
    }
    SHORT_BUYING = true
    SHORT_BUY_TIME = Unix()
    while (true) {
        let now = Unix()
        let expire = SHORT_BUY_TIME + (60 * 30)
        let order = exchange.GetOrder(orderId)
        if (null === order) {
            continue
        }
        // 买入成功处理
        if (1 === order.Status || 2 === order.Status) {
            SHORT_NEXT_BUY_PRICE = order.Price * ((100 + DOUBLE_THROW_RATIO) / 100)
            SHORT_STEP = SHORT_STEP + 1
            SHORT_BUYING = false
            SHORT_EMPTY_STEP_TIME = null
            let sellPrice = order.Price * ((100 - PROFIT_RATIO) / 100)
            SHORT_ORDER_LIST.push({
                buyPrice: order.Price,
                sellPrice: sellPrice,
                quantity: order.Amount,
                isSell: false,
            })
            break
        }
        // 买入超时处理
        if (now >= expire) {
            exchange.CancelOrder(orderId)
            SHORT_BUYING = false
            SHORT_BUY_TIME = null
            SHORT_NEXT_BUY_PRICE = ticker.Last * ((100 + DOUBLE_THROW_RATIO) / 100)
            return
        }
    }
}


function manySell(ticker) {
    // 遍历卖出订单
    for (let item of MANY_ORDER_LIST) {
        if (item.isSell) {
            continue
        }
        if (ticker.Last >= item.sellPrice) {
            item.isSell = true;
            exchange.SetDirection("closebuy")
            let orderId = exchange.Sell(ticker.Last, item.quantity)
            if (!orderId) {
                return
            }
            while (true) {
                let order = exchange.GetOrder(orderId)
                if (null === order) {
                    continue
                }
                if (1 === order.Status || 2 === order.Status) {
                    MANY_NEXT_BUY_PRICE = ticker.Last * ((100 - BUY_PRICE_RATIO) / 100)
                    MANY_STEP = MANY_STEP - 1
                    if (0 === MANY_STEP) {
                        MANY_EMPTY_STEP_TIME = Unix()
                    }
                    break
                }
            }
        }
    }
}

function shortSell(ticker) {
    // 遍历卖出订单
    for (let item of SHORT_ORDER_LIST) {
        if (item.isSell) {
            continue
        }
        if (ticker.Last <= item.sellPrice) {
            item.isSell = true;
            exchange.SetDirection("closesell")
            let orderId = exchange.Buy(ticker.Last, item.quantity)
            if (!orderId) {
                return
            }
            while (true) {
                let order = exchange.GetOrder(orderId)
                if (null === order) {
                    continue
                }
                if (1 === order.Status || 2 === order.Status) {
                    SHORT_NEXT_BUY_PRICE = ticker.Last * ((100 + BUY_PRICE_RATIO) / 100)
                    SHORT_STEP = SHORT_STEP - 1
                    if (0 === SHORT_STEP) {
                        SHORT_EMPTY_STEP_TIME = Unix()
                    }
                    break
                }
            }
        }
    }
}

function check(ticker) {
    let now = Unix()
    if (null !== CHECK_TIME) {
        let expire = CHECK_TIME + (60 * 10)
        if (now < expire) {
            return
        }
    }
    CHECK_TIME = now

    if (null !== MANY_EMPTY_STEP_TIME) {
        let expire = MANY_EMPTY_STEP_TIME + (60 * 30)
        if (now >= expire) {
            MANY_NEXT_BUY_PRICE = ticker.Last * ((100 - DOUBLE_THROW_RATIO) / 100)
            Log('没有买涨持仓, 调整买入价: ' + MANY_NEXT_BUY_PRICE)
        }
    }
    
    if (null !== SHORT_EMPTY_STEP_TIME) {
        let expire = SHORT_EMPTY_STEP_TIME + (60 * 30)
        if (now >= expire) {
            SHORT_NEXT_BUY_PRICE = ticker.Last * ((100 + DOUBLE_THROW_RATIO) / 100)
            Log('没有做空持仓, 调整买入价: ' + SHORT_NEXT_BUY_PRICE)
        }
    }
}

function onTick() {
    // 在这里写策略逻辑,将会不断调用,例如打印行情信息
    let ticker = exchange.GetTicker()
    if (!ticker) {
        return
    }
    if (FIRST_BUY) {
        // 首次做多购买
        firstManyBuy(ticker)
        // 首次做空购买
        firstShortBuy(ticker)
        FIRST_BUY = false
        return
    }
    
    // 做多买入
    manyBuy(ticker)
    // 做空买入
    shortBuy(ticker)
    // 做多卖出
    manySell(ticker)
    // 做空卖出
    shortSell(ticker)
    // 空仓检测
    check(ticker)
}

function main() {
    // 开合约
    exchange.SetContractType("swap")

    while(true){
        onTick()
        // Sleep函数主要用于数字货币策略的轮询频率控制,防止访问交易所API接口过于频繁
        Sleep(60000)
    }
}


Связанные

Больше

Хекси8Можно ли использовать несколько валют?

Рич_рориЧто означает check..... регулярное увеличение/уменьшение порога покупки?

артронаПочему у этого нет параметров стратегии?

"Экзод" [перевод стратегии]Также обнаружена проблема, что во время ретро-тестирования 2020-1-1 до 2020-6 все роботы останавливаются до 3-30 числа, кроме того, когда тестируется ETH, то в ходе тестирования 2021-1-1 до 201-6-21 будет останавливаться до 1-2 числа, не знаю, является ли это проблемой fmz или роботов.

ЭванЭто не может быть настоящим хеджированием. Это как контрактная сетка.

"Экзод" [перевод стратегии]Мы не получили никакого ответа, только несколько слов, и мы работали 7 дней, 200 ножей и 70 золотых. По моему исследованию было обнаружено, что обновление позиции в течение 10 минут не имеет смысла, что приводит к медленным изменениям, и не открывает двустороннюю позицию. Например, сегодня BTC упал на 5% и не открыл позицию. Нужно ли здесь оптимизировать? Например, продлить диапазон обнаружения? Кроме того, если в крупных рынках открывается двусторонний прорыв, если один прорыв является минимальным, то не очень понятно. 2. взрыв по умолчанию накладывать деньги, чтобы не взрыв необходимо обеспечить 1000 ножей до 2000 ножей и более средств, я дваста ножей сегодня, если нет каких-то странных просыпаться я уже взрыв, временный дополнительный гарантийный сумма. Если средств недостаточно, вы можете также самостоятельно адаптировать количество накладывания, здесь напомните, чтобы не смотреть на код взрыв. 3.Пожалуйста, спросите, так как никогда не прекращаются убытки, так что при достаточном капитале никогда не будет взрыва, но почему в рецензировании возникают убытки? Эта стратегия мне очень нравится, вы можете получать прибыль независимо от направления, корректировка размеров размеров и капиталовложения не является большим риском, чувство корректировки открытых и открытых цены можно оптимизировать, в зависимости от капитала добавления адаптировать размеров размеров размеров и т.д.

ДаXБрат в Telegram

"Экзод" [перевод стратегии]Это решение, и мы сможем обменять его на биткоин.

"Экзод" [перевод стратегии]Просмотр повторного проверки чувствует себя хорошо, но, похоже, не может использоваться на реальном диске? Я открываю токен bch, который возвращает ошибку, Sell ((490.14, 0.001): map[err_code:1067 err_msg:The volume field is illegal. Please re-enter. status:error ts:1.625132342294e+12].

wbsyНикаких реальных дисков?

"Экзод" [перевод стратегии]Это ужасная кривая прибыли, потеря более 120%.

Пьяный поднимает лампу и смотрит на меч.Смеялся надо мной.

"Экзод" [перевод стратегии]Невыносимо, сегодня у нас не хватает денег, и я очень надеюсь на 2.0, пожалуйста, спросите, как я могу испытать новую стратегию.

ветерЭти проблемы были обнаружены в разработке 2.0. Причина, по которой вы не можете сделать покупку, заключается в том, что процент открытых сделок фиксирован, то есть выросли на один процент, вы сделали покупку, упали на один процент, купили покупку. Поскольку падение цены составляет один процент, и процент падения цены на покупку является одинаковым, от 1000 до 1500 тонн, 1000 процентов и 1500 процентов отличаются друг от друга, то покупка вакансий сложнее, а изменение цены слишком часто, что приводит к тому, что вакансии могут быть не куплены. Проблема остановки убытков, в версии 2.0 была сделана определенная обработка, очень простая обработка остановки убытков, но с точки зрения данных обратного измерения эффект также возможен, когда вы покупаете или делаете свободные позиции, когда вы достигаете определенного порога, вы начинаете продавать целый пакет, 1.0 не обрабатывается, поэтому возникают некоторые заказы, которые никогда не могут быть выполнены, например, в BTC 65000 количество покупателей 0.001, тогда BTC упал этот набор никогда не выйдет. /upload/asset/2034c4ec56c423120b9c6.png /upload/asset/203032c94e60a3915cc9f.png /upload/asset/2030b880b030476977f4b.png /upload/asset/2030d89e9fd59f528be4c.png

ветерЯ проверил, на каком реальном диске работает Binance, что другие платформы могут сообщать о некоторых ошибках.

ветерФизические диски еще работают, нужно время

ветерПосмотрите на последнюю кривую, в которой появилась ошибка.