{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "%config InlineBackend.figure_format='svg'\n", "import random\n", "from numba import jit" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "继续关于用Monte Carlo模拟的方法来研究betting strategy的文章,这是第三篇,目标是对 Martingale 策略进一步做一些分析。\n", "\n", "前一篇的最后,分析了用 Martingale 策略当事先设定一个目标盈利时的表现,这相当于设置了「止盈位」,这一篇进一步看一下,如果再设置「止损位」会发生什么。\n", "\n", "与前面相同的一些东西就不再重复了:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Win rate: 0.488797 \tLoss rate: 0.511203\n" ] } ], "source": [ "@jit(nopython=True)\n", "def win_dice(n=49):\n", " roll = random.randint(1, 100)\n", " return bool(roll <= n)\n", "\n", "wins = 0\n", "losses = 0\n", "for _ in range(1000000):\n", " if win_dice():\n", " wins += 1\n", " else:\n", " losses += 1\n", "print('Win rate:', wins/1000000, '\\tLoss rate:', losses/1000000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "对上一篇写的带止盈的函数作少量修改,加入止损的考虑:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "@jit(nopython=True)\n", "def martingale_leave_at_win_or_loss(funds, init_wager, wager_count, stop_profit, stop_loss):\n", " # stop_profit, stop_loss 为绝对金额\n", " # 返回了三种结果的状态和下注的次数,状态用数字表示 ,含义如下:\n", " # 1 : 止盈,达到盈利目标,退出\n", " # 0 : 直到最大下注数也没有发生上面情况(概率很低)\n", " # -1 : 止损,亏损达到止损位,退出\n", " balance = funds\n", " wager = init_wager\n", " vY = -funds * np.ones(wager_count) / 10\n", "\n", " win_previous = True\n", " previous_wager_amount = init_wager\n", " for i in range(wager_count):\n", " if win_previous:\n", " if win_dice():\n", " pass\n", " balance += wager\n", " win_previous = True\n", " else:\n", " balance -= wager\n", " win_previous = False\n", " else:\n", " wager = min(previous_wager_amount * 2, balance - (funds-stop_loss))\n", " if win_dice():\n", " balance += wager\n", " win_previous = True\n", " wager = init_wager\n", " else:\n", " balance -= wager\n", " win_previous = False\n", " previous_wager_amount = wager\n", " vY[i] = balance\n", " if balance >= funds + stop_profit:\n", " return 1, i+1, vY[:i+1]\n", " elif balance <= funds - stop_loss:\n", " return -1, i+1, vY[:i+1]\n", "\n", " return 0, i+1, vY" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这个函数有一点改进,把 balance 的序列,即 vY 也返回了,避免了在函数体中画图,使得整个函数可以用 nopython 模式编译。测试一下速度:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10000 loops, best of 3: 32.1 µs per loop\n" ] } ], "source": [ "stat, i, balance = martingale_leave_at_win_or_loss(100, 1, 10000, 25, 20)\n", "\n", "%timeit stat, i, balance = martingale_leave_at_win_or_loss(100, 1, 10000, 15, 10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "测试一下上面的程序是不是有错误" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4 8\n" ] }, { "data": { "image/svg+xml": [ "\r\n", "\r\n", "\r\n", "\r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", "\r\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "n_win = 0\n", "n_loss = 0\n", "for _ in range(12):\n", " stat, i, balance = martingale_leave_at_win_or_loss(100, 1, 10000, 25, 20)\n", " if stat == -1:\n", " n_loss += 1\n", " elif stat == 1:\n", " n_win += 1\n", " plt.plot(balance)\n", " plt.axhline(y=125, ls='dotted')\n", " plt.axhline(y=80, ls='dotted')\n", "print(n_win, n_loss)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "看起来结果似乎是正确的。再做一个验证,如果把止损或止赢设为1,这样就只能赌一次,理论上胜率是跟掷骰子的概率是相同的:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Win percentage is 49.01, loss percentage is 50.99\n" ] } ], "source": [ "n_win = 0\n", "n_loss = 0\n", "n_sim = 1000000\n", "stop_profit = 1\n", "stop_loss = 1\n", "\n", "for _ in range(n_sim):\n", " stat, i, _ = martingale_leave_at_win_or_loss(1000, 1, 10000, stop_profit, stop_loss)\n", " if stat == -1:\n", " n_loss += 1\n", " elif stat == 1:\n", " n_win += 1\n", " else:\n", " print('What are the odds?!')\n", "print('Win percentage is {:.2f}, loss percentage is {:.2f}'.format(n_win/n_sim*100, n_loss/n_sim*100))" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "从结果来看确实如此,暂时认为上面的结果没有问题。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "下面作一些更定量的分析:\n", "\n", "1. 验证是不是任何止盈止损组合下期望值都是负的\n", "2. 研究给定止盈线上最佳止损线是多少\n", "\n", "为了限制参数的个数,把初始资金固定为1000,初始赌注固定为1。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "先看第一点,验证**是不是任何止盈止损组合下期望值都是负的**:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Stop-profit 10, stop-loss 5. Expectation is -0.39 (30.71 69.29)\n", "Stop-profit 10, stop-loss 20. Expectation is -0.98 (63.40 36.60)\n", "Stop-profit 10, stop-loss 30. Expectation is -1.07 (72.31 27.69)\n", "Stop-profit 50, stop-loss 25. Expectation is -3.42 (28.78 71.22)\n", "Stop-profit 50, stop-loss 50. Expectation is -5.15 (44.85 55.15)\n", "Stop-profit 50, stop-loss 100. Expectation is -6.63 (62.25 37.75)\n", "Stop-profit 200, stop-loss 100. Expectation is -17.51 (27.50 72.50)\n", "Stop-profit 200, stop-loss 200. Expectation is -25.13 (43.72 56.28)\n", "Stop-profit 200, stop-loss 500. Expectation is -39.04 (65.85 34.15)\n" ] } ], "source": [ "n_sim = int(1e5)\n", "params = [[10, 5], [10, 20], [10,30], # low stop_profit\n", " [50, 25], [50, 50], [50, 100], # normal stop_profit\n", " [200, 100], [200, 200], [200, 500]]\n", "\n", "for param in params:\n", " n_win = 0\n", " n_loss = 0\n", " for _ in range(n_sim):\n", " stat, i, _ = martingale_leave_at_win_or_loss(1000, 1, 10000, param[0], param[1])\n", " if stat == -1:\n", " n_loss += 1\n", " elif stat == 1:\n", " n_win += 1\n", " else:\n", " print('What are the odds?!')\n", " print('Stop-profit {}, stop-loss {}. Expectation is {:.2f} ({:.2f} {:.2f})'.format(param[0], param[1],\n", " n_win/n_sim*param[0] - n_loss/n_sim*param[1],\n", " n_win/n_sim*100, n_loss/n_sim*100))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "上面模拟了9组不同止盈和止损位置的参数组合,涵盖了高低止盈和止损不同范围,所有的期望值都为负。\n", "\n", "另外,也注意到对相同的止盈位,设置不同的止损位期望值也不同,而且似乎止损位设得越高(允许的损失越小),期望值越高,看看是不是这样:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "50 10. 50 20. 50 50. 50 100. 50 200. 50 500. 100 10. 100 20. 100 50. 100 100. 100 200. 100 500. 200 10. 200 20. 200 50. 200 100. 200 200. 200 500. " ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/svg+xml": [ "\r\n", "\r\n", "\r\n", "\r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", "\r\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "n_sim = int(1e5)\n", "stop_profits = [50, 100, 200]\n", "stop_losses = [10, 20, 50, 100, 200, 500]\n", "\n", "for stop_profit in stop_profits:\n", " expectations = []\n", " for stop_loss in stop_losses:\n", " print(stop_profit, stop_loss, end='. ')\n", " n_win = 0\n", " n_loss = 0\n", " for _ in range(n_sim):\n", " stat, i, _ = martingale_leave_at_win_or_loss(1000, 1, 10000, stop_profit, stop_loss)\n", " if stat == -1:\n", " n_loss += 1\n", " elif stat == 1:\n", " n_win += 1\n", " else:\n", " print('What are the odds?!')\n", " expectations.append(n_win/n_sim*stop_profit - n_loss/n_sim*stop_loss)\n", " plt.plot(stop_losses, expectations, 'o-', label=str(stop_profit))\n", "plt.legend(loc=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "从这张图来看,结论还是很明显的,把止损位设得越高,最终期望值也会越高(尽管不管怎么努力都是负的)。\n", "\n", "稍微想一下,似乎可以这样理解:在止盈位固定时,止损位设得越低,预期的下注次数就越多,也就是留在游戏中的时间更长,输的概率就越大。\n", "\n", "当然其实参照前面验证期望值的那部分输出的结果,这样的理解原则上没有问题,但细节上其实是错的:因为止损位设得更低时,碰到止损位的概率其实也会降低,反而赢的概率会更高,但倒回来,尽管输的概率更低了,但概率上的降低并不足以抹平损失额的增长,总期望值还是降低的。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "最后一点比较感兴趣的是,上一张图比较的是期望值的绝对值,而显然止盈位越高,输的也可能会更多,如果比较相对的期望值呢:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "50 10. 50 20. 50 50. 50 100. 50 200. 50 500. 100 10. 100 20. 100 50. 100 100. 100 200. 100 500. 200 10. 200 20. 200 50. 200 100. 200 200. 200 500. " ] }, { "data": { "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/svg+xml": [ "\r\n", "\r\n", "\r\n", "\r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", " \r\n", "\r\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "n_sim = int(1e5)\n", "stop_profits = [50, 100, 200]\n", "stop_losses = [10, 20, 50, 100, 200, 500]\n", "\n", "for stop_profit in stop_profits:\n", " expectations = []\n", " for stop_loss in stop_losses:\n", " print(stop_profit, stop_loss, end='. ')\n", " n_win = 0\n", " n_loss = 0\n", " for _ in range(n_sim):\n", " stat, i, _ = martingale_leave_at_win_or_loss(1000, 1, 10000, stop_profit, stop_loss)\n", " if stat == -1:\n", " n_loss += 1\n", " elif stat == 1:\n", " n_win += 1\n", " else:\n", " print('What are the odds?!')\n", " expectations.append((n_win/n_sim*stop_profit - n_loss/n_sim*stop_loss) / stop_profit)\n", " plt.plot(stop_losses, expectations, 'o-', label=str(stop_profit))\n", "plt.legend(loc=0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "从相对期望值来看,规律大致是倒过来的,当把止盈位设高时,相对的期望值也会更高一点。\n", "\n", "前面的讨论都在看期望值,其实是有点偏离了「赌博」的本质了,毕竟这种游戏本质上肯定是输的。「赌博」有几种典型的心态:\n", "\n", "1. 我有1000元,我想赌10把,赚到10%(100元)就走;\n", "2. 我有1000元,我想玩10把,如果亏了10%就不玩了;\n", "3. 我有1000元,我想一直玩,一直到赚了200或亏了100为止;\n", "\n", "借助上面的工具,可以分别模拟这几种情况能达到目标的概率,这里就不再展开了。" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.0" } }, "nbformat": 4, "nbformat_minor": 2 }