В процессе загрузки ресурсов... загрузка...

Куантизация монетного круга выглядит совершенно по-новому - приближает вас к квантизации монетного круга.

Автор:Изобретатели количественного измерения - мечты, Создано: 2021-05-28 09:50:12, Обновлено: 2023-09-21 21:06:08

img

Куантизация монетного круга. Новый взгляд на монетный круг.

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

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

    Первая деталь, которую мы должны рассмотреть, это дизайн бесконечной сетки.createNetТак? Функция создает сетевую структуру, в которой сетевые линии имеют ограниченное количество чисел. Так что, если цена выходит за пределы этой сетевой структуры при выполнении стратегии (выходит за пределы сетевой линии, которая находится в верхней части, то есть самая высокая цена, а в нижней части, то есть самая низкая цена)? Таким образом, первое, что мы должны сделать, это добавить механизм расширения в структуру данных сетки.

    Начните писать основную функцию политики, которая является кодом, который начинает выполнять эту политику.

    var diff = 50                                 // 全局变量,网格间距,可以设计成参数,方便讲解,我们把这个参数写死在代码里。
    function main() {
        // 实盘开始运行后,从这里开始执行策略代码
        var ticker = _C(exchange.GetTicker)       // 获取市场最新的行情数据ticker,ticker这个数据的结构参看FMZ API文档:https://www.fmz.com/api#ticker
        var net = createNet(ticker.Last, diff)    // 我们上篇设计的初始构造网格数据结构的函数,这里构造一个网格数据结构net
    
        while (true) {                            // 然后程序逻辑就进入了这个while死循环,策略执行到此将不停的循环执行这里{}符号之内的代码
            ticker = _C(exchange.GetTicker)       // 死循环代码部分的第一行,获取最新的行情数据,更新给ticker变量
            // 检查网格范围
            while (ticker.Last >= net[net.length - 1].price) {
                net.push({
                    buy : false,
                    sell : false,
                    price : net[net.length - 1].price + diff,
                })
            }
            while (ticker.Last <= net[0].price) {
                var price = net[0].price - diff
                if (price <= 0) {
                    break
                }
                net.unshift({
                    buy : false,
                    sell : false,
                    price : price,
                })
            }
            
            // 还有其它代码...
        }
    }
    

    Для расширения структуры данных сетки используется следующая строка кода (выделенная из верхнего кода):

          // 检查网格范围
          while (ticker.Last >= net[net.length - 1].price) {   // 如果价格超过网格最高价格的网格线
              net.push({                                       // 就在网格最高价格的网格线之后加入一个新的网格线
                  buy : false,                                 // 初始化卖出标记
                  sell : false,                                // 初始化买入标记
                  price : net[net.length - 1].price + diff,    // 在之前最高价格的基础上再加一个网格间距
              })
          }
          while (ticker.Last <= net[0].price) {                // 如果价格低于网格最低价格的网格线
              var price = net[0].price - diff                  // 区别于向上添加,要注意向下添加新网格线的价格不能小于等于0,所以这里要判断
              if (price <= 0) {                                // 小于等于0就不添加了,跳出这层循环
                  break
              }
              net.unshift({                                    // 就在网格最低价格的网格线之前添加一个新的网格线
                  buy : false,
                  sell : false,
                  price : price,
              })
          }
    

    В следующей статье мы рассмотрим, как конкретно реализовать транзакционные триггеры.

    var diff = 50
    var amount = 0.002       // 增加一个全局变量,也可以设计成参数,当然为了简便讲解,我们也写死在策略代码,
                             // 这个参数控制每次网格线上触发交易时的交易量
    function main() {
        var ticker = _C(exchange.GetTicker)
        var net = createNet(ticker.Last, diff)
        var preTicker = ticker       // 在主循环(死循环)开始前,设置一个变量,记录上一次的行情数据
        while (true) {
            ticker = _C(exchange.GetTicker)
            // 检查网格范围
            while (ticker.Last >= net[net.length - 1].price) {
                net.push({
                    buy : false,
                    sell : false,
                    price : net[net.length - 1].price + diff,
                })
            }
            while (ticker.Last <= net[0].price) {
                var price = net[0].price - diff
                if (price <= 0) {
                    break
                }
                net.unshift({
                    buy : false,
                    sell : false,
                    price : price,
                })
            }  
    
            // 检索网格
            for (var i = 0 ; i < net.length ; i++) {     // 遍历网格数据结构中的所有网格线
                var p = net[i]
                if (preTicker.Last < p.price && ticker.Last > p.price) {         // 上穿,卖出,当前节点已经交易过不论SELL BUY ,都不再交易
                    if (i != 0) {
                        var downP = net[i - 1]
                        if (downP.buy) {
                            exchange.Sell(-1, amount, ticker)
                            downP.buy = false 
                            p.sell = false 
                            continue
                        }
                    }
                    if (!p.sell && !p.buy) {
                        exchange.Sell(-1, amount, ticker)
                        p.sell = true
                    }
                } else if (preTicker.Last > p.price && ticker.Last < p.price) {  // 下穿,买入
                    if (i != net.length - 1) {
                        var upP = net[i + 1]
                        if (upP.sell) {
                            exchange.Buy(-1, amount * ticker.Last, ticker)
                            upP.sell = false 
                            p.buy = false 
                            continue
                        }
                    }
                    if (!p.buy && !p.sell) {
                        exchange.Buy(-1, amount * ticker.Last, ticker)
                        p.buy = true 
                    } 
                }
            }
            preTicker = ticker    // 把当前的行情数据记录在preTicker中,在下一次循环中,作为“上一次”行情数据和最新的对比,判断上穿下穿
            Sleep(500)
        }
    }  
    

    Вы можете посмотреть:

    • Условия проникновения в сеть:preTicker.Last < p.price && ticker.Last > p.price
    • Условия проникновения в сеть:preTicker.Last > p.price && ticker.Last < p.price

    Это то, о чем мы говорили в предыдущей статье:

    img

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

    Если нанесены, то цена определяется ниже текущей сетчатки и последней сетчатки buy, если buy означает true, то последняя сетчатка buy перемещается на false, а сетчатка sell перемещается на false.

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

    В этом случае, если вы хотите, чтобы ваш ребенок был уверен в себе, вы должны быть уверены, что вы не можете быть уверенным в себе.

