В ответ на потребности многих пользователей, платформа FMZ недавно поддержала децентрализованную платформу dYdX. Друзья с стратегиями могут с радостью добывать на dYdX. Не так давно я хотел написать случайную торговую стратегию. Неважно, получаю ли я прибыль или нет. Цель состоит в том, чтобы практиковать мою технику и учить дизайн стратегии. Итак, следующее, давайте вместе разработаем стратегию случайной платформы. Не беспокойтесь о производительности стратегии, и просто научитесь дизайну стратегии.
Скриншот стратегии добычи в статье.
Добро пожаловать друзья, которые имеют хорошие идеи стратегии майнинга, чтобы поделиться!
Давайте проведем мозговой штурм! Мы планируем разработать стратегию для размещения заказов случайным образом, не смотря на показатели или цены. Заказ не более чем делать длинный и короткий, что делает ставку на вероятность. Затем мы используем случайные числа от 1 до 100, чтобы определить, делать длинный или короткий.
Условие выполнения длины: случайные числа от 1 до 50. Условие короткого действия: случайные числа от 51 до 100.
Для длинной и короткой сделки требуется 50 номеров. Далее давайте подумаем о том, как закрыть позиции. Поскольку это ставка, должен быть стандарт выигрыша или проигрыша. Затем давайте установим фиксированный стандарт стопПрофита и стопЛосса в качестве стандарта выигрыша или проигрыша. Возьмем стопПрофит как выигрыш, а стопЛосс как проигрыш. Что касается целесообразности стопПрофита и стопЛосса, это на самом деле влияет на соотношение прибыли и убытка, а также на процент выигрыша! (Эффективно ли разработать стратегию таким образом? Можно ли гарантировать, что это положительное математическое ожидание? В любом случае, давайте сделаем это сначала! Потому что это для обучения и исследования!)
Торговля не является бесплатной, и есть такие факторы, как сдвиг точки и сборы, которые достаточно, чтобы вытащить наш случайный торговый выигрышный процент на стороне менее 50% думая об этом, как продолжить дизайн отсюда? Для увеличения позиций лучше разрабатывать масштабирование на несколько. Поскольку это ставка, вероятность последовательного проигрыша 10 или 8 раз не должна быть очень большой. Поэтому я хочу разрабатывать размещение небольшой суммы ордера в первой сделке, как можно меньше. Затем, если я проиграю ставку, увеличить сумму ордера и продолжать размещать случайные ордера.
Стратегия вполне простая.
Исходный код конструкции:
var openPrice = 0
var ratio = 1
var totalEq = null
var nowEq = null
function cancelAll() {
while (1) {
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
break
}
for (var i = 0 ; i < orders.length ; i++) {
exchange.CancelOrder(orders[i].Id, orders[i])
Sleep(500)
}
Sleep(500)
}
}
function main() {
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("reset all data", "#FF0000")
}
exchange.SetContractType(ct)
var initPos = _C(exchange.GetPosition)
if (initPos.length != 0) {
throw "Position detected when starting the strategy!"
}
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("setPrecision", pricePrecision, amountPrecision)
if (!IsVirtual()) {
var recoverTotalEq = _G("totalEq")
if (!recoverTotalEq) {
var currTotalEq = _C(exchange.GetAccount).Balance // equity
if (currTotalEq) {
totalEq = currTotalEq
_G("totalEq", currTotalEq)
} else {
throw "fail to obtain the initial equity"
}
} else {
totalEq = recoverTotalEq
}
} else {
totalEq = _C(exchange.GetAccount).Balance
}
while (1) {
if (openPrice == 0) {
// update account information, and calculate the profit
var nowAcc = _C(exchange.GetAccount)
nowEq = IsVirtual() ? nowAcc.Balance : nowAcc.Balance // equity
LogProfit(nowEq - totalEq, nowAcc)
var direction = Math.floor((Math.random()*100)+1) // 1~50 , 51~100
var depth = _C(exchange.GetDepth)
if (depth.Asks.length <= 2 || depth.Bids.length <= 2) {
Sleep(1000)
continue
}
if (direction > 50) {
// long
openPrice = depth.Bids[1].Price
exchange.SetDirection("buy")
exchange.Buy(Math.abs(openPrice) + slidePrice, amount * ratio)
} else {
// short
openPrice = -depth.Asks[1].Price
exchange.SetDirection("sell")
exchange.Sell(Math.abs(openPrice) - slidePrice, amount * ratio)
}
Log("place", direction > 50 ? "buy order" : "sell order", ",price:", Math.abs(openPrice))
continue
}
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
var pos = _C(exchange.GetPosition)
if (pos.length == 0) {
openPrice = 0
continue
}
// detect close positions
while (1) {
var depth = _C(exchange.GetDepth)
if (depth.Asks.length <= 2 || depth.Bids.length <= 2) {
Sleep(1000)
continue
}
var stopLossPrice = openPrice > 0 ? Math.abs(openPrice) - stopLoss : Math.abs(openPrice) + stopLoss
var stopProfitPrice = openPrice > 0 ? Math.abs(openPrice) + stopProfit : Math.abs(openPrice) - stopProfit
var winOrLoss = 0 // 1 win , -1 loss
// plot
$.PlotLine("bid", depth.Bids[0].Price)
$.PlotLine("ask", depth.Asks[0].Price)
// stop loss
if (openPrice > 0 && depth.Bids[0].Price < stopLossPrice) {
exchange.SetDirection("closebuy")
exchange.Sell(depth.Bids[0].Price - slidePrice, pos[0].Amount)
winOrLoss = -1
} else if (openPrice < 0 && depth.Asks[0].Price > stopLossPrice) {
exchange.SetDirection("closesell")
exchange.Buy(depth.Asks[0].Price + slidePrice, pos[0].Amount)
winOrLoss = -1
}
// stop profit
if (openPrice > 0 && depth.Bids[0].Price > stopProfitPrice) {
exchange.SetDirection("closebuy")
exchange.Sell(depth.Bids[0].Price - slidePrice, pos[0].Amount)
winOrLoss = 1
} else if (openPrice < 0 && depth.Asks[0].Price < stopProfitPrice) {
exchange.SetDirection("closesell")
exchange.Buy(depth.Asks[0].Price + slidePrice, pos[0].Amount)
winOrLoss = 1
}
// detect pending orders
Sleep(2000)
var orders = _C(exchange.GetOrders)
if (orders.length == 0) {
pos = _C(exchange.GetPosition)
if (pos.length == 0) {
if (winOrLoss == -1) {
ratio++
} else if (winOrLoss == 1) {
ratio = 1
}
break
}
} else {
// cancel pending orders
cancelAll()
Sleep(2000)
pos = _C(exchange.GetPosition)
// after canceling, update positions, which needs to be detected again
if (pos.length == 0) {
if (winOrLoss == -1) {
ratio++
} else if (winOrLoss == 1) {
ratio = 1
}
break
}
}
var tbl = {
"type" : "table",
"title" : "info",
"cols" : ["totalEq", "nowEq", "openPrice", "bid1Price", "ask1Price", "ratio", "pos.length"],
"rows" : [],
}
tbl.rows.push([totalEq, nowEq, Math.abs(openPrice), depth.Bids[0].Price, depth.Asks[0].Price, ratio, pos.length])
tbl.rows.push(["pos", "type", "amount", "price", "--", "--", "--"])
for (var j = 0 ; j < pos.length ; j++) {
tbl.rows.push([j, pos[j].Type, pos[j].Amount, pos[j].Price, "--", "--", "--"])
}
LogStatus(_D(), "\n", "`" + JSON.stringify(tbl) + "`")
}
} else {
// cancel pending orders
// reset openPrice
cancelAll()
openPrice = 0
}
Sleep(1000)
}
}
Параметры стратегии:
Стратегия нуждается в названии, и давайте назовем его "Угадай, что больше (версия dYdX).
Бактэст только для справки! Это в основном для проверки, есть ли какие-либо ошибки в стратегии; обратный тест с Binance Futures.
Но я чувствую, что система обратного теста совпала... давай запустим ее в настоящем боте для наблюдения.
Эта стратегия предназначена только для обучения и справочной работы.Не надо.!! Не надо.Использовать его в настоящем боте!