Coverage for strategies / oneil_common_types.py: 100%

125 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-04 15:08 +0000

1# strategies/oneil/common_types.py 

2from dataclasses import dataclass 

3import os 

4from strategies.base_strategy_config import BaseStrategyConfig 

5 

6@dataclass 

7class OneilUniverseConfig(BaseStrategyConfig): 

8 """오닐 유니버스(종목 발굴) 관련 설정.""" 

9 # 유니버스 필터 

10 min_avg_trading_value_5d: int = 10_000_000_000 # 5일 평균 거래대금 100억 원 

11 near_52w_high_pct: float = 20.0 # 52주 최고가 대비 20% 이내 

12 

13 # 워치리스트 갱신 시각 (장 시작 후 경과 분) 

14 watchlist_refresh_minutes: tuple = (10, 30, 60, 90, 60*3, 60*5) 

15 

16 # 스퀴즈 조건 

17 bb_period: int = 20 

18 multiplier: float = 2.0 # 표준편차의 배수 

19 squeeze_tolerance: float = 1.2 # BB 폭이 20일 최소폭의 1.2배 이내 

20 

21 # 마켓 타이밍 

22 kosdaq_etf_code: str = "229200" # KODEX 코스닥150 

23 kospi_etf_code: str = "069500" # KODEX 200 

24 market_ma_period: int = 20 

25 market_ma_rising_days: int = 3 

26 

27 # V2 스코어링 

28 rs_period_days: int = 63 

29 rs_top_percentile: float = 10.0 

30 rs_score_points: float = 30.0 

31 profit_growth_threshold_pct: float = 25.0 

32 profit_growth_score_points: float = 20.0 

33 api_chunk_size: int = 10 

34 

35 # 전일기준우량주 / 당일급등주 설정 

36 premium_stocks_file: str = os.path.join("data", "premium_stocks.json") 

37 premium_stocks_kospi_size: int = 20 

38 premium_stocks_kosdaq_size: int = 40 

39 

40 premium_stocks_cap_min: int = 200_000_000_000 # 2000억 

41 premium_stocks_cap_max: int = 20_000_000_000_000 # 20조 

42 daily_surge_size: int = 30 

43 

44 max_watchlist: int = premium_stocks_kospi_size + premium_stocks_kosdaq_size + daily_surge_size # 최대 감시 종목 수 

45 

46 # 돌파 기준 기간 (데이터 수집용) 

47 high_breakout_period: int = 20 

48 

49 # 스마트 머니 (수급) 스코어링 

50 smart_money_lookback_days: int = 3 # 3일 누적 기준 

51 smart_money_to_mcap_pct: float = 0.5 # 시총의 0.5% 이상 매집 시 

52 smart_money_to_tv_pct: float = 10.0 # 또는 누적 거래대금의 10% 이상 매집 시 

53 smart_money_score_points: float = 15.0 # +15점 부여 

54 

55 

56@dataclass 

57class OneilBreakoutConfig(BaseStrategyConfig): 

58 """오닐 돌파 매매 전략(Strategy B) 설정.""" 

59 # 매수 조건 

60 volume_breakout_multiplier: float = 1.5 # 20일 평균 거래량의 150% 

61 program_net_buy_min: int = 0 # pgtr_ntby_qty > 0 

62 program_to_trade_value_pct: float = 10.0 # (프로그램순매수금/거래대금) >= 10% 

63 program_to_market_cap_pct: float = 0.5 # (프로그램순매수금/시총) >= 0.5% 

64 

65 # 매도 조건 

66 stop_loss_pct: float = -5.0 

67 trailing_stop_pct: float = 8.0 

68 time_stop_days: int = 5 

69 time_stop_box_range_pct: float = 2.0 

70 trend_exit_ma_period: int = 10 

71 

72 # 자금 관리 

73 total_portfolio_krw: int = 10_000_000 

74 position_size_pct: float = 5.0 

75 min_qty: int = 1 

76 

77 

78@dataclass 

79class OSBWatchlistItem: 

80 """감시 종목 정보 (Universe Service -> Strategy 전달 객체).""" 

81 code: str 

82 name: str 

83 market: str # "KOSPI" or "KOSDAQ" 

84 high_20d: int # 20일 최고가 (돌파 기준) 

85 ma_20d: float # 20일 이동평균 

86 ma_50d: float # 50일 이동평균 

87 avg_vol_20d: float # 20일 평균 거래량 

88 bb_width_min_20d: float # 최근 20일간 BB 밴드폭 최소값 

89 prev_bb_width: float # 전일 BB 밴드폭 

90 w52_hgpr: int # 52주 최고가 

91 avg_trading_value_5d: float # 5일 평균 거래대금 

92 market_cap: int = 0 # 시가총액 

93 

94 # 스코어링 

95 rs_return_3m: float = 0.0 

96 rs_score: float = 0.0 

97 profit_growth_score: float = 0.0 

98 smart_money_score: float = 0.0 

99 total_score: float = 0.0 

100 

101 

102@dataclass 

103class OSBPositionState: 

104 """보유 포지션 추적 상태.""" 

105 entry_price: int # 진입가 

106 entry_date: str # 진입일 (YYYYMMDD) 

