라오어님의 무한매수법 백테스팅 하기

요즘 핫! 하다는 ‘라오어의 무한매수법’!!

지인으로부터 추천을 받아 연구를 시작해보았다.. 라오어님이 이런저런 백테스트를 해보고 가장 좋은 결과를 알려주긴 했지만,

‘그래도 눈으로 확인해봐야지..!’ 라는 생각으로 파이썬으로 간단하게 코드를 짜보았습니다. 역시 라오어님이 이야기한데로 결과가 나왔습니다.!!

TQQQ 기준으로 5년만에 10000달러가 40000달러가 되는 기적을 보았습니다(4배!!, 수수료+세금은 미고려)(모든 수익은 재투자)

아래는 백테스팅 코드를 돌렸을 때 매도 타이밍 및 수익입니다.

2016-05-31 [수익청산] initMoney(10000) Count(0) Mean(0.000000) SELL(0.000000)
2016-07-20 [수익청산] initMoney(10581) Count(688) Mean(8.450063) SELL(9.295069)
2016-09-21 [매도청산] initMoney(11098) Count(1036) Mean(10.087881) SELL(10.586667)
2016-12-14 [매도청산] initMoney(11637) Count(1037) Mean(10.455939) SELL(10.975833)
2017-01-26 [수익청산] initMoney(12342) Count(616) Mean(11.451227) SELL(12.596350)
2017-03-29 [매도청산] initMoney(13202) Count(886) Mean(13.693258) SELL(14.663333)
2017-05-01 [수익청산] initMoney(13727) Count(353) Mean(14.870194) SELL(16.357213)
2017-07-13 [매도청산] initMoney(14045) Count(788) Mean(17.118016) SELL(17.521667)
2017-09-21 [매도청산] initMoney(14117) Count(753) Mean(18.596762) SELL(18.693333)
2017-10-30 [수익청산] initMoney(14956) Count(427) Mean(19.649055) SELL(21.613961)
2018-01-04 [매도청산] initMoney(16411) Count(638) Mean(22.885402) SELL(25.165001)
2018-01-23 [수익청산] initMoney(16868) Count(170) Mean(26.877530) SELL(29.565283)
2018-03-09 [수익청산] initMoney(17735) Count(316) Mean(27.444626) SELL(30.189088)
2018-05-14 [수익청산] initMoney(18912) Count(459) Mean(25.641079) SELL(28.205187)
2018-06-14 [수익청산] initMoney(19718) Count(280) Mean(28.799059) SELL(31.678965)
2018-07-25 [수익청산] initMoney(20693) Count(312) Mean(31.234551) SELL(34.358006)
2018-08-30 [수익청산] initMoney(21685) Count(299) Mean(33.194582) SELL(36.514040)
2018-12-13 [매도청산] initMoney(17482) Count(741) Mean(28.872112) SELL(23.200001)
2019-01-09 [수익청산] initMoney(17924) Count(232) Mean(19.031293) SELL(20.934423)
2019-01-31 [수익청산] initMoney(18455) Count(247) Mean(21.500061) SELL(23.650067)
2019-03-15 [수익청산] initMoney(19623) Count(464) Mean(25.179752) SELL(27.697728)
2019-04-23 [수익청산] initMoney(20687) Count(356) Mean(29.875365) SELL(32.862902)
2019-07-03 [수익청산] initMoney(22289) Count(532) Mean(30.112594) SELL(33.123853)
2019-09-27 [매도청산] initMoney(20858) Count(682) Mean(32.113086) SELL(30.014999)
2019-10-28 [수익청산] initMoney(21756) Count(285) Mean(31.512877) SELL(34.664165)
2019-12-16 [수익청산] initMoney(23398) Count(440) Mean(37.321659) SELL(41.053825)
2020-01-13 [수익청산] initMoney(24368) Count(222) Mean(43.687928) SELL(48.056721)
2020-02-05 [수익청산] initMoney(25068) Count(142) Mean(49.317113) SELL(54.248824)
2020-05-07 [수익청산] initMoney(27460) Count(726) Mean(32.939793) SELL(36.233772)
2020-05-26 [수익청산] initMoney(28096) Count(168) Mean(37.852381) SELL(41.637619)
2020-06-08 [수익청산] initMoney(28688) Count(142) Mean(41.720211) SELL(45.892232)
2020-06-23 [수익청산] initMoney(29318) Count(136) Mean(46.333898) SELL(50.967287)
2020-07-06 [수익청산] initMoney(29734) Count(85) Mean(48.946177) SELL(53.840795)
2020-07-13 [수익청산] initMoney(30041) Count(54) Mean(56.884444) SELL(62.572888)
2020-08-06 [수익청산] initMoney(31001) Count(165) Mean(58.153000) SELL(63.968300)
2020-08-24 [수익청산] initMoney(31747) Count(114) Mean(65.461930) SELL(72.008123)
2020-09-01 [수익청산] initMoney(32192) Count(58) Mean(76.730863) SELL(84.403949)
2020-10-12 [수익청산] initMoney(33488) Count(196) Mean(66.110817) SELL(72.721899)
2020-11-05 [수익청산] initMoney(34305) Count(119) Mean(68.636344) SELL(75.499979)
2020-12-01 [수익청산] initMoney(35292) Count(133) Mean(74.245037) SELL(81.669541)
2021-01-08 [수익청산] initMoney(37214) Count(223) Mean(86.199260) SELL(94.819186)
2021-01-25 [수익청산] initMoney(37851) Count(67) Mean(94.936045) SELL(104.429649)
2021-04-09 [수익청산] initMoney(40860) Count(310) Mean(97.094484) SELL(106.803932)

