思考 关于日内最大回撤的计算

对人来说,因为有分时线的存在,最大回撤一目了然,
但对程序来说,最大回撤结束点,累积最高点 - close,其中差值最大的那个点,是回撤终点,而终点之前的最高价就是回撤起点,
用python来写就是:
i = np.argmax((np.maximum.accumulate(df['close']) - df['close'])) # 最大回撤结束的位置
if i == 0:
j = 0
else:
j = np.argmax(df['close'][:i]) # 回撤开始的位置
显然,根据最传统的定义,最理想的是用 完整的tick序列,其次是用1分钟线,问题在于如果票少,获取时间并不多,但如果有几十个甚至200个票,那么下载时间就不可接受了
这里有2种分支:

A、比较传统的,即用tick 自己合成1m线,因为不需要单独下载,所以时效性很有保证,缺点是复杂性,虽然自己合成不需要下载,但当出现意外情况【极端是下午才开程序】,那么只能依靠下载1m K线进行衔接,也就是说,下载的频率从1分钟一次, 可能变成了5分钟、15分钟、甚至1小时一次,另外非正常情况只在合成的K线衔接不上的时候。

B、剑走偏锋,所谓回撤究竟是什么,我认为 是一种记忆,当一个tick 出现,所带来的 最新价 lastPrice,它其实是对 前面出现过的 high 与 low 进行比价,其流程如下:
1、所接受到的 第一个tick ,将它的价格 记为 high
2、后续一个tick 大于 这个high 那么更新 high ,反之就对 low 赋值
3、后续价格,只要不高于 high ,就只用更低的价格 更新 low 【此时 high 与 low 之间的差值就是一段回撤】
4、当后续价格 大于高,那么 重复上述过程即可

用python写出来大概这个样子:



那么是否能可行,只能拿1m 的线去构建伪装的 tick 来进行测试了
发表时间 2024-10-16 23:04     来自重庆

赞同来自:

0

xcdk2018

赞同来自:

微信推送了一个文章,第一反应,这瓜保真吗?



用艾玛转载看了一下,近70个交易日



仔细想想定义背后的解释:

枢轴点(Pivot Point, P) pivot = (high + low + close) / 3 = low + (high-low + close - low)/3 即 low + ( 振幅 + 最低点持有盈利)/3
也就是作者认为 中枢 不仅与振幅相关,还与最低点介入后,盈利相关

第一阻力位(R1): R1 = 2 * P - 低点 = low + (high-low)*2/3 + (close - low)*2/3

第一支撑位(S1): S1 = 2 * P - 高点 = low - (high-low)/3 + (close - low)*2/3

S1 与 R1 差一个 振幅 ,也就是一开始 认为单向波动不过50%振幅,信他个鬼,收敛这么快的吗?
初始中轴: low + 振幅/6 + 最低介入盈利的2/3

第二阻力位(R2): R2 = P + (高点 - 低点)

第二支撑位(S2): S2 = P - (高点 - 低点)

S2与R2 直接不装了,单向一个振幅

第三阻力位(R3): R3 = P + 2 * (高点 - 低点)

第三支撑位(S3): S3 = P - 2 * (高点 - 低点)

S3与R3 单向2个振幅

看似很科学,我可以骂人吗?0.5振幅、1倍、2倍,好厉害,垃圾,睡觉

2024-10-28 22:04修改 来自重庆 引用
0

xcdk2018

赞同来自:

思考 振幅 与 回撤
只要日k线的 high 不等于 low,那么振幅就必然大于0。实现振幅振幅的方式,只能是涨或跌。

1,先涨后涨,即平稳上涨,那么最大回撤只能出现在见高点后
2,先跌后涨,那么最大回撤可能在V的左段,或后续见高点之后
3,先跌后跌,即平稳下跌,那么最大回撤,就是见低点的过程
4,先涨后跌,那么最大回撤只能出现在见高点后。

简单来说,上涨实现振幅,任何买入都安全,下跌实现振幅,任何买入都套牢。

这尼玛不就是在纯粹的拍涨跌吗?

