The strategy of losing in fair game and its improvement


Consider a scenario: each time a speculator takes out 10% of the current principal for coin tossing test (fair game, 50% win or lose), a total of 60 tests, 30 win or lose, then how much will his principal be?

Calculation: x = 1.1^30 * 0.9^30 * 100% = 0.99^30 * 100% =73.97%

This brings about a problem: a fair game, if the strategy is wrong, it may be lost in the long run.

Note: the essence of this question is the same as "what is the final price of a stock after experiencing 30 times of 10% rise and 30 times of 10% fall".

1, Arithmetic reason

From an arithmetic point of view, the winning rate must be slightly higher than 52.5% in order not to lose for a long time. Take 1000 times as an example:
1. 1 525 ∗ 0. 9 475 = 1. 1 50 ∗ 0.9 9 475 = 0.9916 ≈ 1 1.1^{525} * 0.9^{475} = 1.1^{50} * 0.99^{475} = 0.9916 \approx 1 1.1525∗0.9475=1.150∗0.99475=0.9916≈1
However, according to the theory of large numbers, the more coin experiments, the probability approaches 50%. When the number of experiments is enough, the probability of winning slightly higher than 52.5% becomes very small, so you have to lose.

2, Logical reason

From a logical point of view, it is inappropriate to reduce investment when falling behind and increase investment when taking the lead. Take the starting 10000 as an example:
1) If you lose first and then win, then 10000 loses 1000 and becomes 9000. If you win 900, it becomes 9900
2) If you win first and then lose, 10000 will win 1000 and become 11000, and then lose 1100 and become 9900

Only in turn, it is reasonable to increase investment when falling behind and reduce investment when taking the lead. For example:
1) Lose first and then win, 10000 becomes 9000, increase investment by 1100, and win and then become 10100
2) Win first and then lose, 10000 becomes 11000, reduce investment by 900, and lose and then become 10100

However, this strategy also has two problems: first, it is a bit similar to the double investment method. If you lose several times in a row at the beginning, you will have the risk of losing all; Second, when taking the lead, the capital is large, but the investment each time is less, and the capital utilization rate is reduced.

3, Python improvements

In fact, the scheme of "taking out 10% of the current principal each time" is not as good as the scheme of "fixed amount". Applied to the scenario of fund purchase, the former is similar to the "fixed share" fixed investment scheme, and the latter is the "fixed amount" fixed investment scheme.

Now try the improvement scheme:
1) Based on the net value x0 of a day
2) When the net value breaks through to the next benchmark: it rises to twice of x0 and falls to half of x0, switch the benchmark
3) After the last operation, if the net value changes by more than 3%, operate again: if it falls, make up the position (see the multiple below); if it rises and holds, reduce the position (see the multiple below, until it is cleared if it is insufficient)
4) When the net value is [1,2) times x0, the multiple is 1 times; when the net value is [0.9,1) times x0, the multiple is 2 times;...; when the net value is [0.5,0.6) times x0, the multiple is 6 times. However, if the current position is too much (greater than 2 times the multiple), the replenishment multiple is only 1 times (the position reduction multiple does not affect)

The following is the source code of the scheme, which is divided into three paragraphs in Jupyter notebook:

import requests
import time
import execjs

fileTest = './data/accTest.csv'
jjTest = '001630'

def getUrl(fscode):
    head = ''
    tail = '.js?v='+ time.strftime("%Y%m%d%H%M%S",time.localtime())
    return head+fscode+tail

# Obtain net value according to fund code
def getWorth(fscode):
    content = requests.get(getUrl(fscode))
    jsContent = execjs.compile(content.text)
    name = jsContent.eval('fS_name')
    code = jsContent.eval('fS_code')
    #Trend of unit net worth
    netWorthTrend = jsContent.eval('Data_netWorthTrend')
    #Cumulative net worth trend
    ACWorthTrend = jsContent.eval('Data_ACWorthTrend')
    netWorth = []
    ACWorth = []
    for dayWorth in netWorthTrend:
    for dayACWorth in ACWorthTrend:
    return netWorth, ACWorth

ACWorthTestFile = open(fileTest, 'w')
_, ACWorth = getWorth(jjTest)
if len(ACWorth) > 0:
    ACWorthTestFile.write(",".join(list(map(str, ACWorth))))
    print('{} data downloaded'.format(jjTest))

The first paragraph is as above, climbing the fund in the daily fund network. 001630 is the ETF connection C of Tianhong CSI computer theme, which has two characteristics:
1) in the Alipay fund, buy 0 rate, hold 7 days to sell 0 rate.
2) The fund was established in July 2015. It has been more than five years since its establishment (February 2021). Since its establishment, the cumulative rise and fall range is about - 10% (the current net value of the fund is about 0.9 yuan), with a size of more than 1 billion

import csv