그리고 이건 허접하지만..백테스팅 코드!

import requests
import time
import datetime

start_time_str = '2016-06-01'
end_time_str = '2021-06-01'
ticker = "TQQQ"

initMoney = 10000
splitCount = 40
oneMoney = initMoney / splitCount

period1 = str(int(time.mktime(datetime.datetime.strptime(start_time_str, '%Y-%m-%d').timetuple())))
period2 = str(int(time.mktime(datetime.datetime.strptime(end_time_str,   '%Y-%m-%d').timetuple())))

HISTORY_DATA_URL = 'https://query1.finance.yahoo.com/v7/finance/download/'+ticker + '?period1='+period1+'&period2='+period2+'&interval=1d&events=history&includeAdjustedClose=true'
response = requests.get(HISTORY_DATA_URL)

stock_reader = response.text.split("\n")

DATE = 0
OPEN = 1
HIGH = 2
LOW = 3
CLOSE = 4
ADJCLOSE = 5
VOLUME = 6

stockCount = 0
stockMeanValue = 0
buyCount = 0


def buy_close(close_value, money) :
    global stockCount, stockMeanValue, buyCount, initMoney

    #print(money)
    c = int(money / close_value)
    stockMeanValue = ( ( stockCount * stockMeanValue ) + (c * close_value ) ) / (stockCount + c)
    stockCount += c

    initMoney -= (close_value * c)

    #print("[BUY ] initMoney(%d) Count(%d) Mean(%f) BUY(%f)" % (initMoney, stockCount, stockMeanValue, close_value))

    return

SELL_RATE = 1.10

isFirst = True
ccc = 0
for row in stock_reader :
    row = row.split(",")
    ccc += 1
    #if ccc > 100 : break
    if row[HIGH] == 'High' : continue

    if initMoney - oneMoney < 0 :
        initMoney += (stockCount * float(row[CLOSE]) )
        oneMoney = initMoney / splitCount
        print("%s [매도청산] initMoney(%d) Count(%d) Mean(%f) SELL(%f)" % (row[DATE], initMoney, stockCount, stockMeanValue, float(row[CLOSE])))
        stockCount = 0
        stockMeanValue = 0
    elif stockMeanValue * SELL_RATE < float(row[HIGH]) :
        initMoney += (stockCount * stockMeanValue * SELL_RATE )
        oneMoney = initMoney / splitCount
        print("%s [수익청산] initMoney(%d) Count(%d) Mean(%f) SELL(%f)" % (row[DATE], initMoney, stockCount, stockMeanValue, stockMeanValue * SELL_RATE))
        stockCount = 0
        stockMeanValue = 0
        

        
    if stockMeanValue < float(row[CLOSE]) :
        buy_close(float(row[CLOSE]), oneMoney / 2)

    buy_close(float(row[CLOSE]), oneMoney / 2)