107 peak_price: int # 진입 후 최고가 (트레일링 스탑용) 

108 breakout_level: int # 진입 시 20일 최고가 

109 

110 

111@dataclass 

112class OneilPocketPivotConfig(BaseStrategyConfig): 

113 """포켓 피봇 & BGU 전략(Strategy C) 설정.""" 

114 # 공통 스마트 머니 필터 

115 program_to_trade_value_pct: float = 10.0 # PG순매수금/거래대금 >= 10% 

116 program_to_market_cap_pct: float = 0.3 # PG순매수금/시총 >= 0.3% 

117 execution_strength_min: float = 120.0 # 체결강도 >= 120% 

118 

119 # Entry A: Pocket Pivot 

120 pp_ma_proximity_lower_pct: float = -2.0 # MA 대비 하한 (-2%) 

121 pp_ma_proximity_upper_pct: float = 4.0 # MA 대비 상한 (+4%) 

122 pp_down_day_lookback: int = 10 # 하락일 거래량 비교 기간 (일) 

123 

124 # Entry B: BGU (Buyable Gap-Up) 

125 bgu_gap_pct: float = 4.0 # 시가 갭 >= 4% 

126 bgu_volume_multiplier: float = 3.0 # 50일 평균거래량의 300% 

127 bgu_whipsaw_after_minutes: int = 10 # 장 시작 후 10분 경과 후 진입 

128 

129 # 매도: 손절 

130 pp_stop_loss_below_ma_pct: float = -2.0 # PP: 지지MA 대비 -2% 이탈 시 손절 

131 

132 # 매도: 7주 홀딩 룰 

133 holding_rule_days: int = 35 # 7주 = 35거래일 

134 holding_rule_ma_period: int = 50 # 50일선 기준 

135 holding_profit_anchor_pct: float = 5.0 # +5% 이상 수익 시 holding_start_date 기록 (1회만) 

136 

137 # 매도: 부분 익절 

138 partial_profit_trigger_pct: float = 15.0 # +15% 도달 시 50% 익절 

139 partial_sell_ratio: float = 0.5 # 50% 매도 

140 

141 # 매도: 하드 스탑 

142 hard_stop_from_peak_pct: float = -10.0 # 고점 대비 -10% 하락 시 즉시 청산 

143 

144 # 자금 관리 

145 total_portfolio_krw: int = 10_000_000 

146 position_size_pct: float = 5.0 

147 min_qty: int = 2 # 부분 익절을 위해 최소 2주 매수 

148 

149 

150@dataclass 

151class PPPositionState: 

152 """포켓 피봇 / BGU 포지션 추적 상태.""" 

153 entry_type: str # "PP" or "BGU" 

154 entry_price: int # 진입가 

155 entry_date: str # 진입일 (YYYYMMDD) 

156 peak_price: int # 진입 후 최고가 

157 supporting_ma: str # PP전용: "10"/"20"/"50" (지지 MA 종류) 

158 gap_day_low: int # BGU전용: 갭업 당일 장중 저가 

159 partial_sold: bool = False # deprecated (JSON 하위호환용) 

160 holding_start_date: str = "" # 수익 안착일 (+5% 돌파 시 1회만 기록, 7주 룰 기산점) 

161 last_partial_sell_price: int = 0 # 마지막 부분익절 가격 (0=미실행, >0=기준가) 

162 

163 

164@dataclass 

165class HTFConfig(BaseStrategyConfig): 

166 """하이 타이트 플래그 전략 설정.""" 

167 # Phase 1: 깃대 (Pole) 

168 pole_lookback_days: int = 40 # 40거래일 스캔 

169 pole_min_surge_ratio: float = 1.90 # max(high)/min(low) >= 1.90 

170 

171 # Phase 2: 깃발 (Flag) 

172 flag_min_days: int = 5 # 최소 횡보 기간 (한국형: Short Stroke 대응) 

173 flag_max_days: int = 25 # 최대 횡보 기간 

174 flag_max_drawdown_pct: float = 20.0 # 고점 대비 최대 하락폭 (종가 기준) 

175 flag_volume_shrink_ratio: float = 1.2 # 깃발 평균거래량 < 50일평균 * 1.2 

176 

177 # Phase 3: 돌파 (Breakout) 

178 volume_breakout_multiplier: float = 2.0 # 예상거래량 >= 50일평균 * 200% 

179 execution_strength_min: float = 120.0 # 체결강도 >= 120% 

180 

181 # Phase 4: 청산 (Exit) 

182 stop_loss_pct: float = -5.0 # 칼손절 

183 trailing_ma_period: int = 10 # 10일 MA 트레일링스탑 

184 

185 # 자금 관리 

186 total_portfolio_krw: int = 10_000_000 

187 position_size_pct: float = 5.0 

188 min_qty: int = 1 

189 

190 

191@dataclass 

192class HTFPositionState: 

193 """HTF 포지션 추적 상태.""" 

194 entry_price: int # 진입가 

195 entry_date: str # 진입일 (YYYYMMDD) 

196 peak_price: int # 진입 후 최고가 

197 pole_high: int # 깃대 최고점 (돌파 기준가)