Exemple de conception de stratégie dYdX
En réponse à de nombreuses demandes des utilisateurs, la plateforme FMZ a récemment pris en charge l'échange décentralisé dYdX. Les amis avec des stratégies peuvent exploiter dYdX avec plaisir. Il se trouve que je voulais écrire une stratégie de trading aléatoire il y a longtemps. Peu importe que je gagne ou que je perde de l’argent. Le but est de pratiquer et d’enseigner la conception de stratégies en même temps. Alors, concevons ensemble une stratégie d’échange aléatoire. Ne vous souciez pas des performances de la stratégie. Apprenons simplement à concevoir une stratégie.
Commençons par vous montrer quelques techniques d’exploitation minière
Captures d'écran de l'exploitation minière stratégique dans cet article.
Les amis qui ont de bonnes idées de stratégie minière sont également invités à laisser un message !
Conception de stratégie de trading stochastique
« Pensons sauvagement » ! Je prévois de concevoir une stratégie qui place des ordres de manière aléatoire sans tenir compte des indicateurs ou des prix. Les ordres ne sont rien d'autre que des positions longues ou courtes, et tout ce que vous avez à faire est de prédire les probabilités. Ensuite, nous utilisons des nombres aléatoires de 1 à 100 pour déterminer les positions longues et courtes.
Conditions longues : nombres aléatoires 1 à 50.
Conditions de vente à découvert : nombres aléatoires 51 à 100.
Les chiffres pour les positions longues et courtes sont de 50. Ensuite, réfléchissons à la manière de clôturer la position. Comme il s’agit d’un pari, il doit y avoir une norme pour gagner et perdre. Ensuite, lors de la transaction, nous définissons un take-profit fixe et un stop-loss comme norme pour gagner ou perdre. Si vous arrêtez le profit, vous gagnez ; si vous arrêtez la perte, vous perdez. Quant aux paramètres appropriés de take-profit et de stop-loss, cela affecte en fait le ratio de profit et de perte, oh oui ! Cela affecte également le taux de gain ! (Cette stratégie de conception est-elle efficace ? Peut-elle garantir une espérance mathématique positive ? Faisons-le d’abord ! Après tout, c’est pour l’apprentissage et la recherche !)
Le trading n'est pas gratuit. Des facteurs tels que les frais de glissement et de traitement suffisent à ramener notre taux de gain de trading aléatoire à moins de 50 %. Comment dois-je continuer à concevoir en gardant cela à l’esprit ?
Il est préférable de concevoir une augmentation de positions multiples. Comme il s'agit d'un pari, la probabilité de perdre 8 transactions aléatoires sur 10 d'affilée ne devrait pas être très élevée. Je souhaite donc concevoir la première transaction de manière à ce qu'elle ait une taille de commande très petite, la plus petite possible. Ensuite, si vous perdez le pari, augmentez la quantité de commande et continuez à passer des commandes aléatoires.
OK, la conception de la stratégie est aussi simple que cela.
Code source de la conception :
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("重置所有数据", "#FF0000")
}
exchange.SetContractType(ct)
var initPos = _C(exchange.GetPosition)
if (initPos.length != 0) {
throw "策略启动时有持仓!"
}
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("设置精度", 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 "获取初始权益失败"
}
} else {
totalEq = recoverTotalEq
}
} else {
totalEq = _C(exchange.GetAccount).Balance
}
while (1) {
if (openPrice == 0) {
// 更新账户信息,计算收益
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("下", direction > 50 ? "买单" : "卖单", ",价格:", 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
}
// 平仓检测
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
// 画线
$.PlotLine("bid", depth.Bids[0].Price)
$.PlotLine("ask", depth.Asks[0].Price)
// 止损
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
}
// 止盈
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
}
// 检测挂单
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 {
// 撤销挂单
cancelAll()
Sleep(2000)
pos = _C(exchange.GetPosition)
// 撤销后更新持仓,需要再次检查
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 {
// 撤销挂单
// 重置openPrice
cancelAll()
openPrice = 0
}
Sleep(1000)
}
}
Paramètres de la stratégie :
Oh oui! La stratégie a besoin d’un nom, appelons-la « Devinez la taille (version dYdX) ».
Backtesting
Les backtesting sont fournis à titre de référence uniquement._<!
L’objectif principal est de vérifier s’il y a des bugs dans la stratégie et d’utiliser le backtesting des contrats à terme de Binance.
Le backtesting est terminé, aucun bug. Mais j'ai l'impression que j'ai peut-être sur-ajusté le système de backtest... T_T, laissez-moi l'essayer en temps réel.
Trading réel
Cette stratégie est destinée à l'apprentissage et à la référence uniquement.10 millions~10 millionsNe l'utilisez pas pour de vrai ! !
问一下, dydx去中心化交易所现在是否支持现货交易? 还是只能永续合约? 从来没用过 去中心化交易所, 如果dydx支持现货交易, 可以考虑做个现货网格交易策略. 还有就是去中心化交易所, 确认买卖是否成功还需要等待时间, 不像中心化交易所那么闪电般快, 需要旷工确认. 要是速度这些克服了, 又支持写网格等量化策略, 那是非常好.
- 1











