如何在Python中生成市场的分形图

3

我希望在Python中生成这个:

http://classes.yale.edu/fractals/RandFrac/Market/TradingTime/Example1/Example1.html

但是我对这个概念非常困惑,也很陌生。有人知道这方面的库或者代码片段吗?

enter image description here

编辑: 根据我所理解的,你需要每次将分形图形分为两部分。因此,您需要从连接两个中间点的线计算y轴点。然后,两个部分需要按照分形的形式进行形成?

"我希望用Python生成这个。" 你想要生成一个关于分形的网站吗?有许多有趣的Web框架可供选择。你试过Django吗?" - Kevin
@Kevin 谢谢您提供的信息。恶心的 iframe,唉。我已经更新了链接。 - Tjorriemorrie
你的问题并不是很清晰。你想生成一个看起来有点逼真的股票市场图表吗?还是你想实现这个'价格 vs. 交易时间'的归一化?此外,是否有输入数据,或者你只是想要随机生成图表? - tobias_k
@tobias_k 只需使用这种分形方法生成市场图表。我可以使用相同的函数并重复实现交易时间归一化,所以不用担心。 - Tjorriemorrie
请在标题中添加“图形”一词...我看到“分形市场”就像,嗷嗷? - kumarharsh
显示剩余2条评论
3个回答

9

我不是100%确定你在问什么,但是根据你的评论,我理解你想要使用链接中描述的递归算法生成一个真实看起来的股市曲线。

就我所理解的链接页面和一些父页面的描述,它的工作原理如下:

您将获得起点和终点以及一些转折点,形式为(t1, v1)(t2, v2)等,例如start=(0,0), end=(1,1), turns = [(1/4, 1/2), (3/4, 1/4)],其中tivi是介于0和1之间的分数。
  • 您确定实际的拐点缩放到startend之间的间隔,并计算这些点之间的差异,即从pi到达pi+1需要走多远。
  • 您对这些段进行洗牌,以引入一些随机性;当它们放在一起时,它们仍然覆盖完全相同的距离,即它们连接原始的startend点。
  • 通过递归调用不同点之间的新段的函数来重复执行。
  • 这是我刚刚写的一些Python代码:

    from __future__ import division
    from random import shuffle
    
    def make_graph(depth, graph, start, end, turns):
        # add points to graph
        graph.add(start)
        graph.add(end)
    
        if depth > 0:   
            # unpack input values
            fromtime, fromvalue = start
            totime, tovalue = end
    
            # calcualte differences between points
            diffs = []
            last_time, last_val = fromtime, fromvalue
            for t, v in turns:
                new_time = fromtime + (totime - fromtime) * t
                new_val = fromvalue + (tovalue - fromvalue) * v
                diffs.append((new_time - last_time, new_val - last_val))
                last_time, last_val = new_time, new_val
    
            # add 'brownian motion' by reordering the segments
            shuffle(diffs)
    
            # calculate actual intermediate points and recurse
            last = start
            for segment in diffs:
                p = last[0] + segment[0], last[1] + segment[1]
                make_graph(depth - 1, graph, last, p, turns)
                last = p
            make_graph(depth - 1, graph, last, end, turns)
    
    from matplotlib import pyplot
    depth = 8
    graph = set()
    make_graph(depth, graph, (0, 0), (1, 1), [(1/9, 2/3), (5/9, 1/3)])
    pyplot.plot(*zip(*sorted(graph)))
    pyplot.show()
    

    以下是一些示例输出:

    enter image description here


    1
    非常好,是我正在寻找的东西。不过还有一件事,depth = 1 应该给出 len(graph) 等于4,等等。是否可以从一开始就使用一个 set,或者我应该在之后使 graph 成为唯一的? - Tjorriemorrie
    @Tjorriemorrie 很好的发现,这不是本意。看起来点被多次添加,例如对于从 (0,0) 开始的每个更小的线段都添加了(0,0)。或者,您可以只添加中间点(我在第一个版本中就是这样),但那么您必须单独处理第一个起点和终点。如建议的那样,我将“图”更改为“集合”以避免这种情况;其他一切都照常工作。 - tobias_k
    2
    谢谢,这是一些非常出色的Python编程 :) 并且+1让我很容易地切换“shuffle”。 - Tjorriemorrie
    @tobias_k:这段代码能否扩展以使用实际日期时间值作为x轴,并生成逼真的分形OHLC数据点?我想尝试创建一个合成流Bokeh金融图,可以使用分形生成器作为OHLC引擎。 - GoFaster
    @GoFaster 我不是市场专家,但我认为这应该可行。只需将 x 轴上的 0.0 替换为开盘时间,将 1.0 替换为收盘时间,并相应地插值计算中间值即可。 - tobias_k
    @GoFaster:我有同样的需求。@tobias_k的分形解决方案是一个非维度化的[0,0]x[1,1]分形。您可以使用支持求和、减法和浮点数乘法的任何数据作为“起始”和“结束”点。由于似乎没有人回答这个特定的问题,我将发布我的谦虚解决方案,使用pandas。所有的功劳归@tobias_k所有。 - asterio gonzalez

    0

    使用 @tobias_k 的解决方案和 pandas,我们可以将归一化分形图形进行翻译和缩放,变成基于时间的图形。

    import arrow
    import pandas as pd
    import time
    
    depth = 5
    # the "geometry" of fractal
    turns = [
            (1 / 9, 0.60),
            (5 / 9, 0.30),
            (8 / 9, 0.70),
        ]
    
    # select start / end time 
    t0 = arrow.now().floor("hours")
    t1 = t0.shift(days=5)
    start = (pd.to_datetime(t0._datetime), 1000)
    end = (pd.to_datetime(t1._datetime), 2000)
    
    # create a non-dimensionalized [0,0]x[1,1] Fractal
    _start, _end = (0, 0), (1, 1)  
    graph = set()
    make_graph(depth, graph, _start, _end, turns)
    # just check graph length
    assert len(graph) == (len(turns) + 1) ** depth + 1
    
    # create a pandas dataframe from the normalized Fractal
    df = pd.DataFrame(graph)
    df.sort_values(0, inplace=True)
    df.reset_index(drop=True, inplace=True)
    
    # translate to real coordinates
    X = pd.DataFrame(
            data=[(start[0].timestamp(), start[1]), (end[0].timestamp(), end[1])]
            ).T
    delta = X[1] - X[0]
    Y = df.mul(delta) + X[0]
    Y[0] = [*map(lambda x: pd.to_datetime(x, unit="s"), Y[0])]
    
    # now resample and interpolate data according to *grid* size
    grid ="min"
    Z = Y.set_index(0)
    A = Z.resample(grid).mean().interpolate()
    
    # plot both graph to check errors
    import matplotlib.pyplot as plt
    ax = Z.plot()
    A.plot(ax=ax)
    plt.show()
    

    显示两个图表:

    Both graphs

    并缩放以查看插值和对齐到网格的差异:

    enter image description here


    0

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接