bhardwajaditya/trader-in-broker

Executor de ordens para ações indianas (NSE, BSE). Converte ordens aprovadas pelo /trader-in-risk em bilhetes para Zerodha Kite (padrão) ou Upstox, e nunca envia nada sem seu sim.

O que é trader-in-broker?

O trader-in-broker é um executor de ordens para os mercados indianos (NSE, BSE), projetado para funcionar com agentes de IA como Claude. Ele pega ordens que passaram pela validação de risco do /trader-in-risk e as transforma em bilhetes executáveis para as corretoras Zerodha Kite (padrão) ou Upstox. Como as corretoras indianas eliminaram ordens bracket, uma única operação é dividida em três ordens separadas: uma compra, uma stop-loss a mercado (SL-M) e uma venda alvo (LIMIT). O bilhete avisa explicitamente que essas duas últimas não estão vinculadas (sem OCO), o que exige que o usuário cancele manualmente a ordem restante se uma for executada. Por padrão, o sistema opera em modo simulado (paper), usando um livro-razão local que calcula lucros e perdas realizados após os custos estimados (corretagem, STT, taxa de selo, GST e perda máxima no stop). Para ir ao vivo, o usuário deve definir 'paper': false no config.json, digitar um 'sim' explícito no chat e clicar em 'Allow once' no cartão de permissão do Claude para cada chamada de ordem. O trader-in-broker também possui uma função de flatten para fechar posições MIS até as 15:10 IST, antes do ajuste automático da corretora, gerando ordens de venda a mercado. As chaves e tokens de API nunca são expostos no chat: para a Kite, o usuário configura seu próprio servidor MCP local; para a Upstox, usa-se a skill oficial ou a interface do aplicativo.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/bhardwajaditya/day-trader-skill-india/tree/main/trader-in-broker

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que trader-in-broker faz?

O Order Executor é a única skill deste pacote que pode levar a uma ordem real, por isso é a mais restrita. Uma ordem chega ao mercado somente após estas barreiras, todas as vezes, para cada ordem:

  1. trader-in-risk aprovou esta ordem exata hoje (combinada por impressão digital; os mesmos ORDER_FIELDS e hash de trader-in-risk/check.py).
  2. "paper": false em trader-in/config.json. Com paper (o padrão) nada é enviado; as execuções vão para um livro-razão simulado local.
  3. O usuário digitou um sim explícito para esta ordem no chat.
  4. O usuário clicou em Allow once no cartão de permissão do Claude para cada chamada place_order, porque as ferramentas de ordem estão definidas como "Needs approval".

Sem sim, sem ordem. Um sim cobre um bilhete (sua compra e suas pernas de stop e alvo), nunca um lote.

${CLAUDE_SKILL_DIR} abaixo é a pasta desta skill (onde este SKILL.md reside).

python3 "${CLAUDE_SKILL_DIR}/ticket.py" show                      # todos os bilhetes, READY ou não
python3 "${CLAUDE_SKILL_DIR}/ticket.py" approve --index 1 --reply "sim"
python3 "${CLAUDE_SKILL_DIR}/ticket.py" paper-fill --index 1 --price 1196.30           # paper: a compra
python3 "${CLAUDE_SKILL_DIR}/ticket.py" paper-fill --symbol RELIANCE --side sell --qty 12 --price 1212.70 --leg target
python3 "${CLAUDE_SKILL_DIR}/ticket.py" paper                     # o livro-razão paper e o P&L
python3 "${CLAUDE_SKILL_DIR}/ticket.py" result --index 1 --leg entry --status placed --broker-id ID --filled-qty 12 --filled-price 1196.30
python3 "${CLAUDE_SKILL_DIR}/ticket.py" result --index 1 --leg stop --status placed --broker-id ID
python3 "${CLAUDE_SKILL_DIR}/ticket.py" fill --symbol RELIANCE --side sell --qty 12 --price 1212.70 --leg target
python3 "${CLAUDE_SKILL_DIR}/ticket.py" flatten --symbol RELIANCE --qty 12
python3 "${CLAUDE_SKILL_DIR}/ticket.py" log

