最近,FMZ公式グループで議論されているマルティンゲール型戦略は多く,当社のプラットフォームでは仮想通貨契約のマルティンゲール型戦略は多くありません.したがって,この機会を利用して簡単な仮想通貨先物マルティンゲール型戦略を設計しました.なぜマルティンゲール型戦略と呼ばれるのですか?マルティンゲール戦略の潜在的なリスクは確かに小さいので,マルティンゲール戦略に従って設計する必要はありません.しかし,このタイプの戦略にはまだ多くのリスクがあり,マルティンゲール型戦略のパラメータ設定はリスクと密接に関連しており,リスクは無視してはならない.
この記事では,主にマルティンゲール型戦略の設計について説明し,学びます.戦略のアイデア自体は既に非常に明確です.したがって,FMZユーザーとして,戦略設計についてもっと検討することができます.
仮想通貨先物戦略を設計する際に,総資本はしばしば使用されます.特に浮動利益を計算する必要があるとき,利益を計算したいからです. 保有ポジションがマージンを占めるため,待機されている注文も使用されます. その時点で,APIインターフェースは,exchange.GetAccount()
FMZのプラットフォームは,利用可能な資産と待機中の注文凍結資産を取得するために呼ばれています. 実際,ほとんどの仮想通貨先物プラットフォームは,総資本のデータを提供していますが,このプロパティはFMZに均一にパッケージされていません.
異なるプラットフォームのデータを取得するための機能を別々に設計します.
// OKEX V5 obtains the total equity
function getTotalEquity_OKEX_V5() {
var totalEquity = null
var ret = exchange.IO("api", "GET", "/api/v5/account/balance", "ccy=USDT")
if (ret) {
try {
totalEquity = parseFloat(ret.data[0].details[0].eq)
} catch(e) {
Log("Fail to obtain the total equity of the account!")
return null
}
}
return totalEquity
}
// Binance Ftures
function getTotalEquity_Binance() {
var totalEquity = null
var ret = exchange.GetAccount()
if (ret) {
try {
totalEquity = parseFloat(ret.Info.totalWalletBalance)
} catch(e) {
Log("Fail to obtain the total equity!")
return null
}
}
return totalEquity
}
についてtotalEquity
呼び出しエントリとして関数を書き,対応する関数をプラットフォーム名に従って呼びます.
function getTotalEquity() {
var exName = exchange.GetName()
if (exName == "Futures_OKCoin") {
return getTotalEquity_OKEX_V5()
} else if (exName == "Futures_Binance") {
return getTotalEquity_Binance()
} else {
throw "Do not support the platform"
}
}
主な機能と主論理を設計する前に 準備のための補助機能も設計する必要があります
待機中の注文をすべてキャンセル
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)
}
}
この機能は,FMZ戦略スクエア上の戦略例コードをよく読んでいる人に馴染みがあると考えられ,多くの戦略が同様の設計を使用している.機能は,現在の待機注文リストを取得し,その後,注文を一つずつキャンセルすることです.
フューチャー・オーダーを投注する操作
function trade(distance, price, amount) {
var tradeFunc = null
if (distance == "buy") {
tradeFunc = exchange.Buy
} else if (distance == "sell") {
tradeFunc = exchange.Sell
} else if (distance == "closebuy") {
tradeFunc = exchange.Sell
} else {
tradeFunc = exchange.Buy
}
exchange.SetDirection(distance)
return tradeFunc(price, amount)
}
function openLong(price, amount) {
return trade("buy", price, amount)
}
function openShort(price, amount) {
return trade("sell", price, amount)
}
function coverLong(price, amount) {
return trade("closebuy", price, amount)
}
function coverShort(price, amount) {
return trade("closesell", price, amount)
}
フューチャー取引には4つの方向性があります:オープン・ロング・ポジション (openLong),オープン・ショート・ポジション (openShort),閉鎖・ロング・ポジション (coverLong),閉鎖・ショート・ポジション (coverShort).したがって,これらの操作に対応する4つのオーダー関数を設計しました.もし,注文の配置のみを考えると,方向性,注文価格,注文金額などいくつかの必要要素があります.
デザインした機能はtrade
操作を処理するためにdirection (distance)
, order price (price)
そしてorder amount (amount)
指定されている.
オープン・ロング・ポジション (openLong),オープン・ショート・ポジション (openShort),閉鎖・ロング・ポジション (coverLong),閉鎖・ショート・ポジション (coverShort) の関数呼び出しは,最終的にtrade
つまり,指定された方向,価格と金額に従って,先物プラットフォームに注文をします.
戦略の考え方は非常にシンプルです.現在の価格をベースラインとして,ベースラインの上下から一定の距離からセールオーダー (ショート) とバイオーダー (ロング) を配置します.一方からのオーダーが実行された場合,残りのすべてのオーダーをキャンセルし,その後,ポジション価格に応じて特定の距離で新しいクローズオーダーが配置され,バイオーダーが更新された現在の価格に置かれますが,バイオーダーはオーダーの金額を倍にしません.
初期作業 2つの変数が必要です. この2つの変数は,
var buyOrderId = null
var sellOrderId = null
OKEX_V5シミュレーションボットの使用オプションは戦略インターフェースのパラメータで設計されているため,コードでいくつかの処理を行う必要があります:
var exName = exchange.GetName()
// switch to OKEX V5 simulated bot
if (isSimulate && exName == "Futures_OKCoin") {
exchange.IO("simulate", true)
}
すべての情報をリセットするオプションも 戦略パラメータで設計されているので コードで処理する必要があります:
if (isReset) {
_G(null)
LogReset(1)
LogProfitReset()
LogVacuum()
Log("Reset all data", "#FF0000")
}
永続契約に設定します. 永続契約に設定します.
exchange.SetContractType("swap")
また,注文価格と注文金額の精度問題を考慮する必要があります. 精度が正しく設定されていない場合,戦略計算プロセス中に失われます. データに多くの小数点がある場合,プラットフォームインターフェースによって注文が拒否されるのは簡単です.
exchange.SetPrecision(pricePrecision, amountPrecision)
Log("set percision", pricePrecision, amountPrecision)
デザインにおける単純なデータ復元機能
if (totalEq == -1 && !IsVirtual()) {
var recoverTotalEq = _G("totalEq")
if (!recoverTotalEq) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
totalEq = currTotalEq
_G("totalEq", currTotalEq)
} else {
throw "Fail to obtain the initial equity"
}
} else {
totalEq = recoverTotalEq
}
}
パラメータを設定します. 設定する場合は,このパラメータを設定します.totalEq
. このパラメータが -1 に設定されている場合,戦略は保存された総株式データを読み取る. 保存された総株式データが存在しない場合,現在読み取られている総株式は,実行進行中の戦略の初期総株式として使用されます. その後,総株式が増加した場合,それは利益を得ていることを意味します. 総株式が減少した場合,それは損失があることを意味します. 総株式データが読み取られている場合,データを実行し続けるために使用します.
主な論理 初期作業が完了した後,私たちは最終的に戦略の主要な論理部分にたどり着きました.説明の便宜のために,私はコードに直接コメントを書きました.
while (1) { // the main logic of the strategy is designed as an infinite loop
var ticker = _C(exchange.GetTicker) // read the current market information first, in which we mainly use the latest trading price
var pos = _C(exchange.GetPosition) // read the current position data
if (pos.length > 1) { // judge the position data; due to the strategy logic, it is unlikely to have long and short positions at the same time, so if there are long and short positions at the same time, an error will be thrown
Log(pos)
throw "concurrently with long and short positions" // raise an error, and stop the strategy
}
// according to the status
if (pos.length == 0) { // according to the position status, make different operations; if pos.length == 0, it means currently no position
// when there is no position yet, calculate the equity
if (!IsVirtual()) {
var currTotalEq = getTotalEquity()
if (currTotalEq) {
LogProfit(currTotalEq - totalEq, "Current total equity:", currTotalEq)
}
}
buyOrderId = openLong(ticker.Last - targetProfit, amount) // pend buy order of open long position
sellOrderId = openShort(ticker.Last + targetProfit, amount) // pend sell order of open short position
} else if (pos[0].Type == PD_LONG) { // there are long positions; pending position and amount are
var n = 1
var price = ticker.Last
buyOrderId = openLong(price - targetProfit * n, amount)
sellOrderId = coverLong(pos[0].Price + targetProfit, pos[0].Amount)
} else if (pos[0].Type == PD_SHORT) { // there are short positions; pending position and amount are different
var n = 1
var price = ticker.Last
buyOrderId = coverShort(pos[0].Price - targetProfit, pos[0].Amount)
sellOrderId = openShort(price + targetProfit * n, amount)
}
if (!sellOrderId || !buyOrderId) { // if opending orders of one side fails, cancel all pending orders and try again
cancelAll()
buyOrderId = null
sellOrderId = null
continue
}
while (1) { // finish pending the order, and start to monitor the order
var isFindBuyId = false
var isFindSellId = false
var orders = _C(exchange.GetOrders)
for (var i = 0 ; i < orders.length ; i++) {
if (buyOrderId == orders[i].Id) {
isFindBuyId = true
}
if (sellOrderId == orders[i].Id) {
isFindSellId = true
}
}
if (!isFindSellId && !isFindBuyId) { // both buy order and sell order are detected to be executed
cancelAll()
break
} else if (!isFindBuyId) { // a buy order execution is detected
Log("buy order executed")
cancelAll()
break
} else if (!isFindSellId) { // a sell order execution is detected
Log("sell order executed")
cancelAll()
break
}
LogStatus(_D())
Sleep(3000)
}
Sleep(500)
}
論理とデザインは完全に説明されています
2021年5月19日の市場価格を 戦略に切り替えてみましょう
マルティンゲール戦略に似た戦略には リスクもあります
戦略アドレス:https://www.fmz.com/strategy/294957
本物のボットで操作しないでください!