Implementar rapidamente uma ferramenta de negociação quantitativa semiautomática
No comércio de futuros de commodities, a arbitragem intertemporária é um método de negociação comum. Este tipo de arbitragem não é livre de risco. Quando a direção unilateral do spread continua a se expandir, a posição de arbitragem estará em um estado de perda flutuante. No entanto, desde que a posição de arbitragem seja adequadamente controlada, ainda é muito operacional e viável.
Neste artigo, tentamos mudar para outra estratégia de negociação, em vez de construir uma estratégia de negociação totalmente automatizada, realizamos uma ferramenta de negociação quantitativa interativa semi-automática para facilitar a arbitragem intertemporal na negociação de futuros de commodities.
O foco deste artigo é sobre como construir estratégias semi-automáticas com funções interativas.
A arbitragem intertemporal é um conceito muito simples.
In economics and finance, arbitrage is the practice of taking advantage of a price difference between two or more markets: striking a combination of matching deals that capitalize upon the imbalance, the profit being the difference between the market prices at which the unit is traded. When used by academics, an arbitrage is a transaction that involves no negative cash flow at any probabilistic or temporal state and a positive cash flow in at least one state; in simple terms, it is the possibility of a risk-free profit after transaction costs. For example, an arbitrage opportunity is present when there is the opportunity to instantaneously buy something for a low price and sell it for a higher price.
O quadro estratégico é o seguinte:
Function main(){
While(true){
If(exchange.IO("status")){ // Determine the connection status of the CTP protocol.
LogStatus(_D(), "Already connected to CTP !") // Market Opening time, login connection is normal.
} else {
LogStatus(_D(), "CTP not connected!") // Not logged in to the trading front end.
}
}
}
Se o protocolo CTP estiver conectado corretamente, então precisamos configurar o contrato de negociação e, em seguida, obter a cotação do mercado.
Function main(){
While(true){
If(exchange.IO("status")){ // Determine the connection status of the CTP protocol.
exchange.SetContractType("rb2001") // Set the far month contract
Var tickerA = exchange.GetTicker() // far-month contract quote data
exchange.SetContractType("rb1910") // Set the near month contract
Var tickerB = exchange.GetTicker() // near-month contract quote data
Var diff = tickerA.Last - tickerB.Last
$.PlotLine("diff", diff)
LogStatus(_D(), "Already connected to CTP !") // Market Opening time, login connection is normal.
} else {
LogStatus(_D(), "CTP not connected!") // Not logged in to the trading front end.
}
}
}
Obter os dados do mercado, calcular a diferença, e desenhar o gráfico para registrar. deixe-o simplesmente refletir as flutuações recentes na diferença de preço.
Use a função de $.PlotLine
Na página de edição de estratégia, você pode adicionar controles interativos diretamente à estratégia:
Use a funçãoGetCommand
no código de estratégia para capturar o comando que foi enviado para o robô após o controle de estratégia acima foi acionado.
Depois que o comando é capturado, diferentes comandos podem ser processados de forma diferente.
A parte de negociação do código pode ser empacotada utilizando a função var q = $.NewTaskQueue()
para gerar o objeto de controle da transaçãoq
(declarada como variável global).
var cmd = GetCommand()
if (cmd) {
if (cmd == "plusHedge") {
q.pushTask(exchange, "rb2001", "sell", 1, function(task, ret) {
Log(task.desc, ret)
if (ret) {
q.pushTask(exchange, "rb1910", "buy", 1, 123, function(task, ret) {
Log("q", task.desc, ret, task.arg)
})
}
})
} else if (cmd == "minusHedge") {
q.pushTask(exchange, "rb2001", "buy", 1, function(task, ret) {
Log(task.desc, ret)
if (ret) {
q.pushTask(exchange, "rb1910", "sell", 1, 123, function(task, ret) {
Log("q", task.desc, ret, task.arg)
})
}
})
} else if (cmd == "coverPlus") {
q.pushTask(exchange, "rb2001", "closesell", 1, function(task, ret) {
Log(task.desc, ret)
if (ret) {
q.pushTask(exchange, "rb1910", "closebuy", 1, 123, function(task, ret) {
Log("q", task.desc, ret, task.arg)
})
}
})
} else if (cmd == "coverMinus") {
q.pushTask(exchange, "rb2001", "closebuy", 1, function(task, ret) {
Log(task.desc, ret)
if (ret) {
q.pushTask(exchange, "rb1910", "closesell", 1, 123, function(task, ret) {
Log("q", task.desc, ret, task.arg)
})
}
})
}
}
q.poll()