fix: 收敛退出放宽到0.02%+净利为正, 恢复到0.02%即退不亏钱
This commit is contained in:
@@ -135,8 +135,9 @@ Round trip (2 legs entry + 2 legs exit): configurable, default **0.21%** total f
|
|||||||
- `entering` map prevents duplicate entries on same coin
|
- `entering` map prevents duplicate entries on same coin
|
||||||
3. **Scale-in** adds another leg-worth when spread widens another `scale_step_pct` (default 0.10%)
|
3. **Scale-in** adds another leg-worth when spread widens another `scale_step_pct` (default 0.10%)
|
||||||
4. **Exit** conditions (whichever hits first):
|
4. **Exit** conditions (whichever hits first):
|
||||||
- **Net profit ≥ `take_profit_pct`** → **利润止盈**
|
- **Net profit ≥ `take_profit_pct`** → **利润止盈**(大盈利退出)
|
||||||
- **Spread converges to ≤ 0 (prices equal or reversed)** → **价差收敛止盈**
|
- **Spread narrowed to ≤ 0.02% + netPnl > 0** → **价差收敛止盈**(小盈利退出)
|
||||||
|
- **Spread flipped negative** → **价差反转平仓**(紧急止损)
|
||||||
- **Position held > `position_timeout_sec`** → **超时平仓**
|
- **Position held > `position_timeout_sec`** → **超时平仓**
|
||||||
5. **Direction**: BG → HL (buy BG, sell HL) or HL → BG (buy HL, sell BG)
|
5. **Direction**: BG → HL (buy BG, sell HL) or HL → BG (buy HL, sell BG)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
u := url.URL{Scheme: "wss", Host: "indexer.dydx.trade", Path: "/v4/ws"}
|
||||||
|
log.Printf("Connecting to %s", u.String())
|
||||||
|
|
||||||
|
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("dial:", err)
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
done := make(chan struct{})
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer close(done)
|
||||||
|
for {
|
||||||
|
_, message, err := c.ReadMessage()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("read:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("recv: %s", string(message))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Subscribe
|
||||||
|
sub := map[string]string{"type": "subscribe", "channel": "v4_markets"}
|
||||||
|
subData, _ := json.Marshal(sub)
|
||||||
|
c.WriteMessage(websocket.TextMessage, subData)
|
||||||
|
log.Printf("sent sub: %s", string(subData))
|
||||||
|
|
||||||
|
// Try pings
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
|
// Try JSON ping
|
||||||
|
ping := map[string]string{"type": "ping"}
|
||||||
|
pingData, _ := json.Marshal(ping)
|
||||||
|
err := c.WriteMessage(websocket.TextMessage, pingData)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("JSON ping error: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("sent JSON ping: %s", string(pingData))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try raw WS ping frame
|
||||||
|
err = c.WriteMessage(websocket.PingMessage, []byte("ping"))
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("WS ping error: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("sent WS ping frame")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(30 * time.Second)
|
||||||
|
fmt.Println("Done - checking if still connected")
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
fmt.Println("Connection closed")
|
||||||
|
default:
|
||||||
|
fmt.Println("Still connected!")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -534,12 +534,19 @@ func (t *Trader) checkExit(pos *ArbPosition, bgP, hlP, diffPct float64, notifier
|
|||||||
exitReason = "利润止盈"
|
exitReason = "利润止盈"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit when spread converges to zero or reverses (prices same or flipped)
|
// Convergence exit: spread narrowed significantly and we're profitable
|
||||||
if diffPct <= 0 {
|
// Prevents positions from sitting at near-zero spread waiting for timeout
|
||||||
|
if diffPct <= 0.02 && netPnl > 0 {
|
||||||
shouldExit = true
|
shouldExit = true
|
||||||
exitReason = "价差收敛止盈"
|
exitReason = "价差收敛止盈"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emergency reversal: spread flipped negative — cut losses
|
||||||
|
if diffPct < 0 {
|
||||||
|
shouldExit = true
|
||||||
|
exitReason = "价差反转平仓"
|
||||||
|
}
|
||||||
|
|
||||||
// Timeout: configured max hold time
|
// Timeout: configured max hold time
|
||||||
if elapsed > t.cfg.PositionTimeout {
|
if elapsed > t.cfg.PositionTimeout {
|
||||||
shouldExit = true
|
shouldExit = true
|
||||||
|
|||||||
Reference in New Issue
Block a user