ticket.py nunca fala com uma corretora. Ele renderiza bilhetes, verifica se uma resposta é um sim real para aquela ordem, mantém o livro-razão paper, constrói o bilhete de flatten e mantém o registro em trader-in/state/broker.json. --now "2026-10-27 10:15" (ou apenas 10:15) fixa o relógio no IST. Símbolos são aceitos como RELIANCE, RELIANCE.NS, NSE:RELIANCE, M&M, BSE:500325, 500325.BO.

O que lê e escreve

arquivoo quê
trader-in/orders.jsonas ordens propostas (trader-in-budget escreve; flatten substitui)
trader-in/config.jsonbroker (kite ou upstox), paper, product, flat_by, costs, capital_inr
trader-in/state/risk.jsonos vereditos do trader-in-risk; apenas um PASS de hoje é READY
trader-in/state/broker.jsoncada sim, não, placed, perna placed e filled, com a perda máxima de cada entrada incl. custos
trader-in/state/paper.jsono livro-razão paper: caixa, posições abertas, negócios fechados, P&L realizado após custos estimados
trader-in/portfolio.jsoncaixa e ações (posições keyed por symbol como RELIANCE.NS, com exchange)
trader-in/plan.jsono horário flat-by para flatten
trader-in/universe.json(Upstox) ISINs do scanner, se presentes
trader-in/state/EQUITY_L.csv(Upstox) lista de ações da NSE, baixada uma vez quando um ISIN é necessário

Um negócio, três ordens (leia isto antes de cada bracket)

trader-in-budget escreve um "bracket" (entrada, stop, alvo). Zerodha e Upstox não oferecem mais ordens bracket para isso, então o bilhete as transforma em:

pernaordemquando
1COMPRA, LIMIT na entrada (ou MARKET), MIS ou CNCagora
2VENDA, SL-M com trigger_price = o stopsomente após a perna 1 ter sido executada
3VENDA, LIMIT no alvosomente após a perna 1 ter sido executada

As pernas 2 e 3 NÃO estão vinculadas (sem OCO). Quando uma é executada, a outra ainda está ativa. Cancele-a imediatamente, ou ela também pode ser executada e deixar o usuário vendido (para MIS) ou ser rejeitada (para CNC). /trader-in-alerts pode monitorar os níveis de stop e alvo e alarmar quando um deles for atingido. Se colocadas antes de a perna 1 ser executada, as pernas 2 e 3 são ordens de venda comuns e podem abrir uma posição vendida.

Cada bilhete mostra os custos estimados (especificação §6: corretagem min(₹20, 0,03%) por perna MIS, STT, taxas da bolsa e SEBI, taxa de selo, 18% GST) e a perda máxima no stop incluindo os custos de ida e volta. Esse mesmo valor é registrado para o limite de perda diária do trader-in-risk. Os custos são sempre uma estimativa: a nota de corretagem tem os reais.

Paper (o padrão)

As corretoras indianas não têm conta paper, então o paper é um livro-razão local em trader-in/state/paper.json. Nada é enviado a lugar nenhum.

  1. ticket.py show, um bilhete READY, o sim do usuário, ticket.py approve.
  2. Quando o preço negocia na entrada, ticket.py paper-fill --index N (o preço limite) ou --price P. Uma compra limite não pode ser executada acima do seu limite.
  3. Quando o stop ou o alvo negocia, registre essa UMA venda: paper-fill --symbol RELIANCE --side sell --qty 12 --price 1188.10 --leg stop. O livro-razão contabiliza o P&L bruto, os custos estimados de ida e volta e o líquido.
  4. ticket.py paper imprime caixa, posições abertas e P&L realizado.

A entrada paper é registrada como placed (com "paper": true), então o trader-in-risk a conta nos limites de negócios por dia e perda diária exatamente como uma ao vivo.

Configuração A: Zerodha Kite (servidor MCP oficial) — o padrão

O servidor da Zerodha é github.com/zerodha/kite-mcp-server (MIT, Go). Verificado em relação ao seu código-fonte e README em 2026-10-27 (último commit 5e044dc, tag v0.4.0-dev24).

O servidor hospedado não pode colocar ordens. O README diz que o hospedado https://mcp.kite.trade/mcp "exclui operações de negociação potencialmente destrutivas por segurança", e as próprias páginas da Zerodha o descrevem como somente leitura (um post do Z-Connect diz que ordens GTT eram a exceção; o escopo mudou ao longo do tempo, então verifique com a lista de ferramentas do Claude após conectar). É gratuito e não precisa de chave de API: a ferramenta login retorna um link Kite, o usuário faz login com sua própria senha Kite e 2FA no navegador, nunca no chat.

