[TOC]

FMZ は定量取引プラットフォームとして、主にプログラマティックトレーダー向けに設計されています。しかし、基本的な取引ターミナルも提供しています。機能はシンプルですが、時には非常に便利です。たとえば、取引所が混雑していて開けない場合でも、APIが機能している場合は、ターミナルを使用して注文をキャンセルできます。 、注文、見積アカウントの表示などを行うことができます。取引端末のエクスペリエンスを向上させるために、プラグイン機能が追加されました。時には、ラダーペンディングオーダー、アイスバーグオーダー、ワンクリックヘッジ、ワンクリッククローズなど、取引を支援する小さな機能が必要になります。実行ログを見る必要は実際にはありません。少し面倒です。新しいロボットを作成します。ターミナルでプラグインをクリックするだけです。 、対応する機能をすぐに実現できるため、手動取引が大幅に容易になります。プラグインの場所は次のとおりです。

プラグイン操作には、即時操作とバックグラウンド操作の 2 つのモードがあります。バックグラウンドで実行することは、ロボットを作成することと同じです (通常の料金が適用されます)。即時操作の原理はデバッグツールと同じです。取引端末ページの管理者にコードを送信して実行し、チャートと表の返却をサポートします(デバッグツールも現在これをサポートするためにアップグレードされています)。 ) も同様に、5 分間のみ実行可能、無料、言語無制限です。実行時間が非常に短いプラグインでは即時実行モードを使用できますが、実行時間が長い複雑な戦略ではロボットを実行する必要があります。
ポリシーを記述するときは、ポリシー タイプとしてプラグインを選択する必要があります。 プラグインのメイン関数の戻り値の結果は、実行後にターミナルにポップアップ表示され、文字列、描画、表をサポートします。プラグイン実行中はログを見ることができないため、プラグインの実行結果を返すことができます。
図のように検索ボックスで直接検索します。取引プラグインタイプの戦略のみ実行できることに注意してくださいをクリックし、[追加] をクリックします。パブリックプラグインはStrategy Squareで見つかります: https://www.fmz.com/square/21/1

戦略をクリックすると、パラメータ設定インターフェイスに入ります。パラメータがない場合は、直接実行されます。取引端末によって選択されたカストディアン、取引ペア、およびKライン期間は、対応するデフォルトのパラメータです。実行ポリシーをクリックして実行を開始し、「今すぐ実行」モードを選択します (デフォルトの実行モードを覚えておくことができます)。プラグインはログを表示しません。

アイコンをクリックするとプラグインが停止します。すべてのプラグインは 1 つのデバッグ ツール プロセスで実行されるため、すべてのプラグインが停止されます。

プラグインは一定期間コードを実行し、いくつかの簡単な操作を実行できます。多くの場合、手動で繰り返す必要がある操作はプラグインを使用して実装できるため、トランザクションがより便利になります。以下、具体的な例を挙げて紹介していきますが、提供されているソースコードを参考にして、独自の戦略をカスタマイズすることもできます。
先物のクロス期間ヘッジは非常に一般的な戦略です。頻度はそれほど高くないため、多くの人が手動で操作し、1 つの契約をロングし、もう 1 つの契約をショートして、価格差の傾向を分析できます。取引端末でプラグインを使用すると、エネルギーを節約できます。
最初に紹介したいのは、期間間の価格差プラグインです。
var chart = {
__isStock: true,
title : { text : '差价分析图'},
xAxis: { type: 'datetime'},
yAxis : {
title: {text: '差价'},
opposite: false,
},
series : [
{name : "diff", data : []},
]
}
function main() {
exchange.SetContractType('quarter')
var recordsA = exchange.GetRecords(PERIOD_M5) //周期可以自行定制
exchange.SetContractType('this_week')
var recordsB = exchange.GetRecords(PERIOD_M5)
for(var i=0;i<Math.min(recordsA.length,recordsB.length);i++){
var diff = recordsA[recordsA.length-Math.min(recordsA.length,recordsB.length)+i].Close - recordsB[recordsB.length-Math.min(recordsA.length,recordsB.length)+i].Close
chart.series[0].data.push([recordsA[recordsA.length-Math.min(recordsA.length,recordsB.length)+i].Time, diff])
}
return chart
}
ワンクリックで、最近のインターピリオドスプレッドを一目で確認できます。プラグインのソースコードのコピーアドレス: https://www.fmz.com/strategy/187755

