
Estratégias que preferem mercados voláteis, como a estratégia de grade e a estratégia Martingale, têm desvantagens inerentes. Estratégias semelhantes foram testadas no mercado de contratos ETH por algum tempo. Também costumo conversar e compartilhar experiências com jogadores novos e antigos no FMZ.COM. Em relação a esse tipo de estratégia, há um ponto que concordo plenamente com o que um amigo disse. Ou seja, ao fazer contratos no círculo das criptomoedas, o risco de operar comprado é um pouco menor do que o de operar vendido. Ou, para simplificar, a pior queda possível é zero, mas o lado positivo é ilimitado.
Então, estratégias como Martingale e grid somente operar longo e não curto, e distribuir os riscos de seleção de fundo em um longo prazo seriam melhores do que fazer negociações bilaterais? Essa ideia parece boa, mas ninguém sabe se ela resistirá à prática. Mas pelo menos podemos simplesmente testar essa ideia. Então temos o tópico do artigo de hoje: elaborar uma estratégia de bottom-picking de contratos.
O código para implementar essa ideia é realmente muito simples, graças à flexibilidade da plataforma, ao encapsulamento da interface, ao poderoso sistema de backtesting, etc. O código inteiro ocupa apenas 60 linhas (por questões de padrões de escrita de código, muitas abreviações não são usadas).
O design da estratégia é muito simples. De acordo com o preço inicial no início da lógica, ordens de compra são colocadas em intervalos para baixo. Se o preço continuar a cair, continue a colocar ordens de compra para continuar pescando no fundo. Em seguida, coloque uma ordem de fechamento com base no preço da posição mais uma certa diferença de lucro e aguarde o fechamento da posição. Se a posição for fechada, a lógica acima será repetida com o preço atual como preço inicial. A estratégia não mantém posições curtas, apenas posições longas.
Código fonte da estratégia:
function cancelAll() {
while (true) {
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(interval)
}
}
}
function getLong(arr, kind) {
var ret = null
for (var i = 0 ; i < arr.length ; i++) {
if (arr[i].Type == (kind == "pos" ? PD_LONG : ORDER_TYPE_BUY)) {
ret = arr[i]
}
}
return ret
}
function pendingBidOrders(firstPrice) {
var index = 0
var amount = baseAmount
while (true) {
var pos = _C(exchange.GetPosition)
var price = firstPrice - index * baseSpacing
amount *= ratio
index++
exchange.SetDirection("buy")
exchange.Buy(price, amount)
if (pos.length != 0) {
var longPos = getLong(pos, "pos")
if (longPos) {
exchange.SetDirection("closebuy")
exchange.Sell(longPos.Price + profitTarget, longPos.Amount)
}
}
while (true) {
Sleep(interval)
if (!getLong(_C(exchange.GetOrders), "orders")) {
cancelAll()
break
}
if (!getLong(_C(exchange.GetPosition), "pos")) {
cancelAll()
return
}
}
}
}
function main() {
exchange.SetContractType(symbol)
while (true) {
pendingBidOrders(_C(exchange.GetTicker).Last)
}
}
O design dos parâmetros também é muito simples:

Existem apenas esses poucos parâmetros.
Basta definir o intervalo de tempo do backtest:

Execução de backtest:


Parece muito com uma estratégia do tipo grade ou Martin~. Os novos alunos que estão começando a aprender têm medo de estratégias longas e desanimam facilmente? Uma introdução breve e concisa às estratégias é mais adequada, facilitando a assimilação de ideias estratégicas e o aprendizado do design lógico.
O código de estratégia é apenas para fins de aprendizado e pesquisa.