Hospedado, somente leitura (cotações, posições, margens, ordens, histórico):

  • Claude Desktop: Settings > Developer > Edit Config, adicione o bloco "kite" de claude_desktop_config.example.json (executa npx mcp-remote https://mcp.kite.trade/mcp; precisa de Node.js), reinicie.
  • Claude Code: claude mcp add --transport http kite https://mcp.kite.trade/mcp (ou o mesmo comando npx mcp-remote como um servidor stdio: claude mcp add kite -- npx mcp-remote https://mcp.kite.trade/mcp).

Para colocar ordens através do Claude, o usuário executa sua própria cópia do servidor com seu próprio aplicativo Kite Connect:

  1. Crie um aplicativo Kite Connect em developers.kite.trade (verifique o preço atual lá). Sua URL de redirecionamento deve apontar para o callback do servidor local; no código-fonte do servidor, o caminho do callback é /callback em APP_HOST:APP_PORT (padrão http://localhost:8080/callback). Não testamos isso de ponta a ponta.
  2. A partir de 1º de abril de 2026, as páginas de suporte da Zerodha dizem que a colocação de ordens através da API precisa de um IP estático na lista de permissões com a Zerodha (regras de retail-algo da NSE/SEBI). Uma conexão residencial sem IP estático pode ter ordens rejeitadas. Verifique a regra atual da Zerodha antes de ir ao vivo.
  3. Compile-o: git clone https://github.com/zerodha/kite-mcp-server && cd kite-mcp-server && go build -o kite-mcp-server (Go 1.21+).
  4. Adicione o bloco "kite-orders" de claude_desktop_config.example.json: o caminho completo para o binário, APP_MODE stdio, e o usuário digita KITE_API_KEY e KITE_API_SECRET no próprio arquivo. No Claude Code: claude mcp add kite-orders -e APP_MODE=stdio -e KITE_API_KEY="$KITE_API_KEY" -e KITE_API_SECRET="$KITE_API_SECRET" -- /caminho/completo/para/kite-mcp-server com os valores exportados no shell do usuário primeiro. Mantenha apenas um dos kite / kite-orders se você não precisar de ambos.
  5. Reinicie, peça ao Claude para chamar login, o usuário abre o link e faz login. As sessões Kite expiram diariamente (os tokens de acesso do Kite Connect duram até a manhã seguinte), então espere fazer login novamente a cada dia de negociação.

Chaves e tokens nunca vão para o chat. Nunca peça por eles, nunca leia o arquivo de configuração de volta para a conversa. Se o usuário colar uma chave ou token, diga a ele para deletar aquela mensagem e regenerá-la em developers.kite.trade.

Permissões de ferramenta. Customize > Connectors (Claude Desktop), abra o servidor Kite, defina:

  • place_order, modify_order, cancel_order, place_gtt_order, modify_gtt_order, delete_gtt_order: Needs approval. Nunca Always allow.
  • ferramentas somente leitura (get_profile, get_margins, get_holdings, get_positions, get_orders, get_order_history, get_order_trades, get_trades, get_gtts, get_quotes, get_ltp, get_ohlc, get_historical_data, search_instruments, login): Always allow está ok.
  • No Claude Code, mantenha-as em ask em .claude/settings.json: "permissions": {"ask": ["mcp__kite-orders__place_order", "mcp__kite-orders__modify_order", "mcp__kite-orders__cancel_order"]}; nunca coloque uma ferramenta de ordem em allow. O servidor também aceita EXCLUDED_TOOLS=place_order,modify_order,cancel_order para uma cópia somente leitura.

Argumentos de place_order (do código-fonte do servidor): variety (regular), exchange (NSE/BSE), tradingsymbol, transaction_type (BUY/SELL), quantity (int), product (MIS/CNC), order_type (MARKET/LIMIT/SL/SL-M), price (LIMIT, SL), trigger_price (SL, SL-M), validity (DAY), optional tag (≤ 20 caracteres; o bilhete adiciona trin + 12 hex da impressão digital para que a ordem possa ser encontrada depois). A ferramenta do servidor não tem argumento market_protection; a NSE agora aplica proteção de mercado a ordens MARKET e SL-M de API, portanto uma ordem a mercado pode ser convertida em um limite protegido pela corretora. Entradas limite evitam isso. Para BSE, o tradingsymbol da Kite é o nome do ativo, não o código numérico: procure com search_instruments.

Configuração B: Upstox ("broker": "upstox")

  • O servidor MCP oficial da Upstox (https://mcp.upstox.com/mcp, instalado do plugin upstox/upstox-plugin-marketplace upstox-mcp) é somente leitura: a página da Upstox diz que você não pode colocar ordens através dele. As conexões expiram diariamente (consentimento OAuth no navegador).
  • A skill de agente oficial da Upstox (/plugin install upstox-skill@upstox-plugins-official no Claude Code, após /plugin marketplace add upstox/upstox-plugin-marketplace) pode colocar ordens com a API de ordem v3. Ela lê um token de acesso diário da variável de ambiente UPSTOX_ACCESS_TOKEN (definida pelo usuário em seu próprio shell, nunca no chat), mostra sua própria pré-visualização e aguarda confirmação. A Upstox diz que não funciona no chat plain do Claude Desktop.
  • Ou o usuário coloca a ordem no aplicativo Upstox a partir do bilhete.

O bilhete imprime o corpo para POST https://api-hft.upstox.com/v3/order/place (v2 /v2/order/place está marcado como obsoleto; ele aceita os mesmos campos, menos slice): quantity (int), product (I intraday = MIS, D delivery = CNC), validity DAY, price (0 para MARKET / SL-M), instrument_token, order_type, transaction_type, disclosed_quantity 0, trigger_price (0 a menos que SL / SL-M), is_amo false (a Upstox ignora), tag, e market_protection: -1 (automático) em MARKET e SL-M, já que 0 é rejeitado para ordens de mercado de API.

instrument_token é NSE_EQ|<ISIN> (ou BSE_EQ|<ISIN>). O ISIN vem de, em ordem: --isin, um isin na ordem, trader-in/universe.json do scanner, senão a EQUITY_L.csv da NSE (baixada uma vez com um User-Agent de navegador para trader-in/state/EQUITY_L.csv, archives. depois nsearchives.). Limitação BSE: a lista NSE mapeia apenas símbolos NSE. Um código de ativo BSE como 500325.BO não pode ser mapeado, então passe --isin; para um símbolo de nome .BO, o ISIN da listagem NSE é usado (mesma empresa), mas verifique. Não verificamos o formato do arquivo de instrumentos da Upstox aqui. Sem um ISIN, um bilhete Upstox ao vivo não é READY; bilhetes paper não precisam de um.

Etapas: a entrada

  1. ticket.py show. Apenas bilhetes READY vão para o usuário. Um bilhete que NÃO é READY ou BLOCKED volta para /trader-in-risk (não tem broker JSON).
  2. Mostre UM bilhete, incluindo o aviso de não OCO, e pergunte: "Colocar esta ordem? Responda sim ou não." Uma ordem por pergunta. Nunca ofereça "sim para todos".
  3. ticket.py approve --index N --reply "<a resposta do usuário, palavra por palavra>". "Não registrado" significa que a resposta não foi um sim explícito para esta ordem ("claro", "haan", "sim para todos", um sim nomeando outra ação ou valor). Pergunte novamente. Nunca transforme uma resposta em sim por conta própria.
  4. Paper: paper-fill como acima. Ao vivo, Kite: chame place_order com exatamente o JSON da perna 1; o usuário clica em Allow once. Confirme a execução (get_order_history / get_positions), depois place_order perna 2, depois perna 3, cada uma com seu próprio Allow once. Ao vivo, Upstox: entregue os corpos para a skill de agente Upstox ou o aplicativo, uma perna de cada vez, mesma ordem.
  5. Registre cada perna ao vivo: ticket.py result --index N --leg entry|stop|target --status placed|denied|failed --broker-id <id> (--filled-qty, --filled-price na entrada). Apenas a entrada conta como uma ordem para o trader-in-risk; as pernas são registradas como leg_placed. Uma ordem com falha não é repetida sem uma nova verificação e um novo sim.

Etapas: enquanto está aberta, e sair até flat_by

  • /trader-in-alerts monitora o stop, o alvo e o horário flat-by.
  • Quando o stop ou o alvo é executado: ao vivo, ticket.py fill ... --leg stop (lembra você de cancelar a outra perna agora: get_orders, depois cancel_order, Needs approval); paper, paper-fill ... --leg stop.
  • Até flat_by (15:10 IST padrão), qualquer coisa ainda aberta é fechada. As corretoras ajustam automaticamente as posições MIS abertas a partir de cerca de 15:20 IST e cobram uma taxa por isso (Zerodha lista ₹50 + GST por ordem), portanto não deixe para elas:
    1. Ao vivo: pergunte à corretora quantas ações são mantidas: get_positions (somente leitura).
    2. ticket.py flatten --symbol RELIANCE --qty 12 escreve uma venda MARKET (mesmo produto) em trader-in/orders.json.
    3. Execute o flatten (paper: paper-fill --symbol ... --side sell; ao vivo: place_order com o JSON de flatten, Allow once).
    4. ticket.py result ... --leg flatten.

A perda máxima absoluta (para o trader-in-risk e para o usuário)

Cada entrada de bilhete e broker inclui max_loss_inr = o valor máximo que esta operação pode perder se for parada imediatamente e os custos de ida e volta forem incorridos:

(preço de entrada - preço de stop) × quantidade + custos de ida + custos de volta

max_loss_inr nunca é negativo. Se o alvo for atingido primeiro, o prejuízo é limitado ao custo de ida (e o lucro bruto é a diferença alvo-entrada menos a volta). O trader-in-risk soma o max_loss_inr de todas as posições abertas ao seu limite de perda diária.

Operações intradiárias MIS múltiplas

Uma segunda ordem de compra (mesmo símbolo) aumenta a posição. O trader-in-risk aplica seu limite de posição máxima (por símbolo e total). O flatten fecha tudo, não um lote.

Ordens BSE

exchange: "BSE", o tradingsymbol da Kite é o nome do ativo (não o código numérico: search_instruments), instrument_token para Upstox é BSE_EQ|<ISIN> (definir --isin). A lista de ações NSE não tem ISINs BSE. A Kite também precisa do código do ativo BSE para o exchange.

Lembrete: sempre mostrar o valor de perda máxima do bilhete

Cada vez que você mostra um bilhete (em ticket.py show, no chat), mostre max_loss_inr.


(Versão truncada para tradução. O SKILL.md original continua com conteúdo adicional sobre configuração e operação.)

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

bhardwajaditya/trader-in-alerts

Price Alerts for Indian stocks (NSE, BSE). Rings when a price, a stop or the opening bell hits. Turns the trade plan into three alerts in one go (the stop, the target and "flat by" at your flat-by time, 15:10 IST by default, before brokers square off MIS at about 15:20), plus above / below / stop / target levels in rupees, percent moves from the previous close for stocks and for Nifty, Bank Nifty or Sensex, any time of day, the 09:15 IST opening bell and the 09:00 pre-open, each ringing once so you are not spammed. Reminds you that the stop and target are separate orders at Zerodha, Upstox and other Indian brokers (no OCO for MIS): when one fills, cancel the other. Knows NSE hours in IST with the 2026 NSE holidays, the Budget-day and Muhurat special sessions, fetches free delayed Yahoo quotes for .NS / .BO tickers one at a time, and writes trader-in/prices.json (INR) for sizing and the risk check. Use when the user says "alert me when", "tell me if Reliance hits 1,200", "watch my stop", "watch my trade",…

bhardwajaditya/trader-in-news

News Monitor for Indian stocks (NSE / BSE). Tracks breaking news on every stock you watch and flags what moves it: Yahoo Finance and Google News (India edition) headlines, each company's exchange corporate announcements on NSE with a BSE fallback (financial results, board meeting outcomes, dividends, buybacks, acquisitions, credit ratings, KMP resignations and appointments, insider trading / SAST, promoter pledges, fund raising) and how far each stock is from the previous close in rupees. Shows only what is new since the last check, newest first, in IST, tags each item (earnings, analyst, deal, capital, people, halt, regulatory, macro...) and never repeats one. Use when the user says "any news on Reliance", "why is TCS moving", "news on my Nifty watchlist", "morning briefing", "pre-market news", "check NSE announcements", "any corporate announcements", "did HDFC Bank file anything", "monitor the news on my Indian stocks", or after /trader-in-scanner finds setups.

Habilidades Relacionadas