올해 새로 합류한 챌린지 프로젝트 분들이랑 정이 많이 들어버렸다.
회식 2차로 보드게임 카페도 가보고, 재밌어서 늦게까지 있기도 하고...
덕분에 재밌게 일하니 좋은데, 연말에 해산할 생각에 아쉽다.
대장테마, 주도주 선발이 어느 정도 안정화 되어 이제
매수/매도 전략을 최적화 화려한다.
무엇을 살 것인지 -> 언제 살 것인가 & 언제 팔 것인가
해당 과정은 이전에 해본 적이 있기에 비교적 수월할 것 같다.
가설을 세우고, 데이터로 확인하고, 백테스팅으로 확인한다.
1. 매수 시간이 영향을 줄 것인가?
- 오후 시간대는 수익을 정리하려는 경향이 있기에, 매수를 삼가하는 것이 좋을 것이다.
df["buy_time"] = pd.to_datetime(df["buy_time"])
df["buy_time_slot"] = df["buy_time"].dt.strftime("%H:%M")
df["buy_time_slot"] = (
pd.to_datetime(df["buy_time_slot"], format="%H:%M").dt.floor("5T").dt.strftime("%H:%M")
)
buy_time_slot_avg = (
df.groupby("buy_time_slot")
.agg(
average_profit=("profit_pct", "mean"), # 평균 수익률
count=("profit_pct", "size"), # 데이터 개수
)
.reset_index()
)
# 시각화
plt.figure(figsize=(12, 6))
# 막대 색상 설정: 양수는 붉은색, 음수는 푸른색
colors = ["red" if val > 0 else "blue" for val in buy_time_slot_avg["average_profit"]]
# 막대그래프 생성
bars = plt.bar(
x=buy_time_slot_avg["buy_time_slot"], height=buy_time_slot_avg["average_profit"], color=colors
)
# 데이터 라벨 추가
for index, row in buy_time_slot_avg.iterrows():
plt.text(
x=index,
y=row["average_profit"],
s=f"{int(row['count'])}", # 데이터 개수
ha="center",
va="bottom" if row["average_profit"] > 0 else "top",
fontsize=10,
color="black",
)
# 그래프 설정
plt.title("Average Profit by 5-Minute (Buy) Time Slot", fontsize=16)
plt.xlabel("Time Slot (10-Minute Intervals)", fontsize=12)
plt.ylabel("Average Profit (%)", fontsize=12)
plt.xticks(rotation=45)
plt.grid(visible=True, linestyle="--", alpha=0.6)
plt.tight_layout()
plt.show()
결과를 보니, 오후 2시 이후에는 굳이 매수를 안해도 될 것 같다.
손실이 더 많고, 수익을 보더라도 미미하기에 수수료만 떼인다.
코드를 추가해준다.
def _is_buy_conditions_met(self, row, close):
if self.datetime.time() >= datetime.time(14, 0):
return False
2. 상승률이 너무 높거나 낮은 것은 걸러야 하는가?
12% 이상부터는 대부분이 마이너스이다. 일부 상승분이 있긴하지만, 손실이 더 커서 필터링 조건을 강화한다.
if not (1 <= row["DoD"] <= 12):
return False
Before
총 거래 수: 59.0
총 순수익: 46,180,390 원
📊 총 수익률: 46.18%
✅ 승률: 44.07%
After
총 거래 수: 43.0
총 순수익: 53,938,300 원
📊 총 수익률: 53.94%
✅ 승률: 51.16%
거래 수는 줄고, 수익률은 늘고, 승률은 올랐다.
overfitting 일 수도 있지만, 이건 백테스팅 데이터 수를 늘리며 보강한다.
이제 좀 쓸만한 전략이 된 거 같다.
3. RSI 기준은 어느 정도가 적절한가?
매수 기준으로 참고하는 보조지표 중 하나로 RSI를 활용 중이다.
현재는 RSI 75 이하일 때만 매수하도록 조건을 걸어놨는데, 이는 적절한지 확인이 필요하다.
import seaborn as sns
import matplotlib.pyplot as plt
for col in factors:
# profit_pct 양수/음수 구분 컬럼
color_map = df['profit_pct'].apply(lambda x: 'red' if x > 0 else 'blue')
plt.figure(figsize=(7,5))
plt.scatter(df[col], df['profit_pct'], c=color_map, alpha=0.4)
plt.title(f"{col} vs profit_pct")
plt.xlabel(col)
plt.ylabel('profit_pct')
plt.axhline(0, color='gray', linestyle='--')
plt.show()
눈으로 확인해보니, RSI 70 이상일 때 주로 손실이 발생한다.
매수 조건을 70으로 내려 강화한다.
'Quant' 카테고리의 다른 글
연산 최적화 (2) | 2025.07.07 |
---|---|
보조지표 추가, ADX (0) | 2025.07.06 |
전략 최적화 (2) (4) | 2025.06.30 |
전략 최적화 (1) (6) | 2025.06.29 |
주도주 변경 최소화 (2) (2) | 2025.06.22 |