[TOC]
FMZ é uma plataforma de negociação quantitativa, principalmente para servir os comerciantes programatizados. Mas também fornece um terminal de negociação básico, embora funcional simples, às vezes também pode ser útil, por exemplo, a bolsa está ocupada e não pode ser aberta, mas a API ainda pode funcionar, em que pode ser retirado através do terminal, fazer pedidos, consultar contas de transação, etc. Para aperfeiçoar a experiência do terminal de negociação, agora foram adicionados funções de plug-in.
O plug-in tem dois modos de execução, o de execução imediata e o de execução em segundo plano. A execução em segundo plano é equivalente à criação de um robô (a taxa normal). O princípio da execução imediata e o debugger são os mesmos: o administrador que envia um código para a página do terminal de transações é executado e suporta o retorno de gráficos e tabelas (a ferramenta de depuração também é atualmente atualizada), o mesmo pode ser executado em apenas 5 minutos, sem cobrança, sem limites de linguagem.
Quando se escreve uma política, é necessário selecionar o tipo de política como um plug-in.O resultado do retorno da função principal do plug-in aparece no terminal após a execução, suportando strings, diagramas e tabelas. Como a execução do plug-in não é visível no registro, é possível retornar o resultado do retorno do plug-in.
O Google Maps é uma ferramenta de pesquisa de conteúdo que permite a pesquisa de conteúdos em diferentes idiomas.Observação: só é possível executar a política de tipo de plugin de transaçãoO Plugin está disponível no site do Google, e pode ser acessado através do site do Google AdWords.https://www.fmz.com/square/21/1
Clique na política para entrar na interface de configuração de parâmetros, se não houver parâmetros, será executado diretamente, o administrador, o par de transações e o ciclo de linha K selecionados pelo terminal de transações são os parâmetros correspondentes por padrão. Clique na política de execução para iniciar a execução, e execute o modo de parâmetro imediatamente se você selecionar o parâmetro (lembre o modo de operação padrão).
Clique no indicador para parar o plug-in, pois todos os plug-ins são executados em um processo de ferramenta de depuração.
O plug-in pode executar código por um período de tempo, executar algumas operações simples, muitas vezes as operações manuais que precisam de execução repetida podem ser realizadas com o plug-in, fácil de negociar.
Os futuros são uma estratégia muito comum e, como a freqüência não é muito alta, muitas pessoas operam manualmente, exigindo um contrato para fazer mais, um contrato para fazer mais, além de analisar os movimentos dos diferenciais. Usar um plug-in no terminal de negociação economizará sua energia.
A primeira coisa a fazer é mostrar um plugin de diferença de gráficos:
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
}
Clique aqui para ver a diferença de curto prazo recente e o endereço de cópia do código do plugin:https://www.fmz.com/strategy/187755
Com a análise de diferença, descobrir que o diferencial está se aproximando, é uma oportunidade de fazer um contrato de trimestre vazio, fazer mais de uma semana, que pode ser usado com um plug-in de hedge de um botão, clique e ajude automaticamente o seu trimestre vazio mais de uma semana, muito mais rápido do que a operação manual. O princípio de implementação da estratégia é o preço de deslizamento abrir o mesmo número de posições, pode ser executado várias vezes, lentamente atingir a posição necessária, evitando o impacto do mercado, pode mudar o parâmetro padrão, atingindo uma velocidade mais rápida.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())
}
Espera que o diferencial converja, precisa de equilíbrio, pode executar um plug-in de equilíbrio de um botão, equilíbrio de velocidade mais rápida.
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)
}
}
}
}
O mais comum é o encargo do iceberg, que desmonta o bloco em folhetos, embora possa ser executado como um robô, mas um plug-in de 5 minutos é suficiente. O encargo do iceberg tem dois tipos, um é o de comer, outro é o de pendurar, se houver uma vantagem de taxas de processamento, você pode optar por pendurar, ou seja, o tempo de execução é mais longo.
O código abaixo é o código do plugin Iceberg:https://www.fmz.com/strategy/191771O código-fonte é vendido: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
}
}
}
A ocupação de compra ou venda é também uma forma de entrega lenta, com um impacto menor no mercado. Esta estratégia também tem algumas melhorias, sendo possível alterar manualmente o volume mínimo de negociação ou precisão. Compras:https://www.fmz.com/strategy/191582A venda: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)
}
}
Às vezes, para vender um preço de envio melhor ou pendurar uma encomenda pendente, é possível pendurar várias encomendas em intervalos determinados. Este plugin também pode ser usado para pendurar encomendas de futuros.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'
}
Os softwares de negociação de futuros usados geralmente têm muitas funções avançadas de listagem pendente, como listagem pendente de prejuízos, listagem pendente de condições, etc., que podem ser facilmente escritos em plugins.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)
}
}
Depois de ver tantas funções pequenas, você deve ter suas próprias ideias, talvez escreva um plugin para facilitar suas transações manuais.
- Sim, sim.O que é que causa a denúncia? Error: Futures_OP 0: 400: {"error_message":"Open orders exist","code":35017,"error_code":"35017","message":"Open orders exist"} Buy ((5000, 0.1): 400: {"error_message":"order_size error","result":"true","error_code":"35063","order_id":"-1"}
Ervas daninhasVerifique a documentação da bolsa ou consulte o atendimento ao cliente da bolsa