Algos

Troca Contínua

Rola continuamente uma posição de um instrumento que está vencendo para o próximo contrato, coordenando o fechamento da perna da frente e a abertura da perna seguinte para preservar a exposição durante a rolagem.

Exatamente duas pernas: o contrato da frente sendo encerrado e o seguinte sendo aberto.

Quando usar

  • Você está rolando posições em futuros ou em termo antes do vencimento.
  • Quer uma rolagem suave e automática, em vez de uma troca abrupta.
  • Precisa de execução coordenada para não ficar descoberto durante a troca.

Início rápido

from investflex import AsyncInvestflexClient
from investflex.models.algos import TrocaContinua
from investflex.models.common import ExecutionType, SecurityExchange, Side, TimeInForce, Trigger

c = TrocaContinua(
    name="win-roll",
    init_time="09:00:00",
    end_time="23:53:00",
    time_in_force=TimeInForce.DAY,
    # gatilhos (NOTA: cont usa entry/exit triggers, não trigger_value)
    execution_type=ExecutionType.ENTRY,
    trigger=Trigger.SPREAD,                 # ou Trigger.FINANCIAL_DIFF
    entry_trigger_value=162915.0,
    exit_trigger_value=-162900.0,
    entry_trigger_type=Trigger.SPREAD,      # mesmo domínio 1/11 de `trigger`
    exit_trigger_type=Trigger.SPREAD,
    simultaneous_trigger_mode="Y",
    start_on_exit_trigger="N",
    allow_partial_exit="Y",
    legs=[
        dict(symbol="WING25", side=Side.BUY,  quantity=1,
             alloc_account="YOUR_ACCOUNT", security_exchange=SecurityExchange.XBMF,
             resting="Y", max_clip_size=1, first_timeout=5000),
        dict(symbol="WDOH25", side=Side.SELL, quantity=1,
             alloc_account="YOUR_ACCOUNT", security_exchange=SecurityExchange.XBMF,
             resting="Y", max_clip_size=1, first_timeout=5000),
    ],
)

async with AsyncInvestflexClient.from_env() as client:
    handle = await client.algos.create(c)
    print(handle.clord_id, handle.status.name)
import {
  InvestflexClient,
  TrocaContinua,
  ExecutionType,
  SecurityExchange,
  Side,
  TimeInForce,
  Trigger,
} from "@investflex/sdk";

const c = new TrocaContinua({
  name: "win-roll",
  initTime: "09:00:00",
  endTime: "23:53:00",
  timeInForce: TimeInForce.DAY,
  // gatilhos (NOTA: cont usa entry/exit triggers, não trigger_value)
  executionType: ExecutionType.ENTRY,
  trigger: Trigger.SPREAD, // ou Trigger.FINANCIAL_DIFF
  entryTriggerValue: 162915.0,
  exitTriggerValue: -162900.0,
  entryTriggerType: Trigger.SPREAD, // mesmo domínio 1/11 de `trigger`
  exitTriggerType: Trigger.SPREAD,
  simultaneousTriggerMode: "Y",
  startOnExitTrigger: "N",
  allowPartialExit: "Y",
  legs: [
    {
      symbol: "WING25",
      side: Side.BUY,
      quantity: 1,
      allocAccount: "YOUR_ACCOUNT",
      securityExchange: SecurityExchange.XBMF,
      resting: "Y",
      maxClipSize: 1,
      firstTimeout: 5000,
    },
    {
      symbol: "WDOH25",
      side: Side.SELL,
      quantity: 1,
      allocAccount: "YOUR_ACCOUNT",
      securityExchange: SecurityExchange.XBMF,
      resting: "Y",
      maxClipSize: 1,
      firstTimeout: 5000,
    },
  ],
});

const client = InvestflexClient.fromEnv();
const handle = await client.algos.create(c);
console.log(handle.clOrdId, handle.status);

await client.close();

Parâmetros

Estratégia

Campo Tipo Obrigatório Editável Padrão Observações
name str sim não — Rótulo.
init_time HH:MM:SS sim não — Início da janela.
end_time HH:MM:SS sim não — Fim da janela.
expire_date YYYYMMDD não não 20380101 Validade da ordem-dia.
text str não não — Comentário livre.
basket_id str não não — Chave opcional de agrupamento.
time_in_force enum não não DAY Veja 02-enums.md.
execution_type ExecutionType sim não — ExecutionType.ENTRY, ExecutionType.GAIN_LOSS.
trigger Trigger sim não — Trigger.SPREAD (1) ou Trigger.FINANCIAL_DIFF (11).
trigger_value número não sim — Alvo de gain quando execution_type=GAIN_LOSS; nível de entrada quando ENTRY.
entry_trigger_value número sim sim — Nível de entrada do ciclo de rolagem.
exit_trigger_value número sim sim — Nível de saída; o sinal importa (negativo = sai quando a diferença cai abaixo).
entry_trigger_type Trigger não não — Mesmo domínio 1 / 11 de trigger.
exit_trigger_type Trigger não não — Mesmo domínio, para a saída.
simultaneous_trigger_mode "Y" / "N" não não N Y observa entrada e saída em paralelo; N só arma a saída após a entrada executar.
start_on_exit_trigger "Y" / "N" não não N Y rearma a entrada após cada saída — é o que torna a rolagem contínua.
allow_partial_exit "Y" / "N" não não N Permite saída parcial.
close_positions_on_end "Y" / "N" não não N Zera a posição ao fim da janela.
to_market_trigger_value número condicional sim — Alvo de loss quando execution_type=GAIN_LOSS.
to_market_trigger_value_enabled "Y" / "N" não não — Y apenas quando execution_type=ExecutionType.GAIN_LOSS.
exec_strategy ExecStrategy não não 2 1=Agressora, 2=Resting, 5=MIT.
execution_limit int não não 7
execution_limit_value número não não 0.0
compensate_exec CompensateExec não não 2 0=Nenhuma, 1=Clip seguinte, 2=Gradual.
book_depth BookDepth não sim 1 Nível do book observado.
ignore_offers_lt int não sim 0 Ignora ofertas menores que N.
simulate_sniper_on_resting "Y" / "N" não não N
init_suspended "Y" / "N" não não N Cria o algo suspenso.
bypass_firewall "Y" / "N" não não N

Banda de preço

Campo Tipo Obrigatório Editável Padrão Observações
band_price_ref "Y" / "N" não não — Habilita a banda; os campos abaixo só valem com "Y".
band_price_symbol str não não — Instrumento de referência.
band_price_exchange str não não XBSP
band_price_high número não sim — Limite superior.
band_price_low número não sim — Limite inferior.
inside_band_start_only "Y" / "N" não não N Só inicia se estiver dentro da banda.

Stop fixo

Campo Tipo Obrigatório Editável Padrão Observações
stop_type 1 não não — Apenas 1 (stop fixo). Diferente do stop type do oco2.
stop_loss_trigger_type 3 não não — Apenas 3 (trigger financeiro).
stop_gain_trigger_type 3 não não — Apenas 3 (trigger financeiro).
stop_loss número não sim —
stop_gain número não sim —

Nota: cont é a única estratégia que carrega ao mesmo tempo trigger_value e o par entry_trigger_value / exit_trigger_value. O par conduz o ciclo de rolagem; trigger_value mantém a semântica de entrada/gain compartilhada com spread e lgshort.

Pernas

Exatamente duas: o contrato da frente sendo encerrado e o seguinte sendo aberto.

Campo Tipo Obrigatório Editável Observações
symbol str sim não Código do instrumento.
side Side.BUY / Side.SELL sim não
quantity int sim sim Contratos da perna (> 0).
alloc_account str sim não Conta da corretora.
max_clip_size int sim sim 0..100000; 0 significa sem limite de clip.
security_exchange str não não Padrão XBSP; use XBMF para derivativos B3.
resting "Y" / "N" não sim Y fica na fila, N agride.
first_timeout int não sim 100..100000 ms até a primeira reavaliação.
ord_type int não não Padrão 2 (limitada).
route str não não

Editando uma Troca Contínua em execução

await client.algos.edit(
    handle.clord_id,
    EntryTriggerValue=162900,
    ExitTriggerValue=-162885,
    StopLoss=500.0,
)
await client.algos.edit(
  handle.clOrdId,
  {
    EntryTriggerValue: 162900,
    ExitTriggerValue: -162885,
    StopLoss: 500.0,
  },
  { strategyCode: "cont" },
);

ToMarketTriggerValue, EntryTriggerValue, ExitTriggerValue, BandPriceHigh, BandPriceLow, IgnoreOffersLT, BookDepth, StopLoss, StopGain. Qualquer outro campo — inclusive AllowPartialExit — é rejeitado no cliente antes do envio.

Comandos de ciclo de vida

await client.algos.commands.cancel(handle.clord_id)
await client.algos.commands.suspend(handle.clord_id)
await client.algos.commands.resume(handle.clord_id)
await client.commands.cancel(handle.clOrdId);
await client.commands.suspend(handle.clOrdId);
await client.commands.resume(handle.clOrdId);

Notas de comportamento

  • O gatilho é avaliado contra a diferença de preço (ou financeira) entre as pernas — o sinal importa: um exit_trigger_value negativo significa sair quando a diferença cai abaixo desse nível.
  • simultaneous_trigger_mode="Y" é típico de uma rolagem contínua: as condições de entrada e saída são monitoradas em paralelo.
  • start_on_exit_trigger="Y" mantém o algo em ciclo: cada execução de saída rearma uma nova entrada, útil para rolagens repetidas dentro da janela.
  • Variantes de 2 pernas são típicas de rolagem de futuros (frente → trás); variantes de 3 pernas adicionam um instrumento de hedge ou base.