feature/multi-symbol-trading #5
@@ -6,8 +6,9 @@ from src.config import Config
|
|||||||
|
|
||||||
|
|
||||||
class BinanceFuturesClient:
|
class BinanceFuturesClient:
|
||||||
def __init__(self, config: Config):
|
def __init__(self, config: Config, symbol: str = None):
|
||||||
self.config = config
|
self.config = config
|
||||||
|
self.symbol = symbol or config.symbol
|
||||||
self.client = Client(
|
self.client = Client(
|
||||||
api_key=config.api_key,
|
api_key=config.api_key,
|
||||||
api_secret=config.api_secret,
|
api_secret=config.api_secret,
|
||||||
@@ -31,7 +32,7 @@ class BinanceFuturesClient:
|
|||||||
return await loop.run_in_executor(
|
return await loop.run_in_executor(
|
||||||
None,
|
None,
|
||||||
lambda: self.client.futures_change_leverage(
|
lambda: self.client.futures_change_leverage(
|
||||||
symbol=self.config.symbol, leverage=leverage
|
symbol=self.symbol, leverage=leverage
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -68,7 +69,7 @@ class BinanceFuturesClient:
|
|||||||
)
|
)
|
||||||
|
|
||||||
params = dict(
|
params = dict(
|
||||||
symbol=self.config.symbol,
|
symbol=self.symbol,
|
||||||
side=side,
|
side=side,
|
||||||
type=order_type,
|
type=order_type,
|
||||||
quantity=quantity,
|
quantity=quantity,
|
||||||
@@ -98,7 +99,7 @@ class BinanceFuturesClient:
|
|||||||
"""STOP_MARKET / TAKE_PROFIT_MARKET 등 Algo Order API(/fapi/v1/algoOrder)로 전송."""
|
"""STOP_MARKET / TAKE_PROFIT_MARKET 등 Algo Order API(/fapi/v1/algoOrder)로 전송."""
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
params = dict(
|
params = dict(
|
||||||
symbol=self.config.symbol,
|
symbol=self.symbol,
|
||||||
side=side,
|
side=side,
|
||||||
algoType="CONDITIONAL",
|
algoType="CONDITIONAL",
|
||||||
type=order_type,
|
type=order_type,
|
||||||
@@ -120,7 +121,7 @@ class BinanceFuturesClient:
|
|||||||
positions = await loop.run_in_executor(
|
positions = await loop.run_in_executor(
|
||||||
None,
|
None,
|
||||||
lambda: self.client.futures_position_information(
|
lambda: self.client.futures_position_information(
|
||||||
symbol=self.config.symbol
|
symbol=self.symbol
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
for p in positions:
|
for p in positions:
|
||||||
@@ -134,14 +135,14 @@ class BinanceFuturesClient:
|
|||||||
await loop.run_in_executor(
|
await loop.run_in_executor(
|
||||||
None,
|
None,
|
||||||
lambda: self.client.futures_cancel_all_open_orders(
|
lambda: self.client.futures_cancel_all_open_orders(
|
||||||
symbol=self.config.symbol
|
symbol=self.symbol
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
await loop.run_in_executor(
|
await loop.run_in_executor(
|
||||||
None,
|
None,
|
||||||
lambda: self.client.futures_cancel_all_algo_open_orders(
|
lambda: self.client.futures_cancel_all_algo_open_orders(
|
||||||
symbol=self.config.symbol
|
symbol=self.symbol
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -153,7 +154,7 @@ class BinanceFuturesClient:
|
|||||||
try:
|
try:
|
||||||
result = await loop.run_in_executor(
|
result = await loop.run_in_executor(
|
||||||
None,
|
None,
|
||||||
lambda: self.client.futures_open_interest(symbol=self.config.symbol),
|
lambda: self.client.futures_open_interest(symbol=self.symbol),
|
||||||
)
|
)
|
||||||
return float(result["openInterest"])
|
return float(result["openInterest"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -166,7 +167,7 @@ class BinanceFuturesClient:
|
|||||||
try:
|
try:
|
||||||
result = await loop.run_in_executor(
|
result = await loop.run_in_executor(
|
||||||
None,
|
None,
|
||||||
lambda: self.client.futures_mark_price(symbol=self.config.symbol),
|
lambda: self.client.futures_mark_price(symbol=self.symbol),
|
||||||
)
|
)
|
||||||
return float(result["lastFundingRate"])
|
return float(result["lastFundingRate"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -180,7 +181,7 @@ class BinanceFuturesClient:
|
|||||||
result = await loop.run_in_executor(
|
result = await loop.run_in_executor(
|
||||||
None,
|
None,
|
||||||
lambda: self.client.futures_open_interest_hist(
|
lambda: self.client.futures_open_interest_hist(
|
||||||
symbol=self.config.symbol, period="15m", limit=limit + 1,
|
symbol=self.symbol, period="15m", limit=limit + 1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
if len(result) < 2:
|
if len(result) < 2:
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ def client():
|
|||||||
config.leverage = 10
|
config.leverage = 10
|
||||||
c = BinanceFuturesClient.__new__(BinanceFuturesClient)
|
c = BinanceFuturesClient.__new__(BinanceFuturesClient)
|
||||||
c.config = config
|
c.config = config
|
||||||
|
c.symbol = config.symbol
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
|
||||||
@@ -36,10 +37,24 @@ def exchange():
|
|||||||
config = Config()
|
config = Config()
|
||||||
c = BinanceFuturesClient.__new__(BinanceFuturesClient)
|
c = BinanceFuturesClient.__new__(BinanceFuturesClient)
|
||||||
c.config = config
|
c.config = config
|
||||||
|
c.symbol = config.symbol
|
||||||
c.client = MagicMock()
|
c.client = MagicMock()
|
||||||
return c
|
return c
|
||||||
|
|
||||||
|
|
||||||
|
def test_exchange_uses_own_symbol():
|
||||||
|
"""Exchange 클라이언트가 config.symbol 대신 생성자의 symbol을 사용한다."""
|
||||||
|
os.environ.update({
|
||||||
|
"BINANCE_API_KEY": "test_key",
|
||||||
|
"BINANCE_API_SECRET": "test_secret",
|
||||||
|
"SYMBOL": "XRPUSDT",
|
||||||
|
})
|
||||||
|
config = Config()
|
||||||
|
with patch("src.exchange.Client"):
|
||||||
|
client = BinanceFuturesClient(config, symbol="TRXUSDT")
|
||||||
|
assert client.symbol == "TRXUSDT"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_set_leverage(config):
|
async def test_set_leverage(config):
|
||||||
with patch("src.exchange.Client") as MockClient:
|
with patch("src.exchange.Client") as MockClient:
|
||||||
|
|||||||
Reference in New Issue
Block a user