Полный анализ стратегии

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

function showTbl(arr) {
    var tbl = {
        type : "table", 
        title : "网格",
        cols : ["网格信息"],
        rows : []
    }
    var arrReverse = arr.slice(0).reverse()
    _.each(arrReverse, function(ele) {
        var color = ""
        if (ele.buy) {
            color = "#FF0000"
        } else if (ele.sell) {
            color = "#00FF00"
        }
        tbl.rows.push([JSON.stringify(ele) + color])
    })
    LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`", "\n 账户信息:", exchange.GetAccount())
}

Полный код стратегии:

/*backtest
start: 2021-04-01 22:00:00
end: 2021-05-22 00:00:00
period: 1d
basePeriod: 1m
exchanges: [{"eid":"OKEX","currency":"ETH_USDT","balance":100000}]
*/

var diff = 50
var amount = 0.002
function createNet(begin, diff) {
    var oneSideNums = 10
    var up = []
    var down = []
    for (var i = 0 ; i < oneSideNums ; i++) {
        var upObj = {
            buy : false,
            sell : false, 
            price : begin + diff / 2 + i * diff,
        }
        up.push(upObj)

        var j = (oneSideNums - 1) - i
        var downObj = {
            buy : false,
            sell : false,
            price : begin - diff / 2 - j * diff,
        }
        if (downObj.price <= 0) {  // 价格不能小于等于0 
            continue
        }
        down.push(downObj)
    }

    return down.concat(up)
}

function showTbl(arr) {
    var tbl = {
        type : "table", 
        title : "网格",
        cols : ["网格信息"],
        rows : []
    }
    var arrReverse = arr.slice(0).reverse()
    _.each(arrReverse, function(ele) {
        var color = ""
        if (ele.buy) {
            color = "#FF0000"
        } else if (ele.sell) {
            color = "#00FF00"
        }
        tbl.rows.push([JSON.stringify(ele) + color])
    })
    LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`", "\n 账户信息:", exchange.GetAccount())
}