既然是这样,那盯着正股呗,正股涨了,我转债赌涨,然后各种买,正股跌了,那就缓缓
至于这样究竟行不行,我觉得还是得回测一把,外加模拟盘模拟一下,毕竟一个债我能盯,要是几十个债,我看个毛线,而且资金也非常有限,是先到先得呢,还是优中选优呢?也是需要思考的
2024-10-20 18:33 来自重庆 引用
0

xcdk2018

赞同来自:

当然,也只能是逼近,因为只有close 是最高点,那么其high 才是有机会是最高,但实际情况是,出现最高点的1m K线 其close 不见得也是最高,低点也同理,还是用艾玛举例,就昨天的情况,逼近后的结果如下: 高点正确,低点有差距,原因如图,最低点出现时,close已经收上去了

2024-10-18 08:41 来自重庆 引用
0

xcdk2018

赞同来自:



如果要尽量解决这种问题【完全解决不可能,close的最高点,可能并不是实际的最高点,同理低点也是】,那么基本上是对1m 所构建的K线需要进行二次检查 即 按照 记录下的时间,把起点换成K线的最高点,最低点,去尽量逼近实际值
2024-10-17 22:16 来自重庆 引用
0

xcdk2018

赞同来自:

关于半路出道的问题,比如中午,或者更极端一点,下午收盘后在运行程序的情况,此时当然不能指望通过tick的更新来建立 回撤记录表,那么就需要2个标记:
第一是创建时间, creation_time,格式为20241017141500 这种形式,后续取小时分秒的部分和 093000 进行比较,只要比这个大,那么就可能需要通过1m 先构建一下 回撤表
第二是 1m 构建的标志,确保上述构建过程只进行一次

这样 回撤的记录,也不需要每次都保存了,也就是以程序运行的时间为起点,前面由1m 来构建【这其实也是以1m线进行测试的过程,即把1m线 伪装成tick 先过一遍】,后面以tick 来构建

也就是多了一个可能都前置过程
2024-10-17 21:29 来自重庆 引用
0

xcdk2018

赞同来自:

我去,原来一秒1次 tick,也是可能漏掉最高价的,也许瞬间的最高价就没有单独的一个tick【或者1秒内出现不止1个tick 这个概率太低了,毕竟说好的3秒一次的行情呢】
艾玛最高价115.112,tick 只看到了最高115.028

2024-10-17 12:13 来自重庆 引用
0

xcdk2018

赞同来自:

@gwxkai
equity_peak=max(equity_peak, current_equity)
max_drawdown = max(max_drawdown, equity_peak - current_equity)

如果你要统计某个时段的,就先把max_drawdown置0
如果你用的bar OHLC,就要使用H和L去计算bar内的equity high和low
可以的,实际使用中,如果追求速度,那么 在更新 low 时,计算一次 drawdown,后续 只迭代 drawdown_record_dict[code_suffix].values() 即可,类型为字典时,get('drawdown',0),那么返回drawdown_list 的最大值 就是 最大回撤,这比后续计算快一倍,因为不需要判断 high、low 的存在,而 np.argmax(drawdown_list) 就是 对应最大回撤记录的 key ,就此可以取得 最大回撤对应的 high 与 low

如果要进一步完善,更新high 时可以记录 回撤起点时间 timetag_start ,更新low 时记录 回撤结束时间 timetag_end,不过对于盘中,意义不是特别大,除非会在意持续回撤时间

2024-10-17 07:17修改 来自重庆 引用
0

gwxkai

赞同来自:

equity_peak=max(equity_peak, current_equity)
max_drawdown = max(max_drawdown, equity_peak - current_equity)

如果你要统计某个时段的,就先把max_drawdown置0
如果你用的bar OHLC,就要使用H和L去计算bar内的equity high和low
2024-10-17 00:40 来自北京 引用
0

xcdk2018

赞同来自:

计算结果也还行,非常简易,也没考虑半路续接问题,但就最大回撤应该可用了

2024-10-17 00:00 来自重庆 引用

要回复问题请先登录注册

发起人

问题状态

  • 最新活动: 2024-10-28 21:59
  • 浏览: 2607
  • 关注: 8