スプレッド分析では、スプレッドが収束していることがわかります。これは、四半期契約をショートし、現在の週をロングするチャンスです。この時点で、ワンクリックヘッジプラグインを使用できます。ワンクリックで、四半期契約をショートし、現在の週を買い戻すのを自動的に支援します。これは手動操作よりも高速です。かなりあります。この戦略の実装原則は、スリッページのある同じ数のポジションを開くことです。これを数回実行して、必要なポジションにゆっくりと到達し、市場への影響を回避することができます。デフォルトのパラメータを変更して、注文をより速く配置することもできます。戦略コピーアドレス: https://www.fmz.com/strategy/191348
function main(){
exchange.SetContractType(Reverse ? Contract_B : Contract_A)
var ticker_A = exchange.GetTicker()
if(!ticker_A){return 'Unable to get quotes'}
exchange.SetDirection('buy')
var id_A = exchange.Buy(ticker_A.Sell+Slip, Amount)
exchange.SetContractType(Reverse ? Contract_B : Contract_A)
var ticker_B = exchange.GetTicker()
if(!ticker_B){return 'Unable to get quotes'}
exchange.SetDirection('sell')
var id_B = exchange.Sell(ticker_B.Buy-Slip, Amount)
if(id_A){
exchange.SetContractType(Reverse ? Contract_B : Contract_A)
exchange.CancelOrder(id_A)
}
if(id_B){
exchange.SetContractType(Reverse ? Contract_B : Contract_A)
exchange.CancelOrder(id_B)
}
return 'Position: ' + JSON.stringify(exchange.GetPosition())
}
価格差が収束するのを待っている間にポジションをクローズする必要がある場合は、ワンクリッククローズプラグインを実行して最速のスピードでポジションをクローズすることができます。
function main(){
while(ture){
var pos = exchange.GetPosition()
var ticker = exchange.GetTicekr()
if(!ticker){return '无法获取ticker'}
if(!pos || pos.length == 0 ){return '已无持仓'}
for(var i=0;i<pos.length;i++){
if(pos[i].Type == PD_LONG){
exchange.SetContractType(pos[i].ContractType)
exchange.SetDirection('closebuy')
exchange.Sell(ticker.Buy, pos[i].Amount - pos[i].FrozenAmount)
}
if(pos[i].Type == PD_SHORT){
exchange.SetContractType(pos[i].ContractType)
exchange.SetDirection('closesell')
exchange.Buy(ticker.Sell, pos[i].Amount - pos[i].FrozenAmount)
}
}
var orders = exchange.Getorders()
Sleep(500)
for(var j=0;j<orders.length;j++){
if(orders[i].Status == ORDER_STATE_PENDING){
exchange.CancelOrder(orders[i].Id)
}
}
}
}
最も一般的なのは、大きな注文を小さな注文に分割するアイスバーグ注文です。ロボットとして実行することもできますが、実際には5分間のプラグインで十分です。アイスバーグ注文には、注文を受けるタイプと注文を出すタイプの2種類があります。手数料割引がある場合は注文を出すタイプを選択できますが、その場合、約定時間は長くなります。
次のコードは、Iceberg Order Buying プラグインのソース コードです: https://www.fmz.com/strategy/191771。ソースコードを販売: https://www.fmz.com/strategy/191772
function main(){
var initAccount = _C(exchange.GetAccount)
while(true){
var account = _C(exchange.GetAccount)
var dealAmount = account.Stocks - initAccount.Stocks
var ticker = _C(exchange.GetTicker)
if(BUYAMOUNT - dealAmount >= BUYSIZE){
var id = exchange.Buy(ticker.Sell, BUYSIZE)
Sleep(INTERVAL*1000)
if(id){
exchange.CancelOrder(id) // May cause error log when the order is completed, which is all right.
}else{
throw 'buy error'
}
}else{
account = _C(exchange.GetAccount)
var avgCost = (initAccount.Balance - account.Balance)/(account.Stocks - initAccount.Stocks)
return 'Iceberg order to buy is done, avg cost is '+avgCost
}
}
}
常に 1 つ買うか 1 つ売るかの価格を占めることも、商品をゆっくりと出荷する方法であり、市場への影響は比較的小さくなります。この戦略にはまだ改善の余地があります。最小取引量や精度は手動で変更できます。 購入: https://www.fmz.com/strategy/191582 販売: https://www.fmz.com/strategy/191730
function GetPrecision(){
var precision = {price:0, amount:0}
var depth = exchange.GetDepth()
for(var i=0;i<exchange.GetDepth().Asks.length;i++){
var amountPrecision = exchange.GetDepth().Asks[i].Amount.toString().indexOf('.') > -1 ? exchange.GetDepth().Asks[i].Amount.toString().split('.')[1].length : 0
precision.amount = Math.max(precision.amount,amountPrecision)
var pricePrecision = exchange.GetDepth().Asks[i].Price.toString().indexOf('.') > -1 ? exchange.GetDepth().Asks[i].Price.toString().split('.')[1].length : 0
precision.price = Math.max(precision.price,pricePrecision)
}
return precision
}
function main(){
var initAccount = exchange.GetAccount()
if(!initAccount){return '无法获取账户信息'}
var precision = GetPrecision()
var buyPrice = 0
var lastId = 0
var done = false
while(true){
var account = _C(exchange.GetAccount)
var dealAmount = account.Stocks - initAccount.Stocks
var ticker = _C(exchange.GetTicker)
if(BuyAmount - dealAmount > 1/Math.pow(10,precision.amount) && ticker.Buy > buyPrice){
if(lastId){exchange.CancelOrder(lastId)}
var id = exchange.Buy(ticker.Buy, _N(BuyAmount - dealAmount,precision.amount))
if(id){
lastId = id
}else{
done = true
}
}
if(BuyAmount - dealAmount <= 1/Math.pow(10,precision.amount)){done = true}
if(done){
var avgCost = (initAccount.Balance - account.Balance)/dealAmount
return 'order is done, avg cost is ' + avgCost // including fee cost
}
Sleep(Intervel*1000)
}
}
場合によっては、より良い価格で販売したり、掘り出し物を待ったりするために、一定の間隔で複数の注文を出すことができます。このプラグインは先物の保留注文にも使用できます。ソースコードのコピーアドレス: https://www.fmz.com/strategy/190017
function main() {
var ticker = exchange.GetTicker()
if(!ticker){
return 'Unable to get price'
}
for(var i=0;i<N;i++){
if(Type == 0){
if(exchange.GetName().startsWith('Futures')){
exchange.SetDirection('buy')
}
exchange.Buy(Start_Price-i*Spread,Amount+i*Amount_Step)
}else if(Type == 1){
if(exchange.GetName().startsWith('Futures')){
exchange.SetDirection('sell')
}
exchange.Sell(Start_Price+i*Spread,Amount+i*Amount_Step)
}else if(Type == 2){
exchange.SetDirection('closesell')
exchange.Buy(Start_Price-i*Spread,Amount+i*Amount_Step)
}
else if(Type == 3){
exchange.SetDirection('closebuy')
exchange.Sell(Start_Price+i*Spread,Amount+i*Amount_Step)
}
Sleep(500)
}
return 'order complete'
}
一般的に使用されている先物取引ソフトウェアには、ストップロス注文の配置、条件付き注文の配置など、プラグインに簡単に記述できる高度な注文配置機能が多数備わっていることがよくあります。保留中の注文を実行後すぐに閉じることができるプラグインを紹介します。コピーアドレス: https://www.fmz.com/strategy/187736
var buy = false
var trade_amount = 0
function main(){
while(true){
if(exchange.IO("status")){
exchange.SetContractType(Contract)
if(!buy){
buy = true
if(Direction == 0){
exchange.SetDirection('buy')
exchange.Buy(Open_Price, Amount)
}else{
exchange.SetDirection('sell')
exchange.Sell(Open_Price, Amount)
}
}
var pos = exchange.GetPosition()
if(pos && pos.length > 0){
for(var i=0;i<pos.length;i++){
if(pos[i].ContractType == Contract && pos[i].Type == Direction && pos[i].Amount-pos[i].FrozenAmount>0){
var cover_amount = math.min(Amount-trade_amount, pos[i].Amount-pos[i].FrozenAmount)
if(cover_amount >= 1){
trade_amount += cover_amount
if(Direction == 0){
exchange.SetDirection('closebuy_today')
exchange.Sell(Close_Price, cover_amount)
}else{
exchange.SetDirection('closesell_today')
exchange.Buy(Close_Price, cover_amount)
}
}
}
}
}
} else {
LogStatus(_D(), "未连接CTP !")
Sleep(10000)
}
if(trade_amount >= Amount){
Log('任务完成')
return
}
Sleep(1000)
}
}
たくさんの小さな機能を見た後、あなたは独自のアイデアを持っているはずです。それらをプラグインに書き込んで、手動取引を容易にすることもできます。