투자하시는데 도움이 됐으면 합니다.

사실 들어오시는 분들은 수익률과 코드가 필요해서 오실테니…………긴 말은 생략;;(귀찮..)

관련 글

라오어님의 무한매수법 백테스팅 하기”의 4개의 댓글

    1. 안녕하세요~ 코드가 도움이 되셨다니 다행입니다.
      아마 밑에서 4번째줄 관련해서 문의하신것 같은데….워드프레스 문제인지 가운데 문자가 빠져서 안보이네요ㅠ.
      아마 <= 가 아닌지 문의하셨을 것 같은데. 상기 코드는 당일 종가가 평단가보다 비싸다면(손해보고 있는 중이라면..) 한주를 추가 매수하는 로직으로 평단가와 당일종가가 소숫점 2자리까리 정확하게 같을 확률이 워낙 낮을뿐만 아니라, 백테스트상 큰 차이는 발생하지 않을것 같습니다. 편하실대로 고쳐서 쓰시면 됩니다~

  1. 안녕하세요 코드 정말 감사합니다. 코드를 일부 보완하여 테스트 돌려봤는데 의문이듭니다. 예를들어 FNGU의 경우 2018-01-23이 상장일인데, 2018-06-20일 주가 8.66에서 줄곧 하락하여 2019-06-03일 주가2.6까지 내리 흘러내리며 탈출 기회를 주지 않았습니다. 이 경우 손실이 라오어님 말씀인 손실이 1년에 1~2번이라 할 수 없고, 2018-06-20~2019-06-20 1년구간은 2018년6월20일에 시작했을때 2018년6월21일에 시작했을때 2018년6월22일에 시작했을때 등의 경우의 수를 다 따지면 1년 252영업일중 거의 대부분 손해라 봐야 합니다. 즉 테스트를 특정일자에서 시작한것으로만 가정하여(위 코드에선 TQQQ 2016-06-01) 40영업일 또는 40영업일 이내 10%수익일로 끊어가며(위 코드에선 초기금액이 소진되는날까지,40일 이상) 손실 경우의 수를 횟수를 카운트하면 특정한 날짜하루의 백테스트일 뿐이라 1년에 1~2번 손실이라 할 수 없는데 어떻게 생각하시는지요?

    1. 안녕하세요~ 글로 소통을 하다보니 질문이 정확하게 이해가 되지 않습니다^^;
      제가 이해한데로 일단 답변을 드리면,
      매도를 하기전까지 손실은 손실로 치지 않습니다.
      (손실을 확정짓기 전까지는 손실이 아닌거죠…)

      라오어님의 무한매수법의 기본 컨셉은..
      ‘원금을 40분할 한 뒤, 지속적인 물타기를 하다 반등이 오는 타이밍에 매도하여 수익을 실현한다’ 입니다.

      그래서 손실로 보이는 구간이 있더라도 원금을 모두 투입하여 손절하는 상황이 오기전까지는 손실로 인정하지 않습니다.
      (개인적으로 모든 투자에 하루하루 수익률에 의미를 부여하다보면 극심한 스트레스로 원칙을 가지는 투자를 할 수 없다고 생각합니다. 매도하기 전까지는 수익도 손실도 아니라고 생각하는게 맞다고 생각합니다)

      하루하루 계좌가 마이너스가 나더라도 3배 레버리지의 특성상, 한번 반등만으로도 마이너스 수익률에서 +10%가 되어 익절할 수 있다는게 이 무한매수법의 핵심논리 입니다.(제가 이해한 범위에서는..)

      두서없이 써서 만족스러운 답변이 되셨나 모르겠습니다. 추가적인 질문이 있으시면 댓글 남겨주세요~

      감사합니다.
      즐거운 투자하시길 바랍니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다