with open(fileTest) as f:
    row = csv.reader(f, delimiter=',')
    for r in row:
        #Remove the data recorded as None (the data of the day is missing)
        r = [float(x) for x in r if x != 'None']

show_days = 1500 #Use only the most recent show_days (about 250 trading days in a year)

if len(r) > show_days:
    r = r[len(r)-show_days:]

x0 = r[0] #Current benchmark
x1 = x0 #Net value deposited
x2 = x0 #Net value at last operation
a = 10000 #Standard share (1 time)
y = 0 #Current holding multiple
z = 0 #Accumulated profit (including floating profit and loss)
s = [0] #Historical profit rate (not multiplied by standard share, i.e. z/a)
t = [0] #Historical multiples multiplied by 0.1 (i.e. 0.1y, multiplied by 0.1 for graphic display)

for i in range(1,len(r)):
    x3 = r[i]

    #Refresh floating profit and floating loss
    if y > 0:
        z += a * y * (x3 - x1)


    #Change in net worth over benchmark
    if (x3 >= x0 * 2) or (x3 < x0 / 2):
        #If it falls, buy double the share
        if x3 < x2:
            y += 1
        #On the contrary, if any, sell 1 times the share
        elif y > 0:
            y -= 1

        x0 = x3
        x1 = x3
        x2 = x3

    #Since the last operation, the net value has changed by more than 3%
    elif (x3 > x2 * 1.03) or (x3 < x2 * 0.97):
        if x3 >= x0:
            # [x0, 2x0) 1 times
            i = 1
            i = 2 + int(10 * (1 - x3 / x0))
            #However, if there are too many positions at present, only one time will be used to make up the position (the position reduction will not be affected)
            if (y > 2 * i) and (x3 < x2):
                i = 1

        #If it falls, buy i-fold shares
        if x3 < x2:
            y += i
        #On the contrary, if it is held, it will sell i times of the share
            if y > i:
                y -= i
                y = 0

        x1 = x3
        x2 = x3

        x1 = x3

    t.append(y * 0.1)

print('Accumulated profit and loss:{:.0f}'.format(z))

The second paragraph is the realization of the "improvement scheme" mentioned earlier. Note: when the position is filled due to excessive position and the benchmark is switched, the multiple is 1.
The fund has been established for five and a half years, with nearly 1400 trading days (show_days=1500, i.e. all display).

import numpy as np
from matplotlib import pyplot as plt


r_plot = np.array(r).reshape(-1, 1)
s_plot = np.array(s).reshape(-1, 1)
t_plot = np.array(t).reshape(-1, 1)

# Chart display
plt.plot(r_plot, color='blue', label='Net fund value')
plt.plot(s_plot, color='red', label='Profit and loss')
plt.plot(t_plot, color='yellow', label='Position')
plt.legend(loc='upper left')

The third code is drawing, and the map is as follows:

The blue line is the net value of 001630. It seems very flat, about 1 yuan. In fact, the lowest value is 0.485 yuan and the highest value is 1.0826 yuan.
The yellow line is the position multiple, and the red line is the profit and loss. At the worst time (the net value is about 0.5 yuan), the multiple is nearly 20 times (the Yellow ordinate should be multiplied by 10), and the floating profit and floating loss is about - 1.5 (assuming that 10000 shares are 1 time, that is, the floating loss is 15000); At present, the net value is about 0.9 yuan, and the floating profit and floating loss is 5 (similarly, the floating profit is 50000).

If show_ Change days to 250, that is, check the situation in recent 1 year, and the picture is as follows:

The highest position multiple in the past year is 6, and the current floating profit is more than 7000 (10000 shares, 1 time).

Note: because 001630 has a selling rate of 0 for 7 days and the fund is sold according to the first in first out principle, this paper ignores the penalty rate for selling when the position is less than 7 days. In case of actual combat, pay attention to it by yourself.


Aiming at the characteristic fund 001630 (with fair fundamentals, high popularity and poor performance), this paper puts forward a "moderate" strategy to cover the position - slightly increase the multiple when falling behind. Of course, other funds are also OK. I have tried more than 10 funds (all with a 7-day 0 rate).

As for fund replenishment and position reduction, according to the feeling, two strategies are feasible: one is the "change of more than 3% after the last operation" in this paper, and the other is "rising and falling for several days". Or a combination of the two: 4-5 days in 5 days, with an increase of more than 3%; In the five days, it fell in 4-5 days, and the decline was more than 3%. It is better to use 5 days (5 trading days must meet the requirement of holding for 7 days). I'm also testing these strategies, which are similar, so I won't post them separately.

There is an intuition that now "leeks" don't like to buy stocks, but like to buy funds. Especially female white-collar workers. So, some singles went to the fund section to leave a message "dating notice", which was very interesting.

Tags: Python crawler

Posted by roflpwnt on Sat, 16 Apr 2022 13:30:25 +0930