Components: # 체인 초기화 및 마켓 설정 Initializer: Network: mainnet # 연결할 네트워크 (mainnet 또는 testnet) MarketTickers: # 추적할 마켓 티커 (ID로 변환됨) - INJ/USDT PERP - ETH/USDT BotName: MyBot # 체인 리스닝 구성 ChainListener: ReconnectionDelay: 5 # 재연결 시도 전 대기 시간(초) LargeGapThreshold: 50 # orderbook 스냅샷 요청을 위한 시퀀스 갭 임계값 # 트랜잭션 브로드캐스팅 구성 MessageBroadcaster: ErrorCodesJson: config/error_codes.json # tx 검증을 위한 오류 코드 조회 GranteePool: # authz 트랜잭션 모드용 MaxPendingTxs: 5 # grantee당 최대 대기 중 트랜잭션 ErrorThreshold: 3 # grantee 차단 전 연속 오류 수 BlockDuration: 300 # 오류 후 grantee 차단 시간(초) RotationInterval: 1 # grantee 로테이션 간격(초) RefreshInterval: 300 # 권한 부여 갱신 확인 간격(초) Batch: # 트랜잭션 배칭 설정 MaxBatchSize: 15 # 배치당 최대 메시지 수 MinBatchSize: 3 # 즉시 전송을 트리거하는 최소 메시지 수 MaxGasLimit: 5000000 # 배치당 최대 가스 MaxBatchDelay: 0.5 # 배치 완료 대기 최대 시간(초)
참고: 대부분의 사용자는 Network만 관리하고 수신하려는 모든 마켓을 MarketTickers에 포함하면 됩니다.
이러한 고급 컴포넌트 설정을 수정할 필요가 없습니다. 기본값은 대부분의 사용 사례에서 잘 작동합니다.
Strategies: SimpleStrategy: # 전략 식별자 (선택 사항) # 필수 매개변수 Name: "SimpleStrategy" # 전략 이름 (로그에 사용) Class: "SimpleStrategy" # [필수] 인스턴스화할 Python 클래스 이름 MarketIds: # [필수] 거래할 마켓 - "0x9b9980167ecc3645ff1a5517886652d94a0825e54a77d2057cbbe3ebee015963" # INJ/USDT PERP AccountAddresses: # [필수] 사용할 계정 - "inj1youractualaccount..." # (env의 개인 키와 일치해야 함) TradingAccount: "inj1youractualaccount..." # [필수] 주문 배치용 계정 (env의 개인 키와 일치해야 함) # 선택적 매개변수 FeeRecipient: "inj1feerecipient..." # 거래 수수료를 받을 주소 (해당되는 경우) CIDPrefix: "simple_strat" # 클라이언트 주문 ID 접두사 SubaccountIds: ["0x123..."] # 사용할 특정 subaccount (그렇지 않으면 사용 가능한 모든 것) # 리스크 관리 구성 [선택사항] # 특정 리스크 모델이 없으면 포함할 필요 없음 Risk: "BasicRiskModel" # 적용할 리스크 모델 (리스크 관리 사용 시) RiskConfig: # 리스크 임계값 DrawdownWarning: 0.1 # 10% drawdown 경고 임계값 DrawdownCritical: 0.2 # 20% drawdown 위험 임계값 MarginWarning: 0.7 # 70% 마진 사용 경고 MarginCritical: 0.8 # 80% 마진 사용 위험
필수 전략 매개변수:
Class: Python 클래스 이름과 정확히 일치해야 함
MarketIds: 이 전략에서 거래할 마켓 ID 목록 (hex 형식 사용)
AccountAddresses: 이 전략에서 거래에 사용할 계정 목록
TradingAccount: 주문 실행에 사용되는 계정 (AccountAddresses에 있어야 함)
Strategies: SimpleStrategy: # 기타 매개변수... Granter: "inj1granteraccount..." # 거래 실행 권한을 부여하는 계정 Grantees: # granter를 대신하여 거래를 실행할 수 있는 계정 - "inj1grantee1..." - "inj1grantee2..."
참고: direct execution을 위한 TradingAccount 또는 authorization mode를 위한 Granter와 Grantees를 지정해야 합니다.
프레임워크는 초기화 중에 이 요구 사항을 적용합니다.
from src.core.strategy import Strategy, StrategyResultfrom src.utils.enums import UpdateType, Sideclass SimpleStrategy(Strategy): def __init__(self, logger, config): """ logger와 구성으로 전략 초기화. Args: logger: 전략 로깅을 위한 Logger 인스턴스 config: 전략 구성 딕셔너리 필수 키: - MarketIds: 거래할 마켓 ID 목록 - AccountAddresses: 사용할 계정 주소 목록 선택적 키: - Name: 전략 이름 - Parameters: 전략별 매개변수 - RiskConfig: 리스크 관리 매개변수 """ super().__init__(logger, config) def on_initialize(self, accounts, markets): """ 전략별 상태 및 매개변수 초기화. 전략이 업데이트 처리를 시작하기 전에 한 번 호출됩니다. Args: accounts: account_address -> Account 딕셔너리 markets: market_id -> Market 딕셔너리 """ pass async def _execute_strategy(self, update_type, processed_data): """ 전략별 실행 로직. Args: update_type: 처리 중인 업데이트 유형 processed_data: 핸들러 처리 후 업데이트별 데이터 딕셔너리 공통 필드: - market_id: 마켓 식별자 - account_address: 계정 주소 (계정 업데이트용) - subaccount_id: Subaccount 식별자 (포지션/거래 업데이트용) Returns: StrategyResult: - orders - cancellations - margin updates """ pass
on_initialize 메서드는 마켓과 계정이 로드된 후 프레임워크 시작 중에 한 번 호출됩니다.목적: 전략 상태 및 매개변수 초기화매개변수:
accounts: account_address → Account 객체 딕셔너리
markets: market_id → Market 객체 딕셔너리
반환: [선택사항] 초기 주문이 있는 StrategyResult (있는 경우)
복사
AI에게 묻기
def on_initialize(self, accounts, markets): # 이제 모든 마켓 및 계정 데이터에 접근할 수 있습니다 # 예제: 마켓 메타데이터 접근 for market_id in self.market_ids: market = markets[market_id] self.logger.info(f"Market {market_id} tick sizes: " f"price={market.min_price_tick}, " f"quantity={market.min_quantity_tick}") # 예제: 마켓 정보가 필요한 매개변수 초기화 self.avg_prices = { market_id: markets[market_id].orderbook.tob()[0] for market_id in self.market_ids if markets[market_id].orderbook.tob()[0] } # 예제: 초기 주문 배치 if self.config.get("PlaceInitialOrders", False): result = StrategyResult() # 초기 주문 추가... return result return None # 초기 주문 없음
_execute_strategy 메서드는 “Strategy Execution (execute) Method”의 일부입니다. 기본 클래스 execute 메서드는 전체 실행 흐름을 처리합니다:
초기화 확인: 필요한 경우 전략 초기화
상태 업데이트: 전략의 계정 및 마켓 참조 업데이트
데이터 처리: 적절한 핸들러를 통해 원시 업데이트 데이터 처리
전략 실행: 처리된 데이터로 _execute_strategy 메서드 호출
주문 보강: 주문에 기본값 추가 (수수료 수신자, 클라이언트 ID)
이 메서드를 재정의할 필요는 거의 없습니다. 대신 커스텀 거래 로직이 들어가는 _execute_strategy 구현에 집중하세요:목적: 마켓 데이터 분석 및 거래 신호 생성매개변수:
update_type: 처리 중인 업데이트 유형
processed_data: 관련 필드가 있는 핸들러 처리 데이터 딕셔너리
반환: 주문/취소가 있는 StrategyResult 또는 None
복사
AI에게 묻기
async def _execute_strategy(self, update_type, processed_data): # orderbook 업데이트에만 응답 if update_type != UpdateType.OnOrderbook: return None # 마켓 데이터 가져오기 market_id = processed_data["market_id"] market = self.markets[market_id] # 현재 가격 가져오기 bid, ask = market.orderbook.tob() if not bid or not ask: self.logger.warning(f"Incomplete orderbook for {market_id}") return None # 전략 로직 구현 spread = (ask - bid) / bid if spread < self.min_spread_threshold: self.logger.info(f"Spread too narrow: {spread:.2%}") return None # 주문을 위한 subaccount 가져오기 subaccount_id = self.config.get("SubaccountIds", [""])[0] if not subaccount_id: return None # 제한 초과를 피하기 위해 현재 포지션 확인 position = self.get_position(subaccount_id, market_id) current_size = Decimal("0") if position: current_size = position.get("quantity", Decimal("0")) # 주문 매개변수 결정 result = StrategyResult() # 새 주문 생성 if current_size < self.max_position: buy_order = Order( market_id=market_id, subaccount_id=subaccount_id, order_side=Side.BUY, price=bid, quantity=self.order_size, market_type=market.market_type # v0.5.1부터 필수 필드 ) result.orders.append(buy_order) self.logger.info(f"Creating BUY order at {bid}: {self.order_size}") # 필요한 경우 기존 주문 취소 for order_hash in self.active_orders: result.cancellations.append({ "market_id": market_id, "subaccount_id": subaccount_id, "order_hash": order_hash }) return result
_execute_strategy에서 다음을 수행할 수 있습니다:
업데이트 유형별 필터링으로 특정 이벤트 처리
현재 마켓 데이터 및 계정 상태 접근
주문 배치 전 기존 포지션 확인
마켓 조건에 따른 커스텀 거래 로직 구현
새 주문 생성 및 기존 주문 취소
파생상품 마켓의 포지션 마진 업데이트
모니터링 및 디버깅을 위한 전략 결정 로깅
프레임워크는 반환된 StrategyResult를 기반으로 트랜잭션 생성, 시뮬레이션 및 브로드캐스팅과 같은 실행 세부 사항을 처리합니다.