FMZ.COM, als quantitative Handelsplattform, dient hauptsächlich programmatischen Händlern. Aber es bietet auch ein grundlegendes Handelsterminal. Obwohl die Funktion einfach ist, kann es manchmal nützlich sein. Zum Beispiel, wenn die Börse beschäftigt ist und nicht betrieben werden kann, aber die API funktioniert immer noch. Zu diesem Zeitpunkt können Sie Aufträge abheben, Aufträge platzieren und sie über das Terminal anzeigen. Um die Erfahrung des Handelsterminals zu verbessern, werden jetzt Plug-ins hinzugefügt. Manchmal benötigen wir eine kleine Funktion, um die Transaktion zu unterstützen, wie Ladder pending orders, Eisberg-Orders, One-Click-Hedging, One-Click-Closing-Positions und andere Operationen. Es ist nicht notwendig, das Ausführungsprotokoll zu betrachten. Es ist ein bisschen umständlich, ein neues Roboterlog zu erstellen. Klicken Sie einfach auf das Plugin im Terminal, Die entsprechenden Funktionen können sofort realisiert werden, was manuelle Transaktionen erheblich erleichtern kann. Der
Es gibt zwei Modi der Plug-in-Bedienung, sofortige Bedienung und Hintergrundbedienung. Im Hintergrund laufen ist gleichbedeutend mit der Erstellung eines Roboters (normale Gebühren). Das Prinzip der sofortigen Bedienung ist das gleiche wie das Debug-Tool: Senden Sie ein Stück Code an den Docker der Trading-Terminal-Seite zur Ausführung, und Unterstützung für die Rückgabe von Diagrammen und Tabellen (das Debug-Tool ist derzeit auch auf Unterstützung aktualisiert), das gleiche kann nur für 5 Minuten ausgeführt werden, keine Gebühren, keine Einschränkungen Sprache. Plug-ins mit einer kurzen Ausführungszeit können den sofortigen Laufmodus verwenden, während komplexe und langfristige Laufstrategien immer noch Roboter ausführen müssen.
Wenn Sie eine Strategie schreiben, müssen Sie den Strategie-Typ als Plugin auswählen.main
Funktionreturn
Der Plug-in-Ausführung kann das Protokoll nicht angezeigt werden, so dass Sie das Protokoll nicht anzeigen können.return
das Ausführungsergebnis des Plug-ins.
Suchen Sie direkt im Suchfeld, wie in der Abbildung gezeigt. Beachten Sie, dass nur Trading Plugin-Typ-Strategien ausgeführt werden können, und klicken Sie dann auf Hinzufügen. Die öffentlichen Plugins finden Sie in Strategy Square:https://www.fmz.com/square/21/1
Klicken Sie auf die Strategie, um die Parameter-Einstellungsoberfläche einzugeben. Wenn keine Parameter vorhanden sind, wird sie direkt ausgeführt. Der Docker, das Handelspaar und die vom Handelsterminal ausgewählte K-Line-Periode sind die standardmäßig entsprechenden Parameter. Klicken Sie auf die Ausführungsstrategie, um die Ausführung zu starten, und wählen Sie den
Da alle Plug-ins in einem Debugging-Tool-Prozess ausgeführt werden, werden alle Plug-ins gestoppt.
Plug-ins können Code für einen bestimmten Zeitraum ausführen und einige einfache Operationen durchführen. In vielen Fällen können manuelle Operationen, die wiederholte Operationen erfordern, mit Plug-ins implementiert werden, um Transaktionen zu erleichtern. Im Folgenden werden spezifische Beispiele vorgestellt, und der angegebene Quellcode kann als Referenz verwendet werden, um Ihre eigene Strategie anzupassen.
Futures Intertemporal Hedging Trading ist eine sehr verbreitete Strategie. Da die Frequenz nicht sehr hoch ist, werden viele Leute manuell betrieben. Es ist notwendig, einen Vertrag lang und einen Vertrag kurz zu machen, daher ist es besser, den Spread-Trend zu analysieren. Die Verwendung von Plug-Ins im Handelsterminal spart Ihnen Energie.
Die erste Einführung besteht darin, den Preisunterschied zwischen den Perioden zu erstellen:
var chart = {
__isStock: true,
title : { text : 'Spread analysis chart'},
xAxis: { type: 'datetime'},
yAxis : {
title: {text: 'Spread'},
opposite: false,
},
series : [
{name : "diff", data : []},
]
}
function main() {
exchange.SetContractType('quarter')
var recordsA = exchange.GetRecords(PERIOD_M5) //Cycle can be customized
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
}
Klicken Sie einmal, die jüngste Preisdifferenz zwischen den Perioden ist auf einen Blick klar, die Plug-in Quellcode Kopie Adresse:https://www.fmz.com/strategy/187755
Mit der Spread-Analyse wird festgestellt, dass sich der Spread konvergiert. Es ist eine Gelegenheit, den vierteljährlichen Vertrag zu kürzen und für die laufende Woche lang zu gehen. Dies ist eine Gelegenheit, das One-Click-Hedging-Plug-in zu verwenden, ein Klick hilft Ihnen automatisch, den vierteljährlichen und den wöchentlichen zu kürzen, was schneller ist als der manuelle Betrieb. Das Implementierungsprinzip der Strategie besteht darin, die gleiche Anzahl von Positionen mit einem gleitenden Preis zu öffnen. Sie können mehrmals laufen, um langsam Ihre gewünschte Position zu erreichen, um die Auswirkungen auf den Markt zu vermeiden. Sie können die Standardparameter ändern, um Bestellungen schneller zu platzieren. Strategie-Kopieradresse: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())
}
Warten Sie, bis die Preisdifferenz konvergiert und Sie die Position schließen müssen, können Sie das Ein-Klick-Schließ-Plugin ausführen, um die Position so schnell wie möglich zu schließen.
function main(){
while(ture){
var pos = exchange.GetPosition()
var ticker = exchange.GetTicekr()
if(!ticker){return 'Unable to get ticker'}
if(!pos || pos.length == 0 ){return 'No holding position'}
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)
}
}
}
}
Die häufigste ist die Eisberg-Kommission, die große Aufträge in kleine Aufträge aufteilt. Obwohl sie als Roboter ausgeführt werden kann, reicht ein 5-minütiges Plug-in tatsächlich aus. Es gibt zwei Arten von Eisberg-Aufträgen, einer nimmt Aufträge an und der andere ist ausstehende Aufträge. Wenn es eine bevorzugte Gebühr gibt, können Sie ausstehende Aufträge wählen, was bedeutet, dass die Ausführungszeit länger ist.
Der folgende Code ist der Quellcode des von Iceberg in Auftrag gegebenen Plug-ins:https://www.fmz.com/strategy/191771Zum Verkauf: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
}
}
}
Es ist auch eine Möglichkeit, Produkte langsam zu versenden, um die Kauf- oder Verkaufs-Preisschicht ständig zu besetzen, und die Auswirkungen auf den Markt sind relativ gering.
Kaufen:https://www.fmz.com/strategy/191582
Verkaufen: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 'Unable to get account information'}
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)
}
}
Manchmal können mehrere Bestellungen in einem bestimmten Intervall platziert werden, um einen besseren
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'
}
Häufig verwendete Futures-Trading-Software hat oft viele erweiterte ausstehende Orderfunktionen, wie ausstehende Stop-Loss-Orders, ausstehende Condition-Orders usw., die leicht als Plug-Ins geschrieben werden können.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 is not connected!")
Sleep(10000)
}
if(trade_amount >= Amount){
Log('mission completed')
return
}
Sleep(1000)
}
}
Nach dem Lesen so vieler kleiner Funktionen sollten Sie auch Ihre eigenen Ideen haben.