(05.23) 수정됨.
적삼병
주식 용어 중에 적삼병이라는 용어가 있다.
빨간 양봉이 3개 연속으로 등장하는 패턴을 뜻하는데, 주가 상승의 신호로 알려진 것들 중 하나다.
양봉이 연속으로 등장할 때
양봉이 연속으로 등장하는 경우는 흔하지 않고, (양봉)=(주가 상승)이기 때문에 주가가 크게 상승한 종목의 차트에서 발견하기 쉽다.
이전에 주식 자동매매 패턴을 검토하기 위해 작성한 코드를 기반으로 테스트한다.
조건 1
종가가 전일보다 높은 양봉이 3개 연속으로 등장한 경우 매수하고, 가장 마지막 양봉의 종가기준 -10%가 됐을 때 매도를 하는 로직이다.
class Logic:
count = 0
price_cut = 0
pre_close = 0
def need_buy(self, Open, high, low, close, volume, rate, is_upper, is_lower):
if Open < close:
if not is_upper and 2 < self.count:
self.count = 0
return True
return
def need_sell(self, Open, high, low, close, volume, rate, is_upper, is_lower):
if not is_lower and self.price_cut and close < self.price_cut:
return True
return
def update_count(self, Open, close):
if Open < close and self.pre_close < close:
self.count += 1
else:
self.count = 0
return
def check(self, Open, high, low, close, volume, rate, is_upper=False, is_lower=False):
if not volume:
return
self.update_count(Open, close)
result = None
args = (Open, high, low, close, volume, rate, is_upper, is_lower)
if (
not is_upper
and self.need_buy(*args)
):
self.price_cut = self.get_cut_price(close)
result = 'buy'
elif (
not is_lower
and self.need_sell(*args)
):
self.price_cut = 0
result = 'sell'
if self.price_cut and self.count and self.pre_close < close:
self.price_cut = self.get_cut_price(close)
self.pre_close = close
return result
def get_cut_price(self, price):
return round(price * 0.9)
조건 1 결과
극단값이 매우 큰 결과가 나왔다.
이론상 텐배거를 먹는 것도 가능하지만, 동시에 1/10토막이 나는 것도 경험할 수 있다는 결과가 나온 것이다.
2985. 435570
1. {'매수일': '2025-04-01', '매수가격': 7600, '매도일': '2025-04-14', '매도가격': 27650, '수익률': 263.82}
2986. 393970
1. {'매수일': '2025-04-02', '매수가격': 17520, '매도일': '2025-04-03', '매도가격': 15700, '수익률': -10.39}
2987. 226590
1. {'매수일': '2025-04-03', '매수가격': 9120, '매도일': '2025-04-07', '매도가격': 8170, '수익률': -10.42}
2. {'매수일': '2025-04-17', '매수가격': 10680, '매도일': '2025-05-16', '매도가격': 12210, '수익률': 14.33}
2988. 460870
1. {'매수일': '2025-04-11', '매수가격': 4685, '매도일': '2025-04-28', '매도가격': 6360, '수익률': 35.75}
2989. 098070
1. {'매수일': '2025-03-24', '매수가격': 33200, '매도일': '2025-03-26', '매도가격': 28200, '수익률': -15.06}
2990. 484810
1. {'매수일': '2025-04-17', '매수가격': 23100, '매도일': '2025-04-28', '매도가격': 19210, '수익률': -16.84}
2991. 444530
1. {'매수일': '2025-04-14', '매수가격': 12150, '매도일': '2025-04-22', '매도가격': 14420, '수익률': 18.68}
1. {'매수일': '2025-04-17', '매수가격': 20350, '매도일': '2025-04-21', '매도가격': 18220, '수익률': -10.47}
이익을 본 횟수 : 24,729
평균 이익률 : 26.08%
최대 이익률 : 1256.24%
손실을 본 횟수 : 42,479
평균 손실률 : -12.23%
최대 손실률 : -93.37%
성공률 : 36.79%
조건 2
이번에는 매수 조건을 양봉이 5개 연속되었을 때로 변경하였다.
class Logic:
...
def need_buy(self, Open, high, low, close, volume, rate, is_upper, is_lower):
if Open < close:
if not is_upper and 4 < self.count:
self.count = 0
return True
return
조건 2 결과
조건을 바꿨지만 성공률은 크게 변하지 않았다.
2774. 473980
1. {'매수일': '2024-12-03', '매수가격': 22850, '매도일': '2024-12-06', '매도가격': 20500, '수익률': -10.28}
2. {'매수일': '2025-03-27', '매수가격': 25900, '매도일': '2025-04-08', '매도가격': 23700, '수익률': -8.49}
2775. 394800
1. {'매수일': '2024-11-25', '매수가격': 4400, '매도일': '2024-12-05', '매도가격': 5300, '수익률': 20.45}
2. {'매수일': '2025-02-06', '매수가격': 6280, '매도일': '2025-02-12', '매도가격': 5600, '수익률': -10.83}
2776. 466410
1. {'매수일': '2025-02-05', '매수가격': 18680, '매도일': '2025-02-07', '매도가격': 17390, '수익률': -6.91}
2777. 389680
1. {'매수일': '2025-03-24', '매수가격': 700, '매도일': '2025-03-31', '매도가격': 621, '수익률': -11.29}
2778. 382150
1. {'매수일': '2025-04-15', '매수가격': 13090, '매도일': '2025-04-24', '매도가격': 13450, '수익률': 2.75}
2779. 176750
1. {'매수일': '2025-02-05', '매수가격': 10030, '매도일': '2025-04-07', '매도가격': 10910, '수익률': 8.77}
2780. 373160
1. {'매수일': '2025-04-07', '매수가격': 7850, '매도일': '2025-04-17', '매도가격': 8300, '수익률': 5.73}
2781. 460870
1. {'매수일': '2025-04-15', '매수가격': 4870, '매도일': '2025-04-28', '매도가격': 6360, '수익률': 30.6}
2782. 444530
1. {'매수일': '2025-04-16', '매수가격': 15660, '매도일': '2025-04-22', '매도가격': 14420, '수익률': -7.92}
이익을 본 횟수 : 6,479
평균 이익률 : 25.52%
최대 이익률 : 791.09%
손실을 본 횟수 : 10,959
평균 손실률 : -12.61%
최대 손실률 : -87.19%
성공률 : 37.15%
조건 3
이번에는 익절 조건을 변경하였다.
평균 이익률이 25%였기 때문에, 매수단가 대비 20%를 익절 기준으로 하였다.
매도 주문은 미리 걸어둘 수 있기 때문에 고가가 기준보다 높다면 익절 신호가 나가도록 했다.
또한 매수 조건을 양봉이 연속으로 3번 등장했을 때로 변경했다.
class Logic:
...
def need_buy(self, Open, high, low, close, volume, rate, is_upper, is_lower):
if Open < close:
if not is_upper and 2 < self.count:
self.count = 0
return True
return
def need_sell(self, Open, high, low, close, volume, rate, is_upper, is_lower):
if not is_lower and self.price_cut and close < self.price_cut:
return True
if self.price_take and self.price_take < high:
return True
return
def check(self, Open, high, low, close, volume, rate, is_upper=False, is_lower=False):
if not volume:
return
self.update_count(Open, close)
result = None
args = (Open, high, low, close, volume, rate, is_upper, is_lower)
if (
not is_upper
and self.need_buy(*args)
):
self.price_cut = self.get_cut_price(close)
self.price_take = self.get_take_price(close)
result = 'buy'
elif (
not is_lower
and self.need_sell(*args)
):
self.price_cut = 0
self.price_take = 0
result = 'sell'
if self.price_cut and self.count and self.pre_close < close:
self.price_cut = self.get_cut_price(close)
self.pre_close = close
return result
def get_cut_price(self, price):
return round(price * 0.9)
def get_take_price(self, price):
return round(price * 1.2)
조건 3 결과
익절 조건을 설정하니 성공률이 42%대로 증가했다.
3003. 226590
1. {'매수일': '2025-04-03', '매수가격': 9120, '매도일': '2025-04-07', '매도가격': 8170, '수익률': -10.42}
2. {'매수일': '2025-04-17', '매수가격': 10680, '매도일': '2025-05-02', '매도가격': 12700, '수익률': 18.91}
3. {'매수일': '2025-05-07', '매수가격': 13420, '매도일': '2025-05-16', '매도가격': 12210, '수익률': -9.02}
3004. 460870
1. {'매수일': '2025-04-11', '매수가격': 4685, '매도일': '2025-04-21', '매도가격': 6360, '수익률': 35.75}
3005. 098070
1. {'매수일': '2025-03-24', '매수가격': 33200, '매도일': '2025-03-26', '매도가격': 28200, '수익률': -15.06}
3006. 484810
1. {'매수일': '2025-04-17', '매수가격': 23100, '매도일': '2025-04-28', '매도가격': 19210, '수익률': -16.84}
3007. 444530
1. {'매수일': '2025-04-14', '매수가격': 12150, '매도일': '2025-04-16', '매도가격': 15660, '수익률': 28.89}
2. {'매수일': '2025-04-17', '매수가격': 16120, '매도일': '2025-04-22', '매도가격': 14420, '수익률': -10.55}
3008. 448900
1. {'매수일': '2025-04-17', '매수가격': 20350, '매도일': '2025-04-21', '매도가격': 18220, '수익률': -10.47}
이익을 본 횟수 : 33,785
평균 이익률 : 20.13%
최대 이익률 : 352.62%
손실을 본 횟수 : 46,133
평균 손실률 : -12.51%
최대 손실률 : -93.37%
성공률 : 42.27%
조건 4
매수 조건을 연속되는 양봉이 5번째 등장했을 때로 변경했다.
class Logic:
...
def need_buy(self, Open, high, low, close, volume, rate, is_upper, is_lower):
if Open < close:
if not is_upper and 4 < self.count:
self.count = 0
return True
return
조건 4 결과
조건 3과 성공률은 비슷하게 나왔다.
2791. 473980
1. {'매수일': '2024-12-03', '매수가격': 22850, '매도일': '2024-12-06', '매도가격': 20500, '수익률': -10.28}
2. {'매수일': '2025-03-27', '매수가격': 25900, '매도일': '2025-04-08', '매도가격': 23700, '수익률': -8.49}
2792. 394800
1. {'매수일': '2024-11-25', '매수가격': 4400, '매도일': '2024-11-26', '매도가격': 5720, '수익률': 30.0}
2. {'매수일': '2025-02-06', '매수가격': 6280, '매도일': '2025-02-12', '매도가격': 5600, '수익률': -10.83}
2793. 466410
1. {'매수일': '2025-02-05', '매수가격': 18680, '매도일': '2025-02-07', '매도가격': 17390, '수익률': -6.91}
2794. 389680
1. {'매수일': '2025-03-24', '매수가격': 700, '매도일': '2025-03-31', '매도가격': 621, '수익률': -11.29}
2795. 382150
1. {'매수일': '2025-04-15', '매수가격': 13090, '매도일': '2025-04-18', '매도가격': 15590, '수익률': 19.1}
2796. 176750
1. {'매수일': '2025-02-05', '매수가격': 10030, '매도일': '2025-02-11', '매도가격': 11900, '수익률': 18.64}
2797. 373160
1. {'매수일': '2025-04-07', '매수가격': 7850, '매도일': '2025-04-08', '매도가격': 9320, '수익률': 18.73}
2798. 450950
1. {'매수일': '2025-04-21', '매수가격': 9860, '매도일': '2025-05-15', '매도가격': 11810, '수익률': 19.78}
2799. 460870
1. {'매수일': '2025-04-15', '매수가격': 4870, '매도일': '2025-04-16', '매도가격': 5470, '수익률': 12.32}
2800. 444530
1. {'매수일': '2025-04-16', '매수가격': 15660, '매도일': '2025-04-22', '매도가격': 14420, '수익률': -7.92}
이익을 본 횟수 : 8,594
평균 이익률 : 18.55%
최대 이익률 : 178.07%
손실을 본 횟수 : 10,482
평균 손실률 : -13.07%
최대 손실률 : -91.12%
성공률 : 45.05%
조건 5
이번에는 익절 기준을 10%로 하향 조종했다.
매수 조건은 연속되는 3번째 양봉으로 변경했다.
class Logic:
...
def need_buy(self, Open, high, low, close, volume, rate, is_upper, is_lower):
if Open < close:
if not is_upper and 2 < self.count:
self.count = 0
return True
return
def get_take_price(self, price):
return round(price * 1.1)
조건 5 결과
성공률이 55%로 증가했다.
평균 이익률과 손실률만 두고 본다면 이 조건으로 매매를 한다면 유의미하게 이익을 가져올 수 있다는 뜻이다.
3023. 226590
1. {'매수일': '2025-04-03', '매수가격': 9120, '매도일': '2025-04-07', '매도가격': 8170, '수익률': -10.42}
2. {'매수일': '2025-04-17', '매수가격': 10680, '매도일': '2025-04-21', '매도가격': 11340, '수익률': 6.18}
3. {'매수일': '2025-05-07', '매수가격': 13420, '매도일': '2025-05-16', '매도가격': 12210, '수익률': -9.02}
3024. 460870
1. {'매수일': '2025-04-11', '매수가격': 4685, '매도일': '2025-04-17', '매도가격': 6230, '수익률': 32.98}
3025. 031210
1. {'매수일': '2025-04-18', '매수가격': 34350, '매도일': '2025-05-15', '매도가격': 34950, '수익률': 1.75}
3026. 098070
1. {'매수일': '2025-03-24', '매수가격': 33200, '매도일': '2025-03-26', '매도가격': 28200, '수익률': -15.06}
3027. 484810
1. {'매수일': '2025-04-17', '매수가격': 23100, '매도일': '2025-04-28', '매도가격': 19210, '수익률': -16.84}
3028. 444530
1. {'매수일': '2025-04-14', '매수가격': 12150, '매도일': '2025-04-16', '매도가격': 15660, '수익률': 28.89}
2. {'매수일': '2025-04-17', '매수가격': 16120, '매도일': '2025-04-18', '매도가격': 16650, '수익률': 3.29}
3029. 448900
1. {'매수일': '2025-04-17', '매수가격': 20350, '매도일': '2025-04-21', '매도가격': 18220, '수익률': -10.47}
이익을 본 횟수 : 56,169
평균 이익률 : 11.54%
최대 이익률 : 162.89%
손실을 본 횟수 : 45,592
평균 손실률 : -12.65%
최대 손실률 : -93.37%
성공률 : 55.2%
조건 6
연속되는 양봉의 수가 성공률에 영향을 주는지 확인하기 위해 매수 조건을 변경했다.
class Logic:
...
def need_buy(self, Open, high, low, close, volume, rate, is_upper, is_lower):
if Open < close:
if not is_upper and 4 < self.count:
self.count = 0
return True
return
조건 6 결과
성공률이 60%가 나왔다.
연속되는 양봉의 수가 어느 정도 영향을 주는 것으로 보인다.
2808. 473980
1. {'매수일': '2024-12-03', '매수가격': 22850, '매도일': '2024-12-06', '매도가격': 20500, '수익률': -10.28}
2. {'매수일': '2025-03-27', '매수가격': 25900, '매도일': '2025-04-08', '매도가격': 23700, '수익률': -8.49}
2809. 394800
1. {'매수일': '2024-11-25', '매수가격': 4400, '매도일': '2024-11-26', '매도가격': 5720, '수익률': 30.0}
2. {'매수일': '2025-02-06', '매수가격': 6280, '매도일': '2025-02-12', '매도가격': 5600, '수익률': -10.83}
2810. 466410
1. {'매수일': '2025-02-05', '매수가격': 18680, '매도일': '2025-02-06', '매도가격': 20600, '수익률': 10.28}
2811. 389680
1. {'매수일': '2025-03-24', '매수가격': 700, '매도일': '2025-03-31', '매도가격': 621, '수익률': -11.29}
2812. 382150
1. {'매수일': '2025-04-15', '매수가격': 13090, '매도일': '2025-04-16', '매도가격': 13350, '수익률': 1.99}
2813. 176750
1. {'매수일': '2025-02-05', '매수가격': 10030, '매도일': '2025-02-10', '매도가격': 11140, '수익률': 11.07}
2814. 373160
1. {'매수일': '2025-04-07', '매수가격': 7850, '매도일': '2025-04-08', '매도가격': 9320, '수익률': 18.73}
2815. 450950
1. {'매수일': '2025-04-21', '매수가격': 9860, '매도일': '2025-05-15', '매도가격': 11810, '수익률': 19.78}
2816. 460870
1. {'매수일': '2025-04-15', '매수가격': 4870, '매도일': '2025-04-16', '매도가격': 5470, '수익률': 12.32}
2817. 444530
1. {'매수일': '2025-04-16', '매수가격': 15660, '매도일': '2025-04-17', '매도가격': 16120, '수익률': 2.94}
이익을 본 횟수 : 12,423
평균 이익률 : 10.36%
최대 이익률 : 60.36%
손실을 본 횟수 : 8,198
평균 손실률 : -13.71%
최대 손실률 : -87.19%
성공률 : 60.24%