function main() {
    var ticker = _C(exchange.GetTicker)
    var net = createNet(ticker.Last, diff)
    var preTicker = ticker 
    while (true) {
        ticker = _C(exchange.GetTicker)
        // 检查网格范围
        while (ticker.Last >= net[net.length - 1].price) {
            net.push({
                buy : false,
                sell : false,
                price : net[net.length - 1].price + diff,
            })
        }
        while (ticker.Last <= net[0].price) {
            var price = net[0].price - diff
            if (price <= 0) {
                break
            }
            net.unshift({
                buy : false,
                sell : false,
                price : price,
            })
        }

        // 检索网格
        for (var i = 0 ; i < net.length ; i++) {
            var p = net[i]
            if (preTicker.Last < p.price && ticker.Last > p.price) {         // 上穿,卖出,当前节点已经交易过不论SELL BUY ,都不再交易
                if (i != 0) {
                    var downP = net[i - 1]
                    if (downP.buy) {
                        exchange.Sell(-1, amount, ticker)
                        downP.buy = false 
                        p.sell = false 
                        continue
                    }
                }
                if (!p.sell && !p.buy) {
                    exchange.Sell(-1, amount, ticker)
                    p.sell = true
                }
            } else if (preTicker.Last > p.price && ticker.Last < p.price) {  // 下穿,买入
                if (i != net.length - 1) {
                    var upP = net[i + 1]
                    if (upP.sell) {
                        exchange.Buy(-1, amount * ticker.Last, ticker)
                        upP.sell = false 
                        p.buy = false 
                        continue
                    }
                }
                if (!p.buy && !p.sell) {
                    exchange.Buy(-1, amount * ticker.Last, ticker)
                    p.buy = true 
                } 
            }
        }

        showTbl(net)
        preTicker = ticker 
        Sleep(500)
    }
}

Посмотрите на эти фотографии.

img

img

img

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


Связанные

Больше

husr12345Это язык C++.

Тони233Я думаю, что здесь есть логическая ошибка, не должна ли быть ошибка в том, чтобы перемещаться по сетке, которая выше текущей цены? Есть также функция exchange.Sell ((-1, amount, ticker) Как эта функция отличается от той, что в API-документации, я смотрю, что в API-документации написано exchange.Sell ((Price, Amount), почему у вас есть три параметра, я не понимаю, это очень сложно, я тоже не понимаю

Тони233Как трудно.

ВызовКогда выпадает и падает, exchange.Buy ((-1, amount * ticker.Last, ticker), amount * ticker.Last - это нелепо.

CYZWXhttps://www.fmz.com/strategy/291160 last_tick = [] линия = [] grid_buy_list = [] def net ((now_price): Глобальная линия print ((now_price) - цена сейчас) линия = [now_price*(1+0.003*i) для i в диапазоне ((-1000,1000) ] Регистрация (линия) - Что? def ontick ((): Global last_tick (Глобальный последний_тик) Глобальная линия глобальная сеть_покупка_список аккаунт = обмен.GetAccount ((() Тикер = обмен.GetTicker ((() last_tick.append ((тикер['Последний']) если len ((last_tick) == 1:возврат elif len ((last_tick) == 100:del last_tick[0] для i в диапазоне ((линия))): если last_tick[-1] > строка[i] и last_tick[-2] < строка[i] и len(grid_buy_list)!= 0 и i > min(grid_buy_list) и счет['Стоки'] >= 0,001: exchange.Sell ((last_tick[-1],0.01) del grid_buy_list[grid_buy_list.index(min(grid_buy_list))] Регистрация (обмен.GetAccount) elif last_tick[-1] < линия[i] и last_tick[-2] > линия[i] и i не в grid_buy_list: exchange.Buy ((last_tick[-1],0.01) grid_buy_list.append ((i) Регистрация (обмен.GetAccount) def main ((): net ((exchange.GetTicker() ['Последний']) Регистрация (обмен.GetAccount) в то время как ((Правда): наклейка))) Сон ((1000)

CYZWXСпасибо, что рассказали подробно, объяснили, что нужно купить, как будто написали версию для пи.

Изобретатели количественного измерения - мечтыСтратегия заключается в том, чтобы использовать язык JavaScript.

Тони233Но, как вы думаете, что это значит?

Изобретатели количественного измерения - мечтыФьючерсы - это количество контрактов, а наличные цены на рынке - это сумма платежа.

Тони233Дэйв, еще один вопрос, это неправда. Обратите внимание: необходимо, чтобы интерфейс подзаказа на бирже поддерживал рыночную цену (тип подзаказа для оплаты, параметр подзаказа для валюты).

Тони233О, я понимаю.

Изобретатели количественного измерения - мечтыФункции API FMZ могут генерировать логические выводы, такие как: Log ((...), exchange.Buy ((Price, Amount), exchange.CancelOrder ((Id) и т.д.