---
name: conbot
description: ConBot (Bybit demo bant/stop-reverse botu) işletim prosedürleri — güvenli derleme ve yeniden başlatma, panel API komutları, borsadan imzalı sorgular (pozisyon, kâr/zarar, komisyon), setup analizi ve release paketleme. ConBot deposunda çalışırken; botu başlat/durdur/yeniden derle, pozisyon veya kâr/zarar sorgula, seviye kurulumunu değerlendir ya da dağıtım paketi üret denildiğinde kullan.
---

# ConBot işletimi

Bot: `C:\Users\beko\Documents\ConBot`. Panel `http://127.0.0.1:8080`
(port doluysa bot 8081, 8082… dener). Emirler Bybit **Demo** hesabına gider.

## İKİ AYRI KURULUM VAR — önce hangisinin çalıştığını bul

Operatör botu çoğu zaman **projeden değil, çıkarılmış dağıtım klasöründen**
çalıştırır (ör. `ConBot\ConBot-v0.4.0-win64\`). O klasörün kendi `.env`,
`config.toml` ve `journal.jsonl` dosyaları vardır ve **asıl canlı kurulum
odur**. Proje kökündeki `config.toml` bayat olabilir.

```powershell
Get-Process conbot | Select-Object Id, Path   # hangi exe calisiyor?
```

Çalışan bota müdahale ederken `-ProjectRoot` ile **onun** klasörünü ver.
Yanlış klasörden başlatmak, operatörün kurulumunu sessizce eski ayarlarla
değiştirir. Scriptler iki düzeni de tanır: geliştirme `target\release\
conbot.exe`, dağıtım `<klasör>\conbot.exe`.

## Değişmez kurallar

0. **Operatör "botu kapatma" dediyse hiçbir koşulda durdurma/yeniden
   başlatma** — derleme ve paketleme çalışan bota dokunmadan yapılabilir
   (`package.ps1` bunu kendi kontrol eder).
1. **Pozisyon açıkken botu yeniden başlatma.** `exchange_stop = "primary"` ile
   pozisyonun stop'u borsada durur (süreç ölse de korur) ama **trailing
   ilerlemez** — stop kaldığı yerde donar ve yeniden açılan bot o pozisyonu
   DEVRALMAZ (flat varsayar). Önce panelden "Pozisyonu Kapat ve Dur" ya da
   `POST /api/stop`.
2. **Derlemeden önce çalışan botu durdur.** Çalışan `conbot.exe` kendi
   dosyasını kilitler; `cargo build` "Access is denied" ile patlar.
3. **PATH şartı** (bu makinede MSVC linker yok):
   `%USERPROFILE%\.cargo\bin` **ve** `%USERPROFILE%\mingw-winlibs\mingw64\bin`.
   Rust varsayılan toolchain'i `stable-x86_64-pc-windows-gnu` olmalı.
4. **`.env`'i asla paketleme, yazdırma veya kopyalama.** API anahtarları
   orada. Scriptler dosyayı okur ama değerleri ekrana basmaz.
   **Commit/push için her zaman `git-push.ps1` kullan** — bu depoda birden
   fazla `.env` kopyası dolaşıyor (çıkarılmış dağıtım klasörleri kendi
   anahtarlarını taşır) ve bir kez push edilen sır geçmişte kalıcıdır.
   Uzak depo: `github.com/brk4lp/ConBot` (**private**).
5. **Config'i elle düzenlerken**: TOML'de skaler alanlar `[tablo]`
   başlıklarından ÖNCE gelmeli. Bot panelden gelen değişikliklerde
   `config.toml`'u yeniden yazar (yorumlar silinir) — normaldir.

## Scriptler

Hepsi `.claude/skills/conbot/scripts/` altında, proje kökünden çalıştırılır.

```powershell
# Güvenli yeniden başlatma: pozisyon kontrolü + durdur + derle + başlat + doğrula
.\.claude\skills\conbot\scripts\restart.ps1
.\.claude\skills\conbot\scripts\restart.ps1 -DryRun      # emirler borsaya gitmez
.\.claude\skills\conbot\scripts\restart.ps1 -SkipBuild   # sadece yeniden başlat
# Operatörün dağıtım klasöründeki botu (en sık gereken):
.\.claude\skills\conbot\scripts\restart.ps1 -ProjectRoot ".\ConBot-v0.4.0-win64" -SkipBuild

# Borsadan imzalı sorgu (HMAC boilerplate'i tekrar yazma)
.\.claude\skills\conbot\scripts\bybit.ps1 position
.\.claude\skills\conbot\scripts\bybit.ps1 pnl -Symbol ETHUSDT
.\.claude\skills\conbot\scripts\bybit.ps1 wallet
.\.claude\skills\conbot\scripts\bybit.ps1 raw -Path /v5/order/realtime -Params "category=linear"

# Seviye kurulumunu gerçek fiyat hareketiyle karşılaştır
.\.claude\skills\conbot\scripts\analyze-setup.ps1                 # çalışan bottan okur
.\.claude\skills\conbot\scripts\analyze-setup.ps1 -Symbol BTCUSDT -Levels 63757,64422 -Hours 24

# Dağıtım paketi (çalışan bota dokunmaz; şablonlar templates/ klasöründen gelir)
.\.claude\skills\conbot\scripts\package.ps1 -Version 0.4.1

# Git: sır denetimi geçmeden push ETMEZ
.\.claude\skills\conbot\scripts\git-push.ps1 -Message "panel: kısmi TP eklendi"
.\.claude\skills\conbot\scripts\git-guard.ps1        # yalnız denetle (staged)
.\.claude\skills\conbot\scripts\git-guard.ps1 -All   # deponun tamamını denetle
```

`templates/` içindeki `config.toml` **nötr** olmalı (operatörün gerçek
seviyeleri değil) ve `.env` asla pakete girmez — script bunu ayrıca kontrol eder.

## Panel API

**Jeton şart:** her `/api/*` çağrısında `X-ConBot-Auth: <PANEL_TOKEN>` başlığı.
Jeton `.env`'de yoksa açılışta üretilir; log satırı: `PANEL: http://.../#t=...`.
Başlıksız istek 401, beklenmedik `Host` 403 döner.

```powershell
$tok = (Get-Content "C:\Users\beko\Documents\ConBot-v0.7.0-win64\.env" |
        Select-String '^PANEL_TOKEN=').Line.Split('=')[1]
$h = @{ 'X-ConBot-Auth' = $tok }
Invoke-RestMethod "http://127.0.0.1:8080/api/status" -Headers $h
```


```
GET  /api/status     durum + config (phase: standby|idle|armed|waitingband|position|cooldown|halted)
GET  /api/trades     son olaylar (tampon 400 kayıt, her kayıtta symbol)
POST /api/start      işleme başla
POST /api/stop       işlemi durdur (pozisyon varsa kapatır)
POST /api/config     yeni config (JSON); pozisyon açıkken reddedilir
POST /api/markets/order  {"order":[...]} market sırası; marketleri yeniden kurmaz
POST /api/shutdown   botu kapat; açık pozisyon varsa reddedilir
```

Config uygulama kalıbı — mevcut config'i alıp değiştir, tamamını gönder:

```powershell
$b = "http://127.0.0.1:8080"
$cfg = (Invoke-RestMethod "$b/api/status").config
$cfg.levels = @("63757", "64422")
Invoke-RestMethod -Method Post -ContentType "application/json" `
  -Body ($cfg | ConvertTo-Json -Depth 5) "$b/api/config"
```

## Çok marketli yapı

`config.toml` = global `[defaults]` + `[[markets]]` listesi. Her market yalnız
`symbol` ve `levels` vermek zorunda; gerisini varsayılanlardan devralır ya da
kendi değeriyle geçersiz kılar. `BotConfig::resolve()` her market için mevcut
`Config` yapısını üretir — bu yüzden `Strategy` çok marketten habersizdir.

- Tek WebSocket, çok konu: `tickers.SYMBOL` sembol başına, `kline.TF.SYMBOL`
  (sembol, aralık) çifti başına, tekilleştirilmiş.
- Pozisyonlar tek `settleCoin=USDT` çağrısıyla çekilir; market sayısı istek
  sayısını artırmaz.
- **`max_concurrent_positions`** risk kapısı: sınır doluysa diğer marketlere
  `set_qty(0)` verilir, strateji işlem açmaz (`blocked_by_limit`).
- Eski tek-parite config'leri otomatik göç eder (`BotConfig::from_legacy`).
- Panel: üstte özet tablo, altta seçili marketin detayı; alt buton yalnız
  seçili marketi, üstteki iki buton bütün marketleri etkiler. Özet tablo
  sürüklenerek sıralanır; form "Varsayılana Dön" ile marketin geçersiz
  kılmalarını siler (kayıtta yalnız `symbol` + `levels` kalır).
- Journal her kayda `symbol` yazar.
- **Borsa stop** (`exchange_stop`, varsayılan `primary`): trailing stop Bybit'e
  yazılır (`/v5/position/trading-stop`, LastPrice tetikli), bekleyen girişlere
  `stopLoss` iliştirilir, çıkışı borsa yapar. Reverse bu modda **1×** açar.
  Borsa stop'u 3 sn içinde çalışmazsa bot pozisyonu kendisi kapatır.
  Demo'da bu uç ÇALIŞIYOR (pozisyon yokken "zero position" döner — normal).
- **Maker giriş** (`entry_mode`, varsayılan `limit`): girişler tetiğe önceden
  konan PostOnly limit; `orderLinkId` = `cb-SEMBOL-L/S/TP-<run>-n` — `<run>`
  çalışma kimliği ŞART, yoksa yeniden başlayan bot aynı kimliği üretir ve
  Bybit 110072 "duplicate" ile reddeder (bot sessizce emirsiz kalır).
  ATR kaydıkça amend,
  dolum 1 sn'lik hesap sorgusunda tespit edilir, TP bekleyen ReduceOnly maker
  limittir. Stop/reverse market kalır. Bot açılış/kapanışta `cb-` etiketli
  yetim emirleri iptal eder — bota müdahaleden önce borsada bekleyen emir
  olabileceğini unutma (`bybit.ps1 raw -Path /v5/order/realtime`).
  Altyapı tanısı: `conbot --order-selftest` (uzak PostOnly koy/amend/iptal).

## Durum makinesi (kısa)

`Standby` → operatör "İşleme Başla" → `Armed` (tetikler canlı) → tetik →
`InPosition` → stop → reverse (limit dahilinde) veya `Cooldown` → `Armed`.
Fiyat dar bir banda girerse `WaitingBand` (işlem açmaz). Merdivenin tamamen
dışına çıkarsa `Halted`. Config uygulamak her zaman `Standby`'a döndürür.

## PowerShell tuzakları (bu projede yaşandı)

- Zaman damgası: `Get-Date -UFormat %s` ondalık döner ve `* 1000` string
  tekrarına dönüşür. `[DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()` kullan.
- `@(@(...), @(...))` düzleşir; satır listesi için `[pscustomobject]` kullan.
- Native exe'de `2>&1` kullanma; stderr zaten yakalanıyor.
- Scriptler ASCII yazılmalı — PS 5.1, BOM'suz UTF-8 .ps1 dosyalarında Türkçe
  karakterleri bozar.

## Analiz notları

- Kâr/zarar için tek doğru kaynak borsanın `closed-pnl` kaydıdır; `closedPnl`
  komisyon **sonrası** nettir, brüt = `cumEntryValue`/`cumExitValue` farkı
  (kapatan emir `Buy` ise pozisyon Short'tu).
- Bybit **demo** ortamı `/v5/account/fee-rate` desteklemez (retCode 10001);
  komisyon `taker_fee_pct` config değerinden gelir.
- Emir miktarı borsanın `maxOrderQty` **yarısıyla** sınırlıdır, çünkü
  stop&reverse tek emirde `2×qty` gönderir.
