Plotly:如何计算和说明趋势线的上下50%?
Plotly: How to calculate and illustrate the upper and lower 50% of a trend line?
我需要使用 Python 并最好使用 Plotly 来查找(打印)趋势线上下 50% 的点。
到目前为止,我可以使用 plotly 制作一条正线性趋势的趋势线。
我想得到类似这张图的东西,我发现 here:
由于您没有提供数据集,我将根据我之前的回答构建一个解决方案:。这是您的用例的结果图:
我不能保证虚线 100% 是您要查找的内容,因为这将是一个意见问题 如何 您需要的线是如何计算的。我在这里所做的只是找到哪些值位于趋势线上方,取平均值,然后在计算伴随的 top 50 %
行时将该平均值添加到常数项:
[(const+over50) + (trend*i) for i,v in enumerate(df.index)]
但只有当点在趋势线上均匀分布时,使用平均值才有意义。据我所知,您可能更喜欢 count 趋势线上一半的值,并在那里画一条线。但我会把它留给你来决定。无论如何,如果您的最终目标是标记或突出显示这些点,下面的代码片段会让您得到这样的结果:
希望您会发现此建议有用。如果有任何不清楚的地方,请随时告诉我。
带有示例数据的完整代码
import plotly.graph_objects as go
import statsmodels.api as sm
import pandas as pd
import numpy as np
import datetime
from pandas import Timestamp
df = pd.DataFrame({'Date': {3762: Timestamp('2001-06-01 00:00:00'),
3763: Timestamp('2001-06-04 00:00:00'),
3764: Timestamp('2001-06-05 00:00:00'),
3765: Timestamp('2001-06-06 00:00:00'),
3766: Timestamp('2001-06-07 00:00:00'),
3767: Timestamp('2001-06-08 00:00:00'),
3768: Timestamp('2001-06-11 00:00:00'),
3769: Timestamp('2001-06-12 00:00:00'),
3770: Timestamp('2001-06-13 00:00:00'),
3771: Timestamp('2001-06-14 00:00:00'),
3772: Timestamp('2001-06-15 00:00:00'),
3773: Timestamp('2001-06-18 00:00:00'),
3774: Timestamp('2001-06-19 00:00:00'),
3775: Timestamp('2001-06-20 00:00:00'),
3776: Timestamp('2001-06-21 00:00:00'),
3777: Timestamp('2001-06-22 00:00:00'),
3779: Timestamp('2001-06-26 00:00:00'),
3780: Timestamp('2001-06-27 00:00:00'),
3781: Timestamp('2001-06-28 00:00:00'),
3782: Timestamp('2001-06-29 00:00:00'),
3784: Timestamp('2001-07-03 00:00:00'),
3785: Timestamp('2001-07-04 00:00:00'),
3786: Timestamp('2001-07-05 00:00:00'),
3788: Timestamp('2001-07-09 00:00:00'),
3789: Timestamp('2001-07-10 00:00:00'),
3790: Timestamp('2001-07-11 00:00:00'),
3791: Timestamp('2001-07-12 00:00:00'),
3792: Timestamp('2001-07-13 00:00:00'),
3793: Timestamp('2001-07-16 00:00:00'),
3794: Timestamp('2001-07-17 00:00:00'),
3795: Timestamp('2001-07-18 00:00:00'),
3796: Timestamp('2001-07-19 00:00:00'),
3797: Timestamp('2001-07-20 00:00:00'),
3798: Timestamp('2001-07-23 00:00:00'),
3799: Timestamp('2001-07-24 00:00:00'),
3801: Timestamp('2001-07-26 00:00:00'),
3802: Timestamp('2001-07-27 00:00:00'),
3803: Timestamp('2001-07-30 00:00:00'),
3804: Timestamp('2001-07-31 00:00:00'),
3805: Timestamp('2001-08-01 00:00:00'),
3806: Timestamp('2001-08-02 00:00:00'),
3807: Timestamp('2001-08-03 00:00:00'),
3808: Timestamp('2001-08-06 00:00:00'),
3809: Timestamp('2001-08-07 00:00:00'),
3810: Timestamp('2001-08-08 00:00:00'),
3811: Timestamp('2001-08-09 00:00:00'),
3812: Timestamp('2001-08-10 00:00:00'),
3813: Timestamp('2001-08-13 00:00:00'),
3814: Timestamp('2001-08-14 00:00:00'),
3815: Timestamp('2001-08-15 00:00:00'),
3816: Timestamp('2001-08-16 00:00:00'),
3817: Timestamp('2001-08-17 00:00:00'),
3818: Timestamp('2001-08-20 00:00:00'),
3819: Timestamp('2001-08-21 00:00:00'),
3820: Timestamp('2001-08-22 00:00:00'),
3821: Timestamp('2001-08-23 00:00:00'),
3822: Timestamp('2001-08-24 00:00:00'),
3823: Timestamp('2001-08-27 00:00:00'),
3824: Timestamp('2001-08-28 00:00:00'),
3825: Timestamp('2001-08-29 00:00:00'),
3826: Timestamp('2001-08-30 00:00:00'),
3827: Timestamp('2001-08-31 00:00:00'),
3828: Timestamp('2001-09-03 00:00:00'),
3829: Timestamp('2001-09-04 00:00:00'),
3830: Timestamp('2001-09-05 00:00:00'),
3831: Timestamp('2001-09-06 00:00:00'),
3832: Timestamp('2001-09-07 00:00:00'),
3833: Timestamp('2001-09-10 00:00:00'),
3834: Timestamp('2001-09-11 00:00:00'),
3835: Timestamp('2001-09-12 00:00:00'),
3836: Timestamp('2001-09-13 00:00:00'),
3837: Timestamp('2001-09-14 00:00:00'),
3838: Timestamp('2001-09-17 00:00:00'),
3839: Timestamp('2001-09-18 00:00:00'),
3840: Timestamp('2001-09-19 00:00:00'),
3841: Timestamp('2001-09-20 00:00:00'),
3842: Timestamp('2001-09-21 00:00:00'),
3843: Timestamp('2001-09-24 00:00:00'),
3844: Timestamp('2001-09-25 00:00:00'),
3845: Timestamp('2001-09-26 00:00:00'),
3846: Timestamp('2001-09-27 00:00:00'),
3847: Timestamp('2001-09-28 00:00:00'),
3850: Timestamp('2001-10-03 00:00:00'),
3851: Timestamp('2001-10-04 00:00:00'),
3852: Timestamp('2001-10-05 00:00:00'),
3853: Timestamp('2001-10-08 00:00:00'),
3854: Timestamp('2001-10-09 00:00:00'),
3855: Timestamp('2001-10-10 00:00:00'),
3856: Timestamp('2001-10-11 00:00:00'),
3857: Timestamp('2001-10-12 00:00:00'),
3858: Timestamp('2001-10-15 00:00:00'),
3859: Timestamp('2001-10-16 00:00:00'),
3860: Timestamp('2001-10-17 00:00:00'),
3861: Timestamp('2001-10-18 00:00:00'),
3862: Timestamp('2001-10-19 00:00:00'),
3863: Timestamp('2001-10-22 00:00:00'),
3864: Timestamp('2001-10-23 00:00:00'),
3865: Timestamp('2001-10-24 00:00:00'),
3866: Timestamp('2001-10-25 00:00:00'),
3867: Timestamp('2001-10-26 00:00:00')},
'Adj Close': {3762: 9.483521300451965,
3763: 9.488539389609842,
3764: 9.506873417520655,
3765: 9.516059526271494,
3766: 9.52540142267562,
3767: 9.533067841143405,
3768: 9.523360475569014,
3769: 9.512419287352929,
3770: 9.512170110321078,
3771: 9.491669027751996,
3772: 9.480558330676322,
3773: 9.468756875278643,
3774: 9.48293369128291,
3775: 9.466431924131614,
3776: 9.487020913528825,
3777: 9.486001951740908,
3779: 9.469774943465724,
3780: 9.473028427171643,
3781: 9.459371553309266,
3782: 9.475970855997938,
3784: 9.486816137667164,
3785: 9.488542421142602,
3786: 9.472664671722018,
3788: 9.448623120188204,
3789: 9.450451192873874,
3790: 9.435713467289014,
3791: 9.446218508764293,
3792: 9.442466660552066,
3793: 9.443397047352386,
3794: 9.433103851072097,
3795: 9.427642127580112,
3796: 9.41571256910222,
3797: 9.417491092037041,
3798: 9.412174497254961,
3799: 9.4103462690634,
3801: 9.39597479458201,
3802: 9.407728679911855,
3803: 9.399857656975392,
3804: 9.418710567070383,
3805: 9.431781694039891,
3806: 9.430789907045172,
3807: 9.414837561626188,
3808: 9.404986466190781,
3809: 9.39326095182,
3810: 9.389156606132271,
3811: 9.368776387849374,
3812: 9.372953110523751,
3813: 9.366855970805329,
3814: 9.391912461823267,
3815: 9.404395312850555,
3816: 9.378600227328686,
3817: 9.37201776092802,
3818: 9.34650456280641,
3819: 9.344901824694107,
3820: 9.32264802844274,
3821: 9.33656588127212,
3822: 9.315627867418097,
3823: 9.326764237890817,
3824: 9.332604930413563,
3825: 9.327448527151956,
3826: 9.333940224481115,
3827: 9.313842403932533,
3828: 9.29676020844021,
3829: 9.318015638210596,
3830: 9.300468022736998,
3831: 9.27465889826041,
3832: 9.248040717937537,
3833: 9.246317398619535,
3834: 9.25122895807117,
3835: 9.158375285355174,
3836: 9.166305927329747,
3837: 9.175277821947487,
3838: 9.13984812080253,
3839: 9.1386188229253,
3840: 9.165149513582218,
3841: 9.139701196323891,
3842: 9.097641909876808,
3843: 9.13610162204065,
3844: 9.128051597198034,
3845: 9.145455124069166,
3846: 9.169600669798987,
3847: 9.205398199033475,
3850: 9.200001069931528,
3851: 9.238576907009563,
3852: 9.237700631328401,
3853: 9.207118194132338,
3854: 9.245604198507314,
3855: 9.23972830855306,
3856: 9.26128158783136,
3857: 9.237384352858927,
3858: 9.223314822990815,
3859: 9.225080227987517,
3860: 9.236087021069979,
3861: 9.198329565352042,
3862: 9.192770913389573,
3863: 9.189886616720194,
3864: 9.23208619279342,
3865: 9.23439472833901,
3866: 9.23439472833901,
3867: 9.250016773018734},
'Volume': {3762: 0.0,
3763: 0.0,
3764: 0.0,
3765: 0.0,
3766: 0.0,
3767: 0.0,
3768: 0.0,
3769: 0.0,
3770: 0.0,
3771: 0.0,
3772: 0.0,
3773: 0.0,
3774: 0.0,
3775: 0.0,
3776: 0.0,
3777: 0.0,
3779: 0.0,
3780: 0.0,
3781: 0.0,
3782: 0.0,
3784: 0.0,
3785: 0.0,
3786: 0.0,
3788: 257038800.0,
3789: 134407800.0,
3790: 195057600.0,
3791: 174767800.0,
3792: 211230200.0,
3793: 113928800.0,
3794: 139890800.0,
3795: 134535000.0,
3796: 204987000.0,
3797: 147662000.0,
3798: 166057200.0,
3799: 139913800.0,
3801: 221039000.0,
3802: 124388600.0,
3803: 153086200.0,
3804: 227109800.0,
3805: 243126000.0,
3806: 194471600.0,
3807: 168728800.0,
3808: 141753200.0,
3809: 208445200.0,
3810: 178200800.0,
3811: 231948800.0,
3812: 148634200.0,
3813: 137231600.0,
3814: 172713800.0,
3815: 191067400.0,
3816: 422805600.0,
3817: 330698600.0,
3818: 256960200.0,
3819: 225189800.0,
3820: 272482800.0,
3821: 215469200.0,
3822: 241046000.0,
3823: 145020400.0,
3824: 179275400.0,
3825: 188285800.0,
3826: 246490800.0,
3827: 265702000.0,
3828: 185143200.0,
3829: 303746000.0,
3830: 206642600.0,
3831: 239079600.0,
3832: 399700800.0,
3833: 367156400.0,
3834: 0.0,
3835: 0.0,
3836: 0.0,
3837: 0.0,
3838: 0.0,
3839: 0.0,
3840: 333256200.0,
3841: 284966400.0,
3842: 519940400.0,
3843: 442181500.0,
3844: 367545800.0,
3845: 390860600.0,
3846: 296667600.0,
3847: 320775600.0,
3850: 333197400.0,
3851: 358779000.0,
3852: 576213400.0,
3853: 511535600.0,
3854: 409534200.0,
3855: 370696800.0,
3856: 398527200.0,
3857: 388528000.0,
3858: 275161200.0,
3859: 192816600.0,
3860: 414838800.0,
3861: 365696000.0,
3862: 297211400.0,
3863: 236566000.0,
3864: 344018800.0,
3865: 287418600.0,
3866: 0.0,
3867: 346798600.0}})
df = df.tail(25)
# line parameters using statsmodels
df['Date'] = pd.to_datetime(df['Date'])
df['ix']=np.arange(0, len(df))
mod = sm.OLS(df['Adj Close'],sm.add_constant(df.ix)).fit()
const = mod.params[0]
trend = mod.params[1]
# dict that stores adjusted constants (starting points)
extra_lines = [-0.2,-0.1,0, 0.1,0.2] # add or remove as you please
model = [{'Line': 'Line_'+str(i+1), 'value': k, 'const': const+k} for i, k in enumerate(extra_lines)]
df['trend'] = [const + (trend*i) for i,v in enumerate(df.index)]
# make more sensible names
df.columns = ['date', 'value', 'volume', 'ix', 'trend']
# calculate distance from trend lines to 50% over and under the trend line
df['over'] = np.where(df['value']>df['trend'], df['value']-df['trend'], np.nan)
df['under'] = np.where(df['value']<df['trend'], df['trend']-df['value'], np.nan)
over50 = np.mean(df['over'])
under50 = np.mean(df['under'])
df['over50_line'] = [(const+over50) + (trend*i) for i,v in enumerate(df.index)]
df['under50_line'] = [(const-under50) + (trend*i) for i,v in enumerate(df.index)]
df['top50'] = np.where(df['value']>df['trend'], df['value'], np.nan)
df['bottom50'] = np.where(df['value']<df['trend'], df['value'], np.nan)
# plotly figure with sample data
fig = go.Figure(go.Scatter(x=df.ix, y=df['value'],
mode = 'markers',
marker = dict(color='rgba(0,0,255,0.2)',
line=dict(color='blue', width=2),
symbol = 'diamond',
size = 12),
name = 'values'))
# add trend line
fig.add_trace(go.Scatter(x=df.ix, y = df['trend'],
name = 'trend'))
# add line for 50% over the trend line
fig.add_trace(go.Scatter(x=df.ix, y = df['over50_line'],
mode = 'lines',
line = dict(dash='dash', color = 'red', width = 1),
name = 'top 50 %'))
# add line for 50% under the trend line
fig.add_trace(go.Scatter(x=df.ix, y =df['under50_line'],
mode = 'lines',
line = dict(dash='dash', color = 'red', width = 1),
name = 'lower 50%'))
# add markers for top25 / over 50% line
fig.add_trace(go.Scatter(x=df.ix, y=df['top50'],
mode = 'markers',
marker = dict(color='yellow',
#line=dict(color='blue', width=2),
symbol = 'circle',
size = 5),
name = 'over50%'))
# add markers for bottom25 / under 50% line
fig.add_trace(go.Scatter(x=df.ix, y=df['bottom50'],
mode = 'markers',
marker = dict(color='red',
#line=dict(color='blue', width=2),
symbol = 'circle',
size = 5),
name = 'under 50%'))
fig.show()
我需要使用 Python 并最好使用 Plotly 来查找(打印)趋势线上下 50% 的点。 到目前为止,我可以使用 plotly 制作一条正线性趋势的趋势线。
我想得到类似这张图的东西,我发现 here:
由于您没有提供数据集,我将根据我之前的回答构建一个解决方案:
我不能保证虚线 100% 是您要查找的内容,因为这将是一个意见问题 如何 您需要的线是如何计算的。我在这里所做的只是找到哪些值位于趋势线上方,取平均值,然后在计算伴随的 top 50 %
行时将该平均值添加到常数项:
[(const+over50) + (trend*i) for i,v in enumerate(df.index)]
但只有当点在趋势线上均匀分布时,使用平均值才有意义。据我所知,您可能更喜欢 count 趋势线上一半的值,并在那里画一条线。但我会把它留给你来决定。无论如何,如果您的最终目标是标记或突出显示这些点,下面的代码片段会让您得到这样的结果:
希望您会发现此建议有用。如果有任何不清楚的地方,请随时告诉我。
带有示例数据的完整代码
import plotly.graph_objects as go
import statsmodels.api as sm
import pandas as pd
import numpy as np
import datetime
from pandas import Timestamp
df = pd.DataFrame({'Date': {3762: Timestamp('2001-06-01 00:00:00'),
3763: Timestamp('2001-06-04 00:00:00'),
3764: Timestamp('2001-06-05 00:00:00'),
3765: Timestamp('2001-06-06 00:00:00'),
3766: Timestamp('2001-06-07 00:00:00'),
3767: Timestamp('2001-06-08 00:00:00'),
3768: Timestamp('2001-06-11 00:00:00'),
3769: Timestamp('2001-06-12 00:00:00'),
3770: Timestamp('2001-06-13 00:00:00'),
3771: Timestamp('2001-06-14 00:00:00'),
3772: Timestamp('2001-06-15 00:00:00'),
3773: Timestamp('2001-06-18 00:00:00'),
3774: Timestamp('2001-06-19 00:00:00'),
3775: Timestamp('2001-06-20 00:00:00'),
3776: Timestamp('2001-06-21 00:00:00'),
3777: Timestamp('2001-06-22 00:00:00'),
3779: Timestamp('2001-06-26 00:00:00'),
3780: Timestamp('2001-06-27 00:00:00'),
3781: Timestamp('2001-06-28 00:00:00'),
3782: Timestamp('2001-06-29 00:00:00'),
3784: Timestamp('2001-07-03 00:00:00'),
3785: Timestamp('2001-07-04 00:00:00'),
3786: Timestamp('2001-07-05 00:00:00'),
3788: Timestamp('2001-07-09 00:00:00'),
3789: Timestamp('2001-07-10 00:00:00'),
3790: Timestamp('2001-07-11 00:00:00'),
3791: Timestamp('2001-07-12 00:00:00'),
3792: Timestamp('2001-07-13 00:00:00'),
3793: Timestamp('2001-07-16 00:00:00'),
3794: Timestamp('2001-07-17 00:00:00'),
3795: Timestamp('2001-07-18 00:00:00'),
3796: Timestamp('2001-07-19 00:00:00'),
3797: Timestamp('2001-07-20 00:00:00'),
3798: Timestamp('2001-07-23 00:00:00'),
3799: Timestamp('2001-07-24 00:00:00'),
3801: Timestamp('2001-07-26 00:00:00'),
3802: Timestamp('2001-07-27 00:00:00'),
3803: Timestamp('2001-07-30 00:00:00'),
3804: Timestamp('2001-07-31 00:00:00'),
3805: Timestamp('2001-08-01 00:00:00'),
3806: Timestamp('2001-08-02 00:00:00'),
3807: Timestamp('2001-08-03 00:00:00'),
3808: Timestamp('2001-08-06 00:00:00'),
3809: Timestamp('2001-08-07 00:00:00'),
3810: Timestamp('2001-08-08 00:00:00'),
3811: Timestamp('2001-08-09 00:00:00'),
3812: Timestamp('2001-08-10 00:00:00'),
3813: Timestamp('2001-08-13 00:00:00'),
3814: Timestamp('2001-08-14 00:00:00'),
3815: Timestamp('2001-08-15 00:00:00'),
3816: Timestamp('2001-08-16 00:00:00'),
3817: Timestamp('2001-08-17 00:00:00'),
3818: Timestamp('2001-08-20 00:00:00'),
3819: Timestamp('2001-08-21 00:00:00'),
3820: Timestamp('2001-08-22 00:00:00'),
3821: Timestamp('2001-08-23 00:00:00'),
3822: Timestamp('2001-08-24 00:00:00'),
3823: Timestamp('2001-08-27 00:00:00'),
3824: Timestamp('2001-08-28 00:00:00'),
3825: Timestamp('2001-08-29 00:00:00'),
3826: Timestamp('2001-08-30 00:00:00'),
3827: Timestamp('2001-08-31 00:00:00'),
3828: Timestamp('2001-09-03 00:00:00'),
3829: Timestamp('2001-09-04 00:00:00'),
3830: Timestamp('2001-09-05 00:00:00'),
3831: Timestamp('2001-09-06 00:00:00'),
3832: Timestamp('2001-09-07 00:00:00'),
3833: Timestamp('2001-09-10 00:00:00'),
3834: Timestamp('2001-09-11 00:00:00'),
3835: Timestamp('2001-09-12 00:00:00'),
3836: Timestamp('2001-09-13 00:00:00'),
3837: Timestamp('2001-09-14 00:00:00'),
3838: Timestamp('2001-09-17 00:00:00'),
3839: Timestamp('2001-09-18 00:00:00'),
3840: Timestamp('2001-09-19 00:00:00'),
3841: Timestamp('2001-09-20 00:00:00'),
3842: Timestamp('2001-09-21 00:00:00'),
3843: Timestamp('2001-09-24 00:00:00'),
3844: Timestamp('2001-09-25 00:00:00'),
3845: Timestamp('2001-09-26 00:00:00'),
3846: Timestamp('2001-09-27 00:00:00'),
3847: Timestamp('2001-09-28 00:00:00'),
3850: Timestamp('2001-10-03 00:00:00'),
3851: Timestamp('2001-10-04 00:00:00'),
3852: Timestamp('2001-10-05 00:00:00'),
3853: Timestamp('2001-10-08 00:00:00'),
3854: Timestamp('2001-10-09 00:00:00'),
3855: Timestamp('2001-10-10 00:00:00'),
3856: Timestamp('2001-10-11 00:00:00'),
3857: Timestamp('2001-10-12 00:00:00'),
3858: Timestamp('2001-10-15 00:00:00'),
3859: Timestamp('2001-10-16 00:00:00'),
3860: Timestamp('2001-10-17 00:00:00'),
3861: Timestamp('2001-10-18 00:00:00'),
3862: Timestamp('2001-10-19 00:00:00'),
3863: Timestamp('2001-10-22 00:00:00'),
3864: Timestamp('2001-10-23 00:00:00'),
3865: Timestamp('2001-10-24 00:00:00'),
3866: Timestamp('2001-10-25 00:00:00'),
3867: Timestamp('2001-10-26 00:00:00')},
'Adj Close': {3762: 9.483521300451965,
3763: 9.488539389609842,
3764: 9.506873417520655,
3765: 9.516059526271494,
3766: 9.52540142267562,
3767: 9.533067841143405,
3768: 9.523360475569014,
3769: 9.512419287352929,
3770: 9.512170110321078,
3771: 9.491669027751996,
3772: 9.480558330676322,
3773: 9.468756875278643,
3774: 9.48293369128291,
3775: 9.466431924131614,
3776: 9.487020913528825,
3777: 9.486001951740908,
3779: 9.469774943465724,
3780: 9.473028427171643,
3781: 9.459371553309266,
3782: 9.475970855997938,
3784: 9.486816137667164,
3785: 9.488542421142602,
3786: 9.472664671722018,
3788: 9.448623120188204,
3789: 9.450451192873874,
3790: 9.435713467289014,
3791: 9.446218508764293,
3792: 9.442466660552066,
3793: 9.443397047352386,
3794: 9.433103851072097,
3795: 9.427642127580112,
3796: 9.41571256910222,
3797: 9.417491092037041,
3798: 9.412174497254961,
3799: 9.4103462690634,
3801: 9.39597479458201,
3802: 9.407728679911855,
3803: 9.399857656975392,
3804: 9.418710567070383,
3805: 9.431781694039891,
3806: 9.430789907045172,
3807: 9.414837561626188,
3808: 9.404986466190781,
3809: 9.39326095182,
3810: 9.389156606132271,
3811: 9.368776387849374,
3812: 9.372953110523751,
3813: 9.366855970805329,
3814: 9.391912461823267,
3815: 9.404395312850555,
3816: 9.378600227328686,
3817: 9.37201776092802,
3818: 9.34650456280641,
3819: 9.344901824694107,
3820: 9.32264802844274,
3821: 9.33656588127212,
3822: 9.315627867418097,
3823: 9.326764237890817,
3824: 9.332604930413563,
3825: 9.327448527151956,
3826: 9.333940224481115,
3827: 9.313842403932533,
3828: 9.29676020844021,
3829: 9.318015638210596,
3830: 9.300468022736998,
3831: 9.27465889826041,
3832: 9.248040717937537,
3833: 9.246317398619535,
3834: 9.25122895807117,
3835: 9.158375285355174,
3836: 9.166305927329747,
3837: 9.175277821947487,
3838: 9.13984812080253,
3839: 9.1386188229253,
3840: 9.165149513582218,
3841: 9.139701196323891,
3842: 9.097641909876808,
3843: 9.13610162204065,
3844: 9.128051597198034,
3845: 9.145455124069166,
3846: 9.169600669798987,
3847: 9.205398199033475,
3850: 9.200001069931528,
3851: 9.238576907009563,
3852: 9.237700631328401,
3853: 9.207118194132338,
3854: 9.245604198507314,
3855: 9.23972830855306,
3856: 9.26128158783136,
3857: 9.237384352858927,
3858: 9.223314822990815,
3859: 9.225080227987517,
3860: 9.236087021069979,
3861: 9.198329565352042,
3862: 9.192770913389573,
3863: 9.189886616720194,
3864: 9.23208619279342,
3865: 9.23439472833901,
3866: 9.23439472833901,
3867: 9.250016773018734},
'Volume': {3762: 0.0,
3763: 0.0,
3764: 0.0,
3765: 0.0,
3766: 0.0,
3767: 0.0,
3768: 0.0,
3769: 0.0,
3770: 0.0,
3771: 0.0,
3772: 0.0,
3773: 0.0,
3774: 0.0,
3775: 0.0,
3776: 0.0,
3777: 0.0,
3779: 0.0,
3780: 0.0,
3781: 0.0,
3782: 0.0,
3784: 0.0,
3785: 0.0,
3786: 0.0,
3788: 257038800.0,
3789: 134407800.0,
3790: 195057600.0,
3791: 174767800.0,
3792: 211230200.0,
3793: 113928800.0,
3794: 139890800.0,
3795: 134535000.0,
3796: 204987000.0,
3797: 147662000.0,
3798: 166057200.0,
3799: 139913800.0,
3801: 221039000.0,
3802: 124388600.0,
3803: 153086200.0,
3804: 227109800.0,
3805: 243126000.0,
3806: 194471600.0,
3807: 168728800.0,
3808: 141753200.0,
3809: 208445200.0,
3810: 178200800.0,
3811: 231948800.0,
3812: 148634200.0,
3813: 137231600.0,
3814: 172713800.0,
3815: 191067400.0,
3816: 422805600.0,
3817: 330698600.0,
3818: 256960200.0,
3819: 225189800.0,
3820: 272482800.0,
3821: 215469200.0,
3822: 241046000.0,
3823: 145020400.0,
3824: 179275400.0,
3825: 188285800.0,
3826: 246490800.0,
3827: 265702000.0,
3828: 185143200.0,
3829: 303746000.0,
3830: 206642600.0,
3831: 239079600.0,
3832: 399700800.0,
3833: 367156400.0,
3834: 0.0,
3835: 0.0,
3836: 0.0,
3837: 0.0,
3838: 0.0,
3839: 0.0,
3840: 333256200.0,
3841: 284966400.0,
3842: 519940400.0,
3843: 442181500.0,
3844: 367545800.0,
3845: 390860600.0,
3846: 296667600.0,
3847: 320775600.0,
3850: 333197400.0,
3851: 358779000.0,
3852: 576213400.0,
3853: 511535600.0,
3854: 409534200.0,
3855: 370696800.0,
3856: 398527200.0,
3857: 388528000.0,
3858: 275161200.0,
3859: 192816600.0,
3860: 414838800.0,
3861: 365696000.0,
3862: 297211400.0,
3863: 236566000.0,
3864: 344018800.0,
3865: 287418600.0,
3866: 0.0,
3867: 346798600.0}})
df = df.tail(25)
# line parameters using statsmodels
df['Date'] = pd.to_datetime(df['Date'])
df['ix']=np.arange(0, len(df))
mod = sm.OLS(df['Adj Close'],sm.add_constant(df.ix)).fit()
const = mod.params[0]
trend = mod.params[1]
# dict that stores adjusted constants (starting points)
extra_lines = [-0.2,-0.1,0, 0.1,0.2] # add or remove as you please
model = [{'Line': 'Line_'+str(i+1), 'value': k, 'const': const+k} for i, k in enumerate(extra_lines)]
df['trend'] = [const + (trend*i) for i,v in enumerate(df.index)]
# make more sensible names
df.columns = ['date', 'value', 'volume', 'ix', 'trend']
# calculate distance from trend lines to 50% over and under the trend line
df['over'] = np.where(df['value']>df['trend'], df['value']-df['trend'], np.nan)
df['under'] = np.where(df['value']<df['trend'], df['trend']-df['value'], np.nan)
over50 = np.mean(df['over'])
under50 = np.mean(df['under'])
df['over50_line'] = [(const+over50) + (trend*i) for i,v in enumerate(df.index)]
df['under50_line'] = [(const-under50) + (trend*i) for i,v in enumerate(df.index)]
df['top50'] = np.where(df['value']>df['trend'], df['value'], np.nan)
df['bottom50'] = np.where(df['value']<df['trend'], df['value'], np.nan)
# plotly figure with sample data
fig = go.Figure(go.Scatter(x=df.ix, y=df['value'],
mode = 'markers',
marker = dict(color='rgba(0,0,255,0.2)',
line=dict(color='blue', width=2),
symbol = 'diamond',
size = 12),
name = 'values'))
# add trend line
fig.add_trace(go.Scatter(x=df.ix, y = df['trend'],
name = 'trend'))
# add line for 50% over the trend line
fig.add_trace(go.Scatter(x=df.ix, y = df['over50_line'],
mode = 'lines',
line = dict(dash='dash', color = 'red', width = 1),
name = 'top 50 %'))
# add line for 50% under the trend line
fig.add_trace(go.Scatter(x=df.ix, y =df['under50_line'],
mode = 'lines',
line = dict(dash='dash', color = 'red', width = 1),
name = 'lower 50%'))
# add markers for top25 / over 50% line
fig.add_trace(go.Scatter(x=df.ix, y=df['top50'],
mode = 'markers',
marker = dict(color='yellow',
#line=dict(color='blue', width=2),
symbol = 'circle',
size = 5),
name = 'over50%'))
# add markers for bottom25 / under 50% line
fig.add_trace(go.Scatter(x=df.ix, y=df['bottom50'],
mode = 'markers',
marker = dict(color='red',
#line=dict(color='blue', width=2),
symbol = 'circle',
size = 5),
name = 'under 50%'))
fig.show()