IDE: ordens e saídas
Abrir e fechar posições, calcular o tamanho, definir stops e take-profits, e escrever condições de entrada.

Aqui está a API para operar a partir do seu código: abrir posições longas ou curtas, dimensioná-las corretamente, atribuir stops e alvos, e fechá-las quando quiser. Todos os métodos estão disponíveis dentro da sua classe de estratégia.
Abrir uma posição
`self.buy(...)` abre uma posição longa (compra) e `self.sell(...)` abre uma posição curta (venda). Ambos os métodos aceitam os mesmos argumentos para dimensionar e definir saídas.
self.buy(sl_atr=1.5, tp_atr=3.0) # largo con SL a 1.5*ATR y TP a 3*ATR
self.sell(sl_atr=1.5, tp_atr=3.0) # cortoTamanho da posição (obrigatório escolher um)
Você deve indicar como calcular o tamanho de cada ordem usando um desses três argumentos. Se não incluir nenhum, a ordem não sabe quanto arriscar e não será executada.
| Argumento | O que faz | Exemplo |
|---|---|---|
| lots=0.1 | Lotes fixos, independente do saldo ou volatilidade. | lots=0.05 |
| risk_pct=0.02 | Arrisca 2% do saldo. Calcula os lotes automaticamente com base na distância ao SL. | risk_pct=0.01 |
| risk_usd=100 | Arrisca exatamente 100 USD fixos por operação. | risk_usd=50 |
self.buy(sl_atr=1.5, tp_atr=3.0, lots=0.1)
self.buy(sl_atr=1.5, tp_atr=3.0, risk_pct=0.02)
self.buy(sl_atr=1.5, tp_atr=3.0, risk_usd=100)`risk_pct` é o mais recomendado: mantém o risco constante mesmo que o saldo ou a volatilidade do instrumento mude. Existe também `self.sizer` com métodos `fixed`, `risk_percent`, `risk_currency` e `kelly` para cálculos avançados de lotes quando precisar de lógica mais elaborada.
Stops e take-profits: modos de saída
Por padrão, múltiplos de ATR são usados com `sl_atr` e `tp_atr`, mas você pode passar um argumento `exit_mode` para mudar o comportamento de saída. Cada modo tem seus próprios parâmetros.
| Modo | Para que serve | Parâmetros |
|---|---|---|
| atr (padrão) | SL e TP em múltiplos do ATR atual. | sl_atr, tp_atr |
| fixed_pips | Distâncias fixas em pips. | slPips, tpPips |
| percent | SL e TP como porcentagem do preço de entrada. | slPct, tpPct |
| trailing_atr | Trailing stop que acompanha o preço conforme sobe. | trailAtr |
| breakeven | Move o SL para o preço de entrada quando a posição ganha X ATR. | beActivationAtr (+ sl_atr, tp_atr para o SL/TP inicial) |
| structure | SL no mínimo (ou máximo para curtos) das últimas N velas. | lookback (+ tp_atr para o objetivo) |
| time_exit | Fecha a posição automaticamente após N velas. | maxBars (+ sl_atr para proteção) |
| partial_tp | Fecha uma porcentagem da posição no TP1, o restante no TP2. | tp1Atr, tp2Atr, partialPct |
# ATR (por defecto)
self.buy(sl_atr=1.5, tp_atr=3.0)
# Pips fijos
self.buy(exit_mode={"type": "fixed_pips", "slPips": 20, "tpPips": 40})
# Porcentaje del precio
self.buy(exit_mode={"type": "percent", "slPct": 1.0, "tpPct": 2.0})
# Trailing stop (persigue al precio)
self.buy(exit_mode={"type": "trailing_atr", "trailAtr": 1.5})
# Breakeven (mueve el SL a entrada al ganar X*ATR)
self.buy(exit_mode={"type": "breakeven", "beActivationAtr": 1.0}, sl_atr=2.0, tp_atr=4.0)
# Estructura (SL en el mínimo de las últimas N velas)
self.buy(exit_mode={"type": "structure", "lookback": 10}, tp_atr=3.0)
# Salida por tiempo (cierra tras N velas)
self.buy(exit_mode={"type": "time_exit", "maxBars": 20}, sl_atr=2.0)
# TP parcial (cierra parte en TP1, resto en TP2)
self.buy(exit_mode={"type": "partial_tp", "tp1Atr": 1.5, "tp2Atr": 3.0, "partialPct": 50})Fechar posições
| Método | O que fecha |
|---|---|
| self.close() | A primeira posição aberta. |
| self.close(position_id=N) | Uma posição específica identificada pelo seu ID. |
| self.close_all() | Todas as posições abertas. |
| self.close_longs() | Somente as posições longas (compras). |
| self.close_shorts() | Somente as posições curtas (vendas). |
| self.get_position(id) | Retorna o objeto de uma posição aberta pelo seu ID. |
| self.get_positions_by_tag(tag) | Retorna todas as posições que tenham a etiqueta indicada. |
Escrever condições de entrada e saída
As condições são Python puro: você compara valores de indicadores e preços usando os operadores habituais. A tabela abaixo mostra os padrões mais comuns.
| Você quer detectar | Como se escreve |
|---|---|
| Preço acima da EMA | self.bar.close > self.ema.value |
| RSI em sobrevenda | self.rsi.value < 30 |
| Cruzamento altista preço/EMA | self.data.close.crossover(self.ema.value) |
| Cruzamento baixista preço/EMA | self.data.close.crossunder(self.ema.value) |
| Cruzamento altista do MACD sobre sua linha de sinal | self.macd.prev < self.macd.signal and self.macd.value > self.macd.signal |
| Rompimento das máximas das últimas 20 velas | self.bar.close > self.data.high.highest(20) |
def on_bar(self):
tendencia_alcista = self.bar.close > self.ema.value
momentum_ok = self.rsi.value < 35
if not self.in_position and tendencia_alcista and momentum_ok:
self.buy(sl_atr=1.5, tp_atr=3.0, risk_pct=0.01)Várias posições ao mesmo tempo (avançado)
Por padrão sua estratégia trabalha com uma única posição ativa. Se quiser gerenciar várias ao mesmo tempo, defina `max_positions` na classe e use a propriedade `position_count` para controlá-la. As etiquetas (`tag`) ajudam a agrupá-las e encontrá-las depois.
class MiBot(Strategy):
max_positions = 3
def on_bar(self):
if self.position_count < self.max_positions and self.entrada():
self.buy(sl_atr=1.5, tag="scalp", risk_pct=0.01)
for p in self.get_positions_by_tag("scalp"):
if p.pnl_pct > 0.015:
self.close(position_id=p.id)Se não especificar `lots`, `risk_pct` ou `risk_usd`, a ordem não sabe quanto arriscar e não será executada. Escolha sempre um dos três antes de fazer seu primeiro teste.
Use `self.log("...")` para deixar rastros de depuração e entender por que seu bot entrou ou saiu em um momento específico ao revisar o backtest.
Para aprender a ajustar o comportamento da sua estratégia com parâmetros configuráveis e revisar o histórico de operações, continue com o artigo «IDE: parâmetros, validação e histórico».