From 98913165ae6d4c246e93e41d017cd423ede8efa5 Mon Sep 17 00:00:00 2001 From: yutiansut Date: Mon, 7 May 2018 21:09:34 +0800 Subject: [PATCH] #update for spinx doc --- Makefile | 20 + .../doctrees/QUANTAXIS_Trade/README.doctree | Bin 0 -> 34289 bytes _build/doctrees/README.doctree | Bin 0 -> 33259 bytes _build/doctrees/environment.pickle | Bin 0 -> 2488328 bytes _build/doctrees/index.doctree | Bin 0 -> 4737 bytes .../doctrees/source/QUANTAXIS.QAARP.doctree | Bin 0 -> 143334 bytes .../source/QUANTAXIS.QAAnalysis.doctree | Bin 0 -> 88644 bytes .../source/QUANTAXIS.QABacktest.doctree | Bin 0 -> 73214 bytes .../doctrees/source/QUANTAXIS.QACmd.doctree | Bin 0 -> 30628 bytes .../doctrees/source/QUANTAXIS.QAData.doctree | Bin 0 -> 205141 bytes .../source/QUANTAXIS.QAData.proto.doctree | Bin 0 -> 5532 bytes .../source/QUANTAXIS.QAEngine.doctree | Bin 0 -> 54602 bytes .../doctrees/source/QUANTAXIS.QAFetch.doctree | Bin 0 -> 264261 bytes .../source/QUANTAXIS.QAIndicator.doctree | Bin 0 -> 118004 bytes .../source/QUANTAXIS.QAMarket.doctree | Bin 0 -> 304064 bytes _build/doctrees/source/QUANTAXIS.QASU.doctree | Bin 0 -> 116317 bytes .../doctrees/source/QUANTAXIS.QAUtil.doctree | Bin 0 -> 695152 bytes .../doctrees/source/QUANTAXIS.QAWeb.doctree | Bin 0 -> 52847 bytes _build/doctrees/source/QUANTAXIS.doctree | Bin 0 -> 4292 bytes _build/doctrees/source/modules.doctree | Bin 0 -> 2557 bytes _build/html/.buildinfo | 4 + _build/html/.nojekyll | 0 _build/html/QUANTAXIS_Trade/README.html | 208 + _build/html/README.html | 208 + .../_modules/QUANTAXIS/QAARP/QAAccount.html | 447 + .../_modules/QUANTAXIS/QAARP/QAPortfolio.html | 343 + .../html/_modules/QUANTAXIS/QAARP/QARisk.html | 367 + .../_modules/QUANTAXIS/QAARP/QAStrategy.html | 113 + .../html/_modules/QUANTAXIS/QAARP/QAUser.html | 180 + .../QAAnalysis/QAAnalysis_block.html | 218 + .../QAAnalysis/QAAnalysis_dataframe.html | 311 + .../QAAnalysis_machinelearning.html | 125 + .../QAAnalysis/QAAnalysis_series.html | 105 + .../QUANTAXIS/QAAnalysis/QAAnalysis_tick.html | 130 + .../QAAnalysis/QAAnalysis_trade.html | 178 + .../QUANTAXIS/QABacktest/QAAnalysis.html | 340 + .../QUANTAXIS/QABacktest/QABacktest.html | 243 + .../QUANTAXIS/QABacktest/QAResult.html | 185 + .../QABacktest/backtest_setting.html | 126 + _build/html/_modules/QUANTAXIS/QACmd.html | 327 + .../QUANTAXIS/QAData/QADataStruct.html | 941 ++ .../_modules/QUANTAXIS/QAData/data_fq.html | 209 + .../QUANTAXIS/QAData/data_resample.html | 144 + .../_modules/QUANTAXIS/QAData/dsmethods.html | 140 + .../_modules/QUANTAXIS/QAData/schema.html | 179 + .../_modules/QUANTAXIS/QAEngine/QAEvent.html | 132 + .../_modules/QUANTAXIS/QAEngine/QATask.html | 138 + .../QUANTAXIS/QAEngine/QAThreadEngine.html | 282 + _build/html/_modules/QUANTAXIS/QAFetch.html | 256 + .../_modules/QUANTAXIS/QAFetch/Fetcher.html | 200 + .../_modules/QUANTAXIS/QAFetch/QACrawler.html | 148 + .../QUANTAXIS/QAFetch/QAEastMoney.html | 157 + .../_modules/QUANTAXIS/QAFetch/QAQuery.html | 434 + .../QUANTAXIS/QAFetch/QAQuery_Advance.html | 323 + .../_modules/QUANTAXIS/QAFetch/QATdx.html | 974 ++ .../_modules/QUANTAXIS/QAFetch/QATdx_adv.html | 420 + .../_modules/QUANTAXIS/QAFetch/QAThs.html | 185 + .../_modules/QUANTAXIS/QAFetch/QATushare.html | 191 + .../_modules/QUANTAXIS/QAFetch/QAWind.html | 347 + .../QUANTAXIS/QAFetch/QAfinancial.html | 158 + .../_modules/QUANTAXIS/QAFetch/realtime.html | 141 + .../_modules/QUANTAXIS/QAIndicator/base.html | 262 + .../QUANTAXIS/QAIndicator/indicators.html | 700 ++ .../QUANTAXIS/QAMarket/QABacktestBroker.html | 366 + .../_modules/QUANTAXIS/QAMarket/QABroker.html | 225 + .../_modules/QUANTAXIS/QAMarket/QADealer.html | 352 + .../_modules/QUANTAXIS/QAMarket/QAMarket.html | 399 + .../_modules/QUANTAXIS/QAMarket/QAOrder.html | 323 + .../QUANTAXIS/QAMarket/QAOrderHandler.html | 168 + .../QUANTAXIS/QAMarket/QARandomBroker.html | 118 + .../QUANTAXIS/QAMarket/QARealBroker.html | 118 + .../QUANTAXIS/QAMarket/QASimulatedBroker.html | 163 + .../_modules/QUANTAXIS/QAMarket/QATrade.html | 206 + .../QUANTAXIS/QAMarket/shipaneBroker.html | 228 + .../QUANTAXIS/QAMarket/shipaneclient.html | 361 + .../QUANTAXIS/QAMarket/tdxRealBroker.html | 305 + _build/html/_modules/QUANTAXIS/QASU/main.html | 282 + .../_modules/QUANTAXIS/QASU/save_account.html | 137 + .../QUANTAXIS/QASU/save_backtest.html | 164 + .../_modules/QUANTAXIS/QASU/save_local.html | 127 + .../_modules/QUANTAXIS/QASU/save_tdx.html | 648 + .../QUANTAXIS/QASU/save_tdx_file.html | 153 + .../_modules/QUANTAXIS/QASU/save_tushare.html | 221 + _build/html/_modules/QUANTAXIS/QASU/user.html | 126 + .../html/_modules/QUANTAXIS/QAUtil/QABar.html | 230 + .../html/_modules/QUANTAXIS/QAUtil/QACfg.html | 132 + .../_modules/QUANTAXIS/QAUtil/QACode.html | 123 + .../html/_modules/QUANTAXIS/QAUtil/QACsv.html | 141 + .../_modules/QUANTAXIS/QAUtil/QADate.html | 440 + .../QUANTAXIS/QAUtil/QADate_trade.html | 242 + .../_modules/QUANTAXIS/QAUtil/QADict.html | 120 + .../_modules/QUANTAXIS/QAUtil/QAList.html | 115 + .../_modules/QUANTAXIS/QAUtil/QALogs.html | 161 + .../_modules/QUANTAXIS/QAUtil/QAMail.html | 131 + .../_modules/QUANTAXIS/QAUtil/QAMongo.html | 147 + .../QUANTAXIS/QAUtil/QAParameter.html | 423 + .../_modules/QUANTAXIS/QAUtil/QAPlot.html | 170 + .../_modules/QUANTAXIS/QAUtil/QARandom.html | 121 + .../_modules/QUANTAXIS/QAUtil/QASetting.html | 159 + .../html/_modules/QUANTAXIS/QAUtil/QASql.html | 129 + .../_modules/QUANTAXIS/QAUtil/QAText.html | 124 + .../QUANTAXIS/QAUtil/QATransform.html | 145 + .../html/_modules/QUANTAXIS/QAUtil/QAWeb.html | 142 + .../html/_modules/QUANTAXIS/QAWeb/chain.html | 358 + _build/html/_modules/index.html | 158 + .../_modules/sqlalchemy/orm/attributes.html | 1774 +++ .../_sources/QUANTAXIS_Trade/README.rst.txt | 128 + _build/html/_sources/README.rst.txt | 128 + _build/html/_sources/index.rst.txt | 20 + .../_sources/source/QUANTAXIS.QAARP.rst.txt | 54 + .../source/QUANTAXIS.QAAnalysis.rst.txt | 62 + .../source/QUANTAXIS.QABacktest.rst.txt | 46 + .../_sources/source/QUANTAXIS.QACmd.rst.txt | 22 + .../source/QUANTAXIS.QAData.proto.rst.txt | 38 + .../_sources/source/QUANTAXIS.QAData.rst.txt | 93 + .../source/QUANTAXIS.QAEngine.rst.txt | 38 + .../_sources/source/QUANTAXIS.QAFetch.rst.txt | 126 + .../source/QUANTAXIS.QAIndicator.rst.txt | 30 + .../source/QUANTAXIS.QAMarket.rst.txt | 126 + .../_sources/source/QUANTAXIS.QASU.rst.txt | 78 + .../_sources/source/QUANTAXIS.QAUtil.rst.txt | 190 + .../_sources/source/QUANTAXIS.QAWeb.rst.txt | 30 + _build/html/_sources/source/QUANTAXIS.rst.txt | 28 + _build/html/_sources/source/modules.rst.txt | 7 + _build/html/_static/ajax-loader.gif | Bin 0 -> 673 bytes _build/html/_static/alabaster.css | 693 ++ _build/html/_static/basic.css | 665 + _build/html/_static/comment-bright.png | Bin 0 -> 756 bytes _build/html/_static/comment-close.png | Bin 0 -> 829 bytes _build/html/_static/comment.png | Bin 0 -> 641 bytes _build/html/_static/custom.css | 1 + _build/html/_static/doctools.js | 311 + _build/html/_static/documentation_options.js | 9 + _build/html/_static/down-pressed.png | Bin 0 -> 222 bytes _build/html/_static/down.png | Bin 0 -> 202 bytes _build/html/_static/file.png | Bin 0 -> 286 bytes _build/html/_static/jquery-3.2.1.js | 10253 ++++++++++++++++ _build/html/_static/jquery.js | 4 + _build/html/_static/minus.png | Bin 0 -> 90 bytes _build/html/_static/plus.png | Bin 0 -> 90 bytes _build/html/_static/pygments.css | 69 + _build/html/_static/searchtools.js | 761 ++ _build/html/_static/underscore-1.3.1.js | 999 ++ _build/html/_static/underscore.js | 31 + _build/html/_static/up-pressed.png | Bin 0 -> 214 bytes _build/html/_static/up.png | Bin 0 -> 203 bytes _build/html/_static/websupport.js | 808 ++ _build/html/genindex.html | 2782 +++++ _build/html/index.html | 104 + _build/html/objects.inv | Bin 0 -> 8445 bytes _build/html/py-modindex.html | 616 + _build/html/search.html | 93 + _build/html/searchindex.js | 1 + _build/html/source/QUANTAXIS.QAARP.html | 709 ++ _build/html/source/QUANTAXIS.QAAnalysis.html | 439 + _build/html/source/QUANTAXIS.QABacktest.html | 340 + _build/html/source/QUANTAXIS.QACmd.html | 215 + _build/html/source/QUANTAXIS.QAData.html | 1096 ++ .../html/source/QUANTAXIS.QAData.proto.html | 115 + _build/html/source/QUANTAXIS.QAEngine.html | 298 + _build/html/source/QUANTAXIS.QAFetch.html | 909 ++ _build/html/source/QUANTAXIS.QAIndicator.html | 486 + _build/html/source/QUANTAXIS.QAMarket.html | 1208 ++ _build/html/source/QUANTAXIS.QASU.html | 507 + _build/html/source/QUANTAXIS.QAUtil.html | 1454 +++ _build/html/source/QUANTAXIS.QAWeb.html | 303 + _build/html/source/QUANTAXIS.html | 272 + _build/html/source/modules.html | 250 + conf.py | 196 + index.rst | 20 + make.bat | 36 + source/QUANTAXIS.QAARP.rst | 54 + source/QUANTAXIS.QAAnalysis.rst | 62 + source/QUANTAXIS.QABacktest.rst | 46 + source/QUANTAXIS.QACmd.rst | 22 + source/QUANTAXIS.QAData.proto.rst | 38 + source/QUANTAXIS.QAData.rst | 93 + source/QUANTAXIS.QAEngine.rst | 38 + source/QUANTAXIS.QAFetch.rst | 126 + source/QUANTAXIS.QAIndicator.rst | 30 + source/QUANTAXIS.QAMarket.rst | 126 + source/QUANTAXIS.QASU.rst | 78 + source/QUANTAXIS.QAUtil.rst | 190 + source/QUANTAXIS.QAWeb.rst | 30 + source/QUANTAXIS.rst | 28 + source/modules.rst | 7 + 186 files changed, 51379 insertions(+) create mode 100644 Makefile create mode 100644 _build/doctrees/QUANTAXIS_Trade/README.doctree create mode 100644 _build/doctrees/README.doctree create mode 100644 _build/doctrees/environment.pickle create mode 100644 _build/doctrees/index.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QAARP.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QAAnalysis.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QABacktest.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QACmd.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QAData.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QAData.proto.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QAEngine.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QAFetch.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QAIndicator.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QAMarket.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QASU.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QAUtil.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.QAWeb.doctree create mode 100644 _build/doctrees/source/QUANTAXIS.doctree create mode 100644 _build/doctrees/source/modules.doctree create mode 100644 _build/html/.buildinfo create mode 100644 _build/html/.nojekyll create mode 100644 _build/html/QUANTAXIS_Trade/README.html create mode 100644 _build/html/README.html create mode 100644 _build/html/_modules/QUANTAXIS/QAARP/QAAccount.html create mode 100644 _build/html/_modules/QUANTAXIS/QAARP/QAPortfolio.html create mode 100644 _build/html/_modules/QUANTAXIS/QAARP/QARisk.html create mode 100644 _build/html/_modules/QUANTAXIS/QAARP/QAStrategy.html create mode 100644 _build/html/_modules/QUANTAXIS/QAARP/QAUser.html create mode 100644 _build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_block.html create mode 100644 _build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_dataframe.html create mode 100644 _build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_machinelearning.html create mode 100644 _build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_series.html create mode 100644 _build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_tick.html create mode 100644 _build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_trade.html create mode 100644 _build/html/_modules/QUANTAXIS/QABacktest/QAAnalysis.html create mode 100644 _build/html/_modules/QUANTAXIS/QABacktest/QABacktest.html create mode 100644 _build/html/_modules/QUANTAXIS/QABacktest/QAResult.html create mode 100644 _build/html/_modules/QUANTAXIS/QABacktest/backtest_setting.html create mode 100644 _build/html/_modules/QUANTAXIS/QACmd.html create mode 100644 _build/html/_modules/QUANTAXIS/QAData/QADataStruct.html create mode 100644 _build/html/_modules/QUANTAXIS/QAData/data_fq.html create mode 100644 _build/html/_modules/QUANTAXIS/QAData/data_resample.html create mode 100644 _build/html/_modules/QUANTAXIS/QAData/dsmethods.html create mode 100644 _build/html/_modules/QUANTAXIS/QAData/schema.html create mode 100644 _build/html/_modules/QUANTAXIS/QAEngine/QAEvent.html create mode 100644 _build/html/_modules/QUANTAXIS/QAEngine/QATask.html create mode 100644 _build/html/_modules/QUANTAXIS/QAEngine/QAThreadEngine.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/Fetcher.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/QACrawler.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/QAEastMoney.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/QAQuery.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/QAQuery_Advance.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/QATdx.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/QATdx_adv.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/QAThs.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/QATushare.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/QAWind.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/QAfinancial.html create mode 100644 _build/html/_modules/QUANTAXIS/QAFetch/realtime.html create mode 100644 _build/html/_modules/QUANTAXIS/QAIndicator/base.html create mode 100644 _build/html/_modules/QUANTAXIS/QAIndicator/indicators.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/QABacktestBroker.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/QABroker.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/QADealer.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/QAMarket.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/QAOrder.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/QAOrderHandler.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/QARandomBroker.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/QARealBroker.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/QASimulatedBroker.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/QATrade.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/shipaneBroker.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/shipaneclient.html create mode 100644 _build/html/_modules/QUANTAXIS/QAMarket/tdxRealBroker.html create mode 100644 _build/html/_modules/QUANTAXIS/QASU/main.html create mode 100644 _build/html/_modules/QUANTAXIS/QASU/save_account.html create mode 100644 _build/html/_modules/QUANTAXIS/QASU/save_backtest.html create mode 100644 _build/html/_modules/QUANTAXIS/QASU/save_local.html create mode 100644 _build/html/_modules/QUANTAXIS/QASU/save_tdx.html create mode 100644 _build/html/_modules/QUANTAXIS/QASU/save_tdx_file.html create mode 100644 _build/html/_modules/QUANTAXIS/QASU/save_tushare.html create mode 100644 _build/html/_modules/QUANTAXIS/QASU/user.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QABar.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QACfg.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QACode.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QACsv.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QADate.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QADate_trade.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QADict.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QAList.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QALogs.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QAMail.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QAMongo.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QAParameter.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QAPlot.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QARandom.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QASetting.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QASql.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QAText.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QATransform.html create mode 100644 _build/html/_modules/QUANTAXIS/QAUtil/QAWeb.html create mode 100644 _build/html/_modules/QUANTAXIS/QAWeb/chain.html create mode 100644 _build/html/_modules/index.html create mode 100644 _build/html/_modules/sqlalchemy/orm/attributes.html create mode 100644 _build/html/_sources/QUANTAXIS_Trade/README.rst.txt create mode 100644 _build/html/_sources/README.rst.txt create mode 100644 _build/html/_sources/index.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QAARP.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QAAnalysis.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QABacktest.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QACmd.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QAData.proto.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QAData.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QAEngine.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QAFetch.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QAIndicator.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QAMarket.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QASU.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QAUtil.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.QAWeb.rst.txt create mode 100644 _build/html/_sources/source/QUANTAXIS.rst.txt create mode 100644 _build/html/_sources/source/modules.rst.txt create mode 100644 _build/html/_static/ajax-loader.gif create mode 100644 _build/html/_static/alabaster.css create mode 100644 _build/html/_static/basic.css create mode 100644 _build/html/_static/comment-bright.png create mode 100644 _build/html/_static/comment-close.png create mode 100644 _build/html/_static/comment.png create mode 100644 _build/html/_static/custom.css create mode 100644 _build/html/_static/doctools.js create mode 100644 _build/html/_static/documentation_options.js create mode 100644 _build/html/_static/down-pressed.png create mode 100644 _build/html/_static/down.png create mode 100644 _build/html/_static/file.png create mode 100644 _build/html/_static/jquery-3.2.1.js create mode 100644 _build/html/_static/jquery.js create mode 100644 _build/html/_static/minus.png create mode 100644 _build/html/_static/plus.png create mode 100644 _build/html/_static/pygments.css create mode 100644 _build/html/_static/searchtools.js create mode 100644 _build/html/_static/underscore-1.3.1.js create mode 100644 _build/html/_static/underscore.js create mode 100644 _build/html/_static/up-pressed.png create mode 100644 _build/html/_static/up.png create mode 100644 _build/html/_static/websupport.js create mode 100644 _build/html/genindex.html create mode 100644 _build/html/index.html create mode 100644 _build/html/objects.inv create mode 100644 _build/html/py-modindex.html create mode 100644 _build/html/search.html create mode 100644 _build/html/searchindex.js create mode 100644 _build/html/source/QUANTAXIS.QAARP.html create mode 100644 _build/html/source/QUANTAXIS.QAAnalysis.html create mode 100644 _build/html/source/QUANTAXIS.QABacktest.html create mode 100644 _build/html/source/QUANTAXIS.QACmd.html create mode 100644 _build/html/source/QUANTAXIS.QAData.html create mode 100644 _build/html/source/QUANTAXIS.QAData.proto.html create mode 100644 _build/html/source/QUANTAXIS.QAEngine.html create mode 100644 _build/html/source/QUANTAXIS.QAFetch.html create mode 100644 _build/html/source/QUANTAXIS.QAIndicator.html create mode 100644 _build/html/source/QUANTAXIS.QAMarket.html create mode 100644 _build/html/source/QUANTAXIS.QASU.html create mode 100644 _build/html/source/QUANTAXIS.QAUtil.html create mode 100644 _build/html/source/QUANTAXIS.QAWeb.html create mode 100644 _build/html/source/QUANTAXIS.html create mode 100644 _build/html/source/modules.html create mode 100644 conf.py create mode 100644 index.rst create mode 100644 make.bat create mode 100644 source/QUANTAXIS.QAARP.rst create mode 100644 source/QUANTAXIS.QAAnalysis.rst create mode 100644 source/QUANTAXIS.QABacktest.rst create mode 100644 source/QUANTAXIS.QACmd.rst create mode 100644 source/QUANTAXIS.QAData.proto.rst create mode 100644 source/QUANTAXIS.QAData.rst create mode 100644 source/QUANTAXIS.QAEngine.rst create mode 100644 source/QUANTAXIS.QAFetch.rst create mode 100644 source/QUANTAXIS.QAIndicator.rst create mode 100644 source/QUANTAXIS.QAMarket.rst create mode 100644 source/QUANTAXIS.QASU.rst create mode 100644 source/QUANTAXIS.QAUtil.rst create mode 100644 source/QUANTAXIS.QAWeb.rst create mode 100644 source/QUANTAXIS.rst create mode 100644 source/modules.rst diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..2de924a47 --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = QUANTAXIS +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/_build/doctrees/QUANTAXIS_Trade/README.doctree b/_build/doctrees/QUANTAXIS_Trade/README.doctree new file mode 100644 index 0000000000000000000000000000000000000000..dcb04887322856ff4e2b9e4bff533c09c3f61f8c GIT binary patch literal 34289 zcmeHQYiu0HeJ3fBB2OYM$x$50cD=DqLlLxT0~Baeq)5;&1^Nhr)-4dU=>z?c zpauH-&+hE*9EW?i$D{3_qM`Hd%KV2bx7Ww? zasBZ1_ADyLJi{}!R8??h{e!D(mshVmc}cn9s}|~2&$y{6b;DAvs-c>S>p7~YZR{v@ zM{R0bwzJu$?$F!lWo?`A>aUZJwHY};??f=(QbB;%){prWH7KZ_=NJ{=0|SWQLq^R7 zalzrLsk$x-aXn@M8Fn>M^IOSHMXhc+TAgbA;IOA|P*q!>)=%k2^kMx_FwR*wbAI_6 zBU#-x+-or#%9kCrrd@mP{ObEIo-aAB*A7Na!_wLpM*Iqho&>7uhNHIh6dSKRH9RyF zchSK~&Njuf6%~V}fxVutfw6XVQ&Fv&QujUI(OjjeI-8nTWVKtmZK6#}s~V^wvgmnw z4s7vCmvzVXH*{7|GcZPsUp1u);V?BvsoRcHQ$1Cwsx9gqo!UyphomT~0$45Ea?w@T zW7yEtRLih77)Bu`O3Qb3MYA?QfBN~RZ+gbOsahMpx}hm{OS6(bnV6K6RnQf}Gb~SY zR0t*LzG=9=Y8o#<$ZSio>q^x$Fz_w|x}{ZI1Jsp50Xun%tApigqHzmQhk2-)ekb%x zzZ=?o5B|Lq|L()T`=LAfjQ*fLtIz50zA(ylCzO9^mj-2p_2Cvt9}7;*T=Hy(B-OB# z=QOppGsCUKn9+ogq#OTIsid&Nh(aaTxAUwc~*$RVJP?kN_+0eYC$IQOaUNzBpH`;|lA;f$y)&z&}WLtkM zIOID>W5bZTpCgsY1UAZ# z^3ja}=!MYHB#z@YUJ#sEEIm}(#t6e$z<#XR9*iq_gOk##MB;u1V17Cac_Ngo^i{Ib zk>pK5;))#hmH!rO?0VW;JrR4WOWa#M5u05D)DcF3Mfogq*<=k-2o6s%eJS zPpcVzbKW&x&}xbQ^E9>TmY&yOQZ4jnR5#5X$Z^Zm$UiG?RkO5tQUcgJ7-Apxy~!;d z2jnVShNmmKv7zJPnpU-aJYQ3qcFi|c$MAL-0pyk-`6gFZ4CDsLn5rvu! z*m9RFD>K3|(M4s)_8FpTwQ8dy*!9rZ8;)XcS&F4;H8=D$u+I*_v#5bgGJH(bi2Onk z2u0jt;J|}ohZ#qC6JBfzY8my}G6> zD9_^;)I!m11RfZi*d5#wfd8)okk}CmCc^AyN4V#@joTB!j{KouM=1Vks@9I8ZC5qZ zBu%c_2rWIMDjJQJsd_LIO;SA)Sl0 zk!7fAOuy-QL_`RM6hu5e6Z0Z7LR7<^U(uYiG7+vfHH+ayI$mSQl8sXyPqYt)rKWi*CL{_XbVWxym@B~d ztGc4Pk(CQ0%`_Ysg9uE^HjV0zQq@(*1I#AEXT!CvxE^<55F9mZ*$&uj8a9mz0td3K zA%37aWejeOBKeme*-=b1`e&h}FZ8O>$5R?T6dbAe&{(f*Vgi&3Fq8T2B-NBLr)Z|C zgJ+)COh}@pY+w%6f+D++RTsLmtXvI?FyY(0uFUc%s&S)q<33%E zn=21Je*VJyU$Ew)crgxCg0;c+&jPGjL|C)E_S=rRo8uX9_S3MF@8$7U5C@T&a z$JQ}s7^GAB7qZ4Z4rle(C^)1*l@L4`49}$q#7$VC^)#8e9gRPg1(iU35{*8Q#Gwef z^FrBK#b>Cn7~NpF$)#bt}Gysp0B{PF8D19`OBug zQEJw9$&oe~KYr%S!w)SjBC1)BEaZD0K6Cn!#l?ruh9eSNI{o!f;wKV|_p|jZIn%hv~txp1rlq6|;{gW0D*1qtQOqIM;>hH2!y|@E;1MOoWV% zYL?-ttD7moyYkJ$Lqk~d!5k$;4dy}XtA)CQa6BQAw^}Wq!`eNq*_YXZf4PP!8$EFj zD~#d2Z& zT!|Kae9J3g9_wNbl`g8PuAaWfYlfO|kBHfJcG5-k(#3PrCE=VfU1C^{SrC_Ld?Y|(1DfQ4T+ zeT`mQ(7Kf}Tfqutjk!CuHOJVpzFMXiDQqzCNI7gy;MCdmb4BX72+SGKIccXDI9gcS z0>{zgY6(5oHLt2CV>`=w!I(H+5wsMsvZtAI!1fuZhJ}D#c#tnIV}(w02nG0K;Gi~X z^opLng*8C8$ZD4{PpNw7h}~f(POA_Of=&itxv*4v8jAz8@)$N?zgK72|H`b*%=MK; za`|TQX?nvJE*C7L7c6M728yfOK3))op-0%y)tQ!KRJEDw%BHpx!j6kpw((aeoGx8t z@2#=`FA?Bo@nSJ#c`9WqRN^|wk*_&B;X@F6CFC;`ue4~8N|eJoE*3O^q^yO)PeMRqAtI?S z)U-OF8Qv^}jBvb<{gMV~o`;235)yi+TXt`l7zt~`E*q_tnWfWbON;n#X{Nv*;A)#v zrj^t0S)@PSL{x*78QndzxR~@1t5IlcNaWS;=%FOA-rL*&kXXf$5u6A5;c`Gy|(ip#(X^VA_ajYViaprAcZiH1a zS`{j{?9lUvpqR2TK4Pj=CRdHY>9lk-P7I`Jt2HQP`0APg+m<> zY&X;rQs~JJTK2?iJ`*t#IFd!q6E^s29S%J%;v&$3!-}G~pM6d@{t>*D3PNR-iQeOx)h;<(Rix7Wb2C9juUTmCqV_f!i2j&=IC@dQ86V$^ zOuttKF}FZv>d%r4M1MpbNxk*pgb8ILagWI$=O^yF5KL|yI@M)O2BJUW4o9zXIAQU< zNYph6L_tj~zgf{7dNjxphB_HXf?j?nlPORy$w2hS^J(#28E1WGu{Z*slEELW zSiL3#(I1J2qxXNDw)kEo>Nh121+n7M_nTyW|5SqCfaU62G7$YS{dUP4K0W}_I&m=m zL59g-CG6j1Ao?SA_$nt2S0W+*BZHD7C>LC3Fu~tab9hOC2=>V6ZdbhzVHU9%E^_d= z65-w@ftzOzA_9u2J3YhUB?Thb2PI$!MQ-EA&^h;ho%Fs}0(d|4Mq3UNdU=6J?^6=6 zZwS3tC4l!wFWXs>rZ+4Q=`|!^-w=9VkO1Bvy=((Xn%=NLr1upG*g?@74C71GaB&A$ zBHUk;z|BK0-e(VTzW!S>bn<(Fthw!1Wgz1|G&O0iHR@1G^G_aV{)mbCwsU^n34>gd>RmmKuR{Nr(O#rKo(5s=h~!*EK5 z#bBjuP6nbsLb*V(ZE~DOu}~!MtOWM{q-;cZdro(IES=oW*3iWbdmLqHorw8GDdyqG z1e0(4I=U*s=K$8xZ|m6N$T_yFT;!G~!R}yJ*MCj|@nBu!c(~1zbA;cDjQE@kt-0`^7_;i)60Hd{YLZKZ|#aFOc*7yPVg%D@1nx ztqg}=*e#G549{|axDp|JPX?jyschy-^ABa9aubs|W|QLsbI0+@auim__agu9kU<gyWkO zhzNdTPzdsus&V(-Ub7y;=P(>Qb{#*-jNW%7h#i3Dj?!l=9F6cs#N)qYc=Tf2VRh4A zX=LubHY|?92rfkg#_=U-=NsqQ)TB8WWuK39eZSW;GFiJvPDzj%@EXCK3`BqaJH6tB z?{mZBUm_DEtrIzaR)$G0L*Efj#v7J~JGU!6A%l?5vroofR3&l~qzd=&@$`jD#EIP> zyZn?4t=xoXhMtBDM1P~adsYw;w!1?X`bg?nW9N&dcFYJ4!_az9Kf}ahE>6|3aobX0O?*}sUdYrNJKI#(%iPO$u zzQBZz&>^OxvtkcMJea(KNxS6KjDrqcV<%U|gPH4@7$G(hyi-Cjw;DVnFH96fyz%!mN(v!f#{o>uA$V+ zGH`>X=rb}9eN)s!DD@=?K*9IyYbuvDcwdn~&f|MTQ5>G z^d6Id9TdIU5!*W@kn;>Rf|Z{4I3MdgH>>e4KA~p6|JvPx8$s(38i- zc3h0|ciKct#S=#iW$KfM-AZXk1Dc!~;c=!`xbAKq-W*McJ< z80>JdHgQ{sZhgnZ-4wC{vLkJ&7U0H!m$TCjPSkDNqj5=9UKkFhC^0YsobonyXf@j? znI=co!g=cK;2IZQ-Wir)FX?Q`rqtRLTWfM7VO=QRo3ObTw z^4qcCxVDXB;X#e(yGiL-O{@4D05^^E%_-$99n_4(Vhq5vFC(t+5-ZD^qmz`jrC~a`NLq|#B*n16m z+iC!XJgVTuIC8VpK`OXn)XLD`y0P8X$Af9r_i%)GTojBL5Ui=1-)xm*;RAD70i6@! zAb}%wcpEEW88t`*lA@NY`8B%?bAeXJkgLviH5`?dJjo=b>Xnhc*Ps)x&{r90v($>I zftU!(!(1u!x!@>>LDm|JB}YQ@si;}GZkQkr37n@}TB{uAk|kV@QVAW}Uncnu;w&6n zTU({jzLjieW1*(qTtG{Ap&gv0C#XkyqKqAXl%o%voYnq4NPFAsZe6y@Ikqxk{){t?W<>G!NIHXxONg}Y_$3sGJvM2C4Ui%fl z5=?{!0tb~quneTPg{XVwFjX%TgX4e=LGf^M64-_F&nV@0a6%{zvwNc$z18CzN_I<$ z!BKvg3d8H!#+RYCjW5#AYxMJZ{P^KX*WOMG3`NFc)@F^>ulf4jR6-BvM_6n9svk_H z$C$yGsxnsvBmp-pAwA^nLSoV-VLM1VM!H$C%~)($)38TTDdDHx9T%FzixbBbr;SgtEjh2M#>>k zL#|1il14aQd~8@&6EO^$JGy%|llHw~dX`g-2UxqtIzpEC0Q9x^0QBC&fX>7!sXQw@ zcpY@NBEe_75Zw4I$?NAxUgHogqCN?rcpSzPbq8ay?;R!ihB7?A`rO)+Ywu6;){9Y0 z<6Xd`BSu3I)VLqToWWQ*r5*jr$baEk$A%$mB5^NFpmr1P82Ly@nJM=$3p^B-0EhcH z%IM)kR@Q7wLz->+-({dTqu7-Oo?`h+EE_q;&|Ss%G-W34&YdY0K1gTiDd%yHo`DSX zbtGmce;Q`BkHOx{l8E0M%idcXNl_RsbrA+G{m*u37mxpN5RL!nlWR{r6A%7)_rV|U zHu#U8V`(;#tO;3G5TS%gtPwpas#3v#Z=%N19)(??G`Da_HC)2jLoDL4*;gMT>+CKp z;jA;ew2N6c60xpv5l;l8L`?g_JLHT@rzgLo8{qLlLxT0~Baeq)5;&1^O_8HZ2ge=>z?c zpauH-&+hE*9EZ!>R^IOSHMXjzoTAgbA;Gn0jQB_-?)KBV%^g;bVFv?kX;=g>#HLu8OH+0)Xo0e8JP(x(U^Yk3p;FYfEj_t4M zte|FKOc;M^N)^IjYK~I39i^svs!~;3)Hyn}m5L9^P*er5TDIk)tFXtgp{c2sVXZNY zLQIsF@9K(Xt%3gZ^G)CMj9F8))_iqMQ|y*zC4DlnC@IUJD}-lQp5~|!LePEFaDCM@ zUV%{AmSWeHs%c=LT?TYRtGEWJD}@4e{1#XH%hg1~<{0{>4&BVTFr}itc$WcX4j6qSn^5(uP{En_9`R=eA(=RLk|fxmc}A?#;DxrdrX= zC5Ir~&y3d+gH})$J=Iy$yrjp>zR+GZ(Re%Bg+d|3d?(ff2k>NDKNlSE9itsQ)h7zt zL7@s;U_cj{nF|Kbwe{y*8i-{Kz*0CED_MgUjACpUQulGBGMT_e`B6T)F#x>~I+nyy z+{O!nWAmj4OPd&B7z@~s72AU`CF_4&T9ruLPXf$OWFb$4l2yJ&RymTq2}oR#!@l}o zf{k5Gd#5L3?{t}arzc~xYrwjQ&P=sbbIV1!YnzZWSRyi)Zc{bQ(E4dL!*9;I#w%Ja z@pqo4Hr>)o8ceE%{*3Cnxdl0HnHu?H#jR?VHcLtXdj~`8!@f7UrQ?8HWyA1vMK{)T zJY3VNwvXp)O4F|Srs^2p7DK@GAPTBeV+gby8=k^O44}lipfI9Pvj$u4l4WH^I3~KN zY}r0TRIOHRbOgH|8hgW0>_X{1n&jUY1ClX1TPRelxLS$lsV-k{DN92x{W{s zgA==hTLSR^RR9t@V!=e1yV()$xo+e3M6e@&AlMO#znZGGrD&T~%`{1qYc@hj&!~z< zqh+cd%tVt^j|919)FVe&R92Uv!452g4ZrAEP-sZ6@3D5ii*QWaY-wZ}sv6U8dL9uG zLLmhakI%%s$czxxuqT*;!dk#2RkW~oyX6_MC|a!u!xdJw)UB`%Au>=WQwB9BTVOGb zr0zQPJG4xM>rKsKIFXLm7_wyJl*be8gJG#@o{9;Gf{0wv(GKPc@cpW;sBUEC!bmd> z2gV=*)3QyYx}{Wg)$stciSXHQZ7Z(FT^IyM4O_MYHk*b`qk_PJY-@-gXigb}Tcb$+ zsp{almoyWSs3~ih zL$#pDE@ah(?kpJw=6vq>C^pj-dBm@U_zM6AfH zyW+Z!8}HjnKi_CeuW8)WF9kDG40A60_oWbOzWKAqL9CA+H0j|ZJR8;yr0lw z$vU|+loYG8T7hF<5v1q*-kHHgs~=s7a`$Ih5|GH<*SOq)wC=>~IQa18tj>28ug^VQ zXR*7k!uL{Ka>J)!1j{u^eC=v**Vhc!^|h3h+C}PEb9V+lR0&%a6$mn-01uG}Vh%<1 zl+{(`^w}RibLQa(7v>SwtVR~{p@+|$eq?_B;j`h0#FkF~cDRsuJXpw$bxN*!co=N{ zXF=R%yA-#O3tX~tJ|zm#zh#YcB1Heeg@_P79{k82M`tyvpz%Ls(JPnh zojVUkL*LyF20z5sA>N4Q{A8fn8UVO85EL+-w-6#j{?i_OVk!L>j^CKk`Lx6DQYkeT3s&G9facviM-Wv`8?L{Y0bXO7W~UKOxfs(^H^!T=bn2CFJaXO zb2sI@hG;@tETknH*GZ2t(=K0m?(vJ|Czd}ljh)tcty}s#LAv#&H&rzoEjDaw&6j(yo?n(%^?)vkAZ{Qq|qyS_6F7f-6E@9 z#5|?yp(A#OnK-RNI0!l!fW^W>=~*le(8^=jfc;*ZV*e|%HdEJ^=E>!o#b@b_TDV-W zh+eRu!5S#8Zu@va6owvQKi8&Oj#1U7t}E->RtP&TTH3^4p>Vo%iM_YV0=z(go5f4T zkmbejiNcu@)@wml1Ye5tX?oNxUM?v3+t3XxJOJT}kF{4Uc3^#j7E_^K3PY4N#ySqK zgi(p>AV$q6Z0Fts63O@<~iG_%yzEIQZfM$5p5HiB? zUiM2Gpm`n^UP(yk9d6mZVPYh#HM?xImZla?pDoSfzlEs+e}JoPN|}~UKQvE&yosm= zOH;agW_~{DAy%W%){xRIU7KP(EKC){i_^Gx7)1;7>|)`Od8&GN{>;L{!qjyRDAg0! z)1|4?^9yHZ=g-XIiEZt;;__B#NTe}-G1C_79^+U=EaS{u!`uj~Vzeq$ZrP#d4?!_y zV|>I^sZ6dKgVSm0Xq*^G(^hLx%J5Y+1ITYUql9=K`@uPzMSey#gcIs7PGxbD&n(4x8h1cP4!r9$WOGu$7J80Pv zuh~q*NZ?2oIZxQ&t93Z^xQL5D3l1xa;s%0I!(#9GQ*Sj#LnqFI5`G&;8Z5ZFDhV^D zgM%=a*c(x62jgrrLJKcI+FHje*2arrr1Apmf>t(^RP=}&L@{Aq<0UkSmmtRDpn#*6 zDiN`3O0gSeyC8Z-tzo9|7I7O=LzaRXx)iZ_O^VIld6kLK>N4lj5H3Z8-jX8J3wsJl z&%q#;apWU6Oi?07C%h36`ZXy+`^%w}@I>!&QzasLe<($-7k;HAJ!|y1&P9mvTM?^o zO0n8srX7cEJI{m3II`zMyF;yr_O~Ty2O%%jJeDGhf0^p|JsAQq+xmyY>UqwWAzX?~ zI6Oo%VsUQTEfWsF4JF+L>{hOLSAYA!z`(89)~(srt=ZNO&TK0(8n<+p787o*l!)_z zTPr0_=jzV?rInJzEwf3IBJuK=Bt`42ZS2CvI*_&24h~>{`|k6k?j3({l;(qcE{J6V z1A8~a4U3W*F*JEtiZl;)Y4aYI7i?#DbTJ=@dv5$Hf-ZTG0^+qg$BtdcPcbGwBf%$` zX!b2!8%{GRyb6W2H;4*$7>dDrIXbu!k$Fvm3}hMGL)dp2kYz|RzN*-Dwx1Ivik&0T-5y4NT7pzp zVYE07gM71PfGd&gUzR}_!&b9U39<)3go1BU*vcp;C%zXU{+1e^&xo zYX7@dp3!gxGNCZwB|B(zruvLvdf3w}w0lvzLk6NZ<{yk+6mZ7J_af8pkwMHYP?`F( zAOq1GQHN4*Jvd=PnMm9@8RY!LeG7ugjYFrptjIw0M%=;ZH4Y~%z88slSprc|6U%Q_ zGzXu)(XRS6T)nGK#*v_x-^pYO)N3*jz43ffd{@R<-&rhHdA;MZrl`i2ZdZ%n^k@`jHOfV55=jK7y*(q9StR~d-j zh#kDfNyC*$$bZYArnS+Rc zBI-_0ad=6A2=)O9*nW}Q_#t%8yQlG7!BHdpNz#iBl;S zisb#11oj?8y3dmKKN9Tv99$h9+3u2q-k5(h4zBoqGCl&58gUp-%CP9Kl+DOM^hPKb zD7Hp@9O%;B@p-5HI9bcJUK`Bt;mSa%Fycn?vx2(uPH~Vqg2G~ z*JYS>V`+LZ?HRk*{-{?xgtX!gpj4dY;N=t~7sN1}Zl(nPWCS+BbI`uPjGlb$l=K?}Q9ue~G$Z2BJ4XJQ#fz z!^I)K7m0dM1~E5L`fu?WN$RU*_B!`*S^qhN4#s4dw!0^?9Nq8W#o7CAVP8CFfTTub z#fuVDW1sXMc<_b}q;j7kbb{=6!|C+5$-yb=F|1mgbs?32m1e*T?Gq(}Gy zKb&-DH4z#1OA_=E%mhs=8g&|yu z2#n%O(#|)|)2T^wFw8z5+4cQi*T`h;9yuvNrq62xGcpjp`S0|K6TZ(4kAI0wkhD(Z z{8ZLe^HglO^_< z4ccAlFaA2dWaNUG*+v}7-;rUKpZKhy{E7_3{tP7@9?)s>d$6)uFYW$T2BK$bcJ-p) zk%7xUK3NofUk0LQiZWGgY^*Qilcj1WWFUG|wGnnq0avQ%PE?=!WYBUCPcSqSNBDFp z!gx>yBggn4o=Um3xbJk~PQK2FH%kxUGJcfBnID#+)&IrAOnJH{!yz~OGyQEt2BJ54 zI*~Trsqe_SgzZ=_GJaErQGTMcO!n(C5IICHhxdI;1}Z-_SqAP4G7vpev#ZJeT^YFC z6z#mK^~bXQdnRXSDc;RYm!hcsr3_SW!aq3A#T-{6l)sZe5#GDy+>HE zoJM?C0y*az&qO?ppaT{X%7TuHolI=jq;Y6`-`(X=8HnCS_fmV8Rahkd7NQ5N1W z!zZ`$G_s6aNd}^K{mB}@$7G=LQ*SS%dew1acnxBUrj%aDkJFE0M&vB!K!xVlY(vD2Gg!BIqwlK=)4Lgm7LC zhuTppBJd>%0s`&%_GSw_&-5;TDgoR(Z z$ax6HOyyAO+@qv-v3LhpI!xyzapr_KB6{DGq1WY%rTbAID@dGn4)X;jbc7Bu6`d73 zFyeva6-?SCr)C^<=o&k@Djv*S&%_9^iQrulf+27D-!$!!?97?syadS}R)(@x9?r=? zyoaIGB^f^XU3FF{^|A~^4p|qpD##qbh744GYO=iXmJCGC)a)8cy)FaSUy4301JN@@ zU4&9!kN^~X&z`1oS%dc_3FJJ!M-;`uS?)-1C7Qdh$^iAG=8ez5A@QkcXTSYMHc_N1Ob8e{fgLz4(-i%i$atHXc5s#fk^KW3D|zon;o%z zKms|>P$O9BdXMvw&T}KVifykD+4GPD$$0P2d$2d^X$e02u)|_fJW`W$tFu_-)yopx zVqWdbJ}FZIF{cRS{Oo5qK2;Rr7v6|W_?Qf(E(3k>GE#}WC$ZjoSo zvuQ56?Bvm4tc65znsZa5!}c4`vomOfTzel&r??0vH)owN$KR|)IsR0hAd;u~i)xjq zHkCGV97n0M)T&7mzXa>xOniL)EW3*G%g)C6WoP-GyV)eaYyv%bTujatKc1xPOF!O$ z-hm{y3uSc`4N}K~wj5=RT?r2J5_Wj(N-!3kZGv3AN8{wZ zIQ0|X>svStcJxKnL_&|`O!>)`V0;ak1H)5Pa6@PG;rQ@otGyB&3c+B9i?xp1LUijp zChjJX6_6ciOSJ$u0=%59c5tk2+a8Tes`BDsFhPlc5#W?Ju|uobM#&^Osus>uX9w4~ z=<=?x1S3yJ*|=p&R#@g)b^$SZAWFLn;vJ37!Y`Z1X=@@wZcxyX9FyOU1V^<^919O> zJl{=9M`~KdUjw*FoNrDkXX&73BpyS_I1W#)YIIyv`;B0d9kX18eYaRy)*Q!n%3*>s9FV{cl&T_m?`_D#hQpduy^OG4+QF%gnvO0Se*rxWCc}Oc z9Qf0BixnLY2S=f9u9(TOSQ3Ro}xA;&D+hWI(VcYJRg-j)f1*Wd(Fjgo6Z*)ZuNcgk{tq z5lD(!uIAV5GRy^99YL--+tqMXR`Mj1l&V)o`d))hyh2}Pq|H(*rUqgnEDv&}&}V|f zAO=}$ES4Mz%_pK}<+@>lI3#SIY-z1>oJ*E)IZP#VXn&dHJBYJzY;0_lLi<*-owd1| zc5@Cb-MMyfoSvW_>4`FS{85fRaC!{ov-izE2)0Z*^=bzgDoMcH%@c5VHl^4!G_TIU z=w8zVh;dJ?Kn-f1-o7{%oPxqM%dvjN=$At)`)2SyhK*st)Kbn8NFDL024Oyg#LV$6 zl<$bUh0HsfWtIvQC)l$*(>NTy9UMj?Qs~qTA1dtP$=lg|c#AYqRW;(^Daxsb+&wth zn&}@#jBF6gYT&opZ?fd!EJtpn@^3;&>?)m{p4fn6WEEV$BDOoC;g}IRKYa_ZbWQWn z+wm&)j<1)sCb9vR)fzI4v)tQn1P3(hCP@Ug`*=tIPWA*o$7{dgSAwz7K;WPf2$q5L zwh(o%9H#1JVsI3&At)YBP6E4d{u!nC4vq<>VK#3Rqqll|L&?^7n2*zL~ z;%1Xby$I!sHf>XflmdRz-EyHhyf|@8ahmufOU}tFlrCQJVWb=qHRPJKDQSe`#m9za zH4($0nZw&>Gil!&re`_XxSzFatRiHI4?tgu4?yoe4CqX(lFGBfgV%m{D-wKm7lIp~ zA$k2Q$!i>p`LoIH@p?F&wC(Di!#(b<|keqYw?sbPAhP!zJ_`QA8{n zd+I}E<>g&i$z|vHUD|EqUgHv;2!@H6_QgBpj7w*zK7pt?I2OB9u0>2+55>jI{2>nk QJ1`P~_eYw(V)R)|P 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

F68bP=C)@LLF7+ zokIPjajTMEKc21E!Ja}rl{|%dxO*va-jdmE0q%utH{kfBBVB1w{RZ&sBrY}>@-fJr z*~cJnALsnG;M{9~e}UILiDoY!v(YzG~YB+pNwev$k_bc=204JNF{ z9wsLo++y6Q)GIdHl88r+At@iNV{zjXHVC=)os!1Vm$Hfg>~+S1Yxyy9=}Tfo4n=M> zW=DduU`t}?P+pTBuOYOD_mh^v1HuhgDl~VJwM6zDt|kz@%UFIbM0Zl5K1VbqgbeDO zF-H=p)3zjr4l0^}aeXj6iwh^n=^8rs7?nPnC@w%eWh}22h~#`NVgtC4!CN)vL;`Qw zmc-D(yISg79K4q6J4Qxa)Za#k~(+qXgn&e*Yk{gWKk)T{_OJe9yUM6)(zXUg@ z(;(&*7VzC*EUZ>Xyj(db3XWyq#*7(}fV<9?#L$70M>m%3?$j#x(t(Xec>&+7vB+BR zsYkh!lY$OB8`c~dRn|BC)S`X zNW@(HSU(Gca2wSl$`$az?^rTM}_E`5ghvpck&?1vhTcg+{CFwu;U9 zo5(;^UT{m)I-0B|hQog`mR}1u^@3Z19mb99fWL0ckp$}3Y)K3qRCIccPnLx~{5G68 zhsD&@Btodmq5Q#gO}3!AN}zk;1%sJtVDHu?kFTY93Z;<|KF^pd3E>^KBwl8OmnwBz zgrO>d@LP-(q1Au&5Duh~5q_gFR}#Xv*pe7J!d8LpF=KJGa3XI-ihH7r%ss|@NXUGj zEr~QT7O`m@-ilzzf<(;4PuLCabU)Ip}BgW$C=rJd>{RQJjC7u4PEs3~?d|1FT=+G7|)(B&Uqid7P zuux70wHoC`H2Vc(k+q;A7k4n`i+ONa3lcFGr)|AP z5S2ctjG_h~m0pyLO8L7@=%93S^v;WS7{f$c+k<&Q=?@q;B$?Fra}r8*zN|s%3&!H< z=rJcKea^U1NvF@)l88IVdj%|m4oXps!fm<0e=F`n&Mz*;z~43&SPLjJq(NNEUiLSP zS&`uTRa+86hY#K9FBEb6_yoN1uciP{r-Fd+E5<@=K}fy?AjP>1;+Kt?kwE;CEs3Fn zh|*|6RZK#H@u5cDT_s~uy($98%@+-3dVvR@E}3~FaW6x;!I&Kh%C)v6h7Kj+A8#MO zz2mlM81st@2yZYJSgS8)xYK}Z8NM-NRwVeYvn4Tf_|Q}@v}F!oalE_?uePSsaITdC zLRi@0)sCj?2|Q@im|X- z5RwUT365ppI>wAhz_n~i3>`Q!Tmj&UPI;LG59Jmo^ma5^Lm>D*W2v)@2l* zHfBab@kv_}Lr0PBQ68P)pI2Cb_v^;OYJr#C{XAa=?pKT%k%0SUTM|PDj_!UP-*Z~@ zNT^dm0Qk4YLTdq--TMURGKgO^W<~<>FKtN-9Yl28Ep&-@!fW112bx=2z_*Y$xX*XK*KJTldeco>xLq!|heR=!5 z-!N`SGOK^$B$O(BS@(HgdGTOo7g&!u`@GwY8&h)5fJksJKLL$d65vj$(F>>5kx1WVog*+-$bvbY1a~H9yJzU z3r+H16eWX<>D|U0NtoVYOJeAlT17QKXe^EvMwe1iO@xsQ%-fCGkbt?@mP8sDi?Ae) zY{WolK_cejA8m)@AhPKyhhgPFV0~vMI#Y4TX&ralbXc=93Tr-Uj1z5f-Mp~o7mXW| zZ0hGY38g+?*0AP(7>lQ)$DFX{PmLRubo$4(B;p?OhXR&Cr>~)%cVWzh-L1xPI4eBi z)Z9888YaV=>ykV6sNPYjq8J(fx3Lbiu)7Z3M6|@axC+?W{&#P6{s@iKw92W|~hcwHJqTtR^784EoC z5CtPLh^{d+5{UD*Bwi*Eg<%`?L|j3D*fkb<03ZrRWDp-QW<~<>AzKnd2NA9AL{4dn z-I+pSs8L=(_|wKBYe7h^?qI%U1phx{UL*v6(w4-~5k#4%SQGo4dRgUB^{WXy|HN1U zT6mI)r=%1ztbb(8k_77?*phgeV4Vg;8%r4>EDbAFO~CqXV+9NV)+9SJtlu40ap<&^0JERFI4%d)Y^ zT3BWWNStpOLC2UE3BmttOJe8URLg@4t|gN{N(oB%pAQxeM_`IJ$Bh(=1R+X`_tDM zHze89HJpS}moMx7^g(0s=q`)(n6p2<-?&jpr+aNl#Jyuez%uClX_Ra+Ggnx0Ds^&2 zHmjf*^P0v&YJqbxwMiLpDm&CAV<#5|BS@OJe9iqRUZ2o31q=D~9x-Xvro*5tSDZe!*B`EeOfW zR1n)Tet%}niiF?iY)K3qKXi~kR0K?;Nc7OL;|RS(X@T9E%ZCx^b;)D@36^E#zGJKQ z#6_vLB!-S0=|TaE;zC97hE4QV&Ln*Bp43Dg0peA|0Ws5uhTO|YUSZ6Q)CVuKB{6g) z$&jX9A5pmP8s6i&d_8 zp-e2VSdfUhxXN~14i?H*l#4rqUnsjUxllIOuGHwIvOUpK*{6(Aq77{&Z>j7P#tlgp z^;?{TQkyU9QrTCG#naJa&QjTzjT@D8`XyTuasT)$0n4D5%FuLynKIm=INoV{Z{-o8{=38u4BxI1YFCO#L$5wyO2-cVVYA`!1g|4QMF*pa*`AN zvW(i(#(YSqJ!wl~=%`UW2;MVD=M3f*7P$Sov9MaWWpy{ku?*a=7&9UP_sg~O!-7hn29Q|`jxCBQ2bkC$+b`t$vr~JsA@+ zaMv0$A_4bmTM|PD4(%EQ?&l!ec&*$^4}Cfn1b|13h1LR)+%!mWE`xZ;m>CJg+iXb; z9YnH2H5Tb>qVft0@Y=@0YJr#8`+#E^xD&>VNWj%?NxUq;9dcl4cd1eC)ZE^Ky?6B9 z-rHII&>3sibSdDHg#~a=84KGtaEu8VxF?Jmk$`)*Es3E6hjJJK=L4^BT5OQW<(3xE zeau)~E$GOL){{KT*nQNP6A8Otv?Vcg?9jeUioI5?8Un+=HWph8Lo(qZ z&AW`_Ul?;E;rMx55<|z4@`p!i4gJYNvamq!tSevg$pT|S2JQ@FMkL_A`+qHPDBCYE zVsXNp^q%>}1$aA+b*9zz$YejnwG7|Y#;i#2U1>{V==~05Uj~Ypaog=mo!(N=C@%m! zXe_c8faC#N%(sl-eq&xF1ozsK7&?N~s`JbVI_k_RE0Aj%i>ifO)(SQ7E2Fk#%!h

d^B{$BD?|1jTYV=ECD@V} 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

D1Aa%j5v9(jj?vK4^O-oaE7#!^_=$cqa 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®s;eC3u~g6^1VI}S(ei-MyYJ|w$D-1A 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�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Ƚ$rm7^RNI5u^3CR49l?+ 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͘H5r$>3MG6$G$=dv5d}O9ht%{+nCT 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

?coT(%lXGZRg;B3ML4igjD2~N&WPcK?FV@>`! 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 ybH=&gko*o%Lr7$L6%v^S^G?nTIZ7_vDRtYE5X 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 z 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 O`)FQw235B{Hu4`Q-N+6A literal 0 HcmV?d00001 diff --git a/_build/doctrees/source/QUANTAXIS.QABacktest.doctree b/_build/doctrees/source/QUANTAXIS.QABacktest.doctree new file mode 100644 index 0000000000000000000000000000000000000000..1e7d7753007189b0a98568737f97f8698d4ae546 GIT binary patch literal 73214 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 VY%`jGaYr0|PUfDWr6~6G{9jtzX1V|X literal 0 HcmV?d00001 diff --git a/_build/doctrees/source/QUANTAXIS.QACmd.doctree b/_build/doctrees/source/QUANTAXIS.QACmd.doctree new file mode 100644 index 0000000000000000000000000000000000000000..cefec6858bb5e1a1b87f777aa32539235ee20f6d GIT binary patch literal 30628 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 literal 0 HcmV?d00001 diff --git a/_build/doctrees/source/QUANTAXIS.QAData.doctree b/_build/doctrees/source/QUANTAXIS.QAData.doctree new file mode 100644 index 0000000000000000000000000000000000000000..98a4ce620b09979aa27d0f2d111af8e2564580bd GIT binary patch literal 205141 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

FY%8o9vumSw6Vdg_e)QYXRrf~^x;}^+ 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 literal 0 HcmV?d00001 diff --git a/_build/doctrees/source/QUANTAXIS.QAFetch.doctree b/_build/doctrees/source/QUANTAXIS.QAFetch.doctree new file mode 100644 index 0000000000000000000000000000000000000000..0e940a1a3e0b983874250190b0597b767a79f7da GIT binary patch literal 264261 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 Y)9K0jX$qc-I&qAkh11w!2HNNTe@R3))&Kwi literal 0 HcmV?d00001 diff --git a/_build/doctrees/source/QUANTAXIS.QAMarket.doctree b/_build/doctrees/source/QUANTAXIS.QAMarket.doctree new file mode 100644 index 0000000000000000000000000000000000000000..2c75a341df38c5e544a1c1731f430b24b2151b2f GIT binary patch literal 304064 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 Hv+e%@jMN~Z literal 0 HcmV?d00001 diff --git a/_build/doctrees/source/QUANTAXIS.QASU.doctree b/_build/doctrees/source/QUANTAXIS.QASU.doctree new file mode 100644 index 0000000000000000000000000000000000000000..02b4d0b884de24ef82cb0492ab9c2b8243e9673e GIT binary patch literal 116317 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

DET?&Foh*m!<%P2uBf)A{=q=^^DMq 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

j-@g#Tv-i*2O#1AWbARw&@CCAoG*|W4jePc zj6IGEdLZHeL>z#~9uUP0h;#xG2O#2r9*ANFWbAP+K}H;aXdHlyJ&qZAAfuCW2{OZh zV+NVA$GJp(6>^E5J9$L*&;waSQG$#t01+b~Vgy7HL=R+ia%MqBjDUIw_11by6M~Eu2|6 zlQ>W(<*zgLI4;y>xidMlsLS#)8h6NyPO3)q9h3!v^h_XPD@bD|NMj~Q*$PtYf|M-~ zWq}|aBSAVwf{Z<4D>AE7vrc4&gJnzWyYy9L0f-m@5hEaC1Vq-+5oumSC)JT4VgzLD zaRec=I*Acv#0Wi*vBwdF%y6JOlD^7t;0QuS_OSb;X~CfUHj9V0P5f z5gB_NGsuii&Me3%WL<$6vvk1LVcB&QBLSDNG)-) zIPU^sfg(mg#0ZG21CdT3;s8V(&;wD-fQ*(n(>m*MM)8PZMtzl&aa_x_Rt@Z1t4MsM2vul5fE7iB1S;Q0_PI?BV&&v2$|8z^#>U- z0y6fv{;12s-~k!0IcAX2xC0rlIeX9%k=H;JB_N6t5a|RWuYt&GAhL)4h{her=;U02 zjG_c&>~WOP0~wv1OOP23JWD}FF#|FjIF}$Z9Bj;ZmO_6-jDW}j5HSKGMnGg89T71C zqEP`NMnJ|MM-VcrlSTzHVuT*Z*y9L7W;k$WL1s8`1R*o_I7;Y`h!GGm0wS-0NDB~o zjUI@+1~NK15|B~kfyiqhV~;BiJ&@7KxkP;x>JNyb1Z3=SBp@>!D3{QM5L-cdCJ>Fg zARTu>YF&_87o=-Rq__0oHTJEV zgMx?y5ZMEwm;uqK01*cu;$Zf|+*dj4oLM-NG7E?}02zB6GxR`)17{Xwh6Bfp`YPuO zXBPEUPR5xkR9E!Q* zQHYsG#$L=NFEbosE_s>Z5UUX~WC2+KA`3vo2#6Q~5hKb8r!(e+M-)$-NxlFPcZ{a7 z9&^HJi8aO<7MPE^;}+N z>~WOPEg790CF;4H7LF2R#$K!(f2QFOE62&=It_$wiL3*WP9VxUAmRW-F++c3w8UB1 zS%|Z+M>Gz&&e-F)Kt>$U5rtXbY2lbbM&k}-baM7UW;k%nAR~KN@F{zM$ZH_707Ov& zGFmu$Fo{u=WJ=3BH!uP+_PE9%Bd>ud@<7HOM+yCr(aG6EJ(si2QKFv9$vAuH%|FQS zA29+VMnGg;PFA)+#0ZEOp(8Taag9-5B?@(Q^2q4qNT4G!esaD*X6$j4AhSA+pPVoB zjT1u7#07}52Z*uD1ty_9lev$$$17DjS7&t zj&lhek@1tG1Q|sM$oR>*1ex)ZqeSlrVp>2Cq?s&8tqW2{g4DVoWh6+WBuK3bQnoA){3ry#@%&dsm=lnp2O^z7q!WmA z0+F9Uq!Wn72#CfA{ZW`-oV{2p9#LFyCgmCRRsKw4kK;mpl{=H;LVcB&8GEr-yv%Tj zwc=!Pe({K6Mx7L7)Jb_nUZc;UNKhx`&WtmPM-+LSNnQh4o#ZuS6nXSH#vW%6WJV`f z2V^wTK*kMalSxCUIUTWK*kKF8SO8iUMm;Ov3SaNw9hX6$ihq3a<=K*R`$7y*%WAYueW7J!Hm z`W#{eWbAR2Afr(MB1S;Q9@ihb9;1^pi#jO`ERf;A5roWe;LM^=R5>jiL3BN29f&Ld z5hEaC1VoI0$T~VAqm%OtG8z@?q~IBlvByz@j79|=5seCvvBwdF%;@AigUoQ?2tuaz z(1lP=08vf|QtN^=2L&lxK^j3pYF&^

``sY$2mLS&)vHAZ07a*dw-((Hbs@IAHf{ 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 literal 0 HcmV?d00001 diff --git a/_build/doctrees/source/QUANTAXIS.QAWeb.doctree b/_build/doctrees/source/QUANTAXIS.QAWeb.doctree new file mode 100644 index 0000000000000000000000000000000000000000..44013251e9798965b77aa62783440bbde9e383be GIT binary patch literal 52847 zcmd^I3y@q@nI_51WM+~~9xwq00xclvKr#uz@ECTn;s!+`BQF6`igR)@cDZ8w=TkDpVTUJ?Rt!tS{VDV9IxvTD$yZim;anF66 z?t8n_-CDJ&O3yv#p8KEw|IdHE|G(#+$L_wp*?&5U{c}dL#Z1-Co?Vt&QLkMqf)GvGe+Gx3MDdTE}tzMh5Ge%^C)Lw#mLyXV!gI?!W-c=4nG2i&se;uPO(cM)4`}OOG&!{tc*iU^90Cdu7b8s z#{akA|Ec)@R`6}EX8fK>{F+H~jd{k_e(wX$a7ERXmX8N=J;a8j@QPSakfcYFlY&aP zeDifFYGN*)lx|hHn75QGuoFpd%zT$uJSk96A6q>77_3e?ODiQaSJ*k8&Sr(t_vZ>( zW2eVVxdk`Ww6hRKSI#jzO2RU7g&A16b8-X8l3W36>dq>DwN78KZVpV^^)$8PHBi0a z+qul}8l3y+b*%s3m$Wxt+BJcmTLD*vnM83q;TGfF48N?HY2@?8It*hTjPhD(gsq5c zW}Pz_mE@X4GFK3d+n_#(d}4D>bP`XRXH0^7k}o1drv~yb^!Gu}yDp#;7 z0nO02ZItslfT2=*gt1A=kLoD*6$|-YVOnV8l2ORQ^iw+l;^6{EIRm)@L*o!1qt4(5 zIEY_g_bcFqpaPsF+jGW_3>@V;(Ari{2hsOA@chl-Q{F<(La=A=Dv>QnT6H*BV>(-$ zP3H=AXFnxlGQk?_mY(ba}>rQ#m;$yv2IAW36XMfM4q3aB+Azm#v$h zbp{yWOx;<@B~*`aRA6TK44D2#Q>OdCN*V6Vv}g0|k*8GK@V;s&sI0n<#l)rXCQko! zj$Gm%XFxauXQj(N=S6fbu+O|Tu+SNtuIBUH4}X@7?M76)OMtm+Y`k}8iUr#nw78D8 znX~+5h@MA|fOB;QWDCtN?LtUVoU%kaPFD*&07C2pP-3~(ym?0~fs0PHPpenY$zaZSVfzJ6yN z58XAhM~M)?Piquq1%$r0gKm;*hr!uBu6TVsmqR8`_!&>eWE`OBVcc3xGO)THlXb<% zNIjvi2M9eINIxG)Hv~cJBAra%(IKDp4qZ`Ce5%0D{DBwq%pZ0H@2oRWzYBThkEzcA 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 literal 0 HcmV?d00001 diff --git a/_build/html/.buildinfo b/_build/html/.buildinfo new file mode 100644 index 000000000..adad204ab --- /dev/null +++ b/_build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 18e9302a06caccca0fbd1c9498c2e667 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/_build/html/.nojekyll b/_build/html/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/_build/html/QUANTAXIS_Trade/README.html b/_build/html/QUANTAXIS_Trade/README.html new file mode 100644 index 000000000..ac8b5bf5e --- /dev/null +++ b/_build/html/QUANTAXIS_Trade/README.html @@ -0,0 +1,208 @@ + + + + + + + + QUANTAXIS quantitative financial strategy framework — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +

+
+
+
+ +
+

QUANTAXIS quantitative financial strategy framework

+

QUANTAXIS quantitative framework to achieve the stock and futures market, the whole species back to the test.Through the distributed crawler for data capture, to build a response to the data cleaning and market push engine to build a multi-language open response frame. And build interactive visualization of clients and websites.

+'Stories in Ready' +
+

0.4.x Release Note

+

QUANTAXIS Quantitative Financial Strategy Framework is a quantitative analysis solution for small and medium-sized strategy teams.We can quickly implement scene-oriented customization solutions with highly decoupled modularity and standardized protocols. QUANTAXIS is a progressive open Framework, you can according to their own needs, the introduction of their own data, analysis programs, visualization process, you can also RESTful interface, the rapid realization of multi-LAN / WAN collaboration.

+

QUANTAXIS and many excellent domestic quantitative platform is the difference, QA more concerned about the user experience and the actual situation, for the user needs will be more optimized, so will pay more attention to openness, the introduction of custom convenience, and the team Collaborative details are handled, such as custom data introductions, custom policy chart comparison, custom risk and policy portfolio management, and so on.

+ +
+

More info on https://github.com/yutiansut/quantaxis

+

An EXAMPLE of QUANTAXIS BACKTEST like that below:

+
import QUANTAXIS as QA
+from QUANTAXIS import QA_Backtest_stock_day as QB
+
+
+"""
+Written Before:
+===============QUANTAXIS BACKTEST STOCK_DAY's Constant
+Constant:
+QB.account.message
+QB.account.cash
+QB.account.hold
+QB.account.history
+QB.account.assets
+QB.account.detail
+QB.account.init_assest
+
+
+
+QB.strategy_stock_list
+QB.strategy_start_date
+QB.strategy_end_date
+
+
+QB.today
+
+QB.benchmark_code
+
+
+
+
+Function:
+get the market data (based on gap):
+QB.QA_backtest_get_market_data(QB,code,QB.today)
+get the market data as you want:
+QA.QA_fetch_stock_day(code,start,end,model)
+
+
+Order :
+QB.QA_backtest_send_order(QB, code,amount,towards,order: dict)
+
+order has three model:
+1.Limited order order['order_model']=0 or l,L
+attention: this model should have a order['price'] key
+order['price']=xxxx
+
+2.Market order order['order_model']=1 or m,M,market,Market
+3.Strict model order['order_model']=2 or s,S
+    which is buy in the highest price or sell in the lowest price
+
+Query the hold amount
+
+QB.QA_backtest_hold_amount(QB,code)
+
+
+"""
+
+
+@QB.backtest_init
+def init():
+    #
+    QB.setting.QA_util_sql_mongo_ip='127.0.0.1'
+
+    QB.account.init_assest=2500000
+    QB.benchmark_code='hs300'
+
+    QB.strategy_stock_list=['000001','000002','600010','601801','603111']
+    QB.strategy_start_date='2017-03-01'
+    QB.strategy_end_date='2017-07-01'
+
+@QB.before_backtest
+def before_backtest():
+    global risk_position
+    QA.QA_util_log_info(QB.account.message)
+
+
+
+@QB.load_strategy
+def strategy():
+    #print(QB.account.message)
+    #print(QB.account.cash)
+    #input()
+
+    for item in QB.strategy_stock_list:
+        QA.QA_util_log_info(QB.QA_backtest_get_market_data(QB,item,QB.today))
+        if QB.QA_backtest_hold_amount(QB,item)==0:
+            QB.QA_backtest_send_order(QB,item,10000,1,{'order_model':'Market'})
+
+
+        else:
+            #print(QB.QA_backtest_hold_amount(QB,item))
+            QB.QA_backtest_send_order(QB,item,10000,-1,{'order_model':'Market'})
+
+@QB.end_backtest
+def after_backtest():
+    pass
+
+
+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/README.html b/_build/html/README.html new file mode 100644 index 000000000..c787edead --- /dev/null +++ b/_build/html/README.html @@ -0,0 +1,208 @@ + + + + + + + + QUANTAXIS quantitative financial strategy framework — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS quantitative financial strategy framework

+

QUANTAXIS quantitative framework to achieve the stock and futures market, the whole species back to the test.Through the distributed crawler for data capture, to build a response to the data cleaning and market push engine to build a multi-language open response frame. And build interactive visualization of clients and websites.

+'Stories in Ready' +
+

0.4.x Release Note

+

QUANTAXIS Quantitative Financial Strategy Framework is a quantitative analysis solution for small and medium-sized strategy teams.We can quickly implement scene-oriented customization solutions with highly decoupled modularity and standardized protocols. QUANTAXIS is a progressive open Framework, you can according to their own needs, the introduction of their own data, analysis programs, visualization process, you can also RESTful interface, the rapid realization of multi-LAN / WAN collaboration.

+

QUANTAXIS and many excellent domestic quantitative platform is the difference, QA more concerned about the user experience and the actual situation, for the user needs will be more optimized, so will pay more attention to openness, the introduction of custom convenience, and the team Collaborative details are handled, such as custom data introductions, custom policy chart comparison, custom risk and policy portfolio management, and so on.

+ +
+

More info on https://github.com/yutiansut/quantaxis

+

An EXAMPLE of QUANTAXIS BACKTEST like that below:

+
import QUANTAXIS as QA
+from QUANTAXIS import QA_Backtest_stock_day as QB
+
+
+"""
+Written Before:
+===============QUANTAXIS BACKTEST STOCK_DAY's Constant
+Constant:
+QB.account.message
+QB.account.cash
+QB.account.hold
+QB.account.history
+QB.account.assets
+QB.account.detail
+QB.account.init_assest
+
+
+
+QB.strategy_stock_list
+QB.strategy_start_date
+QB.strategy_end_date
+
+
+QB.today
+
+QB.benchmark_code
+
+
+
+
+Function:
+get the market data (based on gap):
+QB.QA_backtest_get_market_data(QB,code,QB.today)
+get the market data as you want:
+QA.QA_fetch_stock_day(code,start,end,model)
+
+
+Order :
+QB.QA_backtest_send_order(QB, code,amount,towards,order: dict)
+
+order has three model:
+1.Limited order order['order_model']=0 or l,L
+attention: this model should have a order['price'] key
+order['price']=xxxx
+
+2.Market order order['order_model']=1 or m,M,market,Market
+3.Strict model order['order_model']=2 or s,S
+    which is buy in the highest price or sell in the lowest price
+
+Query the hold amount
+
+QB.QA_backtest_hold_amount(QB,code)
+
+
+"""
+
+
+@QB.backtest_init
+def init():
+    #
+    QB.setting.QA_util_sql_mongo_ip='127.0.0.1'
+
+    QB.account.init_assest=2500000
+    QB.benchmark_code='hs300'
+
+    QB.strategy_stock_list=['000001','000002','600010','601801','603111']
+    QB.strategy_start_date='2017-03-01'
+    QB.strategy_end_date='2017-07-01'
+
+@QB.before_backtest
+def before_backtest():
+    global risk_position
+    QA.QA_util_log_info(QB.account.message)
+
+
+
+@QB.load_strategy
+def strategy():
+    #print(QB.account.message)
+    #print(QB.account.cash)
+    #input()
+
+    for item in QB.strategy_stock_list:
+        QA.QA_util_log_info(QB.QA_backtest_get_market_data(QB,item,QB.today))
+        if QB.QA_backtest_hold_amount(QB,item)==0:
+            QB.QA_backtest_send_order(QB,item,10000,1,{'order_model':'Market'})
+
+
+        else:
+            #print(QB.QA_backtest_hold_amount(QB,item))
+            QB.QA_backtest_send_order(QB,item,10000,-1,{'order_model':'Market'})
+
+@QB.end_backtest
+def after_backtest():
+    pass
+
+
+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAARP/QAAccount.html b/_build/html/_modules/QUANTAXIS/QAARP/QAAccount.html new file mode 100644 index 000000000..ff41ce3b3 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAARP/QAAccount.html @@ -0,0 +1,447 @@ + + + + + + + + QUANTAXIS.QAARP.QAAccount — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAARP.QAAccount

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import pandas as pd
+import datetime
+from QUANTAXIS.QAEngine.QAEvent import QA_Worker
+from QUANTAXIS.QAMarket.QAOrder import QA_Order
+from QUANTAXIS.QASU.save_account import save_account, update_account
+from QUANTAXIS.QAUtil.QAParameter import (ACCOUNT_EVENT, AMOUNT_MODEL,
+                                          BROKER_TYPE, ENGINE_EVENT, FREQUENCE,
+                                          MARKET_TYPE, TRADE_STATUS)
+from QUANTAXIS.QAUtil.QARandom import QA_util_random_with_topic
+
+# 2017/6/4修改: 去除总资产的动态权益计算
+
+
+
[docs]class QA_Account(QA_Worker): + """[QA_Account] + + 2018/1/5 再次修改 改版本去掉了多余的计算 精简账户更新 + ====================== + + - 不再计算总资产/不再计算当前持仓/不再计算交易对照明细表 + - 不再动态计算账户股票/期货市值 + - 只维护 cash/history两个字段 剩下的全部惰性计算 + + + QA_Account 是QUANTAXIS的最小不可分割单元之一 + + QA_Account是账户类 需要兼容股票/期货/指数 + QA_Account继承自QA_Worker 可以被事件驱动 + QA_Account可以直接被QA_Strategy继承 + + 有三类输入: + 信息类: 账户绑定的策略名/账户的用户名/账户类别/账户识别码/账户的broker + 资产类: 现金/可用现金/交易历史/交易对照表 + 规则类: 是否允许卖空/是否允许t0结算 + + 方法: + 惰性计算:最新持仓/最新总资产/最新现金/持仓面板 + 生成订单/接受交易结果数据 + 接收新的数据/on_bar/on_tick方法/缓存新数据的market_data + + + """ + + def __init__(self, strategy_name=None, user_cookie=None, market_type=MARKET_TYPE.STOCK_CN, frequence=FREQUENCE.DAY, + broker=BROKER_TYPE.BACKETEST, portfolio_cookie=None, account_cookie=None, + sell_available={}, init_assets=None, cash=None, history=None, + margin_level=False, allow_t0=False, allow_sellopen=False): + super().__init__() + self._history_headers = ['datetime', 'code', 'price', + 'amount', 'order_id', 'trade_id', 'account_cookie', 'commission', 'tax'] + # 信息类: + self.strategy_name = strategy_name + self.user_cookie = user_cookie + self.market_type = market_type + self.portfolio_cookie = portfolio_cookie + self.account_cookie = QA_util_random_with_topic( + 'Acc') if account_cookie is None else account_cookie + self.broker = broker + self.frequence = frequence + self.market_data = None + self._currenttime = None + # 资产类 + self.init_assets = 1000000 if init_assets is None else init_assets + self.cash = [self.init_assets] if cash is None else cash + self.cash_available = self.cash[-1] # 可用资金 + self.sell_available = sell_available + self.history = [] if history is None else history + self.time_index = [] + # 规则类 + # 两个规则 + # 1.是否允许t+0 及买入及结算 + # 2.是否允许卖空开仓 + # 3.是否允许保证金交易/ 如果不是false 就需要制定保证金比例(dict形式) + self.allow_t0 = allow_t0 + self.allow_sellopen = allow_sellopen + self.margin_level = margin_level + + def __repr__(self): + return '< QA_Account {}>'.format(self.account_cookie) + + @property + def message(self): + 'the standard message which can be transef' + return { + 'source': 'account', + 'account_cookie': self.account_cookie, + 'portfolio_cookie': self.portfolio_cookie, + 'user_cookie': self.user_cookie, + 'broker': self.broker, + 'market_type': self.market_type, + 'strategy_name': self.strategy_name, + 'current_time': self._currenttime, + + 'allow_sellopen': self.allow_sellopen, + 'allow_t0': self.allow_t0, + 'margin_level': self.margin_level, + 'init_assets': self.init_assets, + 'cash': self.cash, + 'history': self.history, + 'trade_index': self.time_index, + 'running_time': datetime.datetime.now() + } + + @property + def code(self): + """该账户曾交易代码 用set 去重 + """ + return list(set([item[1] for item in self.history])) + + @property + def start_date(self): + return str(self.time_index[0])[0:10] + + @property + def end_date(self): + return str(self.time_index[-1])[0:10] + + @property + def history_table(self): + '交易历史的table' + return pd.DataFrame(data=self.history, columns=self._history_headers).sort_index() + + @property + def cash_table(self): + '现金的table' + _cash = pd.DataFrame(data=[self.cash[1::], self.time_index], index=[ + 'cash', 'datetime']).T + _cash = _cash.assign(date=_cash.datetime.apply(lambda x: str(x)[0:10])).assign( + account_cookie=self.account_cookie) + + return _cash.set_index(['datetime', 'account_cookie'], drop=False).sort_index() + + @property + def hold(self): + '持仓' + return pd.DataFrame(data=self.history, columns=self._history_headers).groupby('code').amount.sum().sort_index() + + @property + def trade(self): + '每次交易的pivot表' + return self.history_table.pivot_table(index=['datetime', 'account_cookie'], columns='code', values='amount').fillna(0).sort_index() + + @property + def daily_cash(self): + '每日交易结算时的现金表' + return self.cash_table.drop_duplicates(subset='date', keep='last').sort_index() + + @property + def daily_hold(self): + '每日交易结算时的持仓表' + data = self.trade.cumsum() + + data = data.assign(account_cookie=self.account_cookie).assign( + date=data.index.levels[0]) + data.date = data.date.apply(lambda x: str(x)[0:10]) + return data.set_index(['date', 'account_cookie'], drop=False).sort_index() + + # 计算assets的时候 需要一个market_data=QA.QA_fetch_stock_day_adv(list(data.columns),data.index[0],data.index[-1]) + # (market_data.to_qfq().pivot('close')*data).sum(axis=1)+user_cookie.get_account(a_1).daily_cash.set_index('date').cash + + @property + def latest_cash(self): + 'return the lastest cash' + return self.cash[-1] + + @property + def current_time(self): + 'return current time (in backtest/real environment)' + return self._currenttime + +
[docs] def reset_assets(self, init_assets=None): + 'reset_history/cash/' + self.sell_available = {} + self.history = [] + self.init_assets = init_assets + self.cash = [self.init_assets] + self.cash_available = self.cash[-1] # 在途资金
+ +
[docs] def receive_deal(self, message): + """[用于更新账户] + + [description] + + update history and cash + """ + if message['header']['status'] is TRADE_STATUS.SUCCESS: + self.time_index.append(str(message['body']['order']['datetime'])) + self.history.append( + [str(message['body']['order']['datetime']), str(message['body']['order']['code']), + float(message['body']['order']['price']), int(message['body']['order']['towards']) * + float(message['body']['order']['amount']), str( + message['header']['order_id']), str(message['header']['trade_id']), str(self.account_cookie), + float(message['body']['fee']['commission']), float(message['body']['fee']['tax'])]) + self.cash.append(float(self.cash[-1]) - float(message['body']['order']['price']) * + float(message['body']['order']['amount']) * message['body']['order']['towards'] - + float(message['body']['fee']['commission'])) + + return self.message
+ +
[docs] def send_order(self, code, amount, time, towards, price, order_model, amount_model): + """[summary] + + Arguments: + code {[type]} -- [description] + amount {[type]} -- [description] + time {[type]} -- [description] + towards {[type]} -- [description] + price {[type]} -- [description] + order_model {[type]} -- [description] + amount_model {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + flag = False + date = str(time)[0:10] if len(str(time)) == 19 else str(time) + time = str(time) if len( + str(time)) == 19 else '{} 09:31:00'.format(str(time)[0:10]) + + amount = amount if amount_model is AMOUNT_MODEL.BY_AMOUNT else int( + amount / price) + if self.market_type is MARKET_TYPE.STOCK_CN: + amount = int(amount / 100) * 100 + + marketvalue = amount * price if amount_model is AMOUNT_MODEL.BY_AMOUNT else amount + + amount_model = AMOUNT_MODEL.BY_AMOUNT + if int(towards) > 0: + # 是买入的情况(包括买入.买开.买平) + if self.cash_available >= marketvalue: + self.cash_available -= marketvalue + flag = True + elif int(towards) < 0: + if self.allow_sellopen: + flag = True + if self.sell_available.get(code, 0) >= amount: + self.sell_available[code] -= amount + flag = True + + if flag and amount > 0: + return QA_Order(user_cookie=self.user_cookie, strategy=self.strategy_name, frequence=self.frequence, + account_cookie=self.account_cookie, code=code, market_type=self.market_type, + date=date, datetime=time, sending_time=time, callback=self.receive_deal, + amount=amount, price=price, order_model=order_model, towards=towards, + amount_model=amount_model) # init + else: + return flag
+ +
[docs] def settle(self): + '同步可用资金/可卖股票' + self.cash_available = self.cash[-1] + self.sell_available = self.hold
+ +
[docs] def on_bar(self, event): + 'while updating the market data' + print(event.market_data)
+ +
[docs] def on_tick(self, event): + 'on tick event' + pass
+ +
[docs] def from_message(self, message): + """resume the account from standard message + 这个是从数据库恢复账户时需要的""" + self.account_cookie = message.get('account_cookie', None) + self.portfolio_cookie = message.get('portfolio_cookie', None) + self.user_cookie = message.get('user_cookie', None) + self.broker = message.get('broker', None) + self.market_type = message.get('market_type', None) + self.strategy_name = message.get('strategy_name', None) + self._currenttime = message.get('current_time', None) + self.allow_sellopen = message.get('allow_sellopen', False) + self.allow_t0 = message.get('allow_t0', False) + self.margin_level = message.get('margin_level', False) + + self.history = message['history'] + self.cash = message['cash'] + self.time_index = message['trade_index'] + self.init_assets = message['init_assets'] + return self
+ + @property + def table(self): + """ + 打印出account的内容 + """ + return pd.DataFrame([self.message, ]).set_index('account_cookie', drop=False).T + +
[docs] def run(self, event): + 'QA_WORKER method' + if event.event_type is ACCOUNT_EVENT.SETTLE: + self.settle() + + elif event.event_type is ACCOUNT_EVENT.UPDATE: + self.receive_deal(event.message) + elif event.event_type is ACCOUNT_EVENT.MAKE_ORDER: + """generate order + if callback callback the order + if not return back the order + """ + data = self.send_order(code=event.code, amount=event.amount, time=event.time, + amount_model=event.amount_model, towards=event.towards, + price=event.price, order_model=event.order_model) + if event.callback: + event.callback(data) + else: + return data + elif event.event_type is ENGINE_EVENT.UPCOMING_DATA: + """update the market_data + 1. update the inside market_data struct + 2. tell the on_bar methods + """ + self._currenttime = event.market_data.datetime[-1] + if self.market_data is None: + self.market_data = event.market_data + else: + self.market_data = self.market_data + event.market_data + self.on_bar(event) + + if event.callback: + event.callback(event)
+ +
[docs] def save(self): + save_account(self.message)
+ +
[docs] def change_cash(self, money): + res = self.cash[-1]+money + if res >= 0: + # 高危操作 + self.cash[-1] = res
+ + +
[docs]class Account_handler(): + def __init__(self): + pass + +
[docs] def get_account(self, message): + pass
+ + +if __name__ == '__main__': + account = QA_Account() + # 创建一个account账户 +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAARP/QAPortfolio.html b/_build/html/_modules/QUANTAXIS/QAARP/QAPortfolio.html new file mode 100644 index 000000000..cfb2b11b7 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAARP/QAPortfolio.html @@ -0,0 +1,343 @@ + + + + + + + + QUANTAXIS.QAARP.QAPortfolio — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAARP.QAPortfolio

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from functools import lru_cache
+import pandas as pd
+from QUANTAXIS.QAARP.QAAccount import QA_Account
+from QUANTAXIS.QAUtil import (DATABASE, QA_util_log_info,
+                              QA_util_random_with_topic)
+
+# pylint: disable=old-style-class, too-few-public-methods
+
+
+
[docs]class QA_Portfolio(): + + """ + QUANTAXIS 多账户 + 以及组合管理 + + # 适用 回测/实盘 + + # PORTFOLIO应当作为一个视图来处理,这个视图作为一个静态的观察点 可以去衡量风险 观察业绩等等 + @2018/02/26 + + :::::::::::::::::::::::::::::::::::::::::::::::: + :: ::STRATEGY 1 -- ACCOUNT 1 --{P1,P3} :: + :: USER ::STRATEGY 2 -- ACCOUNT 2 --{P1,P2} :: + :: ::STRATEGY 3 -- ACCOUNT 3 --{P2,P3} :: + :::::::::::::::::::::::::::::::::::::::::::::::: + + + PORTFOLIO + + 在portfolio中,我们希望通过cookie来控制account_unit + + 对于account的指标,要进行风险控制,组合成最优的投资组合的量 + + 用account的cookie来管理控制account + + portfolio里面的资产主要考虑的是 资金的分配 + """ + + def __init__(self, user_cookie=None, strategy_name=None, init_assets=1000000, cash=None, sell_available=None, history=None): + self.accounts = {} + self.portfolio_cookie = QA_util_random_with_topic('Portfolio') + self.user_cookie = user_cookie + self.strategy_name = strategy_name + # 和account一样的资产类 + self.init_assets = 1000000 if init_assets is None else init_assets + self.cash = [self.init_assets] if cash is None else cash + self.cash_available = self.cash[-1] # 可用资金 + self.sell_available = sell_available + self.history = [] if history is None else history + self.time_index = [] + + for cookie in self.accounts.keys(): + self.accounts[cookie] = QA_Account(account_cookie=cookie) + + def __repr__(self): + return '< QA_Portfolio {} with {} Accounts >'.format(self.portfolio_cookie, len(self.accounts.keys())) + +
[docs] def get_portfolio(self): + 'return the accounts dict' + return self.accounts
+ +
[docs] def add_account(self, account): + 'portfolio add a account/stratetgy' + if account.account_cookie not in self.accounts.keys(): + account.portfolio_cookie = self.portfolio_cookie + account.user_cookie = self.user_cookie + self.accounts[account.account_cookie] = account + else: + pass
+ +
[docs] def new_account(self, account_cookie=None): + 'portfolio create a account/strategy' + if account_cookie is None: + temp = QA_Account(portfolio_cookie=self.portfolio_cookie, + user_cookie=self.user_cookie) + if temp.account_cookie not in self.accounts.keys(): + self.accounts[temp.account_cookie] = temp + return temp + + else: + return self.new_account() + else: + if account_cookie not in self.accounts.keys(): + self.accounts[account_cookie] = QA_Account(portfolio_cookie=self.portfolio_cookie, + user_cookie=self.user_cookie, account_cookie=account_cookie) + return self.accounts[account_cookie] + else: + return self.new_account(account_cookie)
+ +
[docs] def get_account(self, cookie): + 'give the account_cookie and return the account/strategy back' + try: + return self.accounts[cookie] + except: + QA_util_log_info('Can not find this account') + return None
+ +
[docs] def cookie_mangement(self): + pass
+ + @property + def table(self): + return pd.concat([acc.table for acc in self.accounts.values()], axis=1) + +
[docs] def get_cash(self): + """拿到整个portfolio的可用资金 + + 统计每一个时间点的时候的cash总和 + """ + + pass
+ +
[docs] def pull(self, account_cookie=None, collection=DATABASE.account): + 'pull from the databases' + if account_cookie is None: + for item in self.accounts.keys(): + try: + message = collection.find_one({'account_cookie': item}) + QA_util_log_info('{} sync successfully'.format(item)) + except Exception as e: + QA_util_log_info( + '{} sync wrong \\\n wrong info {}'.format(item, e)) + self.accounts[item].from_message(message) + + else: + try: + message = collection.find_one( + {'account_cookie': account_cookie}) + QA_util_log_info('{} sync successfully'.format(item)) + except Exception as e: + QA_util_log_info( + '{} sync wrong \\\n wrong info {}'.format(account_cookie, e)) + self.accounts[account_cookie].from_message(message)
+ +
[docs] def push(self, account_cookie=None, collection=DATABASE.account): + 'push to databases' + message = self.accounts[account_cookie].message + if account_cookie is None: + for item in self.accounts.keys(): + try: + message = collection.find_one_and_update( + {'account_cookie': item}) + QA_util_log_info('{} sync successfully'.format(item)) + except Exception as e: + QA_util_log_info( + '{} sync wrong \\\n wrong info {}'.format(item, e)) + self.accounts[item].from_message(message) + + else: + try: + message = collection.find_one( + {'account_cookie': account_cookie}) + QA_util_log_info('{} sync successfully'.format(item)) + except Exception as e: + QA_util_log_info( + '{} sync wrong \\\n wrong info {}'.format(account_cookie, e)) + self.accounts[account_cookie].from_message(message)
+ + +
[docs]class QA_TEST_MAKEPortfolio(): + + def __init__(self): + """ + this is a dict for account_cookie----account instance + """ + self.account_list = dict() + +
[docs] def make_portfolio(self, account_list): + pass
+ + +
[docs]class QA_PortfolioView(): + """ + 对于Portfolio而言,一切都是基于内部的account的信息的变更而变更的 + + Portfolio不应该有过多可以修改的部分(作为一个view存在) + """ + + def __init__(self, account_list): + """ + ||portfolio|| + ||acc1_cookie--acc1||acc2-cookie--acc2||...|| + + + ||cash||assets||hold||history||trade_index|| + + + ||Risk_analysis||Performace_analysis|| + """ + self.account_list = dict( + zip([account.account_cookie for account in account_list], account_list)) + self.portfolio_cookie = QA_util_random_with_topic('Portfolio') + self.user_cookie = None + # self._broker = None + # self.user_cookie = None + # self._market_type = None + # self._strategy_name = None + # self._currenttime = None + # self._init_assets = None + # self._cash = None + # self._history = None + # self._trade_index = None + + @property + def account_cookie(self): + return [account.account_cookie for account in self.accounts] + + @property + def accounts(self): + """ + return all accounts inside the portfolio view + """ + return list(self.account_list.values()) + + @property + def start_date(self): + return str(pd.to_datetime(pd.Series([account.start_date for account in self.accounts])).min())[0:10] + + @property + def end_date(self): + return str(pd.to_datetime(pd.Series([account.end_date for account in self.accounts])).max())[0:10] + + @property + def code(self): + return pd.concat([pd.Series(account.code) for account in self.accounts]).drop_duplicates().tolist() + + @property + def init_assets(self): + return sum([account.init_assets for account in self.accounts]) + + @property + def daily_cash(self): + res = pd.DataFrame(sum([account.daily_cash.set_index( + 'datetime').cash for account in self.accounts])) + res = res.assign(date=res.index) + res.date = res.date.apply(lambda x: str(x)[0:10]) + return res + + @property + def daily_hold(self): + return pd.concat([account.daily_hold.set_index('date') for account in self.accounts]).groupby('date').sum()
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAARP/QARisk.html b/_build/html/_modules/QUANTAXIS/QAARP/QARisk.html new file mode 100644 index 000000000..0d9f4f039 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAARP/QARisk.html @@ -0,0 +1,367 @@ + + + + + + + + QUANTAXIS.QAARP.QARisk — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAARP.QARisk

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+"""收益性的包括年化收益率、净利润、总盈利、总亏损、有效年化收益率、资金使用率。
+
+风险性主要包括胜率、平均盈亏比、最大回撤比例、最大连续亏损次数、最大连续盈利次数、持仓时间占比、贝塔。
+
+综合性指标主要包括风险收益比,夏普比例,波动率,VAR,偏度,峰度等"""
+
+import math
+from functools import lru_cache
+
+import numpy as np
+import pandas as pd
+
+from QUANTAXIS.QAFetch.QAQuery_Advance import (QA_fetch_index_day_adv,
+                                               QA_fetch_stock_day_adv)
+from QUANTAXIS.QASU.save_account import save_riskanalysis
+from QUANTAXIS.QAUtil.QADate_trade import QA_util_get_trade_gap
+from QUANTAXIS.QAUtil.QAParameter import MARKET_TYPE
+
+
+
[docs]class QA_Risk(): + """QARISK 是一个风险插件 + + 需要加载一个account/portfolio类进来: + 需要有 + code,start_date,end_date,daily_cash,daily_hold + """ + + def __init__(self, account, benchmark_code='000300', benchmark_type=MARKET_TYPE.INDEX_CN): + self.account = account + self.benchmark_code = benchmark_code # 默认沪深300 + self.benchmark_type = benchmark_type + + self.fetch = {MARKET_TYPE.STOCK_CN: QA_fetch_stock_day_adv, + MARKET_TYPE.INDEX_CN: QA_fetch_index_day_adv} + self.market_data = QA_fetch_stock_day_adv( + self.account.code, self.account.start_date, self.account.end_date) + + self.assets = ((self.market_data.to_qfq().pivot('close') * self.account.daily_hold).sum( + axis=1) + self.account.daily_cash.set_index('date').cash).fillna(method='pad') + + self.time_gap = QA_util_get_trade_gap( + self.account.start_date, self.account.end_date) + self.init_assets= self.account.init_assets + + def __repr__(self): + return '< QA_RISK ANALYSIS ACCOUNT/PORTFOLIO >' + + def __call__(self): + return pd.DataFrame([self.message]) + + @property + def max_dropback(self): + """最大回撤 + """ + return max([self.assets.iloc[idx::].max() - self.assets.iloc[idx::].min() for idx in range(len(self.assets))]) / float(self.assets.iloc[0]) + + @property + def profit(self): + return self.calc_profit(self.assets) + + @property + def profit_pct(self): + """利润 + """ + return self.calc_profitpctchange(self.assets) + + @property + def annualize_return(self): + """年化收益 + + Returns: + [type] -- [description] + """ + + return self.calc_annualize_return(self.assets, self.time_gap) + + @property + def volatility(self): + """波动率 + + Returns: + [type] -- [description] + """ + return self.profit_pct.std() * math.sqrt(250) + + @property + def message(self): + return { + 'account_cookie': self.account.account_cookie, + 'portfolio_cookie': self.account.portfolio_cookie, + 'user_cookie': self.account.user_cookie, + 'annualize_return': self.annualize_return, + 'profit': self.profit, + 'max_dropback': self.max_dropback, + 'time_gap': self.time_gap, + 'volatility': self.volatility, + 'benchmark_code': self.benchmark_code, + 'beta': self.beta, + 'alpha': self.alpha, + 'sharpe': self.sharpe, + 'init_assets': self.init_assets, + 'last_assets': self.assets.iloc[-1] + } + + @property + def benchmark_data(self): + """ + 基准组合的行情数据(一般是组合,可以调整) + """ + return self.fetch[self.benchmark_type]( + self.benchmark_code, self.account.start_date, self.account.end_date) + + @property + def benchmark_assets(self): + """ + 基准组合的账户资产队列 + """ + return (self.benchmark_data.open / float(self.benchmark_data.open.iloc[0]) * float(self.init_assets)) + + @property + def benchmark_annualize_return(self): + """基准组合的年化收益 + + Returns: + [type] -- [description] + """ + + return self.calc_annualize_return(self.benchmark_assets, self.time_gap) + + @property + def benchmark_profitpct(self): + """ + benchmark 基准组合的收益百分比计算 + """ + return self.calc_profitpctchange(self.benchmark_assets) + + @property + def beta(self): + """ + beta比率 组合的系统性风险 + """ + return self.calc_beta(self.profit_pct.dropna(), self.benchmark_profitpct.dropna()) + + @property + def alpha(self): + """ + alpha比率 与市场基准收益无关的超额收益率 + """ + return self.calc_alpha(self.annualize_return, self.benchmark_annualize_return, self.beta, 0.05) + + @property + def sharpe(self): + """ + 夏普比率 + + """ + return self.calc_sharpe(self.annualize_return, self.volatility, 0.05) + + @property + def sortino(self): + """ + 索提诺比率 投资组合收益和下行风险比值 + + """ + pass + + @property + def calmar(self): + """ + 卡玛比率 + """ + pass + +
[docs] def set_benchmark(self, code, market_type): + self.benchmark_code = code + self.benchmark_type = market_type
+ +
[docs] def calc_annualize_return(self, assets, days): + return (float(assets.iloc[-1]) / float(assets.iloc[0]) -1 )/(float(days) /250 )
+ + # def calc_profit(self, assets): + # return (assets.iloc[-1] / assets.iloc[1]) - 1 + +
[docs] def calc_profitpctchange(self, assets): + return self.assets[::-1].pct_change()
+ +
[docs] def calc_beta(self, assest_profit, benchmark_profit): + + calc_cov = np.cov(assest_profit, benchmark_profit) + beta = calc_cov[0, 1] / calc_cov[1, 1] + return beta
+ +
[docs] def calc_alpha(self, annualized_returns, benchmark_annualized_returns, beta, r=0.05): + + alpha = (annualized_returns - r) - (beta) * \ + (benchmark_annualized_returns - r) + return alpha
+ +
[docs] def calc_profit(self, assets): + return (float(assets.iloc[-1]) / float(assets.iloc[0])) - 1
+ +
[docs] def calc_sharpe(self, annualized_returns, volatility_year, r=0.05): + '计算夏普比率' + return (annualized_returns - r) / volatility_year
+ +
[docs] def save(self): + """save to mongodb + + """ + save_riskanalysis(self.message)
+ + +
[docs]class QA_Performance(): + """ + QA_Performance是一个绩效分析插件 + + 需要加载一个account/portfolio类进来: + 需要有 + code,start_date,end_date,daily_cash,daily_hold + """ + + def __init__(self, account): + + self.account = account + self._style_title = ['beta', 'momentum', 'size', 'earning_yield', + 'volatility', 'growth', 'value', 'leverage', 'liquidity', 'reversal'] + + @property + def prefer(self): + pass + + @property + def style(self): + """风格分析 + """ + pass + +
[docs] def abnormal_active(self): + """ + 账户的成交发生异常成交记录的分析 + """ + pass
+ +
[docs] def brinson(self): + """Brinson Model analysis + """ + pass
+ +
[docs] def hold(self): + """持仓分析 + """ + pass
+ + @property + def accumulate_return(self): + """ + returns a pd-Dataframe format accumulate return for different periods + """ + pass + +
[docs] def save(self): + """save the performance analysis result to database + """ + pass
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAARP/QAStrategy.html b/_build/html/_modules/QUANTAXIS/QAARP/QAStrategy.html new file mode 100644 index 000000000..2096f8dee --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAARP/QAStrategy.html @@ -0,0 +1,113 @@ + + + + + + + + QUANTAXIS.QAARP.QAStrategy — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAARP.QAStrategy

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from QUANTAXIS.QAARP.QAAccount import QA_Account
+
+
+
[docs]class QA_Strategy(QA_Account): + """account + + [description] + """ + def __init__(self): + super().__init__()
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAARP/QAUser.html b/_build/html/_modules/QUANTAXIS/QAARP/QAUser.html new file mode 100644 index 000000000..1f8088791 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAARP/QAUser.html @@ -0,0 +1,180 @@ + + + + + + + + QUANTAXIS.QAARP.QAUser — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAARP.QAUser

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import pandas as pd
+from QUANTAXIS.QAARP.QAPortfolio import QA_Portfolio
+from QUANTAXIS.QAUtil.QALogs import QA_util_log_info
+from QUANTAXIS.QAUtil.QARandom import QA_util_random_with_topic
+from QUANTAXIS.QAUtil.QASetting import QA_Setting
+
+
+
[docs]class QA_User(): + """QA_User + User--Portfolio--Account/Strategy + """ + + def __init__(self): + self.setting = QA_Setting() + self.portfolio_list = {} + self.user_cookie = QA_util_random_with_topic('USER') + + def __repr__(self): + return '< QA_USER {} with {} portfolio >'.format(self.user_cookie, len(self.portfolio_list.keys())) + + @property + def table(self): + return pd.concat([po.table for po in self.portfolio_list.values()], axis=1) + +
[docs] def client(self): + 'user.client to connect database' + return self.setting.client
+ +
[docs] def connect_database(self, ip='127.0.0.1', port=27017): + 'connect is also a way to change database from IP_A to IP_B' + self.setting.change(ip, port)
+ +
[docs] def login(self, user_name, password): + 'login to a database' + if self.setting.login(user_name, password): + QA_util_log_info('SUCCESS') + else: + QA_util_log_info('FAILD')
+ +
[docs] def new_portfolio(self): + 'create a portfolio' + _portfolio = QA_Portfolio(user_cookie=self.user_cookie) + if _portfolio.portfolio_cookie not in self.portfolio_list.keys(): + self.portfolio_list[_portfolio.portfolio_cookie] = _portfolio + return _portfolio
+ +
[docs] def get_portfolio(self, portfolio): + 'get a portfolio' + return self.portfolio_list[portfolio]
+ +
[docs] def generate_simpleaccount(self): + """make a simple account with a easier way + 如果当前user中没有创建portfolio, 则创建一个portfolio,并用此portfolio创建一个account + 如果已有一个或多个portfolio,则使用第一个portfolio来创建一个account + """ + if len(self.portfolio_list.keys()) < 1: + po = self.new_portfolio() + else: + po = list(self.portfolio_list.values())[0] + ac = po.new_account() + return ac, po
+ +
[docs] def register_account(self, account): + if len(self.portfolio_list.keys()) < 1: + po = self.new_portfolio() + else: + po = list(self.portfolio_list.values())[0] + po.add_account(account) + return (po, account)
+ + +if __name__ == '__main__': + user = QA_User() + portfolio1 = user.new_portfolio() + ac1 = user.get_portfolio(portfolio1).new_account() + + print(user) + print(user.get_portfolio(portfolio1)) + print(user.get_portfolio(portfolio1).get_account(ac1)) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_block.html b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_block.html new file mode 100644 index 000000000..154e7b2fc --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_block.html @@ -0,0 +1,218 @@ + + + + + + + + QUANTAXIS.QAAnalysis.QAAnalysis_block — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAAnalysis.QAAnalysis_block

+# coding:utf-8
+
+# 输入一个stock_list/stock_block
+# 生成相关因子
+
+import datetime
+
+import pandas as pd
+
+from QUANTAXIS.QAAnalysis.QAAnalysis_dataframe import QAAnalysis_stock
+from QUANTAXIS.QAFetch.QAQuery import QA_fetch_stock_info
+from QUANTAXIS.QAFetch.QAQuery_Advance import (QA_fetch_stock_block_adv,
+                                               QA_fetch_stock_day_adv,
+                                               QA_fetch_stock_min_adv)
+from QUANTAXIS.QAFetch.QATdx import QA_fetch_get_stock_info
+from QUANTAXIS.QAFetch.QATdx_adv import QA_Tdx_Executor
+from QUANTAXIS.QAUtil.QADate_trade import QA_util_get_real_datelist
+
+
+
[docs]def get_gap_trade(gap): + return QA_util_get_real_datelist(datetime.date.today() + datetime.timedelta(days=-int(gap)), datetime.date.today())
+ + +#from QUANTAXIS.QAAnalysis.QAAnalysis_dataframe import QAAnalysis_stock +
[docs]class QAAnalysis_block(): + def __init__(self, block=None, block_name=None, lens=90, *args, **kwargs): + + try: + self.block_code = block.code + except: + self.block_code = block + + if block_name is not None: + self.block_code = QA_fetch_stock_block_adv().get_block(block_name).code + self.lens = lens + # self.Executor=QA_Tdx_Executor() + +
[docs] def market_data(self, start, end, _type='day'): + return QA_fetch_stock_day_adv(self.block_code, start, end)
+ + @property + def week_data(self): + 'this weekly data' + 'return a QUANTAXIS DATASTRUCT' + _start, _end = get_gap_trade(7) + return self.market_data(_start, _end) + + @property + def month_data(self): + 'this monthly data' + 'return a QUANTAXIS DATASTRUCT' + _start, _end = get_gap_trade(90) + return self.market_data(_start, _end) + + @property + def _data(self): + _start, _end = get_gap_trade(self.lens) + return self.market_data(_start, _end) + +
[docs] def block_price(self, market_data=None): + if market_data is None: + market_data = self._data.to_qfq() + else: + market_data = market_data.to_qfq() + return QAAnalysis_stock(market_data).price.groupby('date').mean()
+ +
[docs] def block_pcg(self, market_data=None): + if market_data is None: + market_data = self._data.to_qfq() + else: + market_data = market_data.to_qfq() + return QAAnalysis_stock(market_data).day_pct_change.groupby('date').mean()
+ +
[docs] def stock_turnover(self, market_data=None): + if market_data is None: + market_data = self._data.to_qfq() + else: + market_data = market_data.to_qfq() + _data = market_data.data + _info = self.stock_info() + _data['ltgb'] = _data.code.apply(lambda x: _info.liutongguben[x]) + _data['turnover'] = 100 * _data['volume'] / _data['ltgb'] + return _data
+ +
[docs] def block_turnover(self, market_data=None): + return self.stock_turnover(market_data).turnover.groupby('date').mean()
+ +
[docs] def stock_info(self): + data = [] + + for item in self.block_code: + try: + _data = QA_fetch_stock_info(item) + except: + _data = QA_fetch_get_stock_info(item) + data.append(_data) + + return pd.concat(data).set_index('code', drop=False)
+ +
[docs] def res(self): + import matplotlib.pyplot as plt + self.block_pcg().plot() + self.block_turnover().plot() + plt.show()
+ + + +
[docs]class QAAnalysis_codewithblock(): + def __init__(self, block): + self.block = block + self.code = block.code
+ + + + + +if __name__ == "__main__": + import QUANTAXIS as QA + # print(get_this_week()) + ana = QAAnalysis_block( + QA.QA_fetch_stock_block_adv().get_block('昨日涨停').code) + + """ + 计算换手率 + d=QA.QA_fetch_get_stock_day('tdx','000001','2017-11-14','2017-11-15','00').vol.values[0]*100 # 一手100股 + f=QA.QA_fetch_get_stock_info('tdx','000001').liutongguben.values[0] + turnover=d/f + """ + # print(js) + + x = [] + y = [] + block = QA.QA_fetch_stock_block_adv().get_type('gn').block_name + for item in block: + print(item) + data = QAAnalysis_block(block_name=item) + x.append(data.block_pcg()) + y.append(data.block_turnover()) + print(len(x)) + print(len(y)) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_dataframe.html b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_dataframe.html new file mode 100644 index 000000000..d0ed981a7 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_dataframe.html @@ -0,0 +1,311 @@ + + + + + + + + QUANTAXIS.QAAnalysis.QAAnalysis_dataframe — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAAnalysis.QAAnalysis_dataframe

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import statistics
+from functools import lru_cache
+
+
+#import scipy
+#import statsmodels
+#from scipy import integrate, optimize, stats
+
+#from QUANTAXIS.QAData.QADataStruct import QA_DataStruct_Index_day,QA_DataStruct_Index_min,QA_DataStruct_Stock_day,QA_DataStruct_Stock_min
+
+
+
[docs]class QAAnalysis_stock(): + """ + 行情分析器 + + 计算所有的指标 + + """ + + def __init__(self, dataStruct, *args, **kwargs): + try: + # 如果是QA_Data_系列 + self.data = dataStruct.data + self._data = dataStruct + except AttributeError: + # 如果是dataframe + self.data = dataStruct + + # self.data=DataSturct.data + + def __repr__(self): + return '< QAAnalysis_Stock >' + + def __call__(self): + return self.data + + # 使用property进行懒运算 + + @property + def open(self): + return self.data['open'] + + @property + def high(self): + return self.data['high'] + + @property + def low(self): + return self.data['low'] + + @property + def close(self): + return self.data['close'] + + @property + def vol(self): + if 'volume' in self.data.columns: + return self.data['volume'] + else: + return self.data['vol'] + + @property + def volume(self): + if 'volume' in self.data.columns: + return self.data['volume'] + else: + return self.data['vol'] + + @property + def date(self): + + return self.data.index.levels[self.data.index.names.index( + 'date')] if 'date' in self.data.index.names else self.data['date'] + + @property + def datetime(self): + + return self.data.index.levels[self.data.index.names.index( + 'datetime')] if 'datetime' in self.data.index.names else self.data.index.levels[self.data.index.names.index( + 'date')] + + @property + def index(self): + return self.data.index + + # 均价 + @property + def price(self): + return 0.25 * (self.open + self.close + self.high + self.low) + + @property + def max(self): + return self.price.max() + + @property + def min(self): + return self.price.min() + + @property + def mean(self): + return self.price.mean() + # 一阶差分序列 + + @property + def price_diff(self): + return self.price.diff(1) + + # 样本方差(无偏估计) population variance + @property + def pvariance(self): + return statistics.pvariance(self.price) + + # 方差 + @property + def variance(self): + + return statistics.variance(self.price) + # 标准差 + + @property + def day_pct_change(self): + return (self.open - self.close) / self.open + + @property + def stdev(self): + + return statistics.stdev(self.price) + # 样本标准差 + + @property + def pstdev(self): + return statistics.pstdev(self.price) + + # 调和平均数 + @property + def mean_harmonic(self): + return statistics.harmonic_mean(self.price) + + # 众数 + @property + def mode(self): + return statistics.mode(self.price) + + # 波动率 + + # 振幅 + @property + def amplitude(self): + return self.max - self.min + # 偏度 Skewness + + @property + def skewnewss(self): + return self.price.skew() + # 峰度Kurtosis + + @property + def kurtosis(self): + return self.price.kurt() + # 百分数变化 + + @property + def pct_change(self): + return self.price.pct_change() + + # 平均绝对偏差 + @property + def mad(self): + return self.price.mad() + + # 函数 指标计算 +
[docs] @lru_cache() + def add_func(self, func, *arg, **kwargs): + return func(self.data, *arg, **kwargs)
+ + +
[docs]def shadow_calc(data): + """计算上下影线 + + Arguments: + data {DataStruct.slice} -- 输入的是一个行情切片 + + Returns: + up_shadow {float} -- 上影线 + down_shdow {float} -- 下影线 + entity {float} -- 实体部分 + date {str} -- 时间 + code {str} -- 代码 + """ + + up_shadow = abs(data.high - (max(data.open, data.close))) + down_shadow = abs(data.low - (min(data.open, data.close))) + entity = abs(data.open - data.close) + towards = True if data.open < data.close else False + print('=' * 15) + print('up_shadow : {}'.format(up_shadow)) + print('down_shadow : {}'.format(down_shadow)) + print('entity: {}'.format(entity)) + print('towards : {}'.format(towards)) + return up_shadow, down_shadow, entity, data.date, data.code
+ + +
[docs]class shadow(): + def __init__(self, data): + self.data = data + +
[docs] def shadow_panel(self): + return
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_machinelearning.html b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_machinelearning.html new file mode 100644 index 000000000..6eaf0cf33 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_machinelearning.html @@ -0,0 +1,125 @@ + + + + + + + + QUANTAXIS.QAAnalysis.QAAnalysis_machinelearning — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAAnalysis.QAAnalysis_machinelearning

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""
+一个通用的可以接入不同模型的类
+"""
+
+
+
[docs]class QAAnalysis_Machine_Learning(): + def __init__(self, *args, **kwargs): + pass + +
[docs] def training(self): + pass
+ +
[docs] def data_co(self): + pass
+ +
[docs] def cross_valid(self): + pass
+ +
[docs] def load_modules(self): + pass
+ +
[docs] def load_data(self): + pass
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_series.html b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_series.html new file mode 100644 index 000000000..3107f7081 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_series.html @@ -0,0 +1,105 @@ + + + + + + + + QUANTAXIS.QAAnalysis.QAAnalysis_series — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAAnalysis.QAAnalysis_series

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+
[docs]def QAAnalysis_Series_slope(data): + pass
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_tick.html b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_tick.html new file mode 100644 index 000000000..e56d0a8b2 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_tick.html @@ -0,0 +1,130 @@ + + + + + + + + QUANTAXIS.QAAnalysis.QAAnalysis_tick — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAAnalysis.QAAnalysis_tick

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from QUANTAXIS.QAData.QADataStruct import QA_DataStruct_Stock_transaction
+from QUANTAXIS.QAFetch.QATdx import QA_fetch_get_stock_transaction, QA_fetch_get_future_transaction_realtime
+from QUANTAXIS.QAFetch.QAQuery import QA_fetch_stock_info
+
+
+
[docs]class QAAnalysis_Transaction(): + def __init__(self): + self.data = None + self.code = None + self.stock_info = None + +
[docs] def get_data(self, code, start, end): + self.code = code + try: + self.data = QA_DataStruct_Stock_transaction( + QA_fetch_get_stock_transaction(code, start, end)) + return self.data + except Exception as e: + raise e
+ +
[docs] def get_stock_info(self, code): + try: + self.stock_info = QA_fetch_stock_info(code) + except Exception as e: + raise e
+ +
[docs] def winner(self): + pass
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_trade.html b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_trade.html new file mode 100644 index 000000000..2c59c8ece --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAAnalysis/QAAnalysis_trade.html @@ -0,0 +1,178 @@ + + + + + + + + QUANTAXIS.QAAnalysis.QAAnalysis_trade — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAAnalysis.QAAnalysis_trade

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from statistics import mean
+
+import pandas as pd
+
+from QUANTAXIS.QAARP.QAAccount import QA_Account
+from QUANTAXIS.QAARP.QARisk import QA_Performance, QA_Risk
+from QUANTAXIS.QAEngine.QAEvent import QA_Event
+from QUANTAXIS.QAFetch.QAQuery import (QA_fetch_backtest_history,
+                                       QA_fetch_backtest_info)
+from QUANTAXIS.QAFetch.QAQuery_Advance import QA_fetch_stock_day_adv
+from QUANTAXIS.QAMarket.QABacktestBroker import QA_BacktestBroker
+from QUANTAXIS.QAUtil.QADate_trade import (QA_util_date_gap,
+                                           QA_util_get_next_day)
+from QUANTAXIS.QAUtil.QAParameter import (AMOUNT_MODEL, ORDER_DIRECTION,
+                                          ORDER_MODEL)
+
+
+
[docs]class QAAnalysis_trade(): + + """ + Account/Portfolio是一个标准单元,所有成交记录分析 都会被加载到该单元中进行分析 + 当我们只有一个成交记录的时候,我们会创建一个账户单元 + """ + + def __init__(self, init_assets, *args, **kwargs): + self.account = QA_Account(init_assets=init_assets) + self.backtest_broker = QA_BacktestBroker() + +
[docs] def import_trade(self, trade): + """ + trade是一个可迭代的list/generator + """ + for item in trade: + self.make_deal(item.code, item.datetime, item.amount, + item.towards, item.price.item.order_model, item.amount_model)
+ +
[docs] def make_deal(self, code, datetime, amount=100, towards=ORDER_DIRECTION.BUY, price=0, order_model=ORDER_MODEL.MARKET, amount_model=AMOUNT_MODEL.BY_AMOUNT): + """ + 这是一个一定会成交,并且立刻结转(及t+0)的交易入口 + """ + self.account.receive_deal(self.backtest_broker.receive_order(QA_Event(order=self.account.send_order( + code=code, time=datetime, amount=amount, towards=towards, price=price, order_model=order_model, amount_model=amount_model + )))) + self.account.settle()
+ + + + # @property + # def codes(self): + # return self.code + + # def get_stock_tradehistory(self, code): + # return self.history.query('code=="{}"'.format(code)) + + # def get_stock_tradedetail(self, code): + # return self.detail.query('code=="{}"'.format(code)) + + # def get_loss_trade(self, num=5): + # return self.detail[self.detail.pnl_precentage <= 0].sort_values(by=['pnl_precentage'], ascending=True).head(num) + + # def get_profit_trade(self, num=5): + # return self.detail[self.detail.pnl_precentage >= 0].sort_values(by=['pnl_precentage'], ascending=False).head(num) + + # def get_trade_marketdata(self, rx, gap=3): + # return QA_fetch_stock_day_adv(rx.code.values[0], QA_util_date_gap(rx.date.values[0], gap, methods='lt'), QA_util_date_gap(rx.sell_date.values[0][-1], gap, methods='gt')) + + # def get_trade_before_and_after_pnl(self, rx, N=3, M=10): + # data = self.get_trade_marketdata(rx, M) + + +def _mean(list_): + if len(list_) > 0: + return mean(list_) + else: + return 'No Data' +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QABacktest/QAAnalysis.html b/_build/html/_modules/QUANTAXIS/QABacktest/QAAnalysis.html new file mode 100644 index 000000000..0cabb8f2a --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QABacktest/QAAnalysis.html @@ -0,0 +1,340 @@ + + + + + + + + QUANTAXIS.QABacktest.QAAnalysis — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QABacktest.QAAnalysis

+# Encoding:UTF-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+"""
+Analysis Center for Backtest
+we will give some function
+"""
+import math
+import sys
+
+import numpy
+import pandas as pd
+
+from QUANTAXIS.QAFetch.QAQuery import QA_fetch_stock_day
+from QUANTAXIS.QAUtil import QA_util_log_info, trade_date_sse
+
+
+
[docs]def QA_backtest_analysis_backtest(client, code_list, assets_d, account_days, message, total_date, benchmark_data): + + # 主要要从message_history分析 + # 1.收益率 + # 2.胜率 + # 3.回撤 + """ + Annualized Returns: 策略年化收益率。表示投资期限为一年的预期收益率。 + 具体计算方式为 (策略最终价值 / 策略初始价值)^(250 / 回测交易日数量) - 1 + + Alpha:阿尔法 + 具体计算方式为 (策略年化收益 - 无风险收益) - beta × (参考标准年化收益 - 无风险收益),这里的无风险收益指的是中国固定利率国债收益率曲线上10年期国债的年化到期收益率。 + + Beta:贝塔 + 具体计算方法为 策略每日收益与参考标准每日收益的协方差 / 参考标准每日收益的方差 。 + + Sharpe Ratio:夏普比率。表示每承受一单位总风险,会产生多少的超额报酬。 + 具体计算方法为 (策略年化收益率 - 回测起始交易日的无风险利率) / 策略收益波动率 。 + + Volatility:策略收益波动率。用来测量资产的风险性。 + 具体计算方法为 策略每日收益的年化标准差 。 + + Information Ratio:信息比率。衡量超额风险带来的超额收益。 + 具体计算方法为 (策略每日收益 - 参考标准每日收益)的年化均值 / 年化标准差 。 + + Max Drawdown:最大回撤。描述策略可能出现的最糟糕的情况。 + 具体计算方法为 max(1 - 策略当日价值 / 当日之前虚拟账户最高价值) + + + 单次交易收益 + 收益/次数的频次直方图 + 单日最大持仓 + """ + # 数据检查 + if (len(benchmark_data)) < 1: + QA_util_log_info('Wrong with benchmark data ! ') + sys.exit() + + # 计算一个benchmark + # 这个benchmark 是在开始的那天 市价买入和策略所选标的一致的所有股票,然后一直持仓 + data = pd.concat([pd.DataFrame(message['body']['account']['history'], + columns=['time', 'code', 'price', 'towards', 'amount', 'order_id', 'trade_id', 'commission']), + pd.DataFrame(message['body']['account']['assets'], columns=['assets'])], axis=1) + data['time'] = pd.to_datetime(data['time']) + data.set_index('time', drop=False, inplace=True) + + trade_history = message['body']['account']['history'] + cash = message['body']['account']['cash'] + assets = message['body']['account']['assets'] + + #assets_= data.resample('D').last().dropna() + # 计算交易日 + trade_date = account_days + # benchmark资产 + benchmark_assets = QA_backtest_calc_benchmark( + benchmark_data, assets[0]) + # d2=pd.concat([data.resample('D').last(),pd.DataFrame(benchmark_assets,columns=['benchmark'])]) + # benchmark年化收益 + benchmark_annualized_returns = QA_backtest_calc_profit_per_year( + benchmark_assets, len(total_date)) + # 计算账户的收益 + + # days=len(assest_history)-1 + # 策略年化收益 + annualized_returns = QA_backtest_calc_profit_per_year( + assets_d, len(total_date)) + + # 收益矩阵 + assest_profit = QA_backtest_calc_profit_matrix(assets) + benchmark_profit = QA_backtest_calc_profit_matrix(benchmark_assets) + + # 策略日收益 + profit_day = QA_backtest_calc_profit_matrix(assets_d) + # 胜率 + win_rate = QA_backtest_calc_win_rate(assest_profit) + # 日胜率 + win_rate_day = QA_backtest_calc_win_rate(profit_day) + # 年化波动率 + volatility_year = QA_backtest_calc_volatility(profit_day) + benchmark_volatility_year = QA_backtest_calc_volatility(benchmark_profit) + # 夏普比率 + sharpe = QA_backtest_calc_sharpe( + annualized_returns, 0.05, volatility_year) + + # 最大回撤 + max_drop = QA_backtest_calc_dropback_max(assets_d) + + # 计算beta + beta = QA_backtest_calc_beta(profit_day, benchmark_profit) + # 计算Alpha + alpha = QA_backtest_calc_alpha( + annualized_returns, benchmark_annualized_returns, beta, 0.05) + message = { + 'code': code_list, + 'annualized_returns': annualized_returns, + 'benchmark_annualized_returns': benchmark_annualized_returns, + 'assets': assets_d[1:], + 'benchmark_assets': benchmark_assets[1:], + 'vol': volatility_year, + 'benchmark_vol': benchmark_volatility_year, + 'sharpe': sharpe, + 'alpha': alpha, + 'beta': beta, + 'total_date': total_date, + 'trade_date': trade_date, + 'max_drop': max_drop, + 'win_rate': win_rate} + return message
+ + +
[docs]def QA_backtest_calc_assets(trade_history, assets): + assets_d = [] + trade_date = [] + for i in range(0, len(trade_history), 1): + if trade_history[i][0] not in trade_date: + trade_date.append(trade_history[i][0]) + assets_d.append(assets[i]) + else: + assets_d.pop(-1) + assets_d.append(assets[i]) + + return assets_d
+ + +
[docs]def QA_backtest_calc_benchmark(benchmark_data, init_assets): + + return list(benchmark_data['close'] / float(benchmark_data['open'][0]) * float(init_assets))
+ + +
[docs]def QA_backtest_calc_alpha(annualized_returns, benchmark_annualized_returns, beta, r): + + alpha = (annualized_returns - r) - (beta) * \ + (benchmark_annualized_returns - r) + return alpha
+ + +
[docs]def QA_backtest_calc_beta(assest_profit, benchmark_profit): + if len(assest_profit) < len(benchmark_profit): + for i in range(0, len(benchmark_profit) - len(assest_profit), 1): + assest_profit.append(0) + elif len(assest_profit) > len(benchmark_profit): + for i in range(0, len(assest_profit) - len(benchmark_profit), 1): + benchmark_profit.append(0) + calc_cov = numpy.cov(assest_profit, benchmark_profit) + beta = calc_cov[0, 1] / calc_cov[1, 1] + return beta
+ + +
[docs]def QA_backtest_calc_profit(assest_history): + return (assest_history[-1] / assest_history[1]) - 1
+ + +
[docs]def QA_backtest_calc_profit_per_year(assest_history, days): + return math.pow(float(assest_history[-1]) / float(assest_history[0]), 250.0 / float(days)) - 1.0
+ + +
[docs]def QA_backtest_calc_profit_matrix(assest_history): + assest_profit = [] + if len(assest_history) > 1: + assest_profit = [assest_history[i + 1] / assest_history[i] - + 1.0 for i in range(len(assest_history) - 1)] + return assest_profit
+ + +
[docs]def QA_backtest_calc_volatility(assest_profit_matrix): + # 策略每日收益的年化标准差 + assest_profit = assest_profit_matrix + + volatility_day = numpy.std(assest_profit) + volatility_year = volatility_day * math.sqrt(250) + return volatility_year
+ + +
[docs]def QA_backtest_calc_dropback_max(history): + drops = [] + for i in range(1, len(history), 1): + maxs = max(history[:i]) + cur = history[i - 1] + drop = 1 - cur / maxs + drops.append(drop) + max_drop = max(drops) + return max_drop
+ + +
[docs]def QA_backtest_calc_sharpe(annualized_returns, r, volatility_year): + '计算夏普比率' + return (annualized_returns - r) / volatility_year
+ + +
[docs]def QA_backtest_calc_trade_date(history): + '计算交易日期' + trade_date = [] + + # trade_date_sse.index(history[-1][0])-trade_date_sse.index(history[0][0]) + for i in range(0, len(history), 1): + if history[i][0] not in trade_date: + trade_date.append(history[i][0]) + return trade_date
+ + +
[docs]def calc_trade_time(history): + return len(history)
+ + +
[docs]def calc_every_pnl(detail): + pass
+ + +
[docs]def QA_backtest_calc_win_rate(profit_day): + # 大于0的次数 + abovez = 0 + belowz = 0 + for i in range(0, len(profit_day) - 1, 1): + if profit_day[i] > 0: + abovez = abovez + 1 + elif profit_day[i] < 0: + belowz = belowz + 1 + if belowz == 0: + belowz = 1 + if abovez == 0: + abovez = 1 + win_rate = abovez / (abovez + belowz) + return win_rate
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QABacktest/QABacktest.html b/_build/html/_modules/QUANTAXIS/QABacktest/QABacktest.html new file mode 100644 index 000000000..d84bdccff --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QABacktest/QABacktest.html @@ -0,0 +1,243 @@ + + + + + + + + QUANTAXIS.QABacktest.QABacktest — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QABacktest.QABacktest

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import time
+from functools import lru_cache
+
+from QUANTAXIS.QAARP.QAPortfolio import QA_Portfolio
+from QUANTAXIS.QAARP.QAUser import QA_User
+from QUANTAXIS.QAEngine.QAEvent import QA_Event
+from QUANTAXIS.QAFetch.QAQuery_Advance import QA_fetch_stock_day_adv, QA_fetch_stock_min_adv
+from QUANTAXIS.QAMarket.QABacktestBroker import QA_BacktestBroker
+from QUANTAXIS.QAMarket.QAMarket import QA_Market
+from QUANTAXIS.QAUtil.QAParameter import (AMOUNT_MODEL, BROKER_EVENT,
+                                          BROKER_TYPE, ENGINE_EVENT, FREQUENCE,
+                                          MARKET_TYPE, ORDER_DIRECTION,
+                                          ORDER_MODEL)
+
+
+
+
[docs]class QA_Backtest(): + """BACKTEST + + BACKTEST的主要目的: + + - 引入时间轴环境,获取全部的数据,然后按生成器将数据迭代插入回测的BROKER + (这一个过程是模拟在真实情况中市场的时间变化和价格变化) + + - BROKER有了新数据以后 会通知MARKET交易前置,MARKET告知已经注册的所有的ACCOUNT 有新的市场数据 + + - ACCOUNT 获取了新的市场函数,并将其插入他已有的数据中(update) + + - ACCOUNT 底下注册的策略STRATEGY根据新的市场函数,产生新的买卖判断,综合生成信号 + + - 买卖判断通过交易前置发送给对应的BROKER,进行交易 + + - BROKER发送SETTLE指令 结束这一个bar的所有交易,进行清算 + + - 账户也进行清算,更新持仓,可卖,可用现金等 + + - 迭代循环直至结束回测 + + - 回测去计算这段时间的各个账户收益,并给出综合的最终结果 + + """ + + def __init__(self, market_type, frequence, start, end, code_list, commission_fee,): + self.user = QA_User() + self.if_settled = False + self.account = None + self.portfolio = None + + self.market = QA_Market() + self.market_type = market_type + self.frequence = frequence + self.broker = QA_BacktestBroker(commission_fee) + self.broker_name = 'backtest_broker' + + self.start = start + self.end = end + self.code_list = code_list + + if self.market_type is MARKET_TYPE.STOCK_CN and self.frequence is FREQUENCE.DAY: + self.ingest_data = QA_fetch_stock_day_adv( + self.code_list, self.start, self.end).to_qfq().panel_gen + elif self.market_type is MARKET_TYPE.STOCK_CN and self.frequence[-3:] == 'min': + self.ingest_data = QA_fetch_stock_min_adv( + self.code_list, self.start, self.end, self.frequence).to_qfq().panel_gen + + def _generate_account(self): + """generate a simple account + """ + + self.account, self.portfolio = self.user.generate_simpleaccount() + +
[docs] def start_market(self): + """start the market thread and register backtest broker thread + """ + + self.market.start() + self.market.register(self.broker_name, self.broker) + self.market.login(self.broker_name, self.account.account_cookie, + self.account)
+ +
[docs] def run(self): + """generator driven data flow + """ + # 如果出现了日期的改变 才会进行结算的事件 + + _date = None + for data in self.ingest_data:#对于在ingest_data中的数据 + date = data.date[0]# + if self.market_type is MARKET_TYPE.STOCK_CN: #如果是股票市场 + if _date != date:# 如果新的date + self.market._settle(self.broker_name) + elif self.market_type in [MARKET_TYPE.FUND_CN, MARKET_TYPE.INDEX_CN, MARKET_TYPE.FUTURE_CN]: + self.market._settle(self.broker_name) + self.broker.run(QA_Event( + event_type=ENGINE_EVENT.UPCOMING_DATA, + market_data=data)) + self.market.upcoming_data( + self.broker_name, data) + self.market.trade_engine.join() + + _date = date + + self.after_success()
+ +
[docs] def after_success(self): + """called when all trading fininshed, for performance analysis + """ + + for po in self.user.portfolio_list.keys(): + for ac in self.user.get_portfolio(po).accounts.keys(): + accounts = self.user.get_portfolio(po).get_account(ac) + print(accounts.hold) + + print(accounts.history_table) + + self.stop()
+ +
[docs] def stop(self): + """stop all the market trade enging threads and all subthreads + """ + + self.market.trade_engine.stop_all() + self.market.trade_engine.stop()
+ + +
[docs]class BACKTEST_FRAMEWORK(): + pass
+ +if __name__ == '__main__': + backtest = QA_Backtest(market_type=MARKET_TYPE.STOCK_CN, + frequence=FREQUENCE.DAY, + start='2017-01-01', + end='2017-01-31', + code_list=['000001', '600010'], + commission_fee=0.00015) + backtest._generate_account() + backtest.start_market() + backtest.run() + + # backtest.run() +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QABacktest/QAResult.html b/_build/html/_modules/QUANTAXIS/QABacktest/QAResult.html new file mode 100644 index 000000000..40b3d2e1a --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QABacktest/QAResult.html @@ -0,0 +1,185 @@ + + + + + + + + QUANTAXIS.QABacktest.QAResult — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QABacktest.QAResult

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from statistics import mean
+
+import pandas as pd
+
+from QUANTAXIS.QAFetch.QAQuery import (QA_fetch_backtest_history,
+                                       QA_fetch_backtest_info)
+from QUANTAXIS.QAFetch.QAQuery_Advance import QA_fetch_stock_day_adv
+from QUANTAXIS.QAUtil.QADate_trade import QA_util_date_gap
+
+
+
[docs]class backtest_result_analyzer(): + def __init__(self, cookie_id, *args, **kwargs): + self.cookie = cookie_id + self.backtest_history = QA_fetch_backtest_history(cookie=self.cookie) + self.backtest_info = QA_fetch_backtest_info(account_cookie=self.cookie) + + @property + def history(self): + data = pd.DataFrame(self.backtest_history[0]['history'], columns=[ + 'datetime', 'code', 'price', 'towards', 'amounts', 'o_id', 'd_id', 'commission']) + return data.drop(['o_id', 'd_id'], axis=1) + + @property + def detail(self): + detail = pd.DataFrame(self.backtest_history[0]['detail'], columns=['date', 'code', 'price', 'amounts', 'order_id', + 'trade_id', 'sell_price', 'sell_order_id', + 'sell_trade_id', 'sell_date', 'left_amount', + 'commission']) + + detail['sell_average'] = detail['sell_price'].apply(lambda x: _mean(x)) + + try: + detail['pnl_price'] = detail['sell_average'] - \ + detail['price'] + + detail['pnl'] = detail['pnl_price'] * ( + detail['amounts'] - detail['left_amount']) - detail['commission'] + + detail['pnl_precentage'] = detail['pnl_price'] / detail['price'] + except: + pass + + return detail.drop( + ['order_id', 'trade_id', 'sell_order_id', 'sell_trade_id'], axis=1) + + @property + def codes(self): + return self.history.code.unique().tolist() + +
[docs] def get_stock_tradehistory(self, code): + return self.history.query('code=="{}"'.format(code))
+
[docs] def get_stock_tradedetail(self, code): + return self.detail.query('code=="{}"'.format(code))
+ +
[docs] def get_loss_trade(self, num=5): + return self.detail[self.detail.pnl_precentage <= 0].sort_values(by=['pnl_precentage'], ascending=True).head(num)
+ +
[docs] def get_profit_trade(self, num=5): + return self.detail[self.detail.pnl_precentage >= 0].sort_values(by=['pnl_precentage'], ascending=False).head(num)
+ +
[docs] def get_trade_marketdata(self, rx, gap=3): + return QA_fetch_stock_day_adv(rx.code.values[0], QA_util_date_gap(rx.date.values[0], gap, methods='lt'), QA_util_date_gap(rx.sell_date.values[0][-1], gap, methods='gt'))
+ +
[docs] def get_trade_before_and_after_pnl(self, rx, N=3, M=10): + data = self.get_trade_marketdata(rx, M)
+ + +def _mean(list_): + if len(list_) > 0: + return mean(list_) + else: + return 'No Data' + + +if __name__ == '__main__': + ana = backtest_result_analyzer(cookie_id='0.0792467630583924') + print(ana.detail) + code = ana.codes + print(ana.get_stock_tradehistory(code[1])) + print(ana.get_stock_tradedetail(code[1])) + print(ana.get_loss_trade()) + print(ana.get_profit_trade()) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QABacktest/backtest_setting.html b/_build/html/_modules/QUANTAXIS/QABacktest/backtest_setting.html new file mode 100644 index 000000000..cb2a5c44d --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QABacktest/backtest_setting.html @@ -0,0 +1,126 @@ + + + + + + + + QUANTAXIS.QABacktest.backtest_setting — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QABacktest.backtest_setting

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os
+import sys
+
+
+
[docs]class backtest_setting(): + def __init__(self, topic, version, backtest_name, sql_setting): + self.topic = topic + self.version = version + self.backtest_name = backtest_name + + self.sql_setting = sql_setting + + @property + def absoult_path(self): + return sys.path[0] + + @property + def dirs(self): + return '{}{}QUANTAXIS_RESULT{}{}{}{}{}'.format( + self.absoult_path, os.sep, os.sep, self.topic, os.sep, self.version, os.sep) + + @property + def database_uri(self): + return self.sql_setting.client.quantaxis
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QACmd.html b/_build/html/_modules/QUANTAXIS/QACmd.html new file mode 100644 index 000000000..02d57c89d --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QACmd.html @@ -0,0 +1,327 @@ + + + + + + + + QUANTAXIS.QACmd — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QACmd

+# encoding: UTF-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import cmd
+import csv
+import os
+import shutil
+import string
+import sys
+import platform
+import subprocess
+import requests
+
+from QUANTAXIS.QABacktest.QAAnalysis import QA_backtest_analysis_backtest
+from QUANTAXIS.QAUtil import QA_util_log_info, QA_Setting, QA_util_mongo_initial
+from QUANTAXIS import (QA_SU_save_stock_list, QA_SU_save_stock_min, QA_SU_save_stock_xdxr,
+                       QA_SU_save_stock_block, QA_SU_save_stock_info,
+                       QA_SU_save_stock_day, QA_SU_save_index_day, QA_SU_save_index_min,
+                       QA_SU_save_etf_day, QA_SU_save_etf_min)
+
+from QUANTAXIS import __version__
+
+
+
[docs]class CLI(cmd.Cmd): + + def __init__(self): + cmd.Cmd.__init__(self) + self.prompt = 'QUANTAXIS> ' # 定义命令行提示符 + +
[docs] def do_shell(self, arg): + "run a shell commad" + print(">", arg) + sub_cmd = subprocess.Popen(arg, shell=True, stdout=subprocess.PIPE) + print(sub_cmd.communicate()[0])
+ +
[docs] def do_version(self, arg): + QA_util_log_info(__version__)
+ +
[docs] def help_version(self): + print("syntax: version [message]",) + print("-- prints a version message")
+ + #@click.command() + #@click.option('--e', default=1, help='Number of greetings.') +
[docs] def do_examples(self, arg): + QA_util_log_info('QUANTAXIS example') + now_path = os.getcwd() + #project_dir = os.path.dirname(os.path.abspath(__file__)) + + data=requests.get('https://codeload.github.com/yutiansut/QADemo/zip/master') + with open("{}{}QADEMO.zip".format(now_path,os.sep), "wb") as code: + code.write(data.content) + + QA_util_log_info( + 'Successfully generate QADEMO in : {}, for more examples, please visit https://github.com/yutiansut/qademo'.format(now_path))
+ +
[docs] def help_examples(self): + print('make a sample backtest framework')
+ +
[docs] def do_drop_database(self, arg): + QA_util_mongo_initial()
+ +
[docs] def help_drop_database(self): + print('drop quantaxis\'s databases')
+ +
[docs] def do_quit(self, arg): # 定义quit命令所执行的操作 + sys.exit(1)
+ +
[docs] def help_quit(self): # 定义quit命令的帮助输出 + print("syntax: quit",) + print("-- terminates the application")
+ +
[docs] def do_clean(self, arg): + try: + if platform.system() == 'Windows': + os.popen('del back*csv') + os.popen('del *log') + else: + os.popen('rm -rf back*csv') + os.popen('rm -rf *log') + + except: + pass
+ +
[docs] def help_clean(self): + QA_util_log_info('Clean the old backtest reports and logs')
+ +
[docs] def do_exit(self, arg): # 定义quit命令所执行的操作 + sys.exit(1)
+ +
[docs] def help_exit(self): + print('syntax: exit') + print("-- terminates the application")
+ +
[docs] def do_save(self, arg): + # 仅仅是为了初始化才在这里插入用户,如果想要注册用户,要到webkit底下注册 + if arg == '': + print( + "Usage: \n\ + save all : save stock_day/xdxr/ index_day/ stock_list \n\ + save X|x : save stock_day/xdxr/min index_day/min etf_day/min stock_list/block \n\ + save day : save stock_day/xdxr index_day etf_day stock_list \n\ + save min : save stock_min/xdxr index_min etf_min stock_list \n\ + ------------------------------------------------------------ \n\ + save stock_day : save stock_day \n\ + save stock_xdxr : save stock_xdxr \n\ + save stock_min : save stock_min \n\ + save index_day : save index_day \n\ + save index_min : save index_min \n\ + save etf_day : save etf_day \n\ + save etf_min : save etf_min \n\ + save stock_list : save stock_list \n\ + save stock_block: save stock_block \n\ + save stock_info : save stock_info \n\ + ----------------------------------------------------------\n\ + if you just want to save daily data just\n\ + save all+ save stock_block+save stock_info, it about 1G data \n\ + if you want to save save the fully data including min level \n\ + save x + save stock_info \n \n\ + @yutiansut\n\ + @QUANTAXIS\n\ + ") + else: + arg = arg.split(' ') + if len(arg) == 1 and arg[0] == 'all': + if QA_Setting().client.quantaxis.user_list.find({'username': 'admin'}).count() == 0: + QA_Setting().client.quantaxis.user_list.insert( + {'username': 'admin', 'password': 'admin'}) + QA_SU_save_stock_day('tdx') + QA_SU_save_stock_xdxr('tdx') + # QA_SU_save_stock_min('tdx') + QA_SU_save_index_day('tdx') + # QA_SU_save_index_min('tdx') + # QA_SU_save_etf_day('tdx') + # QA_SU_save_etf_min('tdx') + QA_SU_save_stock_list('tdx') + # QA_SU_save_stock_block('tdx') + # QA_SU_save_stock_info('tdx') + elif len(arg) == 1 and arg[0] == 'day': + if QA_Setting().client.quantaxis.user_list.find({'username': 'admin'}).count() == 0: + QA_Setting().client.quantaxis.user_list.insert( + {'username': 'admin', 'password': 'admin'}) + QA_SU_save_stock_day('tdx') + QA_SU_save_stock_xdxr('tdx') + # QA_SU_save_stock_min('tdx') + QA_SU_save_index_day('tdx') + # QA_SU_save_index_min('tdx') + QA_SU_save_etf_day('tdx') + # QA_SU_save_etf_min('tdx') + QA_SU_save_stock_list('tdx') + QA_SU_save_stock_block('tdx') + elif len(arg) == 1 and arg[0] == 'min': + if QA_Setting().client.quantaxis.user_list.find({'username': 'admin'}).count() == 0: + QA_Setting().client.quantaxis.user_list.insert( + {'username': 'admin', 'password': 'admin'}) + # QA_SU_save_stock_day('tdx') + QA_SU_save_stock_xdxr('tdx') + QA_SU_save_stock_min('tdx') + # QA_SU_save_index_day('tdx') + QA_SU_save_index_min('tdx') + # QA_SU_save_etf_day('tdx') + QA_SU_save_etf_min('tdx') + QA_SU_save_stock_list('tdx') + # QA_SU_save_stock_block('tdx') + elif len(arg) == 1 and arg[0] in ['X', 'x']: + if QA_Setting().client.quantaxis.user_list.find({'username': 'admin'}).count() == 0: + QA_Setting().client.quantaxis.user_list.insert( + {'username': 'admin', 'password': 'admin'}) + QA_SU_save_stock_day('tdx') + QA_SU_save_stock_xdxr('tdx') + QA_SU_save_stock_min('tdx') + QA_SU_save_index_day('tdx') + QA_SU_save_index_min('tdx') + QA_SU_save_etf_day('tdx') + QA_SU_save_etf_min('tdx') + QA_SU_save_stock_list('tdx') + QA_SU_save_stock_block('tdx') + # QA_SU_save_stock_info('tdx') + else: + for i in arg: + if i == 'insert_user': + if QA_Setting().client.quantaxis.user_list.find({'username': 'admin'}).count() == 0: + QA_Setting().client.quantaxis.user_list.insert( + {'username': 'admin', 'password': 'admin'}) + else: + eval("QA_SU_save_%s('tdx')" % (i))
+ +
[docs] def help_save(self): + QA_util_log_info('Save all the stock data from pytdx')
+ +
[docs] def do_fn(self, arg): + try: + QA_util_log_info(eval(arg)) + except: + print(Exception)
+ +
[docs] def do_help(self, arg): + QA_util_log_info('MORE EXAMPLE on https://github.com/yutiansut/QADemo')
+ +
[docs] def help(self): + QA_util_log_info('fn+methods name')
+ + +
[docs]def sourcecpy(src, des): + src = os.path.normpath(src) + des = os.path.normpath(des) + if not os.path.exists(src) or not os.path.exists(src): + print("folder is not exist") + sys.exit(1) + # 获得原始目录中所有的文件,并拼接每个文件的绝对路径 + os.chdir(src) + src_file = [os.path.join(src, file) for file in os.listdir()] + for source in src_file: + # 若是文件 + if os.path.isfile(source): + shutil.copy(source, des) # 第一个参数是文件,第二个参数目录 + # 若是目录 + if os.path.isdir(source): + p, src_name = os.path.split(source) + des = os.path.join(des, src_name) + shutil.copytree(source, des) # 第一个参数是目录,第二个参数也是目录
+ +# 创建CLI实例并运行 + + +
[docs]def QA_cmd(): + cli = CLI() + cli.cmdloop()
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAData/QADataStruct.html b/_build/html/_modules/QUANTAXIS/QAData/QADataStruct.html new file mode 100644 index 000000000..2b2fad4f6 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAData/QADataStruct.html @@ -0,0 +1,941 @@ + + + + + + + + QUANTAXIS.QAData.QADataStruct — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAData.QADataStruct

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""
+定义一些可以扩展的数据结构
+
+方便序列化/相互转换
+
+"""
+
+import datetime
+import itertools
+import os
+import platform
+import statistics
+import sys
+import time
+import webbrowser
+from copy import copy
+from functools import lru_cache, partial, reduce
+
+import numpy as np
+import pandas as pd
+from pyecharts import Kline
+
+from QUANTAXIS.QAData.base_datastruct import _quotation_base
+from QUANTAXIS.QAData.data_fq import QA_data_stock_to_fq
+from QUANTAXIS.QAData.data_resample import QA_data_tick_resample
+from QUANTAXIS.QAData.proto import stock_day_pb2  # protobuf import
+from QUANTAXIS.QAData.proto import stock_min_pb2
+from QUANTAXIS.QAFetch.QATdx import QA_fetch_get_stock_realtime
+from QUANTAXIS.QAIndicator import EMA, HHV, LLV, SMA
+from QUANTAXIS.QAUtil import (DATABASE, QA_util_log_info,
+                              QA_util_random_with_topic,
+                              QA_util_to_json_from_pandas,
+                              QA_util_to_pandas_from_json, trade_date_sse)
+from QUANTAXIS.QAUtil.QADate import QA_util_to_datetime
+from QUANTAXIS.QAUtil.QAParameter import FREQUENCE, MARKET_TYPE
+
+
+
[docs]class QA_DataStruct_Stock_day(_quotation_base): + """ + this is a datastruct for stock_day + """ + + def __init__(self, DataFrame, dtype='stock_day', if_fq='bfq'): + super().__init__(DataFrame, dtype, if_fq) + if 'high_limit' not in self.data.columns: + self.data['high_limit'] = round( + (self.data.close.shift(1) + 0.0002) * 1.1, 2) + if 'low_limit' not in self.data.columns: + self.data['low_limit'] = round( + (self.data.close.shift(1) + 0.0002) * 0.9, 2) + if 'next_day_high_limit' not in self.data.columns: + self.data['next_day_high_limit'] = round( + (self.data.close + 0.0002) * 1.1, 2) + if 'next_day_low_limit' not in self.data.columns: + self.data['next_day_low_limit'] = round( + (self.data.close + 0.0002) * 0.9, 2) + + def __repr__(self): + return '< QA_DataStruct_Stock_day with {} securities >'.format(len(self.code)) + __str__ = __repr__ + +
[docs] def to_qfq(self): + if self.if_fq is 'bfq': + if len(self.code) < 1: + self.if_fq = 'qfq' + return self + elif len(self.code) < 20: + return self.new(pd.concat(list(map( + lambda x: QA_data_stock_to_fq(self.data[self.data['code'] == x]), self.code))), self.type, 'qfq') + else: + return self.new( + self.data.groupby('code').apply(QA_data_stock_to_fq), self.type, 'qfq') + else: + QA_util_log_info( + 'none support type for qfq Current type is: %s' % self.if_fq) + return self
+ +
[docs] def to_hfq(self): + if self.if_fq is 'bfq': + if len(self.code) < 1: + self.if_fq = 'hfq' + return self + else: + return self.new(pd.concat(list(map(lambda x: QA_data_stock_to_fq( + self.data[self.data['code'] == x], 'hfq'), self.code))), self.type, 'hfq') + else: + QA_util_log_info( + 'none support type for qfq Current type is: %s' % self.if_fq) + return self
+ + @property + def high_limit(self): + '涨停价' + return self.data.high_limit + + @property + def low_limit(self): + '跌停价' + return self.data.low_limit + + @property + def next_day_low_limit(self): + "明日跌停价" + return self.data.next_day_low_limit + + @property + def next_day_high_limit(self): + "明日涨停价" + return self.data.next_day_high_limit + + @property + def preclose(self): + try: + return self.data.preclose + except: + return None + + @property + def price_chg(self): + try: + return (self.close-self.preclose)/self.preclose + except: + return None
+ + +
[docs]class QA_DataStruct_Stock_min(_quotation_base): + def __init__(self, DataFrame, dtype='stock_min', if_fq='bfq'): + super().__init__(DataFrame, dtype, if_fq) + try: + self.data = DataFrame.ix[:, [ + 'code', 'open', 'high', 'low', 'close', 'volume', 'preclose', 'datetime', 'date']] + except: + self.data = DataFrame.ix[:, [ + 'code', 'open', 'high', 'low', 'close', 'volume', 'datetime', 'date']] + if 'high_limit' not in self.data.columns: + self.data['high_limit'] = round( + (self.data.close.shift(1) + 0.0002) * 1.1, 2) + if 'low_limit' not in self.data.columns: + self.data['low_limit'] = round( + (self.data.close.shift(1) + 0.0002) * 0.9, 2) + self.type = dtype + self.if_fq = if_fq + self.mongo_coll = DATABASE.stock_min + + def __repr__(self): + return '< QA_DataStruct_Stock_Min with {} securities >'.format(len(self.code)) + __str__ = __repr__ + +
[docs] def to_qfq(self): + if self.if_fq is 'bfq': + if len(self.code) < 1: + self.if_fq = 'qfq' + return self + elif len(self.code) < 20: + data = QA_DataStruct_Stock_min(pd.concat(list(map(lambda x: QA_data_stock_to_fq( + self.data[self.data['code'] == x]), self.code))).set_index(['datetime', 'code'], drop=False)) + data.if_fq = 'qfq' + return data + else: + data = QA_DataStruct_Stock_min( + self.data.groupby('code').apply(QA_data_stock_to_fq)) + return data + else: + QA_util_log_info( + 'none support type for qfq Current type is:%s' % self.if_fq) + return self
+ +
[docs] def to_hfq(self): + if self.if_fq is 'bfq': + if len(self.code) < 1: + self.if_fq = 'hfq' + return self + else: + data = QA_DataStruct_Stock_min(pd.concat(list(map(lambda x: QA_data_stock_to_fq( + self.data[self.data['code'] == x], 'hfq'), self.code))).set_index(['datetime', 'code'], drop=False)) + data.if_fq = 'hfq' + return data + else: + QA_util_log_info( + 'none support type for qfq Current type is:%s' % self.if_fq) + return self
+ + @property + def high_limit(self): + '涨停价' + return self.data.high_limit + + @property + def low_limit(self): + '跌停价' + return self.data.low_limit
+ + +
[docs]class QA_DataStruct_Future_day(_quotation_base): + def __init__(self, DataFrame, dtype='future_day', if_fq=''): + self.type = 'future_day' + self.data = DataFrame.ix[:, [ + 'code', 'open', 'high', 'low', 'close', 'trade', 'position', 'datetime', 'date']] + self.mongo_coll = DATABASE.future_day + + def __repr__(self): + return '< QA_DataStruct_Future_day with {} securities >'.format(len(self.code)) + __str__ = __repr__
+ + +
[docs]class QA_DataStruct_Future_min(_quotation_base): + """ + struct for future + """ + + def __init__(self, DataFrame, dtype='future_min', if_fq=''): + self.type = 'future_day' + self.data = DataFrame.ix[:, [ + 'code', 'open', 'high', 'low', 'close', 'trade', 'position', 'datetime', 'date']] + self.mongo_coll = DATABASE.future_min + + def __repr__(self): + return '< QA_DataStruct_Future_min with {} securities >'.format(len(self.code)) + __str__ = __repr__
+ + +
[docs]class QA_DataStruct_Index_day(_quotation_base): + '自定义的日线数据结构' + + def __init__(self, DataFrame, dtype='index_day', if_fq=''): + self.data = DataFrame + self.type = dtype + self.if_fq = if_fq + self.mongo_coll = eval( + 'DATABASE.{}'.format(self.type)) + """ + def __add__(self,DataStruct): + 'add func with merge list and reindex' + assert isinstance(DataStruct,QA_DataStruct_Index_day) + if self.if_fq==DataStruct.if_fq: + self.sync_status(pd.concat()) + """ + + def __repr__(self): + return '< QA_DataStruct_Index_day with {} securities >'.format(len(self.code)) + __str__ = __repr__
+ + +
[docs]class QA_DataStruct_Index_min(_quotation_base): + '自定义的分钟线数据结构' + + def __init__(self, DataFrame, dtype='index_min', if_fq=''): + self.type = dtype + self.if_fq = if_fq + self.data = DataFrame.ix[:, [ + 'code', 'open', 'high', 'low', 'close', 'volume', 'datetime', 'date']] + self.mongo_coll = DATABASE.index_min + + def __repr__(self): + return '< QA_DataStruct_Index_Min with %s securities >' % len(self.code) + + __str__ = __repr__
+ + +
[docs]class QA_DataStruct_Stock_block(): + def __init__(self, DataFrame): + self.data = DataFrame + + def __repr__(self): + return '< QA_DataStruct_Stock_Block >' + + def __call__(self): + return self.data + + @property + def len(self): + """返回DataStruct的长度 + + Returns: + [type] -- [description] + """ + + return len(self.data) + + @property + def block_name(self): + """返回所有的板块名 + + Returns: + [type] -- [description] + """ + + return self.data.groupby('blockname').sum().index.unique().tolist() + + @property + def code(self): + """返回唯一的证券代码 + + Returns: + [type] -- [description] + """ + + return self.data.code.unique().tolist() + +
[docs] def show(self): + """展示DataStruct + + Returns: + dataframe -- [description] + """ + + return self.data
+ +
[docs] def get_code(self, code): + """getcode 获取某一只股票的板块 + + Arguments: + code {str} -- 股票代码 + + Returns: + DataStruct -- [description] + """ + + return QA_DataStruct_Stock_block(self.data[self.data['code'] == code])
+ +
[docs] def get_block(self, _block_name): + """getblock 获取板块 + + Arguments: + _block_name {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + return QA_DataStruct_Stock_block(self.data[self.data['blockname'] == _block_name])
+ +
[docs] def getdtype(self, dtype): + """getdtype + + Arguments: + dtype {str} -- gn-概念/dy-地域/fg-风格/zs-指数 + + Returns: + [type] -- [description] + """ + + return QA_DataStruct_Stock_block(self.data[self.data['type'] == dtype])
+ +
[docs] def get_price(self, _block_name=None): + """get_price + + Keyword Arguments: + _block_name {[type]} -- [description] (default: {None}) + + Returns: + [type] -- [description] + """ + + if _block_name is not None: + try: + code = self.data[self.data['blockname'] + == _block_name].code.unique().tolist() + # try to get a datastruct package of lastest price + return QA_fetch_get_stock_realtime(code) + + except: + return "Wrong Block Name! Please Check" + else: + code = self.data.code.unique().tolist() + return QA_fetch_get_stock_realtime(code)
+ + +
[docs]class QA_DataStruct_Stock_transaction(): + def __init__(self, DataFrame): + """Stock Transaction + + Arguments: + DataFrame {pd.Dataframe} -- [input is one/multi day transaction] + """ + + self.type = 'stock_transaction' + + self.data = DataFrame + if 'amount' not in DataFrame.columns: + if 'vol' in DataFrame.columns: + self.data['amount'] = self.data.vol * self.data.price * 100 + elif 'volume' in DataFrame.columns: + self.data['amount'] = self.data.volume * self.data.price * 100 + self.mongo_coll = DATABASE.stock_transaction + + @property + @lru_cache() + def buyorsell(self): + """return the buy or sell towards 0--buy 1--sell 2--none + + Decorators: + lru_cache + + Returns: + [pd.Series] -- [description] + """ + + return self.data.buyorsell + + @property + @lru_cache() + def price(self): + """return the deal price of tick transaction + + Decorators: + lru_cache + + Returns: + [type] -- [description] + """ + + return self.data.price + + @property + @lru_cache() + def vol(self): + """return the deal volume of tick + + Decorators: + lru_cache + + Returns: + pd.Series -- volume of transaction + """ + + try: + return self.data.volume + except: + return self.data.vol + + volume = vol + + @property + @lru_cache() + def date(self): + """return the date of transaction + + Decorators: + lru_cache + + Returns: + pd.Series -- date of transaction + """ + + return self.data.date + + @property + @lru_cache() + def time(self): + """return the exact time of transaction(to minute level) + + Decorators: + lru_cache + + Returns: + pd.Series -- till minute level + """ + + return self.data.time + + @property + @lru_cache() + def datetime(self): + """return the datetime of transaction + + Decorators: + lru_cache + + Returns: + pd.Series -- [description] + """ + + return self.data.datetime + + @property + @lru_cache() + def order(self): + """return the order num of transaction/ for everyday change + + Decorators: + lru_cache + + Returns: + pd.series -- [description] + """ + + return self.data.order + + @property + @lru_cache() + def index(self): + """return the transaction index + + Decorators: + lru_cache + + Returns: + [type] -- [description] + """ + + return self.data.index + + @property + @lru_cache() + def amount(self): + """return current tick trading amount + + Decorators: + lru_cache + + Returns: + [type] -- [description] + """ + + return self.data.amount + """ + 最新:IF(ISNULL(NEW),PRE,NEW); + IF (ISNULL(RANGE_AVG_PRICE) OR RANGE_AVG_PRICE <= 0) + { + IF (MARKETTYPE == 232 OR MARKETTYPE == 56 OR MARKETTYPE==64 OR MARKETTYPE==128 OR MARKETTYPE==168 OR MARKETTYPE==184 OR MARKETTYPE == 200 OR MARKETTYPE == 80 OR (VOL > 1 AND VOL<100)) + { + b=SUBSAMEDAY(&VOL) ; + m=SUM(b*最新,0); + 均价:IF(m>0,m/VOL,PRE); + } + ELSE IF(CODETYPE!=0 AND MONEY>0) + { + IF(ISNULL(MONEY) OR ISNULL(VOL) OR VOL==0 OR MONEY==0) + 均价:PRE; + ELSE IF(VOL==VOL[1] OR MONEY==MONEY[1]) + 均价:均价[1]; + ELSE + 均价:MONEY/VOL; + } + ELSE IF (MARKETTYPE == 176) + { + b=SUBSAMEDAY(&MONEY); + m=SUM(b*最新,0); + IF(m>0) + 均价:m/MONEY; + } + } + ELSE + { + 均价:RANGE_AVG_PRICE; + } + DRAWGBK(MARKETTYPE==32 AND FORMATTIME(1)<10 AND TRADETIME>242),RGB(0,0,128); + RETURN; + + + hx_star; + hx_star_p; + """ + + def __repr__(self): + return '< QA_DataStruct_Stock_Transaction >' + + def __call__(self): + return self.data + +
[docs] def resample(self, type_='1min'): + """resample methods + + Returns: + [type] -- [description] + """ + + return QA_DataStruct_Stock_min(QA_data_tick_resample(self.data, type_))
+ +
[docs] def get_big_orders(self, bigamount=1000000): + """return big order + + Keyword Arguments: + bigamount {[type]} -- [description] (default: {1000000}) + + Returns: + [type] -- [description] + """ + + return self.data.query('amount>={}'.format(bigamount))
+ +
[docs] def get_medium_order(self, lower=200000, higher=1000000): + """return medium + + Keyword Arguments: + lower {[type]} -- [description] (default: {200000}) + higher {[type]} -- [description] (default: {1000000}) + + Returns: + [type] -- [description] + """ + + return self.data.query('amount>={}'.format(lower)).query('amount<={}'.format(higher))
+ +
[docs] def get_small_order(self, smallamount=200000): + """return small level order + + Keyword Arguments: + smallamount {[type]} -- [description] (default: {200000}) + + Returns: + [type] -- [description] + """ + + return self.data.query('amount<={}'.format(smallamount))
+ +
[docs] def get_time(self, start, end=None): + if end is None: + return self.data.loc[start] + else: + return self.data.loc[start:end]
+ + +class _realtime_base(): + """ + realtime 基类 + + 主要字段有: + code/name + time + open/high/low + + 买卖报价队列:(不同的可能不一样 只提供list) + ask_list[ask1_price/ask1_volume|ask2_price/ask2_volume|ask3_price/ask3_volume....] + bid_list[bid1_price/bid1_volume|bid2_price/bid2_volume|bid3_price/bid3_volume....] + """ + + def __init__(self, market_data): + """转化成dict模式 + + Arguments: + market_data {[type]} -- [description] + """ + + if isinstance(market_data, dict): + self.market_data = market_data + elif isinstance(market_data, pd.DataFrame): + self.market_data = QA_util_to_json_from_pandas(market_data) + + @property + def open(self): + return self.market_data.get('open', None) + + @property + def price(self): + return self.market_data.get('price', None) + + @property + def datetime(self): + return self.market_data.get('datetime', None) + + @property + def high(self): + return self.market_data.get('high', None) + + @property + def low(self): + return self.market_data.get('low', None) + + @property + def code(self): + return self.market_data.get('code', None) + + @property + def last_close(self): + return self.market_data.get('last_close', None) + + @property + def cur_vol(self): + return self.market_data.get('cur_vol', None) + + @property + def bid1(self): + return self.market_data.get('bid1', None) + + @property + def bid_vol1(self): + return self.market_data.get('bid_vol1', None) + + @property + def bid2(self): + return self.market_data.get('bid2', None) + + @property + def bid_vol2(self): + return self.market_data.get('bid_vol2', None) + + @property + def bid3(self): + return self.market_data.get('bid3', None) + + @property + def bid_vol3(self): + return self.market_data.get('bid_vol3', None) + + @property + def bid4(self): + return self.market_data.get('bid4', None) + + @property + def bid_vol4(self): + return self.market_data.get('bid_vol4', None) + + @property + def bid5(self): + return self.market_data.get('bid5', None) + + @property + def bid_vol5(self): + return self.market_data.get('bid_vol5', None) + + @property + def ask1(self): + return self.market_data.get('ask1', None) + + @property + def ask_vol1(self): + return self.market_data.get('ask_vol1', None) + + @property + def ask2(self): + return self.market_data.get('ask2', None) + + @property + def ask_vol2(self): + return self.market_data.get('ask_vol2', None) + + @property + def ask3(self): + return self.market_data.get('ask3', None) + + @property + def ask_vol3(self): + return self.market_data.get('ask_vol3', None) + + @property + def ask4(self): + return self.market_data.get('ask4', None) + + @property + def ask_vol4(self): + return self.market_data.get('ask_vol4', None) + + @property + def ask5(self): + return self.market_data.get('ask5', None) + + @property + def ask_vol5(self): + return self.market_data.get('ask_vol5', None) + + +
[docs]class QA_DataStruct_Stock_realtime(_realtime_base): + def __init__(self, market_data): + if isinstance(market_data, dict): + self.market_data = market_data + elif isinstance(market_data, pd.DataFrame): + self.market_data = QA_util_to_json_from_pandas(market_data) + + def __repr__(self): + return '< QA_REALTIME_STRUCT {}{} >'.format(self.code, self.datetime) + + # @property + # def ask_list(self): + # return self.market_data.ix[:, ['ask1', 'ask_vol1', 'bid1', 'bid_vol1', 'ask2', 'ask_vol2', + # 'bid2', 'bid_vol2', 'ask3', 'ask_vol3', 'bid3', 'bid_vol3', 'ask4', + # 'ask_vol4', 'bid4', 'bid_vol4', 'ask5', 'ask_vol5', 'bid5', 'bid_vol5']] + + # @property + # def bid_list(self): + # return self.market_data.ix[:, ['bid1', 'bid_vol1', 'bid2', 'bid_vol2', 'bid3', 'bid_vol3', 'bid4', 'bid_vol4', 'bid5', 'bid_vol5']] + + @property + def _data(self): + """ + return a dataframe-type result + """ + return pd.DataFrame(self.market_data) + + @property + def ab_board(self): + """ask_bid board + bid3 bid_vol3 + bid2 bid_vol2 + bid1 bid_vol1 + =============== + price /cur_vol + =============== + ask1 ask_vol1 + ask2 ask_vol2 + ask3 ask_vol3 + """ + return 'BID5 {} {} \nBID4 {} {} \nBID3 {} {} \nBID2 {} {} \nBID1 {} {} \n============\nCURRENT {} {} \n============\ + \nASK1 {} {} \nASK2 {} {} \nASK3 {} {} \nASK4 {} {} \nASK5 {} {} \nTIME {} CODE {} '.format( + self.bid5, self.bid_vol5, self.bid4, self.bid_vol4, self.bid3, self.bid_vol3, self.bid2, self.bid_vol2, self.bid1, self.bid_vol1, + self.price, self.cur_vol, + self.ask1, self.ask_vol1, self.ask2, self.ask_vol2, self.ask3, self.ask_vol3, self.ask4, self.ask_vol4, self.ask5, self.ask_vol5, + self.datetime, self.code + ) + +
[docs] def serialize(self): + """to_protobuf + """ + pass
+ + +
[docs]class QA_DataStruct_Stock_realtime_series(): + def __init__(self, sr_series): + + if isinstance(sr_series[0], QA_DataStruct_Stock_realtime): + self.sr_series = sr_series + elif isinstance(sr_series[0], dict): + self.sr_series = [ + QA_DataStruct_Stock_realtime(sr) for sr in sr_series] + self.table = pd.concat([sr._data for sr in self.sr_series])
+ + +
[docs]class QA_DataStruct_Security_list(): + def __init__(self, DataFrame): + self.data = DataFrame.loc[:, ['sse', 'code', 'name']].set_index( + 'code', drop=False) + + @property + def code(self): + return self.data.code + + @property + def name(self): + return self.data.name + +
[docs] def get_stock(self, ST_option): + return self.data
+ +
[docs] def get_index(self): + return self.data
+ +
[docs] def get_etf(self): + return self.data
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAData/data_fq.html b/_build/html/_modules/QUANTAXIS/QAData/data_fq.html new file mode 100644 index 000000000..afa0a678a --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAData/data_fq.html @@ -0,0 +1,209 @@ + + + + + + + + QUANTAXIS.QAData.data_fq — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAData.data_fq

+
+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import datetime
+
+import pandas as pd
+
+from QUANTAXIS.QAFetch import QA_fetch_get_stock_day, QA_fetch_get_stock_xdxr
+from QUANTAXIS.QAUtil import QA_util_log_info, DATABASE
+
+
+
[docs]def QA_data_get_qfq(code, start, end): + '使用网络数据进行复权/需要联网' + xdxr_data = QA_fetch_get_stock_xdxr('tdx', code) + bfq_data = QA_fetch_get_stock_day( + 'tdx', code, '1990-01-01', str(datetime.date.today())).dropna(axis=0) + return QA_data_make_qfq(bfq_data[start:end], xdxr_data)
+ + +
[docs]def QA_data_get_hfq(code, start, end): + '使用网络数据进行复权/需要联网' + xdxr_data = QA_fetch_get_stock_xdxr('tdx', code) + bfq_data = QA_fetch_get_stock_day( + 'tdx', code, '1990-01-01', str(datetime.date.today())).dropna(axis=0) + return QA_data_make_hfq(bfq_data[start:end], xdxr_data)
+ + +
[docs]def QA_data_make_qfq(bfq_data, xdxr_data): + '使用数据库数据进行复权' + info = xdxr_data[xdxr_data['category'] == 1] + bfq_data = bfq_data.assign(if_trade=1) + data = pd.concat([bfq_data, info[['category']] + [bfq_data.index[0]:bfq_data.index[-1]]], axis=1) + data['if_trade'].fillna(value=0, inplace=True) + data = data.fillna(method='ffill') + data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia', + 'songzhuangu']][bfq_data.index[0]:bfq_data.index[-1]]], axis=1) + data = data.fillna(0) + data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu'] + * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu']) + data['adj'] = (data['preclose'].shift(-1) / + data['close']).fillna(1)[::-1].cumprod() + data['open'] = data['open'] * data['adj'] + data['high'] = data['high'] * data['adj'] + data['low'] = data['low'] * data['adj'] + data['close'] = data['close'] * data['adj'] + data['preclose'] = data['preclose'] * data['adj'] + try: + data['high_limit'] = data['high_limit'] * data['adj'] + data['low_limit'] = data['high_limit'] * data['adj'] + except: + pass + return data.query('if_trade==1').drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', + 'if_trade', 'category'], axis=1).query("open != 0")
+ + +
[docs]def QA_data_make_hfq(bfq_data, xdxr_data): + '使用数据库数据进行复权' + info = xdxr_data[xdxr_data['category'] == 1] + bfq_data = bfq_data.assign(if_trade=1) + data = pd.concat([bfq_data, info[['category']] + [bfq_data.index[0]:bfq_data.index[-1]]], axis=1) + + data['if_trade'].fillna(value=0, inplace=True) + data = data.fillna(method='ffill') + + data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia', + 'songzhuangu']][bfq_data.index[0]:bfq_data.index[-1]]], axis=1) + + data = data.fillna(0) + data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu'] + * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu']) + data['adj'] = (data['close'] / data['preclose'].shift(-1) + ).cumprod().shift(1).fillna(1) + data['open'] = data['open'] * data['adj'] + data['high'] = data['high'] * data['adj'] + data['low'] = data['low'] * data['adj'] + data['close'] = data['close'] * data['adj'] + data['preclose'] = data['preclose'] * data['adj'] + try: + data['high_limit'] = data['high_limit'] * data['adj'] + data['low_limit'] = data['high_limit'] * data['adj'] + except: + pass + return data.query('if_trade==1').drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu'], axis=1).query("open != 0")
+ + +
[docs]def QA_data_stock_to_fq(__data, type_='01'): + + def __QA_fetch_stock_xdxr(code, format_='pd', collections=DATABASE.stock_xdxr): + '获取股票除权信息/数据库' + try: + data = pd.DataFrame([item for item in collections.find( + {'code': code})]).drop(['_id'], axis=1) + data['date'] = pd.to_datetime(data['date']) + return data.set_index(['date', 'code'], drop=False) + except: + return pd.DataFrame(data=[],columns=['category', 'category_meaning', 'code', 'date', 'fenhong', + 'fenshu', 'liquidity_after', 'liquidity_before', 'name', 'peigu', 'peigujia', + 'shares_after', 'shares_before', 'songzhuangu', 'suogu', 'xingquanjia']) + '股票 日线/分钟线 动态复权接口' + if type_ in ['01', 'qfq']: + return QA_data_make_qfq(__data, __QA_fetch_stock_xdxr(__data['code'][0])) + elif type_ in ['02', 'hfq']: + return QA_data_make_hfq(__data, __QA_fetch_stock_xdxr(__data['code'][0])) + else: + QA_util_log_info('wrong fq type! Using qfq') + return QA_data_make_qfq(__data, __QA_fetch_stock_xdxr(__data['code'][0]))
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAData/data_resample.html b/_build/html/_modules/QUANTAXIS/QAData/data_resample.html new file mode 100644 index 000000000..b9c105c0c --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAData/data_resample.html @@ -0,0 +1,144 @@ + + + + + + + + QUANTAXIS.QAData.data_resample — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAData.data_resample

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from datetime import time
+
+import pandas as pd
+
+from QUANTAXIS.QAFetch import QA_fetch_get_stock_transaction
+
+
+
[docs]def QA_data_tick_resample(tick, type_='1min'): + """tick采样成任意级别分钟线 + + Arguments: + tick {[type]} -- transaction + + Returns: + [type] -- [description] + """ + + data = tick['price'].resample( + type_, label='right', closed='left').ohlc() + + data['volume'] = tick['vol'].resample( + type_, label='right', closed='left').sum() + data['code'] = tick['code'][0] + + #data = pd.DataFrame() + _temp = tick.drop_duplicates('date')['date'] + for item in _temp: + _data = data[item] + _data = _data[time(9, 31):time(11, 30)].append( + _data[time(13, 1):time(15, 0)]) + data = data.append(_data) + + data['datetime'] = data.index + data['date'] = data['datetime'].apply(lambda x: str(x)[0:10]) + + return data.fillna(method='ffill').set_index(['datetime', 'code'], drop=False)
+ + +if __name__ == '__main__': + tickz = QA_fetch_get_stock_transaction( + 'tdx', '000001', '2017-01-03', '2017-01-05') + print(QA_data_tick_resample(tickz)) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAData/dsmethods.html b/_build/html/_modules/QUANTAXIS/QAData/dsmethods.html new file mode 100644 index 000000000..b19217356 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAData/dsmethods.html @@ -0,0 +1,140 @@ + + + + + + + + QUANTAXIS.QAData.dsmethods — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAData.dsmethods

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+"""DataStruct的方法
+"""
+import pandas as pd
+from QUANTAXIS.QAData.QADataStruct import QA_DataStruct_Stock_day, QA_DataStruct_Stock_min
+
+
+
[docs]def concat(lists): + """类似于pd.concat 用于合并一个list里面的多个DataStruct,会自动去重 + + + + Arguments: + lists {[type]} -- [DataStruct1,DataStruct2,....,DataStructN] + + Returns: + [type] -- new DataStruct + """ + + return lists[0].new(pd.concat([lists.data for lists in lists]).drop_duplicates())
+ + +
[docs]def from_tushare(dataframe, dtype='day'): + """dataframe from tushare + + Arguments: + dataframe {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + if dtype in ['day']: + return QA_DataStruct_Stock_day(dataframe.set_index(['date', 'code'], drop=False), dtype='stock_day') + elif dtype in ['min']: + return QA_DataStruct_Stock_min(dataframe.set_index(['datetime', 'code'], drop=False), dtype='stock_min')
+ + +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAData/schema.html b/_build/html/_modules/QUANTAXIS/QAData/schema.html new file mode 100644 index 000000000..071d2590f --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAData/schema.html @@ -0,0 +1,179 @@ + + + + + + + + QUANTAXIS.QAData.schema — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAData.schema

+import sqlalchemy as sa
+from sqlalchemy import Column, Integer, String, Float, Date
+from sqlalchemy.ext.declarative import declarative_base
+
+Base = declarative_base()
+
+
+
[docs]class full(Base): + __tablename__ = 'full' + + code = Column(String, primary_key=True) + report_date = Column(Date) + trade_date = Column(Date, primary_key=True) + quarter = Column(Integer) + name = Column(String) + eps = Column(Float) + eps_yoy = Column(Float) + bvps = Column(Float) + roe = Column(Float) + epcf = Column(Float) + net_profits = Column(Float) + profits_yoy = Column(Float) + distrib = Column(Float) + net_profit_ratio = Column(Float) + gross_profit_rate = Column(Float) + business_income = Column(Float) + bips = Column(Float) + arturnover = Column(Float) + arturndays = Column(Float) + inventory_turnover = Column(Float) + inventory_days = Column(Float) + currentasset_turnover = Column(Float) + currentasset_days = Column(Float) + mbrg = Column(Float) + nprg = Column(Float) + nav = Column(Float) + targ = Column(Float) + epsg = Column(Float) + seg = Column(Float) + currentratio = Column(Float) + quickratio = Column(Float) + cashratio = Column(Float) + icratio = Column(Float) + sheqratio = Column(Float) + adratio = Column(Float) + cf_sales = Column(Float) + rateofreturn = Column(Float) + cf_nm = Column(Float) + cf_liabilities = Column(Float) + cashflowratio = Column(Float)
+ + +
[docs]class Shares(Base): + __tablename__ = 'shares' + sid = Column(Integer, primary_key=True) + effective_date = Column(Integer, primary_key=True) + shares = Column(Float) + circulation = Column(Float)
+ +
[docs]class fundamental(Base): + __tablename__ = 'fundamental' + + code = Column(String, primary_key=True) + report_date = Column(Date, primary_key=True) + quarter = Column(Integer, primary_key=True) + name = Column(String) + eps = Column(Float) + eps_yoy = Column(Float) + bvps = Column(Float) + roe = Column(Float) + epcf = Column(Float) + net_profits = Column(Float) + profits_yoy = Column(Float) + distrib = Column(Float) + net_profit_ratio = Column(Float) + gross_profit_rate = Column(Float) + business_income = Column(Float) + bips = Column(Float) + arturnover = Column(Float) + arturndays = Column(Float) + inventory_turnover = Column(Float) + inventory_days = Column(Float) + currentasset_turnover = Column(Float) + currentasset_days = Column(Float) + mbrg = Column(Float) + nprg = Column(Float) + nav = Column(Float) + targ = Column(Float) + epsg = Column(Float) + seg = Column(Float) + currentratio = Column(Float) + quickratio = Column(Float) + cashratio = Column(Float) + icratio = Column(Float) + sheqratio = Column(Float) + adratio = Column(Float) + cf_sales = Column(Float) + rateofreturn = Column(Float) + cf_nm = Column(Float) + cf_liabilities = Column(Float) + cashflowratio = Column(Float)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAEngine/QAEvent.html b/_build/html/_modules/QUANTAXIS/QAEngine/QAEvent.html new file mode 100644 index 000000000..291bfa518 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAEngine/QAEvent.html @@ -0,0 +1,132 @@ + + + + + + + + QUANTAXIS.QAEngine.QAEvent — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAEngine.QAEvent

+# encoding: UTF-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from abc import abstractmethod
+"""QUANTAXIS EVENT
+EVENT 是会被推送进QUEUE的任务class
+通过EVENT_QUEUE.get()拿到标准的event,然后执行"""
+
+
+
[docs]class QA_Worker(object): + """JOB是worker 需要接受QA_EVENT 需要完善RUN方法""" + + def __init__(self): + self.type = None + + def __repr__(self): + return '< QA_Worker {} >'.format(self.type) + +
[docs] @abstractmethod + def run(self, event): + raise NotImplementedError
+ + +
[docs]class QA_Event(object): + def __init__(self, event_type=None, func=None, message=None, callback=False, *args, **kwargs): + self.event_type = event_type + self.func = func + self.message = message + self.callback = callback + + for item in kwargs.keys(): + exec('self.{}=kwargs[item]'.format(item))
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAEngine/QATask.html b/_build/html/_modules/QUANTAXIS/QAEngine/QATask.html new file mode 100644 index 000000000..c736aebfe --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAEngine/QATask.html @@ -0,0 +1,138 @@ + + + + + + + + QUANTAXIS.QAEngine.QATask — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAEngine.QATask

+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from QUANTAXIS.QAUtil.QARandom import QA_util_random_with_topic
+
+
+"""标准的QUANTAXIS事件方法,具有QA_Thread,QA_Event等特性,以及一些日志和外部接口"""
+
+
+
[docs]class QA_Task(): + def __init__(self, worker, event, engine=None, callback=False): + self.worker = worker + self.event = event + self.res = None + self.callback = callback + self.task_id = QA_util_random_with_topic('Task') + self.engine = engine + +
[docs] def do(self): + self.res = self.worker.run(self.event) + if self.callback: + self.callback(self.res)
+ + @property + def result(self): + # return { + # 'task_id': self.task_id, + # 'result': self.res, + # 'worker': self.worker, + # 'event': self.event + # } + return { + 'task_id': self.task_id, + 'result': self.res + }
+ + +if __name__ == '__main__': + pass +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAEngine/QAThreadEngine.html b/_build/html/_modules/QUANTAXIS/QAEngine/QAThreadEngine.html new file mode 100644 index 000000000..3f548979f --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAEngine/QAThreadEngine.html @@ -0,0 +1,282 @@ + + + + + + + + QUANTAXIS.QAEngine.QAThreadEngine — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAEngine.QAThreadEngine

+# coding:utf-8
+
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import datetime
+import threading
+import time
+from queue import Queue
+
+from QUANTAXIS.QAEngine.QATask import QA_Task
+from QUANTAXIS.QAUtil import QA_util_log_info, QA_util_random_with_topic
+
+
+"""标准化的QUANATAXIS事件分发,可以快速引入和复用
+每个事件需要携带一个方法,并且是需要立即被执行的时间才能使用这个事件方法"""
+
+
+
[docs]class QA_Thread(threading.Thread): + '这是一个随意新建线程的生产者消费者模型' + + def __init__(self, queue=None, name=None): + threading.Thread.__init__(self) + self.queue = Queue() if queue is None else queue + self.thread_stop = False + self.__flag = threading.Event() # 用于暂停线程的标识 + self.__flag.set() # 设置为True + self.__running = threading.Event() # 用于停止线程的标识 + self.__running.set() # 将running设置为True + self.name = QA_util_random_with_topic( + topic='QAWorker', lens=3) if name is None else name + self.idle = False + + def __repr__(self): + return '< QA_Thread {} >'.format(self.name) + +
[docs] def run(self): + while self.__running.isSet(): + self.__flag.wait() + while not self.thread_stop: + '这是一个阻塞的队列,避免出现消息的遗漏' + + try: + if self.queue.empty() is False: + _task = self.queue.get() # 接收消息 + assert isinstance(_task, QA_Task) + if _task.worker != None: + + _task.do() + + self.queue.task_done() # 完成一个任务 + else: + pass + else: + self.idle = True + except Exception as e: + pass
+ +
[docs] def pause(self): + self.__flag.clear()
+ +
[docs] def resume(self): + self.__flag.set() # 设置为True, 让线程停止阻塞
+ +
[docs] def stop(self): + # self.__flag.set() # 将线程从暂停状态恢复, 如何已经暂停的话 + self.__running.clear() + self.thread_stop = True # 设置为False
+ + def __start(self): + self.queue.start() + +
[docs] def put(self, task): + self.queue.put(task)
+ +
[docs] def put_nowait(self, task): + self.queue.put_nowait(task)
+ +
[docs] def get(self, task): + return self.get(task)
+ +
[docs] def get_nowait(self, task): + return self.get_nowait(task)
+ +
[docs] def qsize(self): + return self.queue.qsize()
+ + +
[docs]class QA_Engine(QA_Thread): + def __init__(self, queue=None, *args, **kwargs): + super().__init__(queue=queue, name='QAENGINE') + self.kernals = {} + self.__flag = threading.Event() # 用于暂停线程的标识 + self.__flag.set() # 设置为True + self.__running = threading.Event() # 用于停止线程的标识 + self.__running.set() # 将running设置为True + + def __repr__(self): + return ' <QA_ENGINE with {} kernals>'.format(list(self.kernals.keys())) + + @property + def kernel_num(self): + return len(self.kernals.keys()) + +
[docs] def create_kernal(self, name): + # ENGINE线程创建一个事件线程 + self.kernals[name] = QA_Thread(name=name)
+ +
[docs] def register_kernal(self, name, kernal): + if name not in self.kernals.keys(): + self.kernals[name] = kernal
+ +
[docs] def start_kernal(self, name): + self.kernals[name].start()
+ +
[docs] def stop_kernal(self, name): + self.kernals[name].stop() + del self.kernals[name]
+ +
[docs] def run_job(self, task): + self.kernals[task.engine].put(task)
+ +
[docs] def stop_all(self): + for item in self.kernals.values(): + item.stop() + self.kernals = {}
+ +
[docs] def stop(self): + # self.__flag.set() # 将线程从暂停状态恢复, 如何已经暂停的话 + self.__running.clear() + self.thread_stop = True
+ +
[docs] def pause(self): + self.__flag.clear()
+ +
[docs] def resume(self): + self.__flag.set() # 设置为True, 让线程停止阻塞
+ +
[docs] def run(self): + while self.__running.isSet(): + self.__flag.wait() + while not self.thread_stop: + '这是一个阻塞的队列,避免出现消息的遗漏' + + try: + if self.queue.empty() is False: + _task = self.queue.get() # 接收消息 + assert isinstance(_task, QA_Task) + if _task.engine is None: + # 如果不指定线程 就在ENGINE线程中运行 + _task.do() + self.queue.task_done() + else: + # + self.run_job(_task) + self.queue.task_done() + else: + self.idle = True + except Exception as e: + raise e
+ # self.run() + +
[docs] def clear(self): + res = True + for item in self.kernals.values(): + if not item.queue.empty(): + res = False + if not item.idle: + res = False + + item.queue.join() + if not self.queue.empty(): + res = False + + return res
+ +
[docs] def join(self): + for item in self.kernals.values(): + item.queue.join() + self.queue.join()
+ + +if __name__ == '__main__': + import queue + q = queue.Queue() +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch.html b/_build/html/_modules/QUANTAXIS/QAFetch.html new file mode 100644 index 000000000..4ef60df51 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch.html @@ -0,0 +1,256 @@ + + + + + + + + QUANTAXIS.QAFetch — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""
+QA fetch module
+
+@yutiansut
+
+QAFetch is Under [QAStandard#0.0.2@10x] Protocol
+
+
+"""
+from QUANTAXIS.QAFetch import QAWind as QAWind
+from QUANTAXIS.QAFetch import QATushare as QATushare
+from QUANTAXIS.QAFetch import QATdx as QATdx
+from QUANTAXIS.QAFetch import QAThs as QAThs
+from QUANTAXIS.QAFetch import QACrawler as QACL
+from QUANTAXIS.QAFetch import QAEastMoney as QAEM
+
+
[docs]def use(package): + if package in ['wind']: + from WindPy import w + # w.start() + return QAWind + elif package in ['tushare', 'ts']: + return QATushare + elif package in ['tdx', 'pytdx']: + return QATdx + elif package in ['ths', 'THS']: + return QAThs
+ + +
[docs]def QA_fetch_get_stock_day(package, code, start, end, if_fq='01', level='day', type_='json'): + Engine = use(package) + if package in ['ths', 'THS', 'wind']: + return Engine.QA_fetch_get_stock_day(code, start, end, if_fq) + elif package in ['ts', 'tushare']: + return Engine.QA_fetch_get_stock_day(code, start, end, if_fq, type_) + elif package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_stock_day(code, start, end, if_fq, level) + else: + return Engine.QA_fetch_get_stock_day(code, start, end)
+ + +
[docs]def QA_fetch_get_stock_realtime(package, code): + Engine = use(package) + return Engine.QA_fetch_get_stock_realtime(code)
+ + +
[docs]def QA_fetch_get_stock_indicator(package, code, start, end): + Engine = use(package) + return Engine.QA_fetch_get_stock_indicator(code, start, end)
+ + +
[docs]def QA_fetch_get_trade_date(package, end, exchange): + Engine = use(package) + return Engine.QA_fetch_get_trade_date(end, exchange)
+ + +
[docs]def QA_fetch_get_stock_min(package, code, start, end, level='1min'): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_stock_min(code, start, end, level) + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_stock_list(package, type_='stock'): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_stock_list(type_) + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_stock_transaction(package, code, start, end, retry=2): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_stock_transaction(code, start, end, retry) + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_stock_transaction_realtime(package, code): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_stock_transaction_realtime(code) + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_stock_xdxr(package, code): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_stock_xdxr(code) + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_index_day(package, code, start, end, level='day'): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_index_day(code, start, end, level) + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_index_min(package, code, start, end, level='1min'): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_index_min(code, start, end, level) + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_stock_block(package): + Engine = use(package) + if package in ['tdx', 'pytdx', 'ths']: + return Engine.QA_fetch_get_stock_block() + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_stock_info(package, code): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_stock_info(code) + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_future_list(package,): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_future_list() + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_future_day(package, code, start, end, frequence='day'): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_future_day(code, start, end, frequence=frequence) + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_future_min(package, code, start, end, frequence='1min'): + Engine = use(package) + if package in ['tdx', 'pytdx']: + return Engine.QA_fetch_get_future_min(code, start, end, frequence=frequence) + else: + return 'Unsupport packages'
+ + +
[docs]def QA_fetch_get_security_bars(code, _type, lens): + return QATdx.QA_fetch_get_security_bars(code, _type, lens)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/Fetcher.html b/_build/html/_modules/QUANTAXIS/QAFetch/Fetcher.html new file mode 100644 index 000000000..a5d1d54a7 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/Fetcher.html @@ -0,0 +1,200 @@ + + + + + + + + QUANTAXIS.QAFetch.Fetcher — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.Fetcher

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""
+QA fetch module
+
+@yutiansut
+
+QAFetch is Under [QAStandard#0.0.2@10x] Protocol
+
+
+"""
+from QUANTAXIS.QAFetch import QAWind as QAWind
+from QUANTAXIS.QAFetch import QATushare as QATushare
+from QUANTAXIS.QAFetch import QATdx as QATdx
+from QUANTAXIS.QAFetch import QAThs as QAThs
+from QUANTAXIS.QAFetch import QAQuery
+from QUANTAXIS.QAFetch import QAQuery_Advance as QAQueryAdv
+from QUANTAXIS.QAFetch import QAEastMoney as QAEM
+from QUANTAXIS.QAUtil.QAParameter import FREQUENCE, MARKET_TYPE, DATASOURCE, OUTPUT_FORMAT, DATABASE_TABLE
+from QUANTAXIS.QAUtil.QASql import QA_util_sql_mongo_setting
+
+
+
[docs]class QA_Fetcher(): + def __init__(self, ip='127.0.0.1', port=27017, username='',password='',): + """ + 初始化的时候 会初始化 + """ + self.ip = ip + self.port = port + self.database = QA_util_sql_mongo_setting(ip, port).quantaxis + self.history = {} + + self.best_ip=QATdx.best_ip + + +
[docs] def change_ip(self, ip, port): + self.database = QA_util_sql_mongo_setting(ip, port).quantaxis + return self
+ +
[docs] def get_quotation(self, code=None, start=None, end=None, frequence=None, market=None, source=None, output=None): + """ + Arguments: + code {str/list} -- 证券/股票的代码 + start {str} -- 开始日期 + end {str} -- 结束日期 + frequence {enum} -- 频率 QA.FREQUENCE + market {enum} -- 市场 QA.MARKET_TYPE + source {enum} -- 来源 QA.DATASOURCE + output {enum} -- 输出类型 QA.OUTPUT_FORMAT + """ + pass
+ +
[docs] def get_info(self,code,frequence,market,source,output): + if source is DATASOURCE.TDX: + res=QATdx.QA_fetch_get_stock_info(code,self.best_ip) + return res + elif source is DATASOURCE.MONGO: + res=QAQuery.QA_fetch_stock_info(code,format=output,collections=self.database.stock_info) + return res
+ +
[docs]def QA_quotation(code, start, end, frequence, market, source, output): + """一个统一的fetch + + Arguments: + code {str/list} -- 证券/股票的代码 + start {str} -- 开始日期 + end {str} -- 结束日期 + frequence {enum} -- 频率 QA.FREQUENCE + market {enum} -- 市场 QA.MARKET_TYPE + source {enum} -- 来源 QA.DATASOURCE + output {enum} -- 输出类型 QA.OUTPUT_FORMAT + + """ + if market is MARKET_TYPE.STOCK_CN: + if frequence is FREQUENCE.DAY: + if source is DATASOURCE.MONGO: + res = QAQueryAdv.QA_fetch_stock_day_adv(code, start, end) + elif source is DATASOURCE.TDX: + res = QATdx.QA_fetch_get_stock_day(code, start, end, '00') + elif source is DATASOURCE.TUSHARE: + res = QATushare.QA_fetch_get_stock_day(code, start, end, '00') + elif frequence in [FREQUENCE.ONE_MIN, FREQUENCE.FIVE_MIN, FREQUENCE.FIFTEEN_MIN, FREQUENCE.THIRTY_MIN, FREQUENCE.SIXTY_MIN]: + if source is DATASOURCE.MONGO: + res = QAQueryAdv.QA_fetch_stock_min_adv( + code, start, end, frequence=frequence) + elif source is DATASOURCE.TDX: + res = QATdx.QA_fetch_get_stock_min( + code, start, end, frequence=frequence) + elif frequence is FREQUENCE.TICK: + if source is DATASOURCE.TDX: + res = QATdx.QA_fetch_get_stock_transaction(code, start, end) + print(type(res)) + return res
+ + +if __name__ == '__main__': + print(QA_quotation('000001', '2017-01-01', '2017-01-31', frequence=FREQUENCE.DAY, + market=MARKET_TYPE.STOCK_CN, source=DATASOURCE.TDX, output=OUTPUT_FORMAT.DATAFRAME)) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/QACrawler.html b/_build/html/_modules/QUANTAXIS/QAFetch/QACrawler.html new file mode 100644 index 000000000..17334757e --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/QACrawler.html @@ -0,0 +1,148 @@ + + + + + + + + QUANTAXIS.QAFetch.QACrawler — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.QACrawler

+# coding: utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import pandas as pd
+from QUANTAXIS.QAUtil.QADate_trade import trade_date_sse
+from QUANTAXIS.QAUtil.QADate import QA_util_date_str2int
+
+_sh_url = 'http://www.sse.com.cn/market/dealingdata/overview/margin/a/rzrqjygk{}.xls'
+_sz_url = 'http://www.szse.cn/szseWeb/ShowReport.szse?SHOWTYPE=xlsx&CATALOGID=1837_xxpl&txtDate={}&tab2PAGENO=1&ENCODE=1&TABKEY=tab2'
+
+
+
[docs]def QA_fetch_get_sh_margin(date): + """return shanghai margin data + + Arguments: + date {str YYYY-MM-DD} -- date format + + Returns: + pandas.DataFrame -- res for margin data + """ + if date in trade_date_sse: + data= pd.read_excel(_sh_url.format(QA_util_date_str2int + (date)), 1).assign(date=date).assign(sse='sh') + data.columns=['code','name','leveraged_balance','leveraged_buyout','leveraged_payoff','margin_left','margin_sell','margin_repay','date','sse'] + return data + else: + pass
+ + +
[docs]def QA_fetch_get_sz_margin(date): + """return shenzhen margin data + + Arguments: + date {str YYYY-MM-DD} -- date format + + Returns: + pandas.DataFrame -- res for margin data + """ + + if date in trade_date_sse: + return pd.read_excel(_sz_url.format(date)).assign(date=date).assign(sse='sz')
+ + +if __name__ == "__main__": + print(QA_fetch_get_sz_margin('2018-01-25')) + print(QA_fetch_get_sh_margin('2018-01-25')) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/QAEastMoney.html b/_build/html/_modules/QUANTAXIS/QAFetch/QAEastMoney.html new file mode 100644 index 000000000..f15530a4a --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/QAEastMoney.html @@ -0,0 +1,157 @@ + + + + + + + + QUANTAXIS.QAFetch.QAEastMoney — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.QAEastMoney

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import requests
+import pandas as pd
+from QUANTAXIS.QAFetch.base import headers, _select_market_code
+
+BusinessAnalysis_url = 'http://emweb.securities.eastmoney.com/PC_HSF10/BusinessAnalysis/BusinessAnalysisAjax?code={}{}'
+headers_em = headers
+headers_em['Host'] = 'emweb.securities.eastmoney.com'
+
+
+
[docs]def QA_fetch_get_stock_analysis(code): + """ + 'zyfw', 主营范围 'jyps'#经营评述 'zygcfx' 主营构成分析 + + date 主营构成 主营收入(元) 收入比例cbbl 主营成本(元) 成本比例 主营利润(元) 利润比例 毛利率(%) + 行业 /产品/ 区域 hq cp qy + """ + market = 'sh' if _select_market_code(code) == 1 else 'sz' + null = 'none' + data = eval(requests.get(BusinessAnalysis_url.format( + market, code), headers=headers_em).text) + zyfw = pd.DataFrame(data.get('zyfw', None)) + jyps = pd.DataFrame(data.get('jyps', None)) + zygcfx = data.get('zygcfx', []) + temp = [] + for item in zygcfx: + try: + data_ = pd.concat([pd.DataFrame(item['hy']).assign(date=item['rq']).assign(classify='hy'), + pd.DataFrame(item['cp']).assign( + date=item['rq']).assign(classify='cp'), + pd.DataFrame(item['qy']).assign(date=item['rq']).assign(classify='qy')]) + + temp.append(data_) + except: + pass + try: + res_zyfcfx = pd.concat(temp).set_index( + ['date', 'classify'], drop=False) + except: + res_zyfcfx = None + + return zyfw, jyps, res_zyfcfx
+ + + +cpbidu = 'http://emweb.securities.eastmoney.com/PC_HSF10/OperationsRequired/OperationsRequiredAjax?times=1&code=sz300059' + +headers_em_OperationsRequired = headers +headers_em_OperationsRequired['Accept'] = '*/*' +headers_em_OperationsRequired['Referer'] = 'http://emweb.securities.eastmoney.com/PC_HSF10/OperationsRequired/Index?type=soft&code=sz300059' + +headers_em_OperationsRequired['X-Requested-With'] = 'XMLHttpRequest' + +research_report = 'http://emweb.securities.eastmoney.com/PC_HSF10/ResearchReport/ResearchReportAjax?code=sz300059&icode=447' +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/QAQuery.html b/_build/html/_modules/QUANTAXIS/QAFetch/QAQuery.html new file mode 100644 index 000000000..4809e2682 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/QAQuery.html @@ -0,0 +1,434 @@ + + + + + + + + QUANTAXIS.QAFetch.QAQuery — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.QAQuery

+# coding: utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import datetime
+
+import numpy
+import pandas as pd
+from pandas import DataFrame
+
+from QUANTAXIS.QAUtil import (DATABASE, QA_Setting, QA_util_date_stamp,
+                              QA_util_date_valid, QA_util_dict_remove_key,
+                              QA_util_log_info, QA_util_code_tolist,
+                              QA_util_sql_mongo_sort_DESCENDING,
+                              QA_util_time_stamp, QA_util_to_json_from_pandas,
+                              trade_date_sse)
+
+
+"""
+按要求从数据库取数据,并转换成numpy结构
+
+"""
+
+
+
[docs]def QA_fetch_stock_day(code, start, end, format='numpy', frequence='day', collections=DATABASE.stock_day): + '获取股票日线' + start = str(start)[0:10] + end = str(end)[0:10] + #code= [code] if isinstance(code,str) else code + + # code checking + code = QA_util_code_tolist(code) + + + if QA_util_date_valid(end) == True: + + __data = [] + cursor = collections.find({ + 'code': {'$in':code}, "date_stamp": { + "$lte": QA_util_date_stamp(end), + "$gte": QA_util_date_stamp(start)}}) + #res=[QA_util_dict_remove_key(data, '_id') for data in cursor] + + res=pd.DataFrame([item for item in cursor]) + try: + res=res.drop('_id',axis=1).assign(volume=res.vol).assign(date=pd.to_datetime(res.date)).drop_duplicates((['date','code'])).set_index('date', drop=False) + #return res + except: + res=None + if format in ['P', 'p', 'pandas', 'pd']: + return res + elif format in ['json', 'dict']: + return QA_util_to_json_from_pandas(res) + # 多种数据格式 + elif format in ['n', 'N', 'numpy']: + return numpy.asarray(res) + elif format in ['list', 'l', 'L']: + return numpy.asarray(res).tolist() + else: + return None + else: + QA_util_log_info('something wrong with date')
+ + +
[docs]def QA_fetch_stock_min(code, start, end, format='numpy', frequence='1min', collections=DATABASE.stock_min): + '获取股票分钟线' + if frequence in ['1min', '1m']: + frequence = '1min' + elif frequence in ['5min', '5m']: + frequence = '5min' + elif frequence in ['15min', '15m']: + frequence = '15min' + elif frequence in ['30min', '30m']: + frequence = '30min' + elif frequence in ['60min', '60m']: + frequence = '60min' + __data = [] + # code checking + code = QA_util_code_tolist(code) + + cursor = collections.find({ + 'code': {'$in': code}, "time_stamp": { + "$gte": QA_util_time_stamp(start), + "$lte": QA_util_time_stamp(end) + }, 'type': frequence + }) + + res=pd.DataFrame([item for item in cursor]) + try: + res=res.drop('_id',axis=1).assign(volume=res.vol).assign(datetime=pd.to_datetime(res.datetime)).drop_duplicates(['datetime','code']).set_index('datetime', drop=False) + #return res + except: + res=None + if format in ['P', 'p', 'pandas', 'pd']: + return res + elif format in ['json', 'dict']: + return QA_util_to_json_from_pandas(res) + # 多种数据格式 + elif format in ['n', 'N', 'numpy']: + return numpy.asarray(res) + elif format in ['list', 'l', 'L']: + return numpy.asarray(res).tolist() + else: + return None
+ + + +
[docs]def QA_fetch_trade_date(): + '获取交易日期' + return trade_date_sse
+ + +
[docs]def QA_fetch_stock_list(collections=DATABASE.stock_list): + '获取股票列表' + return [item for item in collections.find()]
+ + +
[docs]def QA_fetch_stock_full(date, format='numpy', collections=DATABASE.stock_day): + '获取全市场的某一日的数据' + Date = str(date)[0:10] + if QA_util_date_valid(Date) is True: + + __data = [] + for item in collections.find({ + "date_stamp": { + "$lte": QA_util_date_stamp(Date), + "$gte": QA_util_date_stamp(Date)}}): + __data.append([str(item['code']), float(item['open']), float(item['high']), float( + item['low']), float(item['close']), float(item['vol']), item['date']]) + # 多种数据格式 + if format in ['n', 'N', 'numpy']: + __data = numpy.asarray(__data) + elif format in ['list', 'l', 'L']: + __data = __data + elif format in ['P', 'p', 'pandas', 'pd']: + __data = DataFrame(__data, columns=[ + 'code', 'open', 'high', 'low', 'close', 'volume', 'date']) + __data['date'] = pd.to_datetime(__data['date']) + __data = __data.set_index('date', drop=False) + return __data + else: + QA_util_log_info('something wrong with date')
+ + + +
[docs]def QA_fetch_index_day(code, start, end, format='numpy', collections=DATABASE.index_day): + '获取指数日线' + start = str(start)[0:10] + end = str(end)[0:10] + + if QA_util_date_valid(end) == True: + + __data = [] + cursor = collections.find({ + 'code': str(code)[0:6], "date_stamp": { + "$lte": QA_util_date_stamp(end), + "$gte": QA_util_date_stamp(start)}}) + if format in ['dict', 'json']: + return [data for data in cursor] + for item in cursor: + + __data.append([str(item['code']), float(item['open']), float(item['high']), float( + item['low']), float(item['close']), float(item['vol']), item['date']]) + + # 多种数据格式 + if format in ['n', 'N', 'numpy']: + __data = numpy.asarray(__data) + elif format in ['list', 'l', 'L']: + __data = __data + elif format in ['P', 'p', 'pandas', 'pd']: + + __data = DataFrame(__data, columns=[ + 'code', 'open', 'high', 'low', 'close', 'volume', 'date']) + + __data['date'] = pd.to_datetime(__data['date']) + __data = __data.set_index('date', drop=False) + return __data + else: + QA_util_log_info('something wrong with date')
+ + +
[docs]def QA_fetch_indexlist_day(stock_list, date_range, collections=DATABASE.index_day): + '获取多个股票的日线' + __data = [] + for item in stock_list: + __data.append(QA_fetch_index_day( + item, date_range[0], date_range[-1], 'pd', collections)) + return __data
+ + +
[docs]def QA_fetch_index_min( + code, + start, end, + format='numpy', + frequence='1min', + collections=DATABASE.index_min): + '获取股票分钟线' + if frequence in ['1min', '1m']: + frequence = '1min' + elif frequence in ['5min', '5m']: + frequence = '5min' + elif frequence in ['15min', '15m']: + frequence = '15min' + elif frequence in ['30min', '30m']: + frequence = '30min' + elif frequence in ['60min', '60m']: + frequence = '60min' + __data = [] + + cursor = collections.find({ + 'code': str(code), "time_stamp": { + "$gte": QA_util_time_stamp(start), + "$lte": QA_util_time_stamp(end) + }, 'type': frequence + }) + if format in ['dict', 'json']: + return [data for data in cursor] + for item in cursor: + + __data.append([str(item['code']), float(item['open']), float(item['high']), float( + item['low']), float(item['close']), float(item['vol']), item['datetime'], item['time_stamp'], item['date']]) + + __data = DataFrame(__data, columns=[ + 'code', 'open', 'high', 'low', 'close', 'volume', 'datetime', 'time_stamp', 'date']) + + __data['datetime'] = pd.to_datetime(__data['datetime']) + __data = __data.set_index('datetime', drop=False) + if format in ['numpy', 'np', 'n']: + return numpy.asarray(__data) + elif format in ['list', 'l', 'L']: + return numpy.asarray(__data).tolist() + elif format in ['P', 'p', 'pandas', 'pd']: + return __data
+ + +
[docs]def QA_fetch_future_day(): + pass
+ + +
[docs]def QA_fetch_future_min(): + pass
+ + +
[docs]def QA_fetch_future_tick(): + pass
+ + +
[docs]def QA_fetch_stock_xdxr(code, format='pd', collections=DATABASE.stock_xdxr): + '获取股票除权信息/数据库' + data = pd.DataFrame([item for item in collections.find( + {'code': code})]).drop(['_id'], axis=1) + data['date'] = pd.to_datetime(data['date']) + return data.set_index('date', drop=False)
+ + +
[docs]def QA_fetch_backtest_info(user=None, account_cookie=None, strategy=None, stock_list=None, collections=DATABASE.backtest_info): + + return QA_util_to_json_from_pandas(pd.DataFrame([item for item in collections.find(QA_util_to_json_from_pandas(pd.DataFrame([user, account_cookie, strategy, stock_list], index=['user', 'account_cookie', 'strategy', 'stock_list']).dropna().T)[0])]).drop(['_id'], axis=1))
+ + +
[docs]def QA_fetch_backtest_history(cookie=None, collections=DATABASE.backtest_history): + return QA_util_to_json_from_pandas(pd.DataFrame([item for item in collections.find(QA_util_to_json_from_pandas(pd.DataFrame([cookie], index=['cookie']).dropna().T)[0])]).drop(['_id'], axis=1))
+ + +
[docs]def QA_fetch_stock_block(code=None, format='pd', collections=DATABASE.stock_block): + if code is not None: + data = pd.DataFrame([item for item in collections.find( + {'code': code})]).drop(['_id'], axis=1) + return data.set_index('code', drop=False) + else: + data = pd.DataFrame( + [item for item in collections.find()]).drop(['_id'], axis=1) + return data.set_index('code', drop=False)
+ + +
[docs]def QA_fetch_stock_info(code, format='pd', collections=DATABASE.stock_info): + try: + data = pd.DataFrame([item for item in collections.find( + {'code': code})]).drop(['_id'], axis=1) + #data['date'] = pd.to_datetime(data['date']) + return data.set_index('code', drop=False) + except Exception as e: + QA_util_log_info(e) + return None
+ + +
[docs]def QA_fetch_stock_name(code, collections=DATABASE.stock_list): + try: + return collections.find_one({'code': code})['name'] + except Exception as e: + QA_util_log_info(e)
+ + +
[docs]def QA_fetch_quotation(code, date=datetime.date.today(), db=DATABASE): + '获取某一只实时5档行情的存储结果' + try: + collections = db.get_collection( + 'realtime_{}'.format(date)) + return pd.DataFrame([item for item in collections.find( + {'code': code})]).drop(['_id'], axis=1).set_index('datetime', drop=False).sort_index() + except Exception as e: + raise e
+ + +
[docs]def QA_fetch_quotations(date=datetime.date.today(), db=DATABASE): + '获取全部实时5档行情的存储结果' + try: + collections = db.get_collection( + 'realtime_{}'.format(date)) + return pd.DataFrame([item for item in collections.find( + {})]).drop(['_id'], axis=1).set_index('datetime', drop=False).sort_index() + except Exception as e: + raise e
+ + +
[docs]def QA_fetch_account(message={}, db=DATABASE): + """get the account + + Arguments: + query_mes {[type]} -- [description] + + Keyword Arguments: + collection {[type]} -- [description] (default: {DATABASE}) + + Returns: + [type] -- [description] + """ + collection = DATABASE.account + return [QA_util_dict_remove_key(res, '_id') for res in collection.find(message)]
+ + +if __name__ == '__main__': + print(QA_fetch_quotations('000001')) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/QAQuery_Advance.html b/_build/html/_modules/QUANTAXIS/QAFetch/QAQuery_Advance.html new file mode 100644 index 000000000..9a42b2726 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/QAQuery_Advance.html @@ -0,0 +1,323 @@ + + + + + + + + QUANTAXIS.QAFetch.QAQuery_Advance — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.QAQuery_Advance

+# coding: utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import datetime
+import re
+import pymongo
+import pandas as pd
+from pandas import DataFrame
+
+from QUANTAXIS.QAData import (QA_DataStruct_Index_day, QA_DataStruct_Index_min,
+                              QA_DataStruct_Stock_block,
+                              QA_DataStruct_Stock_day, QA_DataStruct_Stock_min,
+                              QA_DataStruct_Stock_transaction)
+from QUANTAXIS.QAFetch.QAQuery import (QA_fetch_indexlist_day,
+                                       QA_fetch_stock_day,
+                                       QA_fetch_stock_full,
+                                       QA_fetch_stock_min)
+from QUANTAXIS.QAUtil import (DATABASE, QA_Setting, QA_util_date_stamp,
+                              QA_util_date_valid, QA_util_log_info,
+                              QA_util_time_stamp)
+
+"""
+按要求从数据库取数据,并转换成numpy结构
+
+"""
+# start='1990-01-01',end=str(datetime.date.today())
+
+
+
[docs]def QA_fetch_stock_day_adv( + code, + start='all', end=None, + if_drop_index=False, + collections=DATABASE.stock_day): + '获取股票日线' + end = start if end is None else end + start = str(start)[0:10] + end = str(end)[0:10] + + if start == 'all': + start = '1990-01-01' + end = str(datetime.date.today()) + + return QA_DataStruct_Stock_day(QA_fetch_stock_day(code, start, end, format='pd').query('volume>1').set_index(['date', 'code'], drop=if_drop_index))
+ + +
[docs]def QA_fetch_stock_min_adv( + code, + start, end=None, + frequence='1min', + if_drop_index=False, + collections=DATABASE.stock_min): + '获取股票分钟线' + if frequence in ['1min', '1m']: + frequence = '1min' + elif frequence in ['5min', '5m']: + frequence = '5min' + elif frequence in ['15min', '15m']: + frequence = '15min' + elif frequence in ['30min', '30m']: + frequence = '30min' + elif frequence in ['60min', '60m']: + frequence = '60min' + __data = [] + + end = start if end is None else end + if len(start) == 10: + start = '{} 09:30:00'.format(start) + if len(end) == 10: + end = '{} 15:00:00'.format(end) + + return QA_DataStruct_Stock_min(QA_fetch_stock_min(code, start, end, format='pd', frequence=frequence).query('volume>1').set_index(['datetime', 'code'], drop=if_drop_index))
+ + +
[docs]def QA_fetch_stock_day_full_adv(date): + '返回全市场某一天的数据' + return QA_DataStruct_Stock_day(QA_fetch_stock_full(date, 'pd').set_index(['date', 'code'], drop=False))
+ + +
[docs]def QA_fetch_index_day_adv( + code, + start, end=None, + if_drop_index=False, + collections=DATABASE.index_day): + '获取指数日线' + end = start if end is None else end + start = str(start)[0:10] + end = str(end)[0:10] + if isinstance(code, str): + if QA_util_date_valid(end) == True: + __data = [] + for item in collections.find({ + 'code': str(code)[0:6], "date_stamp": { + "$lte": QA_util_date_stamp(end), + "$gte": QA_util_date_stamp(start)}}): + __data.append([str(item['code']), float(item['open']), float(item['high']), float( + item['low']), float(item['close']), float(item['vol']), item['date']]) + __data = DataFrame(__data, columns=[ + 'code', 'open', 'high', 'low', 'close', 'volume', 'date']) + __data['date'] = pd.to_datetime(__data['date']) + return QA_DataStruct_Index_day(__data.query('volume>1').set_index(['date', 'code'], drop=if_drop_index)) + else: + QA_util_log_info('something wrong with date') + + elif isinstance(code, list): + return QA_DataStruct_Index_day(pd.concat(QA_fetch_indexlist_day(code, [start, end])).query('volume>1').set_index(['date', 'code'], drop=if_drop_index))
+ + +
[docs]def QA_fetch_index_min_adv( + code, + start, end=None, + frequence='1min', + if_drop_index=False, + collections=DATABASE.index_min): + '获取股票分钟线' + if frequence in ['1min', '1m']: + frequence = '1min' + elif frequence in ['5min', '5m']: + frequence = '5min' + elif frequence in ['15min', '15m']: + frequence = '15min' + elif frequence in ['30min', '30m']: + frequence = '30min' + elif frequence in ['60min', '60m']: + frequence = '60min' + __data = [] + end = start if end is None else end + if len(start) == 10: + start = '{} 09:30:00'.format(start) + if len(end) == 10: + end = '{} 15:00:00'.format(end) + if isinstance(code, str): + for item in collections.find({ + 'code': str(code), "time_stamp": { + "$gte": QA_util_time_stamp(start), + "$lte": QA_util_time_stamp(end) + }, 'type': frequence + }): + + __data.append([str(item['code']), float(item['open']), float(item['high']), float( + item['low']), float(item['close']), float(item['vol']), item['datetime'], item['time_stamp'], item['date']]) + + __data = DataFrame(__data, columns=[ + 'code', 'open', 'high', 'low', 'close', 'volume', 'datetime', 'time_stamp', 'date']) + + __data['datetime'] = pd.to_datetime(__data['datetime']) + return QA_DataStruct_Index_min(__data.query('volume>1').set_index(['datetime', 'code'], drop=if_drop_index)) + + elif isinstance(code, list): + return QA_DataStruct_Index_min(pd.concat([QA_fetch_index_min_adv(code_, start, end, frequence, if_drop_index).data for code_ in code]).set_index(['datetime', 'code'], drop=if_drop_index))
+ + +
[docs]def QA_fetch_stock_transaction_adv( + code, + start, end=None, + if_drop_index=False, + collections=DATABASE.stock_transaction): + end = start if end is None else end + data = DataFrame([item for item in collections.find({ + 'code': str(code), "date": { + "$gte": start, + "$lte": end + }})]) + + data['datetime'] = pd.to_datetime(data['datetime']) + return QA_DataStruct_Stock_transaction(data.set_index('datetime', drop=if_drop_index))
+ + +
[docs]def QA_fetch_security_list_adv(collections=DATABASE.stock_list): + '获取股票列表' + return pd.DataFrame([item for item in collections.find()]).drop('_id', axis=1, inplace=False)
+ + +
[docs]def QA_fetch_stock_list_adv(collections=DATABASE.stock_list): + '获取股票列表' + return pd.DataFrame([item for item in collections.find()]).drop('_id', axis=1, inplace=False)
+ + +
[docs]def QA_fetch_stock_block_adv(code=None, blockname=None, collections=DATABASE.stock_block): + """返回板块 + + Keyword Arguments: + code {[type]} -- [description] (default: {None}) + blockname {[type]} -- [descrioption] (default : {None}) + collections {[type]} -- [description] (default: {DATABASE}) + + Returns: + [type] -- [description] + """ + + if code is not None and blockname is None: + data = pd.DataFrame([item for item in collections.find( + {'code': code})]).drop(['_id'], axis=1) + return QA_DataStruct_Stock_block(data.set_index('code', drop=False).drop_duplicates()) + elif blockname is not None and code is None: + + data = pd.DataFrame([item for item in collections.find( + {'blockname': re.compile(blockname)})]).drop(['_id'], axis=1) + else: + data = pd.DataFrame( + [item for item in collections.find()]).drop(['_id'], axis=1) + return QA_DataStruct_Stock_block(data.set_index('code', drop=False).drop_duplicates())
+ + +
[docs]def QA_fetch_stock_realtime_adv(code=None, num=1, collections=DATABASE.get_collection('realtime_{}'.format(datetime.date.today()))): + """ + 返回当日的上下五档, code可以是股票可以是list, num是每个股票获取的数量 + """ + if code is not None: + if isinstance(code, str): + code = list(code) + + elif isinstance(code, list): + pass + data = pd.DataFrame([item for item in collections.find( + {'code': {'$in': code}}, limit=num*len(code), sort=[('datetime', pymongo.DESCENDING)])]).set_index(['datetime', 'code'], drop=False).drop(['_id'], axis=1) + return data + else: + pass
+ + +if __name__ == '__main__': + QA_fetch_stock_realtime_adv(['000001', '000002'], num=10) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/QATdx.html b/_build/html/_modules/QUANTAXIS/QAFetch/QATdx.html new file mode 100644 index 000000000..4d9e244c7 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/QATdx.html @@ -0,0 +1,974 @@ + + + + + + + + QUANTAXIS.QAFetch.QATdx — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.QATdx

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import datetime
+
+import numpy as np
+import pandas as pd
+from pytdx.exhq import TdxExHq_API
+from pytdx.hq import TdxHq_API
+
+from QUANTAXIS.QAUtil import (QA_util_date_stamp, QA_util_date_str2int,
+                              QA_util_date_valid, QA_util_get_real_date,
+                              QA_util_get_real_datelist, QA_util_get_trade_gap,
+                              QA_util_log_info, QA_util_time_stamp,
+                              QA_util_web_ping, future_ip_list, stock_ip_list,
+                              trade_date_sse)
+
+from QUANTAXIS.QAFetch.base import _select_market_code, _select_type
+
+# 基于Pytdx的数据接口,好处是可以在linux/mac上联入通达信行情
+# 具体参见rainx的pytdx(https://github.com/rainx/pytdx)
+#
+
+
+
[docs]def ping(ip, port=7709, type_='stock'): + api = TdxHq_API() + apix = TdxExHq_API() + __time1 = datetime.datetime.now() + try: + if type_ in ['stock']: + with api.connect(ip, port, time_out=0.7): + if len(api.get_security_list(0, 1)) > 800: + return datetime.datetime.now() - __time1 + else: + print('Bad STOCKIP REPSONSE %s' % ip) + return datetime.timedelta(9, 9, 0) + elif type_ in ['future']: + with apix.connect(ip, port, time_out=0.7): + if apix.get_instrument_count() > 10000: + return datetime.datetime.now() - __time1 + else: + print('Bad FUTUREIP REPSONSE %s' % ip) + return datetime.timedelta(9, 9, 0) + except: + print('Bad REPSONSE %s' % ip) + return datetime.timedelta(9, 9, 0)
+ + +
[docs]def select_best_ip(): + QA_util_log_info('Selecting the Best Server IP of TDX') + + data_stock = [ping(x['ip'], x['port'], 'stock') for x in stock_ip_list] + data_future = [ping(x['ip'], x['port'], 'future') for x in future_ip_list] + + best_stock_ip = stock_ip_list[data_stock.index(min(data_stock))] + best_future_ip = future_ip_list[data_future.index(min(data_future))] + + QA_util_log_info('=== The BEST SERVER ===\n stock_ip {} future_ip {}'.format( + best_stock_ip['ip'], best_future_ip['ip'])) + return {'stock': best_stock_ip, 'future': best_future_ip}
+ + +best_ip = select_best_ip() + +# return 1 if sh, 0 if sz + + +
[docs]def QA_fetch_get_security_bars(code, _type, lens, ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + """按bar长度推算数据 + + Arguments: + code {[type]} -- [description] + _type {[type]} -- [description] + lens {[type]} -- [description] + + Keyword Arguments: + ip {[type]} -- [description] (default: {best_ip}) + port {[type]} -- [description] (default: {7709}) + + Returns: + [type] -- [description] + """ + + api = TdxHq_API() + with api.connect(ip, port): + data = pd.concat([api.to_df(api.get_security_bars(_select_type(_type), _select_market_code( + code), code, (i - 1) * 800, 800)) for i in range(1, int(lens / 800) + 2)], axis=0) + data = data\ + .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\ + .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\ + .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\ + .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\ + .assign(type=_type).set_index('datetime', drop=False, inplace=False).tail(lens) + if data is not None: + return data + else: + return None
+ + +
[docs]def QA_fetch_get_stock_day(code, start_date, end_date, if_fq='00', frequence='day', ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + """获取日线及以上级别的数据 + + + Arguments: + code {str:6} -- code 是一个单独的code 6位长度的str + start_date {str:10} -- 10位长度的日期 比如'2017-01-01' + end_date {str:10} -- 10位长度的日期 比如'2018-01-01' + + Keyword Arguments: + if_fq {str} -- '00'/'bfq' -- 不复权 '01'/'qfq' -- 前复权 '02'/'hfq' -- 后复权 '03'/'ddqfq' -- 定点前复权 '04'/'ddhfq' --定点后复权 + frequency {str} -- day/week/month/quarter/year 也可以是简写 D/W/M/Q/Y + ip {str} -- [description] (default: best_ip['stock']['ip']) ip可以通过select_best_ip()函数重新获取 + port {int} -- [description] (default: {7709}) + + + Returns: + pd.DataFrame/None -- 返回的是dataframe,如果出错比如只获取了一天,而当天停牌,返回None + + Exception: + 如果出现网络问题/服务器拒绝, 会出现socket:time out 尝试再次获取/更换ip即可, 本函数不做处理 + """ + + api = TdxHq_API() + with api.connect(ip, port, time_out=0.7): + + if frequence in ['day', 'd', 'D', 'DAY', 'Day']: + frequence = 9 + elif frequence in ['w', 'W', 'Week', 'week']: + frequence = 5 + elif frequence in ['month', 'M', 'm', 'Month']: + frequence = 6 + elif frequence in ['quarter', 'Q', 'Quarter', 'q']: + frequence = 10 + elif frequence in ['y', 'Y', 'year', 'Year']: + frequence = 11 + start_date = str(start_date)[0:10] + today_ = datetime.date.today() + lens = QA_util_get_trade_gap(start_date, today_) + + data = pd.concat([api.to_df(api.get_security_bars(frequence, _select_market_code( + code), code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0) + + # 这里的问题是: 如果只取了一天的股票,而当天停牌, 那么就直接返回None了 + if len(data) < 1: + return None + data = data[data['open'] != 0] + + if if_fq in ['00', 'bfq']: + data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10]))).set_index('date', drop=False, inplace=False) + + return data.drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)[start_date:end_date].assign(date=data['date'].apply(lambda x: str(x)[0:10])) + + elif if_fq in ['01', 'qfq']: + + xdxr_data = QA_fetch_get_stock_xdxr(code) + bfq_data = data.assign(date=pd.to_datetime(data['datetime'].apply(lambda x: str(x[0:10])))).assign(code=str(code))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10]))).set_index('date', drop=False, inplace=False) + bfq_data = bfq_data.drop( + ['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1) + # + if xdxr_data is not None: + info = xdxr_data[xdxr_data['category'] == 1] + bfq_data['if_trade'] = True + data = pd.concat([bfq_data, info[['category']] + [bfq_data.index[0]:]], axis=1) + + data['date'] = data.index + data['if_trade'].fillna(value=False, inplace=True) + data = data.fillna(method='ffill') + data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia', + 'songzhuangu']][bfq_data.index[0]:]], axis=1) + data = data.fillna(0) + + data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu'] + * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu']) + data['adj'] = (data['preclose'].shift(-1) / + data['close']).fillna(1)[::-1].cumprod() + data['open'] = data['open'] * data['adj'] + data['high'] = data['high'] * data['adj'] + data['low'] = data['low'] * data['adj'] + data['close'] = data['close'] * data['adj'] + data['preclose'] = data['preclose'] * data['adj'] + + data = data[data['if_trade']] + return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date] + else: + + bfq_data['preclose'] = bfq_data['close'].shift(1) + bfq_data['adj'] = 1 + return bfq_data[start_date:end_date] + elif if_fq in ['03', 'ddqfq']: + xdxr_data = QA_fetch_get_stock_xdxr(code) + + info = xdxr_data[xdxr_data['category'] == 1] + + bfq_data = data\ + .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\ + .assign(code=str(code))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\ + .set_index('date', drop=False, inplace=False)\ + .drop(['year', 'month', 'day', 'hour', + 'minute', 'datetime'], axis=1) + + bfq_data['if_trade'] = True + data = pd.concat([bfq_data, info[['category']] + [bfq_data.index[0]:end_date]], axis=1) + + data['date'] = data.index + data['if_trade'].fillna(value=False, inplace=True) + data = data.fillna(method='ffill') + data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia', + 'songzhuangu']][bfq_data.index[0]:end_date]], axis=1) + data = data.fillna(0) + + data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu'] + * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu']) + data['adj'] = (data['preclose'].shift(-1) / + data['close']).fillna(1)[::-1].cumprod() + data['open'] = data['open'] * data['adj'] + data['high'] = data['high'] * data['adj'] + data['low'] = data['low'] * data['adj'] + data['close'] = data['close'] * data['adj'] + data['preclose'] = data['preclose'] * data['adj'] + + data = data[data['if_trade']] + return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date] + + elif if_fq in ['02', 'hfq']: + xdxr_data = QA_fetch_get_stock_xdxr(code) + + info = xdxr_data[xdxr_data['category'] == 1] + + bfq_data = data\ + .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\ + .assign(code=str(code))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\ + .set_index('date', drop=False, inplace=False)\ + .drop(['year', 'month', 'day', 'hour', + 'minute', 'datetime'], axis=1) + + bfq_data['if_trade'] = True + data = pd.concat([bfq_data, info[['category']] + [bfq_data.index[0]:]], axis=1) + + data['date'] = data.index + data['if_trade'].fillna(value=False, inplace=True) + data = data.fillna(method='ffill') + data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia', + 'songzhuangu']][bfq_data.index[0]:]], axis=1) + data = data.fillna(0) + + data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu'] + * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu']) + data['adj'] = (data['preclose'].shift(-1) / + data['close']).fillna(1).cumprod() + data['open'] = data['open'] / data['adj'] + data['high'] = data['high'] / data['adj'] + data['low'] = data['low'] / data['adj'] + data['close'] = data['close'] / data['adj'] + data['preclose'] = data['preclose'] / data['adj'] + data = data[data['if_trade']] + return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date] + + elif if_fq in ['04', 'ddhfq']: + xdxr_data = QA_fetch_get_stock_xdxr(code) + + info = xdxr_data[xdxr_data['category'] == 1] + + bfq_data = data\ + .assign(date=pd.to_datetime(data['datetime'].apply(lambda x: x[0:10])))\ + .assign(code=str(code))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\ + .set_index('date', drop=False, inplace=False)\ + .drop(['year', 'month', 'day', 'hour', + 'minute', 'datetime'], axis=1) + + bfq_data['if_trade'] = True + data = pd.concat([bfq_data, info[['category']] + [bfq_data.index[0]:end_date]], axis=1) + + data['date'] = data.index + data['if_trade'].fillna(value=False, inplace=True) + data = data.fillna(method='ffill') + data = pd.concat([data, info[['fenhong', 'peigu', 'peigujia', + 'songzhuangu']][bfq_data.index[0]:end_date]], axis=1) + data = data.fillna(0) + + data['preclose'] = (data['close'].shift(1) * 10 - data['fenhong'] + data['peigu'] + * data['peigujia']) / (10 + data['peigu'] + data['songzhuangu']) + data['adj'] = (data['preclose'].shift(-1) / + data['close']).fillna(1).cumprod() + data['open'] = data['open'] / data['adj'] + data['high'] = data['high'] / data['adj'] + data['low'] = data['low'] / data['adj'] + data['close'] = data['close'] / data['adj'] + data['preclose'] = data['preclose'] / data['adj'] + data = data[data['if_trade']] + return data.drop(['fenhong', 'peigu', 'peigujia', 'songzhuangu', 'if_trade', 'category'], axis=1)[data['open'] != 0].assign(date=data['date'].apply(lambda x: str(x)[0:10]))[start_date:end_date]
+ + +
[docs]def QA_fetch_get_stock_min(code, start, end, frequence='1min', ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + api = TdxHq_API() + type_ = '' + start_date = str(start)[0:10] + today_ = datetime.date.today() + lens = QA_util_get_trade_gap(start_date, today_) + if str(frequence) in ['5', '5m', '5min', 'five']: + frequence, type_ = 0, '5min' + lens = 48 * lens + elif str(frequence) in ['1', '1m', '1min', 'one']: + frequence, type_ = 8, '1min' + lens = 240 * lens + elif str(frequence) in ['15', '15m', '15min', 'fifteen']: + frequence, type_ = 1, '15min' + lens = 16 * lens + elif str(frequence) in ['30', '30m', '30min', 'half']: + frequence, type_ = 2, '30min' + lens = 8 * lens + elif str(frequence) in ['60', '60m', '60min', '1h']: + frequence, type_ = 3, '60min' + lens = 4 * lens + if lens > 20800: + lens = 20800 + with api.connect(ip, port): + + data = pd.concat([api.to_df(api.get_security_bars(frequence, _select_market_code( + str(code)), str(code), (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0) + data = data\ + .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\ + .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\ + .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\ + .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\ + .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end] + return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
+ + +
[docs]def QA_fetch_get_stock_latest(code, ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + code = [code] if isinstance(code, str) else code + api = TdxHq_API(multithread=True) + with api.connect(ip, port): + data = pd.concat([api.to_df(api.get_security_bars( + 9, _select_market_code(item), item, 0, 1)).assign(code=item) for item in code], axis=0) + return data\ + .assign(date=pd.to_datetime(data['datetime'] + .apply(lambda x: x[0:10])), date_stamp=data['datetime'] + .apply(lambda x: QA_util_date_stamp(str(x[0:10]))))\ + .set_index('date', drop=False)\ + .drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)
+ + +
[docs]def QA_fetch_get_stock_realtime(code=['000001', '000002'], ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + api = TdxHq_API() + __data = pd.DataFrame() + with api.connect(ip, port): + code = [code] if type(code) is str else code + for id_ in range(int(len(code) / 80) + 1): + __data = __data.append(api.to_df(api.get_security_quotes( + [(_select_market_code(x), x) for x in code[80 * id_:80 * (id_ + 1)]]))) + __data['datetime'] = datetime.datetime.now() + data = __data[['datetime', 'active1', 'active2', 'last_close', 'code', 'open', 'high', 'low', 'price', 'cur_vol', + 's_vol', 'b_vol', 'vol', 'ask1', 'ask_vol1', 'bid1', 'bid_vol1', 'ask2', 'ask_vol2', + 'bid2', 'bid_vol2', 'ask3', 'ask_vol3', 'bid3', 'bid_vol3', 'ask4', + 'ask_vol4', 'bid4', 'bid_vol4', 'ask5', 'ask_vol5', 'bid5', 'bid_vol5']] + return data.set_index('code', drop=False, inplace=False)
+ + +
[docs]def QA_fetch_depth_market_data(code=['000001', '000002'], ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + api = TdxHq_API() + __data = pd.DataFrame() + with api.connect(ip, port): + code = [code] if type(code) is str else code + for id_ in range(int(len(code) / 80) + 1): + __data = __data.append(api.to_df(api.get_security_quotes( + [(_select_market_code(x), x) for x in code[80 * id_:80 * (id_ + 1)]]))) + __data['datetime'] = datetime.datetime.now() + data = __data[['datetime', 'active1', 'active2', 'last_close', 'code', 'open', 'high', 'low', 'price', 'cur_vol', + 's_vol', 'b_vol', 'vol', 'ask1', 'ask_vol1', 'bid1', 'bid_vol1', 'ask2', 'ask_vol2', + 'bid2', 'bid_vol2', 'ask3', 'ask_vol3', 'bid3', 'bid_vol3', 'ask4', + 'ask_vol4', 'bid4', 'bid_vol4', 'ask5', 'ask_vol5', 'bid5', 'bid_vol5']] + return data.set_index(['datetime', 'code'], drop=False, inplace=False)
+ + +''' +沪市 +001×××国债现货; +110×××120×××企业债券; +129×××100×××可转换债券; +201×××国债回购; +310×××国债期货; +500×××550×××基金; + + +600×××A股; + +700×××配股; +710×××转配股; +701×××转配股再配股; +711×××转配股再转配股; +720×××红利; +730×××新股申购; +735×××新基金申购; +737×××新股配售; +900×××B股。 + +深市 +深市A股票买卖的代码是以000打头,如:顺鑫农业:股票代码是000860。 +B股买卖的代码是以200打头,如:深中冠B股,代码是200018。 +中小板股票代码以002打头,如:东华合创股票代码是002065。 +创业板股票代码以300打头,如:探路者股票代码是:300005 + + +更多参见 issue https://github.com/QUANTAXIS/QUANTAXIS/issues/158 +@yutiansut +''' + + +
[docs]def for_sz(code): + if str(code)[0:2] in ['00', '30', '02']: + return 'stock_cn' + elif str(code)[0:2] in ['39']: + return 'index_cn' + elif str(code)[0:2] in ['15']: + return 'etf_cn' + else: + return 'undefined'
+ + +
[docs]def for_sh(code): + if str(code)[0] == '6': + return 'stock_cn' + elif str(code)[0] == '0': + return 'index_cn' + elif str(code)[0:2] == '51': + return 'etf_cn' + else: + return 'undefined'
+ + +
[docs]def QA_fetch_get_stock_list(type_='stock', ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + + api = TdxHq_API() + with api.connect(ip, port): + data = pd.concat([pd.concat([api.to_df(api.get_security_list(j, i * 1000)).assign(sse='sz' if j == 0 else 'sh').set_index( + ['code', 'sse'], drop=False) for i in range(int(api.get_security_count(j) / 1000) + 1)], axis=0) for j in range(2)], axis=0) + #data.code = data.code.apply(int) + sz = data.query('sse=="sz"') + sh = data.query('sse=="sh"') + + sz = sz.assign(sec=sz.code.apply(for_sz)) + sh = sh.assign(sec=sh.code.apply(for_sh)) + + if type_ in ['stock', 'gp']: + + return pd.concat([sz, sh]).query('sec=="stock_cn"').sort_index().assign(name=data['name'].apply(lambda x: str(x)[0:6])) + + elif type_ in ['index', 'zs']: + + return pd.concat([sz, sh]).query('sec=="index_cn"').sort_index().assign(name=data['name'].apply(lambda x: str(x)[0:6])) + #.assign(szm=data['name'].apply(lambda x: ''.join([y[0] for y in lazy_pinyin(x)])))\ + #.assign(quanpin=data['name'].apply(lambda x: ''.join(lazy_pinyin(x)))) + elif type_ in ['etf', 'ETF']: + return pd.concat([sz, sh]).query('sec=="etf_cn"').sort_index().assign(name=data['name'].apply(lambda x: str(x)[0:6])) + + else: + return data.assign(code=data['code'].apply(lambda x: str(x))).assign(name=data['name'].apply(lambda x: str(x)[0:6]))
+ #.assign(szm=data['name'].apply(lambda x: ''.join([y[0] for y in lazy_pinyin(x)])))\ + # .assign(quanpin=data['name'].apply(lambda x: ''.join(lazy_pinyin(x)))) + + +
[docs]def QA_fetch_get_index_day(code, start_date, end_date, frequence='day', ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + '指数日线' + api = TdxHq_API() + if frequence in ['day', 'd', 'D', 'DAY', 'Day']: + frequence = 9 + elif frequence in ['w', 'W', 'Week', 'week']: + frequence = 5 + elif frequence in ['month', 'M', 'm', 'Month']: + frequence = 6 + elif frequence in ['Q', 'Quarter', 'q']: + frequence = 10 + elif frequence in ['y', 'Y', 'year', 'Year']: + frequence = 11 + + with api.connect(ip, port): + + start_date = str(start_date)[0:10] + today_ = datetime.date.today() + lens = QA_util_get_trade_gap(start_date, today_) + + if str(code)[0] in ['5', '1']: # ETF + data = pd.concat([api.to_df(api.get_security_bars( + frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0) + else: + data = pd.concat([api.to_df(api.get_index_bars( + frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0) + data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10])))\ + .set_index('date', drop=False, inplace=False)\ + .assign(code=code)\ + .drop(['year', 'month', 'day', 'hour', + 'minute', 'datetime'], axis=1)[start_date:end_date] + return data.assign(date=data['date'].apply(lambda x: str(x)[0:10]))
+ + +
[docs]def QA_fetch_get_index_min(code, start, end, frequence='1min', ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + '指数分钟线' + api = TdxHq_API() + type_ = '' + + start_date = str(start)[0:10] + today_ = datetime.date.today() + lens = QA_util_get_trade_gap(start_date, today_) + if str(frequence) in ['5', '5m', '5min', 'five']: + frequence, type_ = 0, '5min' + lens = 48 * lens + elif str(frequence) in ['1', '1m', '1min', 'one']: + frequence, type_ = 8, '1min' + lens = 240 * lens + elif str(frequence) in ['15', '15m', '15min', 'fifteen']: + frequence, type_ = 1, '15min' + lens = 16 * lens + elif str(frequence) in ['30', '30m', '30min', 'half']: + frequence, type_ = 2, '30min' + lens = 8 * lens + elif str(frequence) in ['60', '60m', '60min', '1h']: + frequence, type_ = 3, '60min' + lens = 4 * lens + + if lens > 20800: + lens = 20800 + with api.connect(ip, port): + + if str(code)[0] in ['5', '1']: # ETF + data = pd.concat([api.to_df(api.get_security_bars( + frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0) + else: + data = pd.concat([api.to_df(api.get_index_bars( + frequence, 1 if str(code)[0] in ['0', '8', '9', '5'] else 0, code, (int(lens / 800) - i) * 800, 800)) for i in range(int(lens / 800) + 1)], axis=0) + data = data\ + .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\ + .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\ + .assign(code=code)\ + .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\ + .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\ + .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end] + # data + return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
+ + +def __QA_fetch_get_stock_transaction(code, day, retry, api): + batch_size = 2000 # 800 or 2000 ? 2000 maybe also works + data_arr = [] + max_offset = 21 + cur_offset = 0 + while cur_offset <= max_offset: + one_chunk = api.get_history_transaction_data( + _select_market_code(str(code)), str(code), cur_offset * batch_size, batch_size, QA_util_date_str2int(day)) + if one_chunk is None or one_chunk == []: + break + data_arr = one_chunk + data_arr + cur_offset += 1 + data_ = api.to_df(data_arr) + + for _ in range(retry): + if len(data_) < 2: + return __QA_fetch_get_stock_transaction(code, day, 0, api) + else: + return data_.assign(date=day).assign(datetime=pd.to_datetime(data_['time'].apply(lambda x: str(day) + ' ' + x)))\ + .assign(code=str(code)).assign(order=range(len(data_.index))).set_index('datetime', drop=False, inplace=False) + + +
[docs]def QA_fetch_get_stock_transaction(code, start, end, retry=2, ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + '历史逐笔成交 buyorsell 1--sell 0--buy 2--盘前' + api = TdxHq_API() + + real_start, real_end = QA_util_get_real_datelist(start, end) + if real_start is None: + return None + real_id_range = [] + with api.connect(ip, port): + data = pd.DataFrame() + for index_ in range(trade_date_sse.index(real_start), trade_date_sse.index(real_end) + 1): + + try: + data_ = __QA_fetch_get_stock_transaction( + code, trade_date_sse[index_], retry, api) + if len(data_) < 1: + return None + except: + QA_util_log_info('Wrong in Getting %s history transaction data in day %s' % ( + code, trade_date_sse[index_])) + else: + QA_util_log_info('Successfully Getting %s history transaction data in day %s' % ( + code, trade_date_sse[index_])) + data = data.append(data_) + if len(data) > 0: + + return data.assign(datetime=data['datetime'].apply(lambda x: str(x)[0:19])) + else: + return None
+ + +
[docs]def QA_fetch_get_stock_transaction_realtime(code, ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + '实时逐笔成交 包含集合竞价 buyorsell 1--sell 0--buy 2--盘前' + api = TdxHq_API() + try: + with api.connect(ip, port): + data = pd.DataFrame() + data = pd.concat([api.to_df(api.get_transaction_data( + _select_market_code(str(code)), code, (2 - i) * 2000, 2000)) for i in range(3)], axis=0) + if 'value' in data.columns: + data = data.drop(['value'], axis=1) + data = data.dropna() + day = datetime.date.today() + return data.assign(date=str(day)).assign(datetime=pd.to_datetime(data['time'].apply(lambda x: str(day) + ' ' + str(x))))\ + .assign(code=str(code)).assign(order=range(len(data.index))).set_index('datetime', drop=False, inplace=False) + except: + return None
+ + +
[docs]def QA_fetch_get_stock_xdxr(code, ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + '除权除息' + api = TdxHq_API() + market_code = _select_market_code(code) + with api.connect(ip, port): + category = { + '1': '除权除息', '2': '送配股上市', '3': '非流通股上市', '4': '未知股本变动', '5': '股本变化', + '6': '增发新股', '7': '股份回购', '8': '增发新股上市', '9': '转配股上市', '10': '可转债上市', + '11': '扩缩股', '12': '非流通股缩股', '13': '送认购权证', '14': '送认沽权证'} + data = api.to_df(api.get_xdxr_info(market_code, code)) + if len(data) >= 1: + data = data\ + .assign(date=pd.to_datetime(data[['year', 'month', 'day']]))\ + .drop(['year', 'month', 'day'], axis=1)\ + .assign(category_meaning=data['category'].apply(lambda x: category[str(x)]))\ + .assign(code=str(code))\ + .rename(index=str, columns={'panhouliutong': 'liquidity_after', + 'panqianliutong': 'liquidity_before', 'houzongguben': 'shares_after', + 'qianzongguben': 'shares_before'})\ + .set_index('date', drop=False, inplace=False) + return data.assign(date=data['date'].apply(lambda x: str(x)[0:10])) + else: + return None
+ + +
[docs]def QA_fetch_get_stock_info(code, ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + '股票基本信息' + api = TdxHq_API() + market_code = _select_market_code(code) + with api.connect(ip, port): + return api.to_df(api.get_finance_info(market_code, code))
+ + +
[docs]def QA_fetch_get_stock_block(ip=best_ip['stock']['ip'], port=best_ip['stock']['port']): + '板块数据' + api = TdxHq_API() + with api.connect(ip, port): + + data = pd.concat([api.to_df(api.get_and_parse_block_info("block_gn.dat")).assign(type='gn'), + api.to_df(api.get_and_parse_block_info( + "block.dat")).assign(type='yb'), + api.to_df(api.get_and_parse_block_info( + "block_zs.dat")).assign(type='zs'), + api.to_df(api.get_and_parse_block_info("block_fg.dat")).assign(type='fg')]) + + if len(data) > 10: + return data.assign(source='tdx').drop(['block_type', 'code_index'], axis=1).set_index('code', drop=False, inplace=False).drop_duplicates() + else: + QA_util_log_info('Wrong with fetch block ')
+ + +""" +期货数据接口 + +1: 获取市场代码 +可以获取该api服务器可以使用的市场列表,类别等信息 +api.get_markets() +返回结果 api.to_df(api.get_markets()) 一般某个服务器返回的类型比较固定,该结果可以缓存到本地或者内存中。 +2017-07-31 21:22:06,067 - PYTDX - INFO - 获取市场代码 + market category name short_name +0 1 1 临时股 TP +1 4 12 郑州商品期权 OZ +2 5 12 大连商品期权 OD +3 6 12 上海商品期权 OS +4 8 12 上海个股期权 QQ +5 27 5 香港指数 FH +6 28 3 郑州商品 QZ +7 29 3 大连商品 QD +8 30 3 上海期货 QS +9 31 2 香港主板 KH +10 32 2 香港权证 KR +11 33 8 开放式基金 FU +12 34 9 货币型基金 FB +13 35 8 招商理财产品 LC +14 36 9 招商货币产品 LB +15 37 11 国际指数 FW +16 38 10 国内宏观指标 HG +17 40 11 中国概念股 CH +18 41 11 美股知名公司 MG +19 43 1 B股转H股 HB +20 44 1 股份转让 SB +21 47 3 股指期货 CZ +22 48 2 香港创业板 KG +23 49 2 香港信托基金 KT +24 54 6 国债预发行 GY +25 60 3 主力期货合约 MA +26 62 5 中证指数 ZZ +27 71 2 港股通 GH +2: 查询代码列表 +参数, 起始位置, 获取数量 +api.get_instrument_info(0, 100) +Demo: get_list_demo +3: 查询市场中商品数量 +api.get_instrument_count() +4: 查询五档行情 +参数 市场ID,证券代码 +市场ID可以通过 get_markets 获得 +api.get_instrument_quote(47, "IF1709") +5: 查询分时行情 +参数 市场ID,证券代码 +市场ID可以通过 get_markets 获得 +api.get_minute_time_data(47, "IF1709") +6: 查询历史分时行情 +参数 市场ID,证券代码,日期 +市场ID可以通过 get_markets 获得 +日期格式 YYYYMMDD 如 20170811 +api.get_history_minute_time_data(31, "00020", 20170811) +7: 查询k线数据 +参数: K线周期, 市场ID, 证券代码,起始位置, 数量 +K线周期参考 TDXParams +市场ID可以通过 get_markets 获得 +api.get_instrument_bars(TDXParams.KLINE_TYPE_DAILY, 8, "10000843", 0, 100) +8: 查询分笔成交 +参数:市场ID,证券代码 +市场ID可以通过 get_markets 获得 +api.get_transaction_data(31, "00020") +注意,这个接口最多返回1800条记录, 如果有超过1800条记录的请求,我们有一个start 参数作为便宜量,可以取出超过1800条记录 +如期货的数据:这个接口可以取出1800条之前的记录,数量也是1800条 +api.get_history_transaction_data(47, "IFL0", 20170810, start=1800) +9: 查询历史分笔成交 +参数:市场ID,证券代码, 日期 +市场ID可以通过 get_markets 获得 +日期格式 YYYYMMDD 如 20170810 +api.get_history_transaction_data(31, "00020", 20170810) + +""" +""" +期货及扩展行情 + +首先会初始化/存储一个代码对应表 extension_market_info + +""" + + +
[docs]def QA_fetch_get_future_list(ip=best_ip['future']['ip'], port=best_ip['future']['port']): + '期货代码list' + apix = TdxExHq_API() + with apix.connect(ip, port): + market_info = apix.get_markets() + num = apix.get_instrument_count() + return pd.concat([apix.to_df( + apix.get_instrument_info((int(num / 500) - i) * 500, 500)) + for i in range(int(num / 500) + 1)], axis=0).set_index('code', drop=False)
+ + +global extension_market_info +extension_market_info = None + + +
[docs]def QA_fetch_get_future_day(code, start_date, end_date, frequence='day', ip=best_ip['future']['ip'], port=best_ip['future']['port']): + '期货数据 日线' + + apix = TdxExHq_API() + start_date = str(start_date)[0:10] + today_ = datetime.date.today() + lens = QA_util_get_trade_gap(start_date, today_) + global extension_market_info + extension_market_info = QA_fetch_get_future_list( + ) if extension_market_info is None else extension_market_info + + with apix.connect(ip, port): + code_market = extension_market_info.query('code=="{}"'.format(code)) + + data = pd.concat([apix.to_df(apix.get_instrument_bars(_select_type( + frequence), int(code_market.market), str(code), (int(lens / 700) - i) * 700, 700))for i in range(int(lens / 700) + 1)], axis=0) + data = data.assign(date=data['datetime'].apply(lambda x: str(x[0:10]))).assign(code=str(code))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(str(x)[0:10]))).set_index('date', drop=False, inplace=False) + + return data.drop(['year', 'month', 'day', 'hour', 'minute', 'datetime'], axis=1)[start_date:end_date].assign(date=data['date'].apply(lambda x: str(x)[0:10]))
+ + +
[docs]def QA_fetch_get_future_min(code, start, end, frequence='1min', ip=best_ip['future']['ip'], port=best_ip['future']['port']): + '期货数据 分钟线' + apix = TdxExHq_API() + type_ = '' + start_date = str(start)[0:10] + today_ = datetime.date.today() + lens = QA_util_get_trade_gap(start_date, today_) + global extension_market_info + extension_market_info = QA_fetch_get_future_list( + ) if extension_market_info is None else extension_market_info + + if str(frequence) in ['5', '5m', '5min', 'five']: + frequence, type_ = 0, '5min' + lens = 48 * lens + elif str(frequence) in ['1', '1m', '1min', 'one']: + frequence, type_ = 8, '1min' + lens = 240 * lens + elif str(frequence) in ['15', '15m', '15min', 'fifteen']: + frequence, type_ = 1, '15min' + lens = 16 * lens + elif str(frequence) in ['30', '30m', '30min', 'half']: + frequence, type_ = 2, '30min' + lens = 8 * lens + elif str(frequence) in ['60', '60m', '60min', '1h']: + frequence, type_ = 3, '60min' + lens = 4 * lens + if lens > 20800: + lens = 20800 + with apix.connect(ip, port): + code_market = extension_market_info.query('code=="{}"'.format(code)) + data = pd.concat([apix.to_df(apix.get_instrument_bars(frequence, int(code_market.market), str( + code), (int(lens / 700) - i) * 700, 700)) for i in range(int(lens / 700) + 1)], axis=0) + + data = data\ + .assign(datetime=pd.to_datetime(data['datetime']), code=str(code))\ + .drop(['year', 'month', 'day', 'hour', 'minute'], axis=1, inplace=False)\ + .assign(date=data['datetime'].apply(lambda x: str(x)[0:10]))\ + .assign(date_stamp=data['datetime'].apply(lambda x: QA_util_date_stamp(x)))\ + .assign(time_stamp=data['datetime'].apply(lambda x: QA_util_time_stamp(x)))\ + .assign(type=type_).set_index('datetime', drop=False, inplace=False)[start:end] + return data.assign(datetime=data['datetime'].apply(lambda x: str(x)))
+ + +
[docs]def QA_fetch_get_future_transaction(ip=best_ip['future']['ip'], port=best_ip['future']['port']): + '期货历史成交分笔' + apix = TdxExHq_API() + with apix.connect(ip, port): + pass
+ + +
[docs]def QA_fetch_get_future_transaction_realtime(ip=best_ip['future']['ip'], port=best_ip['future']['port']): + '期货历史成交分笔' + apix = TdxExHq_API() + with apix.connect(ip, port): + pass
+ + +
[docs]def QA_fetch_get_future_realtime(code, ip=best_ip['future']['ip'], port=best_ip['future']['port']): + '期货实时价格' + pass
+ + +
[docs]def QA_fetch_get_wholemarket_list(): + hq_codelist = QA_fetch_get_stock_list( + type_='all').loc[:, ['code', 'name']].set_index(['code', 'name'], drop=False) + kz_codelist = QA_fetch_get_future_list().loc[:, ['code', 'name']].set_index([ + 'code', 'name'], drop=False) + + return pd.concat([hq_codelist, kz_codelist]).sort_index()
+ + +if __name__ == '__main__': + # print(QA_fetch_get_stock_day('000001','2017-07-03','2017-07-10')) + # print(QA_fetch_get_stock_day('000001', '2013-07-01', '2013-07-09')) + print(QA_fetch_get_stock_realtime('000001')) + #print(QA_fetch_get_index_day('000001', '2017-01-01', '2017-07-01')) + # print(QA_fetch_get_stock_transaction('000001', '2017-07-03', '2017-07-10')) + + print(QA_fetch_get_stock_info('600116')) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/QATdx_adv.html b/_build/html/_modules/QUANTAXIS/QAFetch/QATdx_adv.html new file mode 100644 index 000000000..520ad078e --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/QATdx_adv.html @@ -0,0 +1,420 @@ + + + + + + + + QUANTAXIS.QAFetch.QATdx_adv — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.QATdx_adv

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import datetime
+import queue
+import time
+from concurrent.futures import ThreadPoolExecutor
+from threading import Thread, Timer
+
+import pandas as pd
+from pytdx.hq import TdxHq_API
+
+from QUANTAXIS.QAUtil.QADate_trade import QA_util_if_tradetime
+from QUANTAXIS.QAUtil.QASetting import DATABASE, stock_ip_list
+from QUANTAXIS.QAUtil.QASql import QA_util_sql_mongo_sort_ASCENDING
+from QUANTAXIS.QAUtil.QATransform import QA_util_to_json_from_pandas
+
+
+"""
+准备做一个多连接的连接池执行器Executor
+当持续获取数据/批量数据的时候,可以减小服务器的压力,并且可以更快的进行并行处理
+"""
+
+
+
[docs]class QA_Tdx_Executor(): + def __init__(self, thread_num=2, *args, **kwargs): + self.thread_num = thread_num + self._queue = queue.Queue(maxsize=200) + self.api_no_connection = TdxHq_API() + self._api_worker = Thread( + target=self.api_worker, args=(), name='API Worker') + self._api_worker.start() + + self.executor = ThreadPoolExecutor(self.thread_num) + + def __getattr__(self, item): + try: + api = self.get_available() + func = api.__getattribute__(item) + + def wrapper(*args, **kwargs): + res = self.executor.submit(func, *args, **kwargs) + self._queue.put(api) + return res + return wrapper + except: + return self.__getattr__(item) + + def _queue_clean(self): + self._queue = queue.Queue(maxsize=200) + + def _test_speed(self, ip, port=7709): + + api = TdxHq_API(raise_exception=True, auto_retry=False) + _time = datetime.datetime.now() + try: + with api.connect(ip, port, time_out=0.05): + if len(api.get_security_list(0, 1)) > 800: + return (datetime.datetime.now() - _time).total_seconds() + else: + return datetime.timedelta(9, 9, 0).total_seconds() + except Exception as e: + return datetime.timedelta(9, 9, 0).total_seconds() + +
[docs] def get_market(self, code): + code = str(code) + if code[0] in ['5', '6', '9'] or code[:3] in ["009", "126", "110", "201", "202", "203", "204"]: + return 1 + return 0
+ +
[docs] def get_frequence(self, frequence): + if frequence in ['day', 'd', 'D', 'DAY', 'Day']: + frequence = 9 + elif frequence in ['w', 'W', 'Week', 'week']: + frequence = 5 + elif frequence in ['month', 'M', 'm', 'Month']: + frequence = 6 + elif frequence in ['Q', 'Quarter', 'q']: + frequence = 10 + elif frequence in ['y', 'Y', 'year', 'Year']: + frequence = 11 + elif str(frequence) in ['5', '5m', '5min', 'five']: + frequence = 0 + elif str(frequence) in ['1', '1m', '1min', 'one']: + frequence = 8 + elif str(frequence) in ['15', '15m', '15min', 'fifteen']: + frequence = 1 + elif str(frequence) in ['30', '30m', '30min', 'half']: + frequence = 2 + elif str(frequence) in ['60', '60m', '60min', '1h']: + frequence = 3 + + return frequence
+ + @property + def ipsize(self): + return len(self._queue.qsize()) + + @property + def api(self): + return self.get_available() + +
[docs] def get_available(self): + + if self._queue.empty() is False: + return self._queue.get_nowait() + else: + Timer(0, self.api_worker).start() + return self._queue.get()
+ +
[docs] def api_worker(self): + data = [] + if self._queue.qsize() < 80: + for item in stock_ip_list: + _sec = self._test_speed(ip=item['ip'], port=item['port']) + if _sec < 0.1: + try: + self._queue.put(TdxHq_API(heartbeat=False).connect( + ip=item['ip'], port=item['port'], time_out=0.05)) + except: + pass + else: + self._queue_clean() + Timer(0, self.api_worker).start() + Timer(300, self.api_worker).start()
+ + def _singal_job(self, context, id_, time_out=0.5): + try: + _api = self.get_available() + + __data = context.append(self.api_no_connection.to_df(_api.get_security_quotes( + [(self._select_market_code(x), x) for x in code[80 * id_:80 * (id_ + 1)]]))) + __data['datetime'] = datetime.datetime.now() + self._queue.put(_api) # 加入注销 + return __data + except: + return self.singal_job(context, id_) + +
[docs] def get_realtime(self, code): + context = pd.DataFrame() + + code = [code] if type(code) is str else code + try: + for id_ in range(int(len(code) / 80) + 1): + context = self._singal_job(context, id_) + + data = context[['datetime', 'last_close', 'code', 'open', 'high', 'low', 'price', 'cur_vol', + 's_vol', 'b_vol', 'vol', 'ask1', 'ask_vol1', 'bid1', 'bid_vol1', 'ask2', 'ask_vol2', + 'bid2', 'bid_vol2', 'ask3', 'ask_vol3', 'bid3', 'bid_vol3', 'ask4', + 'ask_vol4', 'bid4', 'bid_vol4', 'ask5', 'ask_vol5', 'bid5', 'bid_vol5']] + data['datetime'] = data['datetime'].apply(lambda x: str(x)) + return data.set_index('code', drop=False, inplace=False) + except: + return None
+ +
[docs] def get_realtime_concurrent(self, code): + code = [code] if type(code) is str else code + + try: + data = {self.get_security_quotes([(self.get_market( + x), x) for x in code[80 * pos:80 * (pos + 1)]]) for pos in range(int(len(code) / 80) + 1)} + return (pd.concat([self.api_no_connection.to_df(i.result()) for i in data]), datetime.datetime.now()) + except: + pass
+ +
[docs] def get_security_bar_concurrent(self, code, _type, lens): + try: + + data = {self.get_security_bars(self.get_frequence(_type), self.get_market( + str(code)), str(code), 0, lens) for code in code} + + return [i.result() for i in data] + + except: + raise Exception
+ + def _get_security_bars(self, context, code, _type, lens): + try: + _api = self.get_available() + for i in range(1, int(lens / 800) + 2): + context.extend(_api.get_security_bars(self.get_frequence( + _type), self.get_market(str(code)), str(code), (i - 1) * 800, 800)) + print(context) + self._queue.put(_api) + return context + except Exception as e: + return self._get_security_bars(context, code, _type, lens) + +
[docs] def get_security_bar(self, code, _type, lens): + code = [code] if type(code) is str else code + context = [] + try: + for item in code: + context = self._get_security_bars(context, item, _type, lens) + return context + except Exception as e: + raise e
+ +
[docs] def save_mongo(self, data, client=DATABASE): + database = DATABASE.get_collection( + 'realtime_{}'.format(datetime.date.today())) + + database.insert_many(QA_util_to_json_from_pandas(data))
+ + +
[docs]def get_bar(): + + _time1 = datetime.datetime.now() + from QUANTAXIS.QAFetch.QAQuery_Advance import QA_fetch_stock_block_adv + code = QA_fetch_stock_block_adv().code + print(len(code)) + x = QA_Tdx_Executor() + print(x._queue.qsize()) + print(x.get_available()) + + while True: + _time = datetime.datetime.now() + if QA_util_if_tradetime(_time): # 如果在交易时间 + data = x.get_security_bar_concurrent(code, 'day', 1) + + print('Time {}'.format( + (datetime.datetime.now() - _time).total_seconds())) + time.sleep(1) + print('Connection Pool NOW LEFT {} Available IP'.format( + x._queue.qsize())) + print('Program Last Time {}'.format( + (datetime.datetime.now() - _time1).total_seconds())) + + return data + else: + print('Not Trading time {}'.format(_time)) + time.sleep(1)
+ + +
[docs]def get_day_once(): + + _time1 = datetime.datetime.now() + from QUANTAXIS.QAFetch.QAQuery_Advance import QA_fetch_stock_block_adv + code = QA_fetch_stock_block_adv().code + x = QA_Tdx_Executor() + return x.get_security_bar_concurrent(code, 'day', 1)
+ + +
[docs]def bat(): + + _time1 = datetime.datetime.now() + from QUANTAXIS.QAFetch.QAQuery_Advance import QA_fetch_stock_block_adv + code = QA_fetch_stock_block_adv().code + print(len(code)) + x = QA_Tdx_Executor() + print(x._queue.qsize()) + print(x.get_available()) + + database = DATABASE.get_collection( + 'realtime_{}'.format(datetime.date.today())) + + print(database) + database.create_index([('code', QA_util_sql_mongo_sort_ASCENDING), + ('datetime', QA_util_sql_mongo_sort_ASCENDING)]) + + for i in range(100000): + _time = datetime.datetime.now() + if QA_util_if_tradetime(_time): # 如果在交易时间 + data = x.get_realtime_concurrent(code) + + data[0]['datetime'] = data[1] + x.save_mongo(data[0]) + + print('Time {}'.format( + (datetime.datetime.now() - _time).total_seconds())) + time.sleep(1) + print('Connection Pool NOW LEFT {} Available IP'.format( + x._queue.qsize())) + print('Program Last Time {}'.format( + (datetime.datetime.now() - _time1).total_seconds())) + else: + print('Not Trading time {}'.format(_time)) + time.sleep(1)
+ + +if __name__ == '__main__': + import time + _time1 = datetime.datetime.now() + from QUANTAXIS.QAFetch.QAQuery_Advance import QA_fetch_stock_block_adv + code = QA_fetch_stock_block_adv().code + + DATABASE.realtime.create_index([('code', QA_util_sql_mongo_sort_ASCENDING), + ('datetime', QA_util_sql_mongo_sort_ASCENDING)]) + + # print(len(code)) + # x = QA_Tdx_Executor() + # print(x._queue.qsize()) + # print(x.get_available()) + # #data = x.get_security_bars(code[0], '15min', 20) + # # print(data) + # # for i in range(5): + # # print(x.get_realtime_concurrent(code)) + + # for i in range(100000): + # _time = datetime.datetime.now() + # if QA_util_if_tradetime(_time): # 如果在交易时间 + # #data = x.get_realtime(code) + # data = x.get_realtime_concurrent(code) + + # data[0]['datetime'] = data[1] + # x.save_mongo(data[0]) + # # print(code[0]) + # #data = x.get_security_bars(code, '15min', 20) + # # if data is not None: + # print(len(data[0])) + # # print(data) + # print('Time {}'.format((datetime.datetime.now() - _time).total_seconds())) + # time.sleep(1) + # print('Connection Pool NOW LEFT {} Available IP'.format(x._queue.qsize())) + # print('Program Last Time {}'.format( + # (datetime.datetime.now() - _time1).total_seconds())) + # # print(threading.enumerate()) + # # +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/QAThs.html b/_build/html/_modules/QUANTAXIS/QAFetch/QAThs.html new file mode 100644 index 000000000..0f879df52 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/QAThs.html @@ -0,0 +1,185 @@ + + + + + + + + QUANTAXIS.QAFetch.QAThs — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.QAThs

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import numpy as np
+import pandas as pd
+import requests
+from lxml import etree
+from QUANTAXIS.QAFetch.base import headers
+
+
+headers_ths = headers
+headers_ths['Referer'] = 'http://www.10jqka.com.cn/'
+headers_ths['Host'] = 'q.10jqka.com.cn'
+headers_data = headers_ths
+headers_data['X-Requested-With'] = 'XMLHttpRequest'
+
+
+
[docs]def QA_fetch_get_stock_day_in_year(code, year, if_fq='00'): + data_ = [] + url = 'http://d.10jqka.com.cn/v2/line/hs_%s/%s/%s.js' % ( + str(code), str(if_fq), str(year)) + try: + for item in requests.get(url).text.split('\"')[3].split(';'): + data_.append(item.split(',')) + + data = pd.DataFrame(data_, index=list(np.asarray(data_).T[0]), columns=[ + 'date', 'open', 'high', 'low', 'close', 'volume', 'amount', 'factor']) + data['date'] = pd.to_datetime(data['date']) + data = data.set_index('date') + return data + except: + pass
+ + +
[docs]def QA_fetch_get_stock_day(code, start, end, if_fq='00'): + start_year = int(str(start)[0:4]) + end_year = int(str(end)[0:4]) + data = QA_fetch_get_stock_day_in_year(code, start_year, if_fq) + if start_year < end_year: + for i2 in range(start_year + 1, end_year + 1): + data = pd.concat( + [data, QA_fetch_get_stock_day_in_year(code, i2, if_fq)], axis=0) + else: + pass + if data is None: + return pd.DataFrame() + else: + return data[start:end]
+ + +
[docs]def QA_fetch_get_stock_block(): + pass
+ # url_list = ['gn', 'dy', 'thshy', 'zjhhy'] # 概念/地域/同花顺板块/证监会板块 + # data = [] + # cookie=input('cookie') + # for item in url_list: + # tree = etree.HTML(requests.get( + # 'http://q.10jqka.com.cn/{}/'.format(item), headers=headers_ths).text) + # gn = tree.xpath('/html/body/div/div/div/div/div/a/text()') + # gpath = tree.xpath('/html/body/div/div/div/div/div/a/@href') + # headers_data['cookie']=cookie + # for r in range(len(gn)): + # headers_data['Referer'] = 'http://q.10jqka.com.cn/{}/detail/code/{}'.format( + # item, gpath[r].split('/')[-2]) + + # for i in range(1, 15): + + # _data = etree.HTML(requests.get( + # 'http://q.10jqka.com.cn/{}/detail/order/desc/page/{}/ajax/1/code/{}'.format(item, i, gpath[r].split('/')[-2]), headers=headers_data).text) + # name = _data.xpath('/html/body/table/tbody/tr/td[3]/a/text()') + # code = _data.xpath('/html/body/table/tbody/tr/td[3]/a/@href') + + # for i2 in range(len(name)): + # print( + # 'Now Crawling-{}-{}-{}-{}'.format(gn[r], code[i2].split('/')[-1], item, 'ths')) + # data.append([gn[r], code[i2].split('/')[-1], item, 'ths']) + + # return pd.DataFrame(data, columns=['blockname', 'code', 'type', 'source']).set_index('code', drop=False) + + +if __name__ == '__main__': + # print(get_k_data_year('000001','2016','01')) + # print(get_k_data_year(600010,2016,'01')) + print(QA_fetch_get_stock_day('000001', '2016-05-01', '2017-07-01', '01')) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/QATushare.html b/_build/html/_modules/QUANTAXIS/QAFetch/QATushare.html new file mode 100644 index 000000000..8ddf1e1a4 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/QATushare.html @@ -0,0 +1,191 @@ + + + + + + + + QUANTAXIS.QAFetch.QATushare — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.QATushare

+# coding: utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import json
+
+import pandas as pd
+import tushare as QATs
+
+from QUANTAXIS.QAUtil import (QA_util_date_int2str, QA_util_date_stamp,
+                              QA_util_log_info, QA_util_to_json_from_pandas)
+
+
+
[docs]def QA_fetch_get_stock_day(name, start='', end='', if_fq='01', type_='json'): + if (len(name) != 6): + name = str(name)[0:6] + + if str(if_fq) in ['qfq', '01']: + if_fq = 'qfq' + elif str(if_fq) in ['hfq', '02']: + if_fq = 'hfq' + elif str(if_fq) in ['bfq', '00']: + if_fq = 'bfq' + else: + QA_util_log_info('wrong with fq_factor! using qfq') + if_fq = 'qfq' + + data = QATs.get_k_data(str(name), start, end, + ktype='D', autype=if_fq, retry_count=200, pause=0.005).sort_index() + + data['date_stamp'] = data['date'].apply(lambda x: QA_util_date_stamp(x)) + data['fqtype'] = if_fq + if type_ in ['json']: + data_json = QA_util_to_json_from_pandas(data) + return data_json + elif type_ in ['pd', 'pandas', 'p']: + data['date'] = pd.to_datetime(data['date']) + data = data.set_index('date', drop=False) + data['date'] = data['date'].apply(lambda x: str(x)[0:10]) + return data
+ + +
[docs]def QA_fetch_get_stock_realtime(): + data = QATs.get_today_all() + data_json = QA_util_to_json_from_pandas(data) + return data_json
+ + +
[docs]def QA_fetch_get_stock_info(name): + data = QATs.get_stock_basics() + data_json = QA_util_to_json_from_pandas(data) + + for i in range(0, len(data_json) - 1, 1): + data_json[i]['code'] = data.index[i] + return data_json
+ + +
[docs]def QA_fetch_get_stock_tick(name, date): + if (len(name) != 6): + name = str(name)[0:6] + return QATs.get_tick_data(name, date)
+ + +
[docs]def QA_fetch_get_stock_list(): + df = QATs.get_stock_basics() + return list(df.index)
+ + +
[docs]def QA_fetch_get_stock_time_to_market(): + data = QATs.get_stock_basics() + return data[data['timeToMarket'] != 0]['timeToMarket'].apply(lambda x: QA_util_date_int2str(x))
+ + +
[docs]def QA_fetch_get_trade_date(end, exchange): + data = QATs.trade_cal() + da = data[data.isOpen > 0] + data_json = QA_util_to_json_from_pandas(data) + message = [] + for i in range(0, len(data_json) - 1, 1): + date = data_json[i]['calendarDate'] + num = i + 1 + exchangeName = 'SSE' + data_stamp = QA_util_date_stamp(date) + mes = {'date': date, 'num': num, + 'exchangeName': exchangeName, 'date_stamp': data_stamp} + message.append(mes) + return message
+# test + +# print(get_stock_day("000001",'2001-01-01','2010-01-01')) +# print(get_stock_tick("000001.SZ","2017-02-21")) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/QAWind.html b/_build/html/_modules/QUANTAXIS/QAFetch/QAWind.html new file mode 100644 index 000000000..6fe96f818 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/QAWind.html @@ -0,0 +1,347 @@ + + + + + + + + QUANTAXIS.QAFetch.QAWind — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.QAWind

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""
+QAWind
+
+QAWind is a data fetch module just for WIND Institution Version
+
+QAWind is under the [QAStandard#0.0.2 @101-1],[QAStandard#0.0.2 @501-0] protocol
+
+@author: yutiansut
+
+@last modified:2017/4/5
+"""
+import datetime
+import re
+import time
+
+import numpy as np
+import pandas as pd
+import pymongo
+
+from QUANTAXIS.QAUtil import QA_util_date_valid, QA_util_log_info
+
+from QUANTAXIS.QAFetch import data_list as data_list
+
+
+
[docs]def QA_fetch_get_stock_info(name, startDate, endDate): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + # get the all stock list on the endDate + # judge the vaild date + if(QA_util_date_valid(endDate) is False): + QA_util_log_info("wrong date") + else: + # tempStr='date='+endDate+";sectorid=a001010100000000" + # data=w.wset("sectorconstituent",tempStr) + data = w.wsd(name, "sec_name,sec_englishname,ipo_date,exch_city,mkt,\ + sec_status,delist_date,issuecurrencycode,curr,RO,parvalue,\ + lotsize,tunit,exch_eng,country,concept,marginornot,SHSC,\ + parallelcode,sec_type,backdoor,backdoordate,windtype", + startDate, endDate) + # QA_util_log_info(data) + if (data.ErrorCode != 0): + QA_util_log_info("Connent to Wind successfully") + return data.Data
+ + +
[docs]def QA_fetch_get_stock_day(name, startDate, endDate, if_fq='01'): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + if(QA_util_date_valid(endDate) == False): + QA_util_log_info("wrong date") + else: + if if_fq in ['00', 'bfq']: + data = w.wsd(name, "sec_name,pre_close,open,high,low,close,volume", + startDate, endDate) + elif if_fq in ['01', 'qfq']: + data = w.wsd(name, "sec_name,pre_close,open,high,low,close,volume", + startDate, endDate, "PriceAdj=F") + elif if_fq in ['02', 'hfq']: + data = w.wsd(name, "sec_name,pre_close,open,high,low,close,volume", + startDate, endDate, "PriceAdj=B") + else: + QA_util_log_info('wrong fq factor! using qfq') + data = w.wsd(name, "sec_name,pre_close,open,high,low,close,volume", + startDate, endDate, "PriceAdj=B") + if (data.ErrorCode == 0): + QA_util_log_info("Connent to Wind successfully") + + return pd.DataFrame(np.asarray(data.Data).T, columns=data.Fields, index=data.Times)
+ + +
[docs]def QA_fetch_get_stock_day_simple(name, startDate, endDate): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + if(QA_util_date_valid(endDate) == False): + QA_util_log_info("wrong date") + else: + data = w.wsd(name, "sec_name,preclose,open,high,low,close,volume", + startDate, endDate, "Fill=Previous;PriceAdj=F") + #data=w.wsd("000002.SZ", "open,high,low,close,volume", "2017-03-03", "2017-04-01", "PriceAdj=B") + QA_util_log_info(data.ErrorCode) + if (data.ErrorCode == 0): + QA_util_log_info("Connent to Wind successfully") + return data.Data
+ + +
[docs]def QA_fetch_get_stock_indicator(name, startDate, endDate): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + if(QA_util_date_valid(endDate) == False): + QA_util_log_info("wrong date") + else: + # ADTM动态买卖气指标,ATR真实波幅,BBI多空指数,BBIBOLL多空布林线,BIAS乖离率,BOLL布林带,CCI顺势指标,CDP逆势操作,DMA平均线差, + # DMI趋向标准,DPO区间震荡线,ENV,EXPMA指数平滑移动平均,KDJ随机指标,slowKD慢速kd,MA简单移动平均,MACD指数平滑移动平均,MIKE麦克指数, + # MTM动力指标,PRICEOSC价格震荡指标,PVT量价趋势指标,RC变化率指数,ROC变动速率,RSI相对强弱指标,SAR抛物转向,SI摆动指标,SOBV能量潮, + # SRMI MI修正指标,STD 标准差,TAPI 加权指数成交值,TRIX 三重指数平滑平均,VHF纵横指标,VMA量简单移动平均,VMACD量指数平滑移动平均, + # VOSC成交量震荡,WVAD威廉变异离散量,vol_ratio量比 + data = w.wsd(name, "ADTM,ATR,BBI,BBIBOLL,BIAS,BOLL,CCI,CDP,\ + DMA,DMI,DPO,ENV,EXPMA,KDJ,slowKD,MA,MACD,\ + MIKE,MTM,PRICEOSC,PVT,RC,ROC,RSI,SAR,SI,\ + SOBV,SRMI,STD,TAPI,TRIX,VHF,VMA,VMACD,VOSC,\ + WVAD,vol_ratio", startDate, endDate, + "ADTM_N1=23;ADTM_N2=8;ADTM_IO=1;ATR_N=14;ATR_IO=1;\ + BBI_N1=3;BBI_N2=6;BBI_N3=12;BBI_N4=24;BBIBOLL_N=10;\ + BBIBOLL_Width=3;BBIBOLL_IO=1;BIAS_N=12;BOLL_N=26;\ + BOLL_Width=2;BOLL_IO=1;CCI_N=14;CDP_IO=1;DMA_S=10;\ + DMA_L=50;DMA_N=10;DMA_IO=1;DMI_N=14;DMI_N1=6;\ + DMI_IO=1;DPO_N=20;DPO_M=6;DPO_IO=1;ENV_N=14;ENV_IO=1;\ + EXPMA_N=12;KDJ_N=9;KDJ_M1=3;KDJ_M2=3;KDJ_IO=1;SlowKD_N1=9;\ + SlowKD_N2=3;SlowKD_N3=3;SlowKD_N4=5;SlowKD_IO=1;MA_N=5;\ + MACD_L=26;MACD_S=12;MACD_N=9;MACD_IO=1;MIKE_N=12;MIKE_IO=1;\ + MTM_interDay=6;MTM_N=6;MTM_IO=1;PRICEOSC_L=26;PRICEOSC_S=12;\ + RC_N=50;ROC_interDay=12;ROC_N=6;ROC_IO=1;RSI_N=6;SAR_N=4;\ + SAR_SP=2;SAR_MP=20;SRMI_N=9;STD_N=26;TAPI_N=6;TAPI_IO=1;\ + TRIX_N1=12;TRIX_N2=20;TRIX_IO=1;VHF_N=28;VMA_N=5;VMACD_S=12;\ + VMACD_L=26;VMACD_N=9;VMACD_IO=1;VOSC_S=12;VOSC_L=26;WVAD_N1=24;\ + WVAD_N2=6;WVAD_IO=1;VolumeRatio_N=5") + if (data.ErrorCode == 0): + QA_util_log_info("Connent to Wind successfully") + return pd.DataFrame(np.asarray(data.Data).T, columns=data.Fields, index=data.Times)
+ + +
[docs]def QA_fetch_get_stock_shape(name, startDate, endDate): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + if(QA_util_date_valid(endDate) == False): + QA_util_log_info("wrong date") + else: + # history_low近期创历史新低,stage_high近期创阶段新高,history_high近期创历史新高,stage_low近期创阶段新高,up_days连涨天数,down_days连跌天数,breakout_ma向上有效突破均线,breakdown_ma向下有效突破均线,bull_bear_ma均线多空排列看涨看跌 + data = w.wsd(name, "history_low,stage_high,history_high,stage_low,up_days,down_days,breakout_ma,breakdown_ma,bull_bear_ma", + startDate, endDate, "n=3;m=60;meanLine=60;N1=5;N2=10;N3=20;N4=30;upOrLow=1") + if (data.ErrorCode == 0): + QA_util_log_info("Connent to Wind successfully") + return pd.DataFrame(np.asarray(data.Data).T, columns=data.Fields, index=data.Times)
+ + +
[docs]def QA_fetch_get_stock_risk(name, startDate, endDate): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + if(QA_util_date_valid(endDate) == False): + QA_util_log_info("wrong date") + else: + data = w.wsd(name, "annualyeild_100w,annualyeild_24m,annualyeild_60m,\ + annualstdevr_100w,annualstdevr_24m,annualstdevr_60m,beta_100w,\ + beta_24m,beta_60m,avgreturn,avgreturny,stdevry,stdcof,\ + risk_nonsysrisk1,r2,alpha2,beta,sharpe,treynor,jensen,jenseny,betadf", + startDate, endDate, "period=2;returnType=1;index=000001.SH;yield=1") + if (data.ErrorCode == 0): + QA_util_log_info("Connent to Wind successfully") + return pd.DataFrame(np.asarray(data.Data).T, columns=data.Fields, index=data.Times)
+ + +
[docs]def QA_fetch_get_stock_xueqiu(name, startDate, endDate): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + if(QA_util_date_valid(endDate) == False): + QA_util_log_info("wrong date") + else: + data = w.wsd(name, "xq_accmfocus,xq_accmcomments,xq_accmshares,\ + xq_focusadded,xq_commentsadded,xq_sharesadded,\ + xq_WOW_focus,xq_WOW_comments,xq_WOW_shares", startDate, endDate, "") + if (data.ErrorCode == 0): + QA_util_log_info("Connent to Wind successfully") + return pd.DataFrame(np.asarray(data.Data).T, columns=data.Fields, index=data.Times)
+ + +
[docs]def QA_fetch_get_stock_financial(name, startDate, endDate): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + pass
+ + +
[docs]def QA_fetch_get_trade_date(endDate, exchange): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + supportExchanges = ["SSE", "SZSE", "CFFEX", "SHFE", "DCE", "CZCE"] + if (exchange in supportExchanges): + #"SSE","SZSE","CFFEX","SHFE","DCE","CZCE" + # 上海股票交易所,深圳股票交易所,中国金融期货交易所,上海期货交易所,大连商品交易所,郑州期货交易所 + exchanges = "TradingCalendar=" + exchange + data = w.tdays("1990-01-01", endDate, exchanges) + # QA_util_log_info(data.Data) + dates = pd.DataFrame(np.asarray(data.Data).T, + columns=data.Fields, index=data.Times) + else: + QA_util_log_info("exchange name problem") + return dates
+ + +
[docs]def QA_fetch_get_stock_list(date): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + if(QA_util_date_valid(date) == False): + QA_util_log_info("wrong date") + else: + awgs = 'date=' + date + ';sectorid=a001010100000000' + data = w.wset("sectorconstituent", awgs) + return pd.DataFrame(np.asarray(data.Data).T, columns=data.Fields, index=data.Times)
+ + +
[docs]def QA_fetch_get_stock_list_special(date, id): + try: + from WindPy import w + except: + QA_util_log_info('No WindPY Module!') + w.start() + if(QA_util_date_valid(date) == False): + QA_util_log_info("wrong date") + else: + if id in ['big', 'small', 'cixin', 'yujing', 'rzrq', 'rq', 'yj', 'st', 'sst']: + awgs = 'date=' + date + ';sectorid=' + \ + data_list.wind_stock_list_special_id[id] + data = w.wset("sectorconstituent", awgs) + return pd.DataFrame(np.asarray(data.Data).T, columns=data.Fields, index=data.Times)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/QAfinancial.html b/_build/html/_modules/QUANTAXIS/QAFetch/QAfinancial.html new file mode 100644 index 000000000..2bf1873f3 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/QAfinancial.html @@ -0,0 +1,158 @@ + + + + + + + + QUANTAXIS.QAFetch.QAfinancial — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.QAfinancial

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os
+import sys
+import requests
+from pytdx.reader.history_financial_reader import HistoryFinancialReader
+from pytdx.crawler.history_financial_crawler import HistoryFinancialCrawler, HistoryFinancialListCrawler
+
+from QUANTAXIS.QASU.save_local import qa_path
+"""
+参见PYTDX 1.65
+"""
+
+FINANCIAL_URL = 'http://down.tdx.com.cn:8001/fin/gpcw.txt'
+
+
+
[docs]def get_filename(): + """ + get_filename + """ + return [l[0] for l in [line.strip().split(",") for line in requests.get(FINANCIAL_URL).text.strip().split('\n')]]
+ + +
[docs]def download(): + """ + 会创建一个download/文件夹 + """ + result = get_filename() + for item in result: + r = requests.get('http://down.tdx.com.cn:8001/fin/{}'.format(item)) + + file = '{}{}{}{}{}'.format(qa_path, os.sep, 'downloads', os.sep, item) + with open(file, "wb") as code: + code.write(r.content)
+ + +
[docs]def get_and_parse(filename): + return HistoryFinancialReader().get_df(filename)
+ + +
[docs]def prase_all(): + """ + 解析目录下的所有文件 + """ + filepath = '{}{}{}{}'.format(qa_path, os.sep, 'downloads', os.sep) + filename = os.listdir(filepath) + data = [] + for item in filename: + file = '{}{}{}{}{}'.format(qa_path, os.sep, 'downloads', os.sep, item) + data += get_and_parse(file) + return data
+ + +if __name__ == '__main__': + # download() + prase_all() +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAFetch/realtime.html b/_build/html/_modules/QUANTAXIS/QAFetch/realtime.html new file mode 100644 index 000000000..8a4e6b557 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAFetch/realtime.html @@ -0,0 +1,141 @@ + + + + + + + + QUANTAXIS.QAFetch.realtime — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAFetch.realtime

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""单线程的实时获取
+""" 
+
+
+from QUANTAXIS.QAFetch.QATdx import select_best_ip, QA_fetch_get_stock_day, QA_fetch_get_stock_list
+from QUANTAXIS.QAData.QADataStruct import QA_DataStruct_Stock_day
+import pandas as pd
+import datetime
+
+
+
[docs]def get_today_all(output='pd'): + """today all + + Returns: + [type] -- [description] + """ + + data = [] + today = str(datetime.date.today()) + codes = QA_fetch_get_stock_list('stock').code.tolist() + bestip = select_best_ip()['stock'] + for code in codes: + try: + l = QA_fetch_get_stock_day( + code, today, today, '00', ip=bestip) + except: + bestip = select_best_ip()['stock'] + l = QA_fetch_get_stock_day( + code, today, today, '00', ip=bestip) + if l is not None: + data.append(l) + + res = pd.concat(data) + if output in ['pd']: + return res + elif output in ['QAD']: + return QA_DataStruct_Stock_day(res.set_index(['date', 'code'], drop=False))
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAIndicator/base.html b/_build/html/_modules/QUANTAXIS/QAIndicator/base.html new file mode 100644 index 000000000..c2cb658cb --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAIndicator/base.html @@ -0,0 +1,262 @@ + + + + + + + + QUANTAXIS.QAIndicator.base — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAIndicator.base

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from functools import reduce
+
+import numpy as np
+import pandas as pd
+
+
+"""
+Series 类
+
+这个是下面以DataFrame为输入的基础函数
+return pd.Series format
+"""
+
+
+
[docs]def EMA(Series, N): + return pd.Series.ewm(Series, span=N, min_periods=N - 1, adjust=True).mean()
+ + +
[docs]def MA(Series, N): + return pd.Series.rolling(Series, N).mean()
+ +# 威廉SMA 参考https://www.joinquant.com/post/867 + + +
[docs]def SMA(Series, N, M=1): + """ + 威廉SMA算法 + + 本次修正主要是对于返回值的优化,现在的返回值会带上原先输入的索引index + 2018/5/3 + @yutiansut + """ + ret = [] + i = 1 + length = len(Series) + # 跳过X中前面几个 nan 值 + while i < length: + if np.isnan(Series.iloc[i]): + i += 1 + else: + break + preY = Series.iloc[i] # Y' + ret.append(preY) + while i < length: + Y = (M * Series.iloc[i] + (N - M) * preY) / float(N) + ret.append(Y) + preY = Y + i += 1 + return pd.Series(ret,index=Series.tail(len(ret)).index)
+ + +
[docs]def DIFF(Series, N=1): + return pd.Series(Series).diff(N)
+ + +
[docs]def HHV(Series, N): + return pd.Series(Series).rolling(N).max().values
+ + +
[docs]def LLV(Series, N): + return pd.Series(Series).rolling(N).min().values
+ + +
[docs]def SUM(Series, N): + return pd.Series.rolling(Series, N).sum()
+ + +
[docs]def ABS(Series): + return abs(Series)
+ + +
[docs]def MAX(A, B): + var = IF(A > B, A, B) + return var
+ + +
[docs]def MIN(A, B): + var = IF(A < B, A, B) + return var
+ + +
[docs]def CROSS(A, B): + if A.iloc[-2] < B.iloc[-2] and A.iloc[-1] > B.iloc[-1]: + return True + else: + return False
+ + +
[docs]def COUNT(COND, N): + var = np.where(COND, 1, 0) + return var[-N:].sum()
+ + +
[docs]def IF(COND, V1, V2): + var = np.where(COND, V1, V2) + return pd.Series(var, index=V1.index)
+ + +
[docs]def REF(Series, N): + var = Series.diff(N) + var = Series - var + return var
+ + +
[docs]def LAST(COND, N1, N2): + """表达持续性 + + Arguments: + COND {[type]} -- [description] + N1 {[type]} -- [description] + N2 {[type]} -- [description] + """ + N2=1 if N2==0 else N2 + assert N2>0 + assert N1>N2 + return COND.iloc[-N1:-N2].all()
+ + +
[docs]def STD(Series, N): + return pd.Series.rolling(Series, N).std()
+ + +
[docs]def AVEDEV(Series, N): + '平均绝对偏差 mean absolute deviation' + return pd.Series(Series).tail(N).mad()
+ + +
[docs]def MACD(Series, FAST, SLOW, MID): + """macd指标 仅适用于Series + 对于DATAFRAME的应用请使用QA_indicator_macd + """ + EMAFAST = EMA(Series, FAST) + EMASLOW = EMA(Series, SLOW) + DIFF = EMAFAST - EMASLOW + DEA = EMA(DIFF, MID) + MACD = (DIFF - DEA) * 2 + DICT = {'DIFF': DIFF, 'DEA': DEA, 'MACD': MACD} + VAR = pd.DataFrame(DICT) + return VAR
+ + +
[docs]def BBIBOLL(Series, N1, N2, N3, N4, N, M): # 多空布林线 + + bbiboll = BBI(Series, N1, N2, N3, N4) + UPER = bbiboll + M * STD(bbiboll, N) + DOWN = bbiboll - M * STD(bbiboll, N) + DICT = {'BBIBOLL': bbiboll, 'UPER': UPER, 'DOWN': DOWN} + VAR = pd.DataFrame(DICT) + return VAR
+ + +
[docs]def BBI(Series, N1, N2, N3, N4): + '多空指标' + + bbi = (MA(Series, N1) + MA(Series, N2) + + MA(Series, N3) + MA(Series, N4)) / 4 + DICT = {'BBI': bbi} + VAR = pd.DataFrame(DICT) + return VAR
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAIndicator/indicators.html b/_build/html/_modules/QUANTAXIS/QAIndicator/indicators.html new file mode 100644 index 000000000..edbc70c2e --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAIndicator/indicators.html @@ -0,0 +1,700 @@ + + + + + + + + QUANTAXIS.QAIndicator.indicators — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAIndicator.indicators

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from functools import reduce
+
+import numpy as np
+import pandas as pd
+
+from QUANTAXIS.QAIndicator.base import *
+
+
+"""
+DataFrame 类
+
+以下的函数都可以被直接add_func
+
+
+"""
+
+
+"""
+1.	趋向指标 
+又叫趋势跟踪类指标,主要用于跟踪并预测股价的发展趋势
+
+包含的主要指标
+1. 移动平均线 MA
+2. 指数平滑移动平均线 MACD
+3. 趋向指标 DMI
+4. 瀑布线 PBX
+5. 平均线差 DMA
+6. 动力指标(动量线)  MTM
+7. 指数平均线 EXPMA
+8. 佳庆指标 CHO
+"""
+
+
+
[docs]def QA_indicator_MA(DataFrame, N): + CLOSE = DataFrame['close'] + return pd.DataFrame({'MA': MA(CLOSE, N)})
+ + +
[docs]def QA_indicator_EMA(DataFrame, N): + CLOSE = DataFrame['close'] + return pd.DataFrame({'EMA': EMA(CLOSE, N)})
+ + +
[docs]def QA_indicator_SMA(DataFrame, N): + CLOSE = DataFrame['close'] + return pd.DataFrame({'SMA': SMA(CLOSE, N)})
+ + +
[docs]def QA_indicator_MACD(DataFrame, short=12, long=26, mid=9): + """ + MACD CALC + """ + CLOSE = DataFrame['close'] + + DIF = EMA(CLOSE, short)-EMA(CLOSE, long) + DEA = EMA(DIF, mid) + MACD = (DIF-DEA)*2 + + return pd.DataFrame({'DIF': DIF, 'DEA': DEA, 'MACD': MACD})
+ + +
[docs]def QA_indicator_DMI(DataFrame, M1=14, M2=6): + """ + 趋向指标 DMI + """ + HIGH = DataFrame.high + LOW = DataFrame.low + CLOSE = DataFrame.close + OPEN = DataFrame.open + + TR = SUM(MAX(MAX(HIGH-LOW, ABS(HIGH-REF(CLOSE, 1))), + ABS(LOW-REF(CLOSE, 1))), M1) + HD = HIGH-REF(HIGH, 1) + LD = REF(LOW, 1)-LOW + DMP = SUM(IF(HD > 0 and HD > LD, HD, 0), M1) + DMM = SUM(IF(LD > 0 and LD > HD, LD, 0), M1) + DI1 = DMP*100/TR + DI2 = DMM*100/TR + ADX = MA(ABS(DI2-DI1)/(DI1+DI2)*100, M2) + ADXR = (ADX+REF(ADX, M2))/2 + + return pd.DataFrame({ + 'DI1': DI1, 'DI2': DI2, + 'ADX': ADX, 'ADXR': ADXR + })
+ + +
[docs]def QA_indicator_PBX(DataFrame, N1=3, N2=5, N3=8, N4=13, N5=18, N6=24): + '瀑布线' + C = DataFrame['close'] + PBX1 = (EMA(C, N1) + EMA(C, 2 * N1) + EMA(C, 4 * N1)) / 3 + PBX2 = (EMA(C, N2) + EMA(C, 2 * N2) + EMA(C, 4 * N2)) / 3 + PBX3 = (EMA(C, N3) + EMA(C, 2 * N3) + EMA(C, 4 * N3)) / 3 + PBX4 = (EMA(C, N4) + EMA(C, 2 * N4) + EMA(C, 4 * N4)) / 3 + PBX5 = (EMA(C, N5) + EMA(C, 2 * N5) + EMA(C, 4 * N5)) / 3 + PBX6 = (EMA(C, N6) + EMA(C, 2 * N6) + EMA(C, 4 * N6)) / 3 + DICT = {'PBX1': PBX1, 'PBX2': PBX2, 'PBX3': PBX3, + 'PBX4': PBX4, 'PBX5': PBX5, 'PBX6': PBX6} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_DMA(DataFrame, M1=10, M2=50, M3=10): + """ + 平均线差 DMA + """ + CLOSE = DataFrame.close + DDD = MA(CLOSE, M1) - MA(CLOSE, M2) + AMA = MA(DDD, M3) + return pd.DataFrame({ + 'DDD': DDD, 'AMA': AMA + })
+ + +
[docs]def QA_indicator_MTM(DataFrame, N=12, M=6): + '动量线' + C = DataFrame.close + mtm = C - REF(C, N) + MTMMA = MA(mtm, M) + DICT = {'MTM': mtm, 'MTMMA': MTMMA} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_EXPMA(DataFrame, P1=5, P2=10, P3=20, P4=60): + """ 指数平均线 EXPMA""" + CLOSE = DataFrame.close + MA1 = EMA(CLOSE, P1) + MA2 = EMA(CLOSE, P2) + MA3 = EMA(CLOSE, P3) + MA4 = EMA(CLOSE, P4) + return pd.DataFrame({ + 'MA1': MA1, 'MA2': MA2, 'MA3': MA3, 'MA4': MA4 + })
+ + +
[docs]def QA_indicator_CHO(DataFrame, N1=10, N2=20, M=6): + """ + 佳庆指标 CHO + """ + HIGH = DataFrame.high + LOW = DataFrame.low + CLOSE = DataFrame.close + VOL = DataFrame.volume + MID = SUM(VOL*(2*CLOSE-HIGH-LOW)/(HIGH+LOW), 0) + CHO = MA(MID, N1)-MA(MID, N2) + MACHO = MA(CHO, M) + return pd.DataFrame({ + 'CHO': CHO, 'MACHO': MACHO + })
+ + +""" + +2. 反趋向指标 +主要捕捉趋势的转折点 + +随机指标KDJ +乖离率 BIAS +变动速率 ROC +顺势指标 CCI +威廉指标 W&R +震荡量(变动速率) OSC +相对强弱指标 RSI +动态买卖指标 ADTM + +""" + + +
[docs]def QA_indicator_KDJ(DataFrame, N=9, M1=3, M2=3): + C = DataFrame['close'] + H = DataFrame['high'] + L = DataFrame['low'] + + RSV = (C - LLV(L, N)) / (HHV(H, N) - LLV(L, N)) * 100 + K = SMA(RSV, M1) + D = SMA(K, M2) + J = 3 * K - 2 * D + DICT = {'KDJ_K': K, 'KDJ_D': D, 'KDJ_J': J} + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_BIAS(DataFrame, N1, N2, N3): + '乖离率' + CLOSE = DataFrame['close'] + BIAS1 = (CLOSE - MA(CLOSE, N1)) / MA(CLOSE, N1) * 100 + BIAS2 = (CLOSE - MA(CLOSE, N2)) / MA(CLOSE, N2) * 100 + BIAS3 = (CLOSE - MA(CLOSE, N3)) / MA(CLOSE, N3) * 100 + DICT = {'BIAS1': BIAS1, 'BIAS2': BIAS2, 'BIAS3': BIAS3} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_ROC(DataFrame, N=12, M=6): + '变动率指标' + C = DataFrame['close'] + roc = 100 * (C - REF(C, N)) / REF(C, N) + ROCMA = MA(roc, M) + DICT = {'ROC': roc, 'ROCMA': ROCMA} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_CCI(DataFrame, N=14): + """ + TYP:=(HIGH+LOW+CLOSE)/3; + CCI:(TYP-MA(TYP,N))/(0.015*AVEDEV(TYP,N)); + """ + typ = (DataFrame['high'] + DataFrame['low'] + DataFrame['close']) / 3 + cci = ((typ - MA(typ, N)) / (0.015 * AVEDEV(typ, N))) + a = 100 + b = -100 + + return pd.DataFrame({ + 'CCI': cci, 'a': a, 'b': b + })
+ + +
[docs]def QA_indicator_WR(DataFrame, N, N1): + '威廉指标' + HIGH = DataFrame['high'] + LOW = DataFrame['low'] + CLOSE = DataFrame['close'] + WR1 = 100 * (HHV(HIGH, N) - CLOSE) / (HHV(HIGH, N) - LLV(LOW, N)) + WR2 = 100 * (HHV(HIGH, N1) - CLOSE) / (HHV(HIGH, N1) - LLV(LOW, N1)) + DICT = {'WR1': WR1, 'WR2': WR2} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_OSC(DataFrame, N=20, M=6): + """变动速率线 + + 震荡量指标OSC,也叫变动速率线。属于超买超卖类指标,是从移动平均线原理派生出来的一种分析指标。 + + 它反应当日收盘价与一段时间内平均收盘价的差离值,从而测出股价的震荡幅度。 + + 按照移动平均线原理,根据OSC的值可推断价格的趋势,如果远离平均线,就很可能向平均线回归。 + """ + C = DataFrame['close'] + OS = (C - MA(C, N)) * 100 + MAOSC = EMA(OS, M) + DICT = {'OSC': OS, 'MAOSC': MAOSC} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_RSI(DataFrame, N1=12, N2=26, N3=9): + '相对强弱指标RSI1:SMA(MAX(CLOSE-LC,0),N1,1)/SMA(ABS(CLOSE-LC),N1,1)*100;' + CLOSE = DataFrame['close'] + LC = REF(CLOSE, 1) + RSI1 = SMA(MAX(CLOSE - LC, 0), N1) / SMA(ABS(CLOSE - LC), N1) * 100 + RSI2 = SMA(MAX(CLOSE - LC, 0), N2) / SMA(ABS(CLOSE - LC), N2) * 100 + RSI3 = SMA(MAX(CLOSE - LC, 0), N3) / SMA(ABS(CLOSE - LC), N3) * 100 + DICT = {'RSI1': RSI1, 'RSI2': RSI2, 'RSI3': RSI3} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_ADTM(DataFrame, N=23, M=8): + '动态买卖气指标' + HIGH = DataFrame.high + LOW = DataFrame.low + OPEN = DataFrame.open + DTM = IF(OPEN <= REF(OPEN, 1), 0, MAX( + (HIGH - OPEN), (OPEN - REF(OPEN, 1)))) + DBM = IF(OPEN >= REF(OPEN, 1), 0, MAX((OPEN - LOW), (OPEN - REF(OPEN, 1)))) + STM = SUM(DTM, N) + SBM = SUM(DBM, N) + ADTM1 = IF(STM > SBM, (STM - SBM) / STM, + IF(STM == SBM, 0, (STM - SBM) / SBM)) + MAADTM = MA(ADTM1, M) + DICT = {'ADTM': ADTM1, 'MAADTM': MAADTM} + + return pd.DataFrame(DICT)
+ + +""" +3. 量能指标 +通过成交量的大小和变化研判趋势变化 +容量指标 VR +量相对强弱 VRSI +能量指标 CR +人气意愿指标 ARBR +成交量标准差 VSTD""" + + +
[docs]def QA_indicator_VR(DataFrame, M1=26, M2=100, M3=200): + VOL = DataFrame.volume + CLOSE = DataFrame.close + LC = REF(CLOSE, 1) + VR = SUM(IF(CLOSE > LC, VOL, 0), M1)/SUM(IF(CLOSE <= LC, VOL, 0), M1)*100 + a = M2 + b = M3 + return pd.DataFrame({ + 'VR': VR, 'a': a, 'b': b + })
+ + +
[docs]def QA_indicator_VRSI(DataFrame, N=6): + + VOL = DataFrame.volume + vrsi = SMA(MAX(VOL-REF(VOL, 1), 0), N, 1) / \ + SMA(ABS(VOL-REF(VOL, 1)), N, 1)*100 + + return pd.DataFrame({'VRSI': vrsi})
+ + +
[docs]def QA_indicator_CR(DataFrame, N=26, M1=5, M2=10, M3=20): + HIGH = DataFrame.high + LOW = DataFrame.low + CLOSE = DataFrame.close + VOL = DataFrame.volume + MID = (HIGH+LOW+CLOSE)/3 + + CR = SUM(MAX(0, HIGH-REF(MID, 1)), N)/SUM(MAX(0, REF(MID, 1)-LOW), N)*100 + MA1 = REF(MA(CR, M1), M1/2.5+1) + MA2 = REF(MA(CR, M2), M2/2.5+1) + MA3 = REF(MA(CR, M3), M3/2.5+1) + return pd.DataFrame({ + 'CR': CR, 'MA1': MA1, 'MA2': MA2, 'MA3': MA3 + })
+ + +
[docs]def QA_indicator_ARBR(DataFrame, M1=26, M2=70, M3=150): + HIGH = DataFrame.high + LOW = DataFrame.low + CLOSE = DataFrame.close + OPEN = DataFrame.open + AR = SUM(HIGH-OPEN, M1)/SUM(OPEN-LOW, M1)*100 + BR = SUM(MAX(0, HIGH-REF(CLOSE, 1)), M1) / \ + SUM(MAX(0, REF(CLOSE, 1)-LOW), M1)*100 + a = M2 + b = M3 + return pd.DataFrame({ + 'AR': AR, 'BR': BR, 'a': a, 'b': b + })
+ + +
[docs]def QA_indicator_VSTD(DataFrame, N=10): + VOL = DataFrame.volume + vstd = STD(VOL, N) + return pd.DataFrame({'VSTD': vstd})
+ + +""" +4. 量价指标 +通过成交量和股价变动关系分析未来趋势 +震荡升降指标ASI +价量趋势PVT +能量潮OBV +量价趋势VPT +""" + + +
[docs]def QA_indicator_ASI(DataFrame, M1=26, M2=10): + """ + LC=REF(CLOSE,1); + AA=ABS(HIGH-LC); + BB=ABS(LOW-LC); + CC=ABS(HIGH-REF(LOW,1)); + DD=ABS(LC-REF(OPEN,1)); + R=IF(AA>BB AND AA>CC,AA+BB/2+DD/4,IF(BB>CC AND BB>AA,BB+AA/2+DD/4,CC+DD/4)); + X=(CLOSE-LC+(CLOSE-OPEN)/2+LC-REF(OPEN,1)); + SI=16*X/R*MAX(AA,BB); + ASI:SUM(SI,M1); + ASIT:MA(ASI,M2); + """ + CLOSE = DataFrame['close'] + HIGH = DataFrame['high'] + LOW = DataFrame['low'] + OPEN = DataFrame['open'] + LC = REF(CLOSE, 1) + AA = ABS(HIGH - LC) + BB = ABS(LOW-LC) + CC = ABS(HIGH - REF(LOW, 1)) + DD = ABS(LC - REF(OPEN, 1)) + + R = IF(AA > BB and AA > CC, AA+BB/2+DD/4, + IF(BB > CC and BB > AA, BB+AA/2+DD/4, CC+DD/4)) + X = (CLOSE - LC + (CLOSE - OPEN) / 2 + LC - REF(OPEN, 1)) + SI = 16*X/R*MAX(AA, BB) + ASI = SUM(SI, M1) + ASIT = MA(ASI, M2) + return pd.DataFrame({ + 'ASI': ASI, 'ASIT': ASIT + })
+ + +
[docs]def QA_indicator_PVT(DataFrame): + CLOSE = DataFrame.close + VOL = DataFrame.volume + PVT = SUM((CLOSE-REF(CLOSE, 1))/REF(CLOSE, 1)*VOL, 0) + return pd.DataFrame({'PVT': PVT})
+ + +
[docs]def QA_indicator_OBV(DataFrame): + """能量潮""" + VOL = DataFrame.volume + CLOSE = DataFrame.close + pd.DataFrame({ + 'OBV': SUM(IF(CLOSE > REF(CLOSE, 1), VOL, IF(CLOSE < REF(CLOSE, 1), -VOL, 0)), 0)/10000 + })
+ + +
[docs]def QA_indicator_VPT(DataFrame, N=51, M=6): + VOL = DataFrame.volume + CLOSE = DataFrame.close + VPT = SUM(VOL*(CLOSE-REF(CLOSE, 1))/REF(CLOSE, 1), 0) + MAVPT = MA(VPT, M) + return pd.DataFrame({ + 'VPT': VPT, 'MAVPT': MAVPT + })
+ + +""" +5. 压力支撑指标 +主要用于分析股价目前收到的压力和支撑 +布林带 BOLL +麦克指标 MIKE +""" + + +
[docs]def QA_indicator_BOLL(DataFrame, N=20, P=2): + '布林线' + C = DataFrame['close'] + boll = MA(C, N) + UB = boll + P * STD(C, N) + LB = boll - P * STD(C, N) + DICT = {'BOLL': boll, 'UB': UB, 'LB': LB} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_MIKE(DataFrame, N=12): + """ + MIKE指标 + 指标说明 + MIKE是另外一种形式的路径指标。 + 买卖原则 + 1 WEAK-S,MEDIUM-S,STRONG-S三条线代表初级、中级、强力支撑。 + 2 WEAK-R,MEDIUM-R,STRONG-R三条线代表初级、中级、强力压力。 + """ + HIGH = DataFrame.high + LOW = DataFrame.low + CLOSE = DataFrame.close + + TYP = (HIGH+LOW+CLOSE)/3 + LL = LLV(LOW, N) + HH = HHV(HIGH, N) + + WR = TYP+(TYP-LL) + MR = TYP+(HH-LL) + SR = 2*HH-LL + WS = TYP-(HH-TYP) + MS = TYP-(HH-LL) + SS = 2*LL-HH + return pd.DataFrame({ + 'WR': WR, 'MR': MR, 'SR': SR, + 'WS': WS, 'MS': MS, 'SS': SS + })
+ + +
[docs]def QA_indicator_BBI(DataFrame, N1=3, N2=6, N3=12, N4=24): + '多空指标' + C = DataFrame['close'] + bbi = (MA(C, N1) + MA(C, N2) + MA(C, N3) + MA(C, N4)) / 4 + DICT = {'BBI': bbi} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_MFI(DataFrame, N=14): + """ + 资金指标 + TYP := (HIGH + LOW + CLOSE)/3; + V1:=SUM(IF(TYP>REF(TYP,1),TYP*VOL,0),N)/SUM(IF(TYP<REF(TYP,1),TYP*VOL,0),N); + MFI:100-(100/(1+V1)); + 赋值: (最高价 + 最低价 + 收盘价)/3 + V1赋值:如果TYP>1日前的TYP,返回TYP*成交量(手),否则返回0的N日累和/如果TYP<1日前的TYP,返回TYP*成交量(手),否则返回0的N日累和 + 输出资金流量指标:100-(100/(1+V1)) + """ + C = DataFrame['close'] + H = DataFrame['high'] + L = DataFrame['low'] + VOL = DataFrame['volume'] + TYP = (C + H + L) / 3 + V1 = SUM(IF(TYP > REF(TYP, 1), TYP * VOL, 0), N) / \ + SUM(IF(TYP < REF(TYP, 1), TYP * VOL, 0), N) + mfi = 100 - (100 / (1 + V1)) + DICT = {'MFI': mfi} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_ATR(DataFrame, N=14): + """ + 输出TR:(最高价-最低价)和昨收-最高价的绝对值的较大值和昨收-最低价的绝对值的较大值 + 输出真实波幅:TR的N日简单移动平均 + 算法:今日振幅、今日最高与昨收差价、今日最低与昨收差价中的最大值,为真实波幅,求真实波幅的N日移动平均 + + 参数:N 天数,一般取14 + + """ + C = DataFrame['close'] + H = DataFrame['high'] + L = DataFrame['low'] + TR = MAX(MAX((H - L), ABS(REF(C, 1) - H)), ABS(REF(C, 1) - L)) + atr = MA(TR, N) + return pd.DataFrame({'TR': TR, 'ATR': atr})
+ + +
[docs]def QA_indicator_SKDJ(DataFrame, N=9, M=3): + """ + 1.指标>80 时,回档机率大;指标<20 时,反弹机率大; + 2.K在20左右向上交叉D时,视为买进信号参考; + 3.K在80左右向下交叉D时,视为卖出信号参考; + 4.SKDJ波动于50左右的任何讯号,其作用不大。 + + """ + CLOSE = DataFrame['close'] + LOWV = LLV(DataFrame['low'], N) + HIGHV = HHV(DataFrame['high'], N) + RSV = EMA((CLOSE - LOWV) / (HIGHV - LOWV) * 100, M) + K = EMA(RSV, M) + D = MA(K, M) + DICT = {'RSV': RSV, 'SKDJ_K': K, 'SKDJ_D': D} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_DDI(DataFrame, N=13, N1=26, M=1, M1=5): + """ + '方向标准离差指数' + 分析DDI柱状线,由红变绿(正变负),卖出信号参考;由绿变红,买入信号参考。 + """ + + H = DataFrame['high'] + L = DataFrame['low'] + DMZ = IF((H + L) <= (REF(H, 1) + REF(L, 1)), 0, + MAX(ABS(H - REF(H, 1)), ABS(L - REF(L, 1)))) + DMF = IF((H + L) >= (REF(H, 1) + REF(L, 1)), 0, + MAX(ABS(H - REF(H, 1)), ABS(L - REF(L, 1)))) + DIZ = SUM(DMZ, N) / (SUM(DMZ, N) + SUM(DMF, N)) + DIF = SUM(DMF, N) / (SUM(DMF, N) + SUM(DMZ, N)) + ddi = DIZ - DIF + ADDI = SMA(ddi, N1, M) + AD = MA(ADDI, M1) + DICT = {'DDI': ddi, 'ADDI': ADDI, 'AD': AD} + + return pd.DataFrame(DICT)
+ + +
[docs]def QA_indicator_shadow(DataFrame): + """ + 上下影线指标 + """ + return { + 'LOW': lower_shadow(DataFrame), 'UP': upper_shadow(DataFrame), + 'BODY': body(DataFrame), 'BODY_ABS': body_abs(DataFrame), 'PRICE_PCG': price_pcg(DataFrame) + }
+ + +
[docs]def lower_shadow(DataFrame): # 下影线 + return abs(DataFrame.low - MIN(DataFrame.open, DataFrame.close))
+ + +
[docs]def upper_shadow(DataFrame): # 上影线 + return abs(DataFrame.high - MAX(DataFrame.open, DataFrame.close))
+ + +
[docs]def body_abs(DataFrame): + return abs(DataFrame.open - DataFrame.close)
+ + +
[docs]def body(DataFrame): + return DataFrame.close - DataFrame.open
+ + +
[docs]def price_pcg(DataFrame): + return body(DataFrame) / DataFrame.open
+ + +
[docs]def amplitude(DataFrame): + return (DataFrame.high - DataFrame.low) / DataFrame.low
+ + +""" + +6. 大盘指标 +通过涨跌家数研究大盘指数的走势 +涨跌比率 ADR +绝对幅度指标 ABI +新三价率 TBR +腾落指数 ADL +广量冲力指标 +指数平滑广量 STIX +""" +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/QABacktestBroker.html b/_build/html/_modules/QUANTAXIS/QAMarket/QABacktestBroker.html new file mode 100644 index 000000000..11fff50a3 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/QABacktestBroker.html @@ -0,0 +1,366 @@ + + + + + + + + QUANTAXIS.QAMarket.QABacktestBroker — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.QABacktestBroker

+# coding :utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import datetime
+
+from QUANTAXIS.QAEngine.QAEvent import QA_Event
+from QUANTAXIS.QAFetch.QAQuery import (QA_fetch_future_day,
+                                       QA_fetch_future_min, QA_fetch_index_day,
+                                       QA_fetch_index_min, QA_fetch_stock_day,
+                                       QA_fetch_stock_min)
+from QUANTAXIS.QAFetch.QATdx import (QA_fetch_get_future_day,
+                                     QA_fetch_get_future_min,
+                                     QA_fetch_get_index_day,
+                                     QA_fetch_get_index_min,
+                                     QA_fetch_get_stock_day,
+                                     QA_fetch_get_stock_min)
+from QUANTAXIS.QAMarket.QABroker import QA_Broker
+from QUANTAXIS.QAMarket.QADealer import QA_Dealer
+from QUANTAXIS.QAMarket.QAOrderHandler import QA_OrderHandler
+from QUANTAXIS.QAUtil.QADate import QA_util_to_datetime
+from QUANTAXIS.QAUtil.QALogs import QA_util_log_info
+from QUANTAXIS.QAUtil.QAParameter import (AMOUNT_MODEL, BROKER_EVENT,
+                                          BROKER_TYPE, ENGINE_EVENT, FREQUENCE,
+                                          MARKET_EVENT, MARKET_TYPE,
+                                          ORDER_MODEL)
+
+
+
[docs]class QA_BacktestBroker(QA_Broker): + """ + QUANTAXIS Broker 部分 + + 回测 + 股票/指数/期货/债券/ETF/基金 + @yutiansut + + + 对于不同的市场规则: + 股票市场 t+1 + 期货/期权/加密货币市场 t+0 + + 股票/加密货币市场不允许卖空 + 期货/期权市场允许卖空 + + t+1的市场是 + 当日的买入 更新持仓- 不更新可卖数量- 资金冻结 + 当日的卖出 及时更新可用资金 + + t+0市场是: + 当日买入 即时更新持仓和可卖 + 当日卖出 即时更新 + + 卖空的规则是 + 允许无仓位的时候卖出证券(按市值和保证金比例限制算) + """ + + def __init__(self, commission_fee_coeff=0.0015, if_nondatabase=False): + """[summary] + + + Keyword Arguments: + commission_fee_coeff {[type]} -- [description] (default: {0}) + environment {[type]} -- [description] (default: {RUNNING_ENVIRONMENT}) + if_nondatabase {[type]} -- [description] (default: {False}) + """ + super().__init__() + self.dealer = QA_Dealer(commission_fee_coeff) + self.order_handler = QA_OrderHandler() + self.engine = { + MARKET_TYPE.STOCK_CN: self.dealer.backtest_stock_dealer} + + self.fetcher = {(MARKET_TYPE.STOCK_CN, FREQUENCE.DAY): QA_fetch_stock_day, (MARKET_TYPE.STOCK_CN, FREQUENCE.FIFTEEN_MIN): QA_fetch_stock_min, + (MARKET_TYPE.STOCK_CN, FREQUENCE.ONE_MIN): QA_fetch_stock_min, (MARKET_TYPE.STOCK_CN, FREQUENCE.FIVE_MIN): QA_fetch_stock_min, + (MARKET_TYPE.STOCK_CN, FREQUENCE.THIRTY_MIN): QA_fetch_stock_min, (MARKET_TYPE.STOCK_CN, FREQUENCE.SIXTY_MIN): QA_fetch_stock_min, + (MARKET_TYPE.INDEX_CN, FREQUENCE.DAY): QA_fetch_index_day, (MARKET_TYPE.INDEX_CN, FREQUENCE.FIFTEEN_MIN): QA_fetch_index_min, + (MARKET_TYPE.INDEX_CN, FREQUENCE.ONE_MIN): QA_fetch_index_min, (MARKET_TYPE.INDEX_CN, FREQUENCE.FIVE_MIN): QA_fetch_index_min, + (MARKET_TYPE.INDEX_CN, FREQUENCE.THIRTY_MIN): QA_fetch_index_min, (MARKET_TYPE.INDEX_CN, FREQUENCE.SIXTY_MIN): QA_fetch_index_min, + (MARKET_TYPE.FUND_CN, FREQUENCE.DAY): QA_fetch_index_day, (MARKET_TYPE.FUND_CN, FREQUENCE.FIFTEEN_MIN): QA_fetch_index_min, + (MARKET_TYPE.FUND_CN, FREQUENCE.ONE_MIN): QA_fetch_index_min, (MARKET_TYPE.FUND_CN, FREQUENCE.FIVE_MIN): QA_fetch_index_min, + (MARKET_TYPE.FUND_CN, FREQUENCE.THIRTY_MIN): QA_fetch_index_min, (MARKET_TYPE.FUND_CN, FREQUENCE.SIXTY_MIN): QA_fetch_index_min} + + self.commission_fee_coeff = commission_fee_coeff + self.market_data = None + self.if_nondatabase = if_nondatabase + self.name = BROKER_TYPE.BACKETEST + self._quotation = {} # 一个可以缓存数据的dict + self.broker_data = None + +
[docs] def run(self, event): + if event.event_type is MARKET_EVENT.QUERY_DATA: + # 查询数据部分 + code = event.code + frequence = event.frequence + start = event.start + end = start if event.end is None else event.end + market_type = event.market_type + res = self.query_data(code, start, end, frequence, market_type) + if event.callback: + event.callback(res) + else: + return res + elif event.event_type is MARKET_EVENT.QUERY_ORDER: + self.order_handler.run(event) + elif event.event_type is ENGINE_EVENT.UPCOMING_DATA: + new_marketdata_dict = event.market_data.dicts + for item in new_marketdata_dict.keys(): + if item not in self._quotation.keys(): + self._quotation[item] = new_marketdata_dict[item] + # if self.broker_data is None: + # self.broker_data = event.market_data + # else: + # self.broker_data.append(event.market_data) + # self.broker_data=event.market_data + + elif event.event_type is BROKER_EVENT.RECEIVE_ORDER: + self.order_handler.run(event) + self.run(QA_Event(event_type=BROKER_EVENT.TRADE, broker=self)) + elif event.event_type is BROKER_EVENT.TRADE: + event = self.order_handler.run(event) + + event.message = 'trade' + if event.callback: + event.callback(event) + elif event.event_type is BROKER_EVENT.SETTLE: + self.order_handler.run(event) + if event.callback: + event.callback('settle')
+ +
[docs] def query_data(self, code, start, end, frequence, market_type=None): + """ + 标准格式是numpy + """ + try: + return self.broker_data.select_time( + start, end).select_code(code).to_numpy() + except: + return self.fetcher[(market_type, frequence)]( + code, start, end, frequence=frequence)
+ +
[docs] def receive_order(self, event): + """ + get the order and choice which market to trade + + """ + order = event.order + + if 'market_data' in event.__dict__.keys(): + self.market_data = self.get_market( + order) if event.market_data is None else event.market_data + else: + self.market_data = self.get_market(order) + + order = self.warp(order) + + return self.dealer.deal(order, self.market_data)
+ +
[docs] def warp(self, order): + """对order/market的封装 + + [description] + + Arguments: + order {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + # 因为成交模式对时间的封装 + + if order.order_model == ORDER_MODEL.MARKET: + + if order.frequence is FREQUENCE.DAY: + # exact_time = str(datetime.datetime.strptime( + # str(order.datetime), '%Y-%m-%d %H-%M-%S') + datetime.timedelta(day=1)) + + order.date = order.datetime[0:10] + order.datetime = '{} 09:30:00'.format(order.date) + elif order.frequence in [FREQUENCE.ONE_MIN, FREQUENCE.FIVE_MIN, FREQUENCE.FIFTEEN_MIN, FREQUENCE.THIRTY_MIN, FREQUENCE.SIXTY_MIN]: + print(order.datetime) + exact_time = str(datetime.datetime.strptime( + str(order.datetime), '%Y-%m-%d %H:%M:%S') + datetime.timedelta(minutes=1)) + order.date = exact_time[0:10] + order.datetime = exact_time + self.market_data = self.get_market(order) + if self.market_data is None: + return order + order.price = (float(self.market_data["high"]) + + float(self.market_data["low"])) * 0.5 + elif order.order_model == ORDER_MODEL.NEXT_OPEN: + try: + exact_time = str(datetime.datetime.strptime( + str(order.datetime), '%Y-%m-%d %H-%M-%S') + datetime.timedelta(day=1)) + order.date = exact_time[0:10] + order.datetime = '{} 09:30:00'.format(order.date) + except: + order.datetime = '{} 15:00:00'.format(order.date) + self.market_data = self.get_market(order) + if self.market_data is None: + return order + order.price = float(self.market_data["close"]) + elif order.order_model == ORDER_MODEL.CLOSE: + + try: + order.datetime = self.market_data.datetime + except: + if len(str(order.datetime)) == 19: + pass + else: + order.datetime = '{} 15:00:00'.format(order.date) + self.market_data = self.get_market(order) + if self.market_data is None: + return order + order.price = float(self.market_data["close"]) + + elif order.order_model == ORDER_MODEL.STRICT: + '加入严格模式' + if order.frequence is FREQUENCE.DAY: + exact_time = str(datetime.datetime.strptime( + order.datetime, '%Y-%m-%d %H-%M-%S') + datetime.timedelta(day=1)) + + order.date = exact_time[0:10] + order.datetime = '{} 09:30:00'.format(order.date) + elif order.frequence in [FREQUENCE.ONE_MIN, FREQUENCE.FIVE_MIN, FREQUENCE.FIFTEEN_MIN, FREQUENCE.THIRTY_MIN, FREQUENCE.SIXTY_MIN]: + exact_time = str(datetime.datetime.strptime( + order.datetime, '%Y-%m-%d %H-%M-%S') + datetime.timedelta(minute=1)) + order.date = exact_time[0:10] + order.datetime = exact_time + self.market_data = self.get_market(order) + if self.market_data is None: + return order + if order.towards == 1: + order.price = float(self.market_data["high"]) + else: + order.price = float(self.market_data["low"]) + + return order
+ +
[docs] def get_market(self, order): + """get_market func + + [description] + + Arguments: + order {orders} -- [description] + + Returns: + [type] -- [description] + """ + + # 首先判断是否在_quotation里面 + + if (order.datetime, order.code) in self._quotation.keys(): + return self._quotation[(QA_util_to_datetime(order.datetime), order.code)] + + else: + try: + data = self.fetcher[(order.market_type, order.frequence)]( + code=order.code, start=order.datetime, end=order.datetime, format='json')[0] + if 'vol' in data.keys() and 'volume' not in data.keys(): + data['volume'] = data['vol'] + elif 'vol' not in data.keys() and 'volume' in data.keys(): + data['vol'] = data['volume'] + return data + except Exception as e: + QA_util_log_info('MARKET_ENGING ERROR: {}'.format(e)) + return None
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/QABroker.html b/_build/html/_modules/QUANTAXIS/QAMarket/QABroker.html new file mode 100644 index 000000000..07ab878eb --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/QABroker.html @@ -0,0 +1,225 @@ + + + + + + + + QUANTAXIS.QAMarket.QABroker — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.QABroker

+# coding :utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+"""
+需要一个可以被修改和继承的基类
+
+2017/8/12
+
+"""
+import datetime
+from abc import abstractmethod
+
+from QUANTAXIS.QAEngine.QAEvent import QA_Event, QA_Worker
+from QUANTAXIS.QAUtil.QAParameter import EVENT_TYPE, FREQUENCE, ORDER_MODEL
+
+
+
[docs]class QA_Broker(QA_Worker): + """MARKET ENGINGE ABSTRACT + + receive_order => warp => get_data => engine + """ + + def __init__(self, *args, **kwargs): + super().__init__() + self.type = EVENT_TYPE.BROKER_EVENT + self.name = None + + def __repr__(self): + return '< QA_MARKET >' + +
[docs] @abstractmethod + def receive_order(self, event): + raise NotImplementedError
+ +
[docs] def get_market(self, order): + pass
+ +
[docs] def warp(self, order): + """对order/market的封装 + + [description] + + Arguments: + order {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + # 因为成交模式对时间的封装 + + if order.order_model == ORDER_MODEL.MARKET: + + if order.frequence is FREQUENCE.DAY: + # exact_time = str(datetime.datetime.strptime( + # str(order.datetime), '%Y-%m-%d %H-%M-%S') + datetime.timedelta(day=1)) + + order.date = order.datetime[0:10] + order.datetime = '{} 09:30:00'.format(order.date) + elif order.frequence in [FREQUENCE.ONE_MIN, FREQUENCE.FIVE_MIN, FREQUENCE.FIFTEEN_MIN, FREQUENCE.THIRTY_MIN, FREQUENCE.SIXTY_MIN]: + print(order.datetime) + exact_time = str(datetime.datetime.strptime( + str(order.datetime), '%Y-%m-%d %H:%M:%S') + datetime.timedelta(minutes=1)) + order.date = exact_time[0:10] + order.datetime = exact_time + self.market_data = self.get_market(order) + if self.market_data is None: + return order + order.price = (float(self.market_data["high"]) + + float(self.market_data["low"])) * 0.5 + elif order.order_model == ORDER_MODEL.NEXT_OPEN: + try: + exact_time = str(datetime.datetime.strptime( + str(order.datetime), '%Y-%m-%d %H-%M-%S') + datetime.timedelta(day=1)) + order.date = exact_time[0:10] + order.datetime = '{} 09:30:00'.format(order.date) + except: + order.datetime = '{} 15:00:00'.format(order.date) + self.market_data = self.get_market(order) + if self.market_data is None: + return order + order.price = float(self.market_data["close"]) + elif order.order_model == ORDER_MODEL.CLOSE: + + try: + order.datetime = self.market_data.datetime + except: + if len(str(order.datetime)) == 19: + pass + else: + order.datetime = '{} 15:00:00'.format(order.date) + self.market_data = self.get_market(order) + if self.market_data is None: + return order + order.price = float(self.market_data["close"]) + + elif order.order_model == ORDER_MODEL.STRICT: + '加入严格模式' + if order.frequence is FREQUENCE.DAY: + exact_time = str(datetime.datetime.strptime( + order.datetime, '%Y-%m-%d %H-%M-%S') + datetime.timedelta(day=1)) + + order.date = exact_time[0:10] + order.datetime = '{} 09:30:00'.format(order.date) + elif order.frequence in [FREQUENCE.ONE_MIN, FREQUENCE.FIVE_MIN, FREQUENCE.FIFTEEN_MIN, FREQUENCE.THIRTY_MIN, FREQUENCE.SIXTY_MIN]: + exact_time = str(datetime.datetime.strptime( + order.datetime, '%Y-%m-%d %H-%M-%S') + datetime.timedelta(minute=1)) + order.date = exact_time[0:10] + order.datetime = exact_time + self.market_data = self.get_market(order) + if self.market_data is None: + return order + if order.towards == 1: + order.price = float(self.market_data["high"]) + else: + order.price = float(self.market_data["low"]) + + return order
+ + +
[docs]class QA_BROKER_EVENT(QA_Event): + def __init__(self, *args, **kwargs): + super().__init__() + + self.event_type = None
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/QADealer.html b/_build/html/_modules/QUANTAXIS/QAMarket/QADealer.html new file mode 100644 index 000000000..1bc017fbc --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/QADealer.html @@ -0,0 +1,352 @@ + + + + + + + + QUANTAXIS.QAMarket.QADealer — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.QADealer

+# coding :utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+#from .market_config import stock_market,future_market,HK_stock_market,US_stock_market
+
+
+from QUANTAXIS.QAUtil import QA_util_log_info, QA_util_random_with_topic
+from QUANTAXIS.QAUtil.QAParameter import MARKET_TYPE, TRADE_STATUS
+
+
+"""撮合类
+
+
+输入是
+
+self.market_data
+self.order
+rules
+
+输出是
+
+standard message
+
+"""
+
+
+
[docs]class commission(): + if_buyside_commission = False + if_sellside_commission = True + if_commission = if_buyside_commission and if_sellside_commission
+ + +
[docs]class dealer_preset(): + def __init__(self, market_type, *args, **kwargs): + + self.market_type = market_type + self.if_price_limit = None # 是否限制涨跌停(美股/加密货币不限制) + self.if_commission = None # 是否收手续费(部分合约/部分加密货币不收手续费) + self.if_tax = None # 是否收税 + self.if_t0 = None # 是否t+0 + self.if_sellopen = None # 是否允许卖空 + self.trading_time = None # 交易时间 + self.commission_coeff = None # 手续费比例 + self.tax_coeff = None # 费率 + +
[docs] def load_preset(self): + if self.market_type is MARKET_TYPE.STOCK_CN: + self.if_price_limit = True # 是否限制涨跌停(美股/加密货币不限制) + self.if_commission = True # 是否收手续费(部分合约/部分加密货币不收手续费) + self.if_tax = True # 是否收税 + self.if_t0 = False # 是否t+0 + self.if_sellopen = False # 是否允许卖空 + self.trading_time = [[930, 1130], [1300, 1500]] # 交易时间 + self.commission_coeff = 0.00025 # 手续费比例 + self.tax_coeff = 0.001 # 费率 + return self + elif self.market_type is MARKET_TYPE.FUTURE_CN: + self.if_price_limit = True # 是否限制涨跌停(美股/加密货币不限制) + self.if_commission = True # 是否收手续费(部分合约/部分加密货币不收手续费) + self.if_tax = False # 是否收税 + self.if_t0 = True # 是否t+0 + self.if_sellopen = True # 是否允许卖空 + self.trading_time = [[930, 1130], [1300, 1500]] # 交易时间 + self.commission_coeff = 0.00025 # 手续费比例 + self.tax_coeff = 0 # 费率 + else: + pass + return self
+ + +
[docs]class QA_Dealer(): + + """[summary] + + + 对于不同的市场规则: + 股票市场 t+1 + 期货/期权/加密货币市场 t+0 + + 股票/加密货币市场不允许卖空 + 期货/期权市场允许卖空 + + t+1的市场是 + 当日的买入 更新持仓- 不更新可卖数量- 资金冻结 + 当日的卖出 及时更新可用资金 + + t+0市场是: + 当日买入 即时更新持仓和可卖 + 当日卖出 即时更新 + + 卖空的规则是 + 允许无仓位的时候卖出证券(按市值和保证金比例限制算) + """ + + def __init__(self, commission_fee_coeff=0.00025, tax_coeff=0.001, *args, **kwargs): + self.commission_fee_coeff = commission_fee_coeff + self.tax_coeff = tax_coeff + self.deal_name = '' + self.deal_engine = {'0x01': self.backtest_stock_dealer} + self.session = {} + self.order = None + self.market_data = None + self.commission_fee = None + self.tax = None + self.status = None + +
[docs] def deal(self, order, market_data): + self.order = order + self.market_data = market_data + self.deal_price = 0 + self.deal_amount = 0 + if order.market_type is MARKET_TYPE.STOCK_CN: + return self.backtest_stock_dealer()
+ +
[docs] def callback_message(self): + # 这是标准的return back message + message = { + 'header': { + 'source': 'market', + 'status': self.status, + 'code': self.order.code, + 'session': { + 'user': self.order.user, + 'strategy': self.order.strategy, + 'account': self.order.account_cookie + }, + 'order_id': self.order.order_id, + 'trade_id': QA_util_random_with_topic('Trade') + }, + 'body': { + 'order': { + 'price': float("%.2f" % float(self.deal_price)), + 'code': self.order.code, + 'amount': self.deal_amount, + 'date': self.order.date, + 'datetime': self.order.datetime, + 'towards': self.order.towards + }, + 'market': { + 'open': self.market_data['open'], + 'high': self.market_data['high'], + 'low': self.market_data['low'], + 'close': self.market_data['close'], + 'volume': self.market_data['volume'], + 'code': self.market_data['code'] + }, + 'fee': { + 'commission': self.commission_fee, + 'tax': self.tax + } + } + } + return message
+ +
[docs] def cal_fee(self): + if self.order.market_type is MARKET_TYPE.STOCK_CN: + if int(self.order.towards) > 0: + commission_fee = self.commission_fee_coeff * \ + float(self.deal_price) * float(self.order.amount) + self.commission_fee = 5 if commission_fee < 5 else commission_fee + + self.tax = 0 # 买入不收印花税 + else: + commission_fee = self.commission_fee_coeff * \ + float(self.deal_price) * float(self.order.amount) + + self.commission_fee = 5 if commission_fee < 5 else commission_fee + + self.tax = self.tax_coeff * \ + float(self.deal_price) * float(self.order.amount) + elif self.order.market_type is MARKET_TYPE.FUTURE_CN: + # 期货不收税 + # 双边手续费 也没有最小手续费限制 + self.commission_fee = self.commission_fee_coeff * \ + float(self.deal_price) * float(self.order.amount) + #self.commission_fee = 5 if commission_fee < 5 else commission_fee + + self.tax = 0 # 买入不收印花税
+ +
[docs] def backtest_stock_dealer(self): + # 新增一个__commission_fee_coeff 手续费系数 + """MARKET ENGINE STOCK + + 在拿到市场数据后对于订单的撮合判断 生成成交信息 + + + trading system + step1: check self.market_data + step2: deal + step3: return callback + """ + try: + if float(self.market_data['open']) == float(self.market_data['high']) == float(self.market_data['close']) == float(self.market_data['low']): + + self.status = TRADE_STATUS.PRICE_LIMIT + self.deal_price = 0 + self.deal_amount = 0 + self.cal_fee() + return self.callback_message() + elif ((float(self.order.price) < float(self.market_data["high"]) and + float(self.order.price) > float(self.market_data["low"])) or + float(self.order.price) == float(self.market_data["low"]) or + float(self.order.price) == float(self.market_data['high'])): + '能成功交易的情况 有滑点调整' + if float(self.order.amount) < float(self.market_data['volume']) * 100 / 16: + self.deal_price = self.order.price + self.deal_amount = self.order.amount + elif float(self.order.amount) >= float(self.market_data['volume']) * 100 / 16 and \ + float(self.order.amount) < float(self.market_data['volume']) * 100 / 8: + """ + add some slippers + + buy_price=mean(max{open,close},high) + sell_price=mean(min{open,close},low) + """ + if int(self.order.towards) > 0: + self.deal_price = (max(float(self.market_data['open']), float( + self.market_data['close'])) + float(self.market_data['high'])) * 0.5 + else: + self.deal_price = (min(float(self.market_data['open']), float( + self.market_data['close'])) + float(self.market_data['low'])) * 0.5 + self.deal_amount = self.order.amount + + else: + self.deal_amount = float(self.market_data['volume']) / 8 + if int(self.order.towards) > 0: + self.deal_price = float(self.market_data['high']) + else: + self.deal_price = float(self.market_data['low']) + + self.cal_fee() + self.status = TRADE_STATUS.SUCCESS + return self.callback_message() + else: + self.status = TRADE_STATUS.FAILED + self.deal_price = 0 + self.deal_amount = 0 + self.cal_fee() + return self.callback_message() + + except Exception as e: + QA_util_log_info('MARKET ENGINE ERROR: {}'.format(e)) + self.status = TRADE_STATUS.NO_MARKET_DATA + return self.callback_message()
+ + + +
[docs]class Stock_Dealer(QA_Dealer): + def __init__(self, *args, **kwargs): + super().__init__()
+ +if __name__ == '__main__': + pass +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/QAMarket.html b/_build/html/_modules/QUANTAXIS/QAMarket/QAMarket.html new file mode 100644 index 000000000..7c5687b9e --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/QAMarket.html @@ -0,0 +1,399 @@ + + + + + + + + QUANTAXIS.QAMarket.QAMarket — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.QAMarket

+# coding :utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from QUANTAXIS.QAARP.QAAccount import QA_Account
+from QUANTAXIS.QAEngine.QAEvent import QA_Event
+from QUANTAXIS.QAEngine.QATask import QA_Task
+from QUANTAXIS.QAMarket.QABacktestBroker import QA_BacktestBroker
+from QUANTAXIS.QAMarket.QARandomBroker import QA_RandomBroker
+from QUANTAXIS.QAMarket.QARealBroker import QA_RealBroker
+from QUANTAXIS.QAMarket.QASimulatedBroker import QA_SimulatedBroker
+from QUANTAXIS.QAMarket.QATrade import QA_Trade
+from QUANTAXIS.QAUtil.QAParameter import (ACCOUNT_EVENT, AMOUNT_MODEL,
+                                          BROKER_EVENT, BROKER_TYPE,
+                                          ENGINE_EVENT, MARKET_EVENT,
+                                          FREQUENCE, ORDER_EVENT,
+                                          ORDER_MODEL)
+from QUANTAXIS.QAUtil.QALogs import QA_util_log_info
+
+
+
[docs]class QA_Market(QA_Trade): + """ + QUANTAXIS MARKET 部分 + + 交易前置/可连接到多个broker中 + + 暂时还是采用多线程engine模式 + + """ + + def __init__(self, *args, **kwargs): + super().__init__() + self.session = {} + self._broker = {BROKER_TYPE.BACKETEST: QA_BacktestBroker, BROKER_TYPE.RANODM: QA_RandomBroker, + BROKER_TYPE.REAL: QA_RealBroker, BROKER_TYPE.SIMULATION: QA_SimulatedBroker} + + self.broker = {} + self.running_time = None + self.last_query_data = None + + def __repr__(self): + return '< QA_MARKET with {} Broker >'.format(list(self.broker.keys())) + +
[docs] def upcoming_data(self, broker, data): + # main thread' + + # if self.running_time is not None and self.running_time!= data.datetime[0]: + # for item in self.broker.keys(): + # self._settle(item) + + self.running_time = data.datetime[0] + for item in self.session.values(): + # session里面是已经注册的account + self.event_queue.put(QA_Task( + worker=item, + event=QA_Event( + event_type=ENGINE_EVENT.UPCOMING_DATA, + market_data=data, + broker_name=broker, + send_order=self.insert_order, + query_data=self.query_data_no_wait, + query_order=self.query_order, + query_assets=self.query_assets, + query_trade=self.query_trade + ) + ))
+ +
[docs] def start(self): + self.trade_engine.start()
+ # self.trade_engine.create_kernal('MARKET') + # self.trade_engine.start_kernal('MARKET') + +
[docs] def connect(self, broker): + if broker in self._broker.keys(): + + self.broker[broker] = self._broker[broker]() # 在这里实例化 + self.trade_engine.create_kernal('{}'.format(broker)) + self.trade_engine.start_kernal('{}'.format(broker)) + # 开启trade事件子线程 + return True + else: + return False
+ +
[docs] def register(self, broker_name, broker): + if broker_name not in self._broker.keys(): + self.broker[broker_name] = broker + self.trade_engine.create_kernal('{}'.format(broker_name)) + self.trade_engine.start_kernal('{}'.format(broker_name)) + return True + else: + return False
+ +
[docs] def get_account(self, account_cookie): + return self.session[account_cookie]
+ +
[docs] def login(self, broker_name, account_cookie, account=None): + if account is None: + if account_cookie not in self.session.keys(): + self.session[account_cookie] = QA_Account( + account_cookie=account_cookie, broker=broker_name) + return True + else: + return False + else: + if account_cookie not in self.session.keys(): + account.broker = broker_name + self.session[account_cookie] = account + return True + else: + return False
+ +
[docs] def logout(self, account_cookie, broker_name): + if account_cookie not in self.session.keys(): + return False + else: + self.session.pop(account_cookie)
+ +
[docs] def get_trading_day(self): + return self.running_time
+ +
[docs] def get_account_id(self): + return list(self.session.keys())
+ +
[docs] def insert_order(self, account_id, amount, amount_model, time, code, price, order_model, towards, market_type, frequence, broker_name): + + flag = False + if order_model in [ORDER_MODEL.CLOSE, ORDER_MODEL.NEXT_OPEN]: + _price = self.query_data_no_wait(broker_name=broker_name, frequence=frequence, + market_type=market_type, code=code, start=time) + + if _price is not None and len(_price) > 0: + price = float(_price[0][4]) + flag = True + else: + QA_util_log_info('MARKET WARING: SOMEING WRONG WITH ORDER \n ') + QA_util_log_info('code {} date {} price {} order_model {} amount_model {}'.format( + code, time, price, order_model, amount_model)) + elif order_model is ORDER_MODEL.MARKET: + _price = self.query_data_no_wait(broker_name=broker_name, frequence=frequence, + market_type=market_type, code=code, start=time) + if _price is not None and len(_price) > 0: + price = float(_price[0][1]) + flag = True + else: + QA_util_log_info('MARKET WARING: SOMEING WRONG WITH ORDER \n ') + QA_util_log_info('code {} date {} price {} order_model {} amount_model {}'.format( + code, time, price, order_model, amount_model)) + + elif order_model is ORDER_MODEL.LIMIT: + # if price > self.last_query_data[0][2] or price < self.last_query_data[0][3]: + flag = True + if flag: + order = self.get_account(account_id).send_order( + amount=amount, amount_model=amount_model, time=time, code=code, price=price, + order_model=order_model, towards=towards) + self.event_queue.put( + QA_Task( + worker=self.broker[self.get_account(account_id).broker], + engine=self.get_account(account_id).broker, + event=QA_Event( + event_type=BROKER_EVENT.RECEIVE_ORDER, + order=order, + callback=self.on_insert_order))) + else: + pass
+ +
[docs] def on_insert_order(self, order): + print(order)
+ + def _renew_account(self): + for item in self.session.values(): + + self.event_queue.put( + QA_Task( + worker=item, + event=QA_Event( + event_type=ACCOUNT_EVENT.SETTLE))) + +
[docs] def query_order(self, broker_name, order_id): + + res = self.event_queue.put( + QA_Task( + worker=self.broker[broker_name], + engine=broker_name, + event=QA_Event( + order_id=order_id + ) + )) + + return res
+ +
[docs] def query_assets(self, account_cookie): + return self.get_account(account_cookie).assets
+ +
[docs] def query_position(self, account_cookie): + return self.get_account(account_cookie).hold
+ +
[docs] def query_cash(self, account_cookie): + return self.get_account(account_cookie).cash_available
+ +
[docs] def query_data_no_wait(self, broker_name, frequence, market_type, code, start, end=None): + return self.broker[broker_name].run(event=QA_Event( + event_type=MARKET_EVENT.QUERY_DATA, + frequence=frequence, + market_type=market_type, + code=code, + start=start, + end=end + ))
+ +
[docs] def query_data(self, broker_name, frequence, market_type, code, start, end=None): + self.event_queue.put( + QA_Task( + worker=self.broker[broker_name], + engine=broker_name, + event=QA_Event( + event_type=MARKET_EVENT.QUERY_DATA, + frequence=frequence, + market_type=market_type, + code=code, + start=start, + end=end, + callback=self.on_query_data + ) + ))
+ +
[docs] def query_currentbar(self, broker_name, market_type, code): + return self.broker[broker_name].run(event=QA_Event( + event_type=MARKET_EVENT.QUERY_DATA, + frequence=FREQUENCE.CURRENT, + market_type=market_type, + code=code, + start=self.running_time, + end=None + ))
+ +
[docs] def on_query_data(self, data): + print('ON QUERY') + print(data) + self.last_query_data = data
+ +
[docs] def on_trade_event(self, event): + print('ON TRADE') + print(event.res)
+ + def _trade(self, event): + "内部函数" + + self.event_queue.put(QA_Task( + worker=self.broker[event.broker_name], + engine=event.broker_name, + event=QA_Event( + event_type=BROKER_EVENT.TRADE, + broker=self.broker[event.broker_name], + broker_name=event.broker_name, + callback=self.on_trade_event + ))) + + def _settle(self, broker_name, callback=False): + # 向事件线程发送BROKER的SETTLE事件 + + # 向事件线程发送ACCOUNT的SETTLE事件 + for item in self.session.values(): + if item.broker is broker_name: + self.event_queue.put( + QA_Task( + worker=item, + engine=broker_name, + event=QA_Event( + event_type=ACCOUNT_EVENT.SETTLE))) + self.event_queue.put(QA_Task( + worker=self.broker[broker_name], + engine=broker_name, + event=QA_Event( + event_type=BROKER_EVENT.SETTLE, + broker=self.broker[broker_name], + callback=callback))) + + print('===== SETTLED {} ====='.format(self.running_time)) + + def _close(self): + pass + +
[docs] def clear(self): + return self.trade_engine.clear()
+ + +if __name__ == '__main__': + + import QUANTAXIS as QA + + user = QA.QA_Portfolio() + # 创建两个account + + a_1 = user.new_account() + a_2 = user.new_account() + market = QA_Market() + + market.connect(QA.RUNNING_ENVIRONMENT.BACKETEST) + # +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/QAOrder.html b/_build/html/_modules/QUANTAXIS/QAMarket/QAOrder.html new file mode 100644 index 000000000..623c7ff75 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/QAOrder.html @@ -0,0 +1,323 @@ + + + + + + + + QUANTAXIS.QAMarket.QAOrder — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.QAOrder

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import pandas as pd
+
+from QUANTAXIS.QAUtil import (QA_util_log_info, QA_util_random_with_topic,
+                              QA_util_to_json_from_pandas)
+from QUANTAXIS.QAUtil.QAParameter import AMOUNT_MODEL, ORDER_STATUS
+
+
+"""
+重新定义Order模式
+
+在2017-12-15的Account-remake-version 分支中
+
+Bid类全部被更名为Order类
+
+用于和 bid_ask 区分
+
+by yutiansut@2017/12/15
+
+
+@2018/1/9
+需要重新考虑 order的重复创建耗时问题
+
+order_frame 是一个管理性面板  但是还是需要一个缓存dict
+
+"""
+
+
+
[docs]class QA_Order(): + def __init__(self, price=None, date=None, datetime=None, sending_time=None, transact_time=None, amount=None, market_type=None, frequence=None, + towards=None, code=None, user=None, account_cookie=None, strategy=None, order_model=None, amount_model=AMOUNT_MODEL.BY_AMOUNT, + order_id=None, trade_id=None, status='100', callback=False, *args, **kwargs): + """委托字段 + price 委托的价格 + date 委托的日期 + datetime 委托的时间 + sending_time 发送委托单的时间 + transact_time 委托成交的时间 + amount 委托量 + market_type 委托的市场 + frequence 频率 + towards 委托方向 + code 委托代码 + user 委托股东 + account_cookie 委托账户的cookie + strategy 策略名 + order_model 委托方式(限价/市价/下一个bar/) + amount_model 委托量模式(按量委托/按总成交额委托) + order_id 委托单id + trade_id 成交id + status 订单状态 + callback 回调函数 + """ + + self.price = price + self.datetime = None + if datetime is None and date is not None: + self.date = date + self.datetime = '{} 09:31:00'.format(self.date) + + elif date is None and datetime is not None: + self.date = datetime[0:10] + self.datetime = datetime + + elif date is not None and datetime is not None: + self.date = date + self.datetime = datetime + else: + pass + self.sending_time = self.datetime if sending_time is None else sending_time # 下单时间 + self.transact_time = transact_time + self.amount = amount + self.towards = towards # side + self.code = code + self.user = user + self.market_type = market_type + self.frequence = frequence + self.account_cookie = account_cookie + self.strategy = strategy + self.type = market_type # see below + self.order_model = order_model + self.amount_model = amount_model + self.order_id = QA_util_random_with_topic( + topic='Order') if order_id is None else order_id + self.trade_id = trade_id + self.status = status + self.callback = callback + + def __repr__(self): + return '< QA_Order datetime:{} code:{} price:{} towards:{} btype:{} order_id:{} account:{} status:{} >'.format( + self.datetime, self.code, self.price, self.towards, self.type, self.order_id, self.account_cookie, self.status) + +
[docs] def info(self): + return vars(self)
+ +
[docs] def to_df(self): + return pd.DataFrame([vars(self), ])
+ +
[docs] def to_dict(self): + return vars(self)
+ +
[docs] def from_dict(self, order): + try: + # QA_util_log_info('QA_ORDER CHANGE: from {} change to {}'.format( + # self.order_id, order['order_id'])) + self.price = order['price'] + self.date = order['date'] + self.datetime = order['datetime'] + self.sending_time = order['sending_time'] # 下单时间 + self.transact_time = order['transact_time'] + self.amount = order['amount'] + self.frequence = order['frequence'] + self.market_type = order['market_type'] + self.towards = order['towards'] + self.code = order['code'] + self.user = order['user'] + self.account_cookie = order['account_cookie'] + self.strategy = order['strategy'] + self.type = order['type'] + self.order_model = order['order_model'] + self.amount_model = order['amount_model'] + self.order_id = order['order_id'] + self.trade_id = order['trade_id'] + self.callback = order['callback'] + return self + except Exception as e: + QA_util_log_info('Failed to tran from dict {}'.format(e))
+ + +
[docs]class QA_OrderQueue(): # also the order tree + """ + 一个待成交队列 + 这里面都是对于方法的封装 + + """ + + def __init__(self): + self.order_list = [] + self.queue = pd.DataFrame() + self._queue = {} + + def __repr__(self): + return '< QA_OrderQueue AMOUNT {} WAITING TRADE {} >'.format(len(self.queue), len(self.pending)) + + def __call__(self): + return self.queue + + def _from_dataframe(self, dataframe): + try: + self.order_list = [QA_Order().from_dict(item) + for item in QA_util_to_json_from_pandas(dataframe)] + return self.order_list + except: + pass + +
[docs] def insert_order(self, order): + order.status = ORDER_STATUS.QUEUED + self.queue = self.queue.append( + order.to_df(), ignore_index=True) + self.queue.set_index('order_id', drop=False, inplace=True) + self._queue[order.order_id] = order + return order
+ + @property + def order_ids(self): + return self.queue.index + +
[docs] def settle(self): + """结算 + + 清空订单簿 + """ + self.queue = pd.DataFrame() + self._queue = {}
+ + @property + def pending(self): + """选择待成交列表 + + [description] + + Returns: + dataframe + """ + try: + return self.queue.query('status!=200').query('status!=500').query('status!=400') + except: + return pd.DataFrame() + + @property + def trade_list(self): + """批量交易 + + [description] + + Returns: + list of orders + """ + + return [self._queue[order_id] for order_id in self.pending.index] + +
[docs] def query_order(self, order_id): + + return self.queue.get(order_id, None)
+ +
[docs] def set_status(self, order_id, new_status): + try: + if order_id in self.order_ids: + self.queue.loc[order_id, 'status'] = new_status + self._queue[order_id].status = new_status + else: + pass + except: + return None
+ + +if __name__ == '__main__': + ax = QA_Order() + + print(ax.info()) + print(ax.to_df()) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/QAOrderHandler.html b/_build/html/_modules/QUANTAXIS/QAMarket/QAOrderHandler.html new file mode 100644 index 000000000..2c5003935 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/QAOrderHandler.html @@ -0,0 +1,168 @@ + + + + + + + + QUANTAXIS.QAMarket.QAOrderHandler — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.QAOrderHandler

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from QUANTAXIS.QAEngine.QAEvent import QA_Event, QA_Worker
+from QUANTAXIS.QAMarket.QAOrder import QA_OrderQueue
+from QUANTAXIS.QAUtil.QAParameter import (BROKER_EVENT, EVENT_TYPE,
+                                          MARKET_EVENT, ORDER_EVENT)
+
+
+
[docs]class QA_OrderHandler(QA_Worker): + """ORDER执行器 + + + ORDEHANDLDER 归属于MARKET前置 + + 仅负责一个无状态的执行层 + + ORDER执行器的作用是因为 + 在实盘中 当一个订单发送出去的时候,市场不会返回一个更新的订单类回来 + 大部分时间都依赖子线程主动查询 或者是一个市场信息来进行判断 + + ORDER_Handler的作用就是根据信息更新Order + + 用于接受订单 发送给相应的marker_broker 再根据返回的信息 进行更新 + + 可用的market_broker: + 1.回测盘 + 2.实时模拟盘 + 3.实盘 + + """ + + def __init__(self, *args, **kwargs): + super().__init__() + self.order_queue = QA_OrderQueue() + self.type = EVENT_TYPE.MARKET_EVENT + + self.event = QA_Event() + +
[docs] def run(self, event): + if event.event_type is BROKER_EVENT.RECEIVE_ORDER: + # 此时的message应该是订单类 + order = self.order_queue.insert_order(event.order) + if event.callback: + event.callback(order) + + elif event.event_type is BROKER_EVENT.TRADE: + res=[] + for item in self.order_queue.trade_list: + result=event.broker.receive_order( + QA_Event(event_type=BROKER_EVENT.TRADE, order=item)) + self.order_queue.set_status( + item.order_id, result['header']['status']) + if item.callback: + item.callback(result) + res.append(result) + event.res = res + + return event + + elif event.event_type is BROKER_EVENT.SETTLE: + self.order_queue.settle() + + elif event.event_type is MARKET_EVENT.QUERY_ORDER: + return self.query_order(event.order_id)
+ +
[docs] def query_order(self, order_id): + return self.order_queue.queue.query()
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/QARandomBroker.html b/_build/html/_modules/QUANTAXIS/QAMarket/QARandomBroker.html new file mode 100644 index 000000000..fef0168bd --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/QARandomBroker.html @@ -0,0 +1,118 @@ + + + + + + + + QUANTAXIS.QAMarket.QARandomBroker — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.QARandomBroker

+# coding :utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from QUANTAXIS.QAMarket.QABroker import QA_Broker
+
+
+
[docs]class QA_RandomBroker(QA_Broker): + def __init__(self, *args, **kwargs): + pass + +
[docs] def get_data(self, order): + pass
+ +
[docs] def warp(self, order): + pass
+ +
[docs] def receive_order(self, order): + pass
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/QARealBroker.html b/_build/html/_modules/QUANTAXIS/QAMarket/QARealBroker.html new file mode 100644 index 000000000..d5401996d --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/QARealBroker.html @@ -0,0 +1,118 @@ + + + + + + + + QUANTAXIS.QAMarket.QARealBroker — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.QARealBroker

+# coding :utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from QUANTAXIS.QAMarket.QABroker import QA_Broker
+
+
+
[docs]class QA_RealBroker(QA_Broker): + def __init__(self, *args, **kwargs): + pass + +
[docs] def get_data(self, order): + pass
+ +
[docs] def warp(self, order): + pass
+ +
[docs] def receive_order(self,order): + pass
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/QASimulatedBroker.html b/_build/html/_modules/QUANTAXIS/QAMarket/QASimulatedBroker.html new file mode 100644 index 000000000..597b3ff20 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/QASimulatedBroker.html @@ -0,0 +1,163 @@ + + + + + + + + QUANTAXIS.QAMarket.QASimulatedBroker — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.QASimulatedBroker

+# coding :utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from QUANTAXIS.QAMarket.QABroker import QA_Broker
+from QUANTAXIS.QAFetch.QATdx import (QA_fetch_get_future_day,
+                                     QA_fetch_get_future_min,
+                                     QA_fetch_get_index_day,
+                                     QA_fetch_get_index_min,
+                                     QA_fetch_get_stock_day,
+                                     QA_fetch_get_stock_min)
+from QUANTAXIS.QAMarket.QADealer import QA_Dealer
+from QUANTAXIS.QAUtil.QAParameter import MARKET_TYPE, FREQUENCE
+from QUANTAXIS.QAUtil.QALogs import QA_util_log_info
+
+
[docs]class QA_SimulatedBroker(QA_Broker): + def __init__(self, *args, **kwargs): + self.dealer = QA_Dealer() + self.fetcher = {(MARKET_TYPE.STOCK_CN, FREQUENCE.DAY): QA_fetch_get_stock_day, (MARKET_TYPE.STOCK_CN, FREQUENCE.FIFTEEN_MIN): QA_fetch_get_stock_min, + (MARKET_TYPE.STOCK_CN, FREQUENCE.ONE_MIN): QA_fetch_get_stock_min, (MARKET_TYPE.STOCK_CN, FREQUENCE.FIVE_MIN): QA_fetch_get_stock_min, + (MARKET_TYPE.STOCK_CN, FREQUENCE.THIRTY_MIN): QA_fetch_get_stock_min, (MARKET_TYPE.STOCK_CN, FREQUENCE.SIXTY_MIN): QA_fetch_get_stock_min, + (MARKET_TYPE.INDEX_CN, FREQUENCE.DAY): QA_fetch_get_index_day, (MARKET_TYPE.INDEX_CN, FREQUENCE.FIFTEEN_MIN): QA_fetch_get_index_min, + (MARKET_TYPE.INDEX_CN, FREQUENCE.ONE_MIN): QA_fetch_get_index_min, (MARKET_TYPE.INDEX_CN, FREQUENCE.FIVE_MIN): QA_fetch_get_index_min, + (MARKET_TYPE.INDEX_CN, FREQUENCE.THIRTY_MIN): QA_fetch_get_index_min, (MARKET_TYPE.INDEX_CN, FREQUENCE.SIXTY_MIN): QA_fetch_get_index_min, + (MARKET_TYPE.FUND_CN, FREQUENCE.DAY): QA_fetch_get_index_day, (MARKET_TYPE.FUND_CN, FREQUENCE.FIFTEEN_MIN): QA_fetch_get_index_min, + (MARKET_TYPE.FUND_CN, FREQUENCE.ONE_MIN): QA_fetch_get_index_min, (MARKET_TYPE.FUND_CN, FREQUENCE.FIVE_MIN): QA_fetch_get_index_min, + (MARKET_TYPE.FUND_CN, FREQUENCE.THIRTY_MIN): QA_fetch_get_index_min, (MARKET_TYPE.FUND_CN, FREQUENCE.SIXTY_MIN): QA_fetch_get_index_min} + +
[docs] def get_market(self, order): + try: + data = self.fetcher[(order.market_type, order.frequence)]( + code=order.code, start=order.datetime, end=order.datetime).values[0] + if 'vol' in data.keys() and 'volume' not in data.keys(): + data['volume'] = data['vol'] + elif 'vol' not in data.keys() and 'volume' in data.keys(): + data['vol'] = data['volume'] + return data + except Exception as e: + QA_util_log_info('MARKET_ENGING ERROR: {}'.format(e)) + return None
+ + + +
[docs] def receive_order(self, event): + order = event.order + + if 'market_data' in event.__dict__.keys(): + self.market_data = self.get_market( + order) if event.market_data is None else event.market_data + else: + self.market_data = self.get_market(order) + + order = self.warp(order) + + return self.dealer.deal(order, self.market_data)
+ +
[docs] def query_data(self, code, start, end, frequence, market_type=None): + """ + 标准格式是numpy + """ + try: + return self.fetcher[(market_type, frequence)]( + code, start, end, frequence=frequence) + except: + pass
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/QATrade.html b/_build/html/_modules/QUANTAXIS/QAMarket/QATrade.html new file mode 100644 index 000000000..da7beba50 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/QATrade.html @@ -0,0 +1,206 @@ + + + + + + + + QUANTAXIS.QAMarket.QATrade — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.QATrade

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from QUANTAXIS.QAEngine.QAThreadEngine import QA_Engine
+
+# 交易封装
+
+
+
[docs]class QA_Trade(): + "多线程+generator模式" + + def __init__(self, *args, **kwargs): + self.trade_engine = QA_Engine() + self.event_queue = self.trade_engine.queue + + # self.spi_thread.start() + +
[docs] def connect(self, *args, **kwargs): + + pass
+ +
[docs] def on_connect(self, *args, **kwargs): + pass
+ +
[docs] def release(self, *args, **kwargs): + pass
+ +
[docs] def get_trading_day(self, *args, **kwargs): + pass
+ +
[docs] def register_spi(self, *args, **kwargs): + pass
+ +
[docs] def get_api_last_error(self, *args, **kwargs): + pass
+ +
[docs] def get_api_version(self, *args, **kwargs): + pass
+ +
[docs] def get_client_id(self, *args, **kwargs): + pass
+ +
[docs] def get_account_id(self, *args, **kwargs): + pass
+ +
[docs] def subscribe_public_topic(self, *args, **kwargs): + pass
+ +
[docs] def login(self, *args, **kwargs): + pass
+ +
[docs] def logout(self, *args, **kwargs): + pass
+ +
[docs] def insert_order(self, *args, **kwargs): + pass
+ +
[docs] def on_insert_order(self, *args, **kwargs): + pass
+ +
[docs] def cancel_order(self, *args, **kwargs): + pass
+ +
[docs] def on_cancel_order(self, *args, **kwargs): + pass
+ +
[docs] def query_order(self, *args, **kwargs): + pass
+ +
[docs] def on_query_order(self, *args, **kwargs): + pass
+ +
[docs] def query_trade(self, *args, **kwargs): + pass
+ +
[docs] def on_query_trade(self, *args, **kwargs): + pass
+ +
[docs] def query_position(self, *args, **kwargs): + pass
+ +
[docs] def on_query_position(self, *args, **kwargs): + pass
+ +
[docs] def query_assets(self, *args, **kwargs): + pass
+ +
[docs] def on_query_assets(self, *args, **kwargs): + pass
+ +
[docs] def query_data(self, *args, **kwargs): + pass
+ +
[docs] def on_query_data(self, *args, **kwargs): + pass
+ +
[docs] def on_error(self, *args, **kwargs): + pass
+ +
[docs] def on_order_event(self, *args, **kwargs): + pass
+ +
[docs] def on_trade_event(self, *args, **kwargs): + pass
+ +
[docs] def on_cancel_order_event(self, *args, **kwargs): + pass
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/shipaneBroker.html b/_build/html/_modules/QUANTAXIS/QAMarket/shipaneBroker.html new file mode 100644 index 000000000..99bb6117e --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/shipaneBroker.html @@ -0,0 +1,228 @@ + + + + + + + + QUANTAXIS.QAMarket.shipaneBroker — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.shipaneBroker

+# coding:utf-8
+
+
+import requests
+import json
+import urllib
+import base64
+import pandas as pd
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
+from QUANTAXIS.QAMarket.QABroker import QA_Broker
+try:
+    from pytdx.log import log
+except ImportError:
+    def log(x):
+        return None
+
+
+
[docs]class SPETradeApi(QA_Broker): + def __init__(self, endpoint="http://127.0.0.1:8888"): + + self._endpoint = endpoint + self._session = requests.Session() + +
[docs] def call(self, func, params=None): + + json_obj = { + "func": func + } + + if params is not None: + json_obj["params"] = params + + response = self._session.post(self._endpoint, json=json_obj) + + text = response.text + + return json.loads(text)
+ +
[docs] def data_to_df(self, result): + if 'data' in result: + data = result['data'] + return pd.DataFrame(data=data)
+ + #------ functions + +
[docs] def ping(self): + + return self.call("ping", {})
+ +
[docs] def logon(self, ip, port, version, yyb_id, account_id, trade_account, jy_passwrod, tx_password): + return self.call("logon", { + "ip": ip, + "port": port, + "version": version, + "yyb_id": yyb_id, + "account_no": account_id, + "trade_account": trade_account, + "jy_password": jy_passwrod, + "tx_password": tx_password + })
+ +
[docs] def logoff(self, client_id): + return self.call("logoff", { + "client_id": client_id + })
+ +
[docs] def query_data(self, client_id, category): + return self.call("query_data", { + "client_id": client_id, + "category": category + })
+ +
[docs] def send_order(self, client_id, category, price_type, gddm, zqdm, price, quantity): + return self.call("send_order", { + 'client_id': client_id, + 'category': category, + 'price_type': price_type, + 'gddm': gddm, + 'zqdm': zqdm, + 'price': price, + 'quantity': quantity + })
+ +
[docs] def cancel_order(self, client_id, exchange_id, hth): + return self.call("cancel_order", { + 'client_id': client_id, + 'exchange_id': exchange_id, + 'hth': hth + })
+ +
[docs] def get_quote(self, client_id, code): + return self.call("get_quote", { + 'client_id': client_id, + 'code': code, + })
+ +
[docs] def repay(self, client_id, amount): + return self.call("repay", { + 'client_id': client_id, + 'amount': amount + })
+ +
[docs] def receive_order(self, event): + """ + 0 限价委托; 上海限价委托 / 深圳限价委托 + 1 市价委托(深圳对方最优价格) + 2 市价委托(深圳本方最优价格) + 3 市价委托(深圳即时成交剩余撤销) + 4 市价委托(上海五档即成剩撤 / 深圳五档即成剩撤) + 5 市价委托(深圳全额成交或撤销) + 6 市价委托(上海五档即成转限价) + """ + return self.send_order(event.client_id, event.category, event.price_type, event.gddm, event.zqdm, event.price, event.quantity)
+ #client_id, category, price_type, gddm, zqdm, price, quantity + +
[docs] def run(self, event): + pass
+ + +if __name__ == "__main__": + import os + api = SPETradeApi(endpoint="http://10.11.5.175:10092/api", + enc_key=b"4f1cf3fec4c84c84", enc_iv=b"0c78abc083b011e7") + #api = SPETradeApi(endpoint="http://10.11.5.175:10092/api") + print("---Ping---") + result = api.ping() + print(result) + + print("---登入---") + acc = os.getenv("TDX_ACCOUNT", "") + password = os.getenv("TDX_PASS", "") + result = api.logon("202.108.253.186", 7708, + "8.23", 32, + acc, acc, password, "") + + print(result) + + if result["success"]: + client_id = result["data"]["client_id"] + + for i in (0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15): + print("---查询信息 cate=%d--" % i) + print(api.data_to_df(api.query_data(client_id, i))) + + print("---查询报价---") + print(api.data_to_df(api.get_quote(client_id, '600315'))) + + print("---登出---") + print(api.logoff(client_id)) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/shipaneclient.html b/_build/html/_modules/QUANTAXIS/QAMarket/shipaneclient.html new file mode 100644 index 000000000..24ae4174a --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/shipaneclient.html @@ -0,0 +1,361 @@ + + + + + + + + QUANTAXIS.QAMarket.shipaneclient — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.shipaneclient

+# -*- coding: utf-8 -*-
+
+import copy
+import datetime
+import re
+from enum import Enum
+from urllib.parse import urlencode
+
+import lxml.html
+import pandas as pd
+import requests
+import six
+import tushare as ts
+from lxml import etree
+from pandas.compat import StringIO
+from requests import Request
+from requests.auth import HTTPBasicAuth
+
+
+
[docs]class MediaType(Enum): + DEFAULT = 'application/json' + JOIN_QUANT = 'application/vnd.joinquant+json'
+ + +
[docs]class ConnectionMethod(Enum): + DIRECT = 'DIRECT' + PROXY = 'PROXY'
+ + +
[docs]class Client(object): + KEY_REGEX = r'key=([^&]*)' + + def __init__(self, logger=None, **kwargs): + if logger is not None: + self._logger = logger + else: + import logging + self._logger = logging.getLogger(__name__) + self._connection_method = ConnectionMethod[kwargs.pop('connection_method', 'DIRECT')] + if self._connection_method is ConnectionMethod.DIRECT: + self._host = kwargs.pop('host', 'localhost') + self._port = kwargs.pop('port', 8888) + else: + self._proxy_base_url = kwargs.pop('proxy_base_url') + self._proxy_username = kwargs.pop('proxy_username') + self._proxy_password = kwargs.pop('proxy_password') + self._instance_id = kwargs.pop('instance_id') + self._base_url = self.__create_base_url() + self._key = kwargs.pop('key', '') + self._client = kwargs.pop('client', '') + self._timeout = kwargs.pop('timeout', (5.0, 10.0)) + + @property + def host(self): + return self._host + + @host.setter + def host(self, value): + self._host = value + + @property + def port(self): + return self._port + + @port.setter + def port(self, value): + self._port = value + + @property + def key(self): + return self._key + + @key.setter + def key(self, value): + self._key = value + + @property + def timeout(self): + return self._timeout + + @timeout.setter + def timeout(self, value): + self._timeout = value + +
[docs] def get_statuses(self, timeout=None): + request = Request('GET', self.__create_url(None, 'statuses')) + self.__send_request(request, timeout)
+ +
[docs] def get_account(self, client=None, timeout=None): + request = Request('GET', self.__create_url(client, 'accounts')) + response = self.__send_request(request, timeout) + return response.json()
+ +
[docs] def get_positions(self, client=None, media_type=MediaType.DEFAULT, timeout=None): + request = Request('GET', self.__create_url(client, 'positions')) + request.headers['Accept'] = media_type.value + response = self.__send_request(request, timeout) + json = response.json() + if media_type == MediaType.DEFAULT: + sub_accounts = pd.DataFrame(json['subAccounts']).T + positions = pd.DataFrame(json['dataTable']['rows'], columns=json['dataTable']['columns']) + portfolio = {'sub_accounts': sub_accounts, 'positions': positions} + return portfolio + return json
+ +
[docs] def get_orders(self, client=None, status="", timeout=None): + request = Request('GET', self.__create_url(client, 'orders', status=status)) + response = self.__send_request(request, timeout) + json = response.json() + df = pd.DataFrame(json['dataTable']['rows'], columns=json['dataTable']['columns']) + return df
+ +
[docs] def buy(self, client=None, timeout=None, **kwargs): + kwargs['action'] = 'BUY' + return self.__execute(client, timeout, **kwargs)
+ +
[docs] def sell(self, client=None, timeout=None, **kwargs): + kwargs['action'] = 'SELL' + return self.__execute(client, timeout, **kwargs)
+ +
[docs] def ipo(self, client=None, timeout=None, **kwargs): + kwargs['action'] = 'IPO' + return self.__execute(client, timeout, **kwargs)
+ +
[docs] def execute(self, client=None, timeout=None, **kwargs): + return self.__execute(client, timeout, **kwargs)
+ +
[docs] def cancel(self, client=None, order_id=None, timeout=None): + request = Request('DELETE', self.__create_order_url(client, order_id)) + self.__send_request(request, timeout)
+ +
[docs] def cancel_all(self, client=None, timeout=None): + request = Request('DELETE', self.__create_order_url(client)) + self.__send_request(request, timeout)
+ +
[docs] def query(self, client=None, navigation=None, timeout=None): + request = Request('GET', self.__create_url(client, '', navigation=navigation)) + response = self.__send_request(request, timeout) + json = response.json() + df = pd.DataFrame(json['dataTable']['rows'], columns=json['dataTable']['columns']) + return df
+ +
[docs] def query_new_stocks(self): + return self.__query_new_stocks()
+ +
[docs] def query_convertible_bonds(self): + return self.__query_convertible_bonds()
+ +
[docs] def purchase_new_stocks(self, client=None, timeout=None): + today = datetime.datetime.strftime(datetime.datetime.today(), '%Y-%m-%d') + df = self.query_new_stocks() + df = df[(df.ipo_date == today)] + self._logger.info('今日有[{}]支可申购新股'.format(len(df))) + for index, row in df.iterrows(): + try: + order = { + 'symbol': row['xcode'], + 'price': row['price'], + 'amountProportion': 'ALL' + } + self._logger.info('申购新股:{}'.format(order)) + self.ipo(client, timeout, **order) + except Exception as e: + self._logger.error( + '客户端[{}]申购新股[{}({})]失败\n{}'.format((client or self._client), row['name'], row['code'], e))
+ +
[docs] def purchase_convertible_bonds(self, client=None, timeout=None): + today = datetime.datetime.strftime(datetime.datetime.today(), '%Y-%m-%d') + df = self.query_convertible_bonds() + df = df[(df.ipo_date == today)] + self._logger.info('今日有[{}]支可申购转债'.format(len(df))) + for index, row in df.iterrows(): + try: + order = { + 'symbol': row['xcode'], + 'price': 100, + 'amountProportion': 'ALL' + } + self._logger.info('申购转债:{}'.format(order)) + self.buy(client, timeout, **order) + except Exception as e: + self._logger.error( + '客户端[{}]申购转债[{}({})]失败\n{}'.format((client or self._client), row['bname'], row['xcode'], e))
+ +
[docs] def create_adjustment(self, client=None, request_json=None, timeout=None): + request = Request('POST', self.__create_url(client, 'adjustments'), json=request_json) + request.headers['Content-Type'] = MediaType.JOIN_QUANT.value + response = self.__send_request(request, timeout) + json = response.json() + return json
+ +
[docs] def start_clients(self, timeout=None): + request = Request('PUT', self.__create_url(None, 'clients')) + self.__send_request(request, timeout)
+ +
[docs] def shutdown_clients(self, timeout=None): + request = Request('DELETE', self.__create_url(None, 'clients')) + self.__send_request(request, timeout)
+ + def __execute(self, client=None, timeout=None, **kwargs): + if not kwargs.get('type'): + kwargs['type'] = 'LIMIT' + request = Request('POST', self.__create_order_url(client), json=kwargs) + response = self.__send_request(request) + return response.json() + + def __query_new_stocks(self): + DATA_URL = 'http://vip.stock.finance.sina.com.cn/corp/view/vRPD_NewStockIssue.php?page=1&cngem=0&orderBy=NetDate&orderType=desc' + html = lxml.html.parse(DATA_URL) + res = html.xpath('//table[@id=\"NewStockTable\"]/tr') + if six.PY2: + sarr = [etree.tostring(node) for node in res] + else: + sarr = [etree.tostring(node).decode('utf-8') for node in res] + sarr = ''.join(sarr) + sarr = sarr.replace('<font color="red">*</font>', '') + sarr = '<table>%s</table>' % sarr + df = pd.read_html(StringIO(sarr), skiprows=[0, 1])[0] + df = df.select(lambda x: x in [0, 1, 2, 3, 7], axis=1) + df.columns = ['code', 'xcode', 'name', 'ipo_date', 'price'] + df['code'] = df['code'].map(lambda x: str(x).zfill(6)) + df['xcode'] = df['xcode'].map(lambda x: str(x).zfill(6)) + return df + + def __query_convertible_bonds(self): + df = ts.new_cbonds() + return df + + def __create_order_url(self, client=None, order_id=None, **params): + return self.__create_url(client, 'orders', order_id, **params) + + def __create_url(self, client, resource, resource_id=None, **params): + all_params = copy.deepcopy(params) + all_params.update(client=(client or self._client)) + all_params.update(key=(self._key or '')) + if resource_id is None: + path = '/{}'.format(resource) + else: + path = '/{}/{}'.format(resource, resource_id) + url = '{}{}?{}'.format(self._base_url, path, urlencode(all_params)) + return url + + def __create_base_url(self): + if self._connection_method is ConnectionMethod.DIRECT: + return 'http://{}:{}'.format(self._host, self._port) + else: + return self._proxy_base_url + + def __send_request(self, request, timeout=None): + if self._connection_method is ConnectionMethod.PROXY: + request.auth = HTTPBasicAuth(self._proxy_username, self._proxy_password) + request.headers['X-Instance-ID'] = self._instance_id + prepared_request = request.prepare() + self.__log_request(prepared_request) + with requests.sessions.Session() as session: + response = session.send(prepared_request, timeout=(timeout or self._timeout)) + self.__log_response(response) + response.raise_for_status() + return response + + def __log_request(self, prepared_request): + url = self.__eliminate_privacy(prepared_request.path_url) + if prepared_request.body is None: + self._logger.info('Request:\n{} {}'.format(prepared_request.method, url)) + else: + self._logger.info('Request:\n{} {}\n{}'.format(prepared_request.method, url, prepared_request.body)) + + def __log_response(self, response): + message = u'Response:\n{} {}\n{}'.format(response.status_code, response.reason, response.text) + if response.status_code == 200: + self._logger.info(message) + else: + self._logger.error(message) + + @classmethod + def __eliminate_privacy(cls, url): + match = re.search(cls.KEY_REGEX, url) + if match is None: + return url + key = match.group(1) + masked_key = '*' * len(key) + url = re.sub(cls.KEY_REGEX, "key={}".format(masked_key), url) + return url
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAMarket/tdxRealBroker.html b/_build/html/_modules/QUANTAXIS/QAMarket/tdxRealBroker.html new file mode 100644 index 000000000..dcab1ab8e --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAMarket/tdxRealBroker.html @@ -0,0 +1,305 @@ + + + + + + + + QUANTAXIS.QAMarket.tdxRealBroker — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAMarket.tdxRealBroker

+# coding:utf-8
+
+
+import requests
+import json
+import urllib
+import base64
+import pandas as pd
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
+from QUANTAXIS.QAMarket.QABroker import QA_Broker
+try:
+    from pytdx.log import log
+except ImportError:
+    def log(x): 
+        return None
+
+
+
[docs]class TdxTradeApiParams: + + """ + 0 资金 + 1 股份 + 2 当日委托 + 3 当日成交 + 4 可撤单 + 5 股东代码 + 6 融资余额 + 7 融券余额 + 8 可融证券 + 9 + 10 + 11 + 12 可申购新股查询 + 13 新股申购额度查询 + 14 配号查询 + 15 中签查询 + """ + QUERY_CATEGORY_CASH = 0 + QUERY_CATEGORY_STOCKS = 1 + QUERY_CATEGORY_ORDER_OF_TODAY = 2 + QUERY_CATEGORY_DEAL_OF_TODAY = 3 + QUERY_CATEGORY_CANCELABLE_ORDER = 4 + QUERY_CATEGORY_SHAREHOLDERS_CODE = 5 + QUERY_CATEGORY_BALANCE_OF_MARGIN_LOAN = 6 + QUERY_CATEGORY_BALANCE_OF_STOCK_LOAN = 7 + QUERY_CATEGORY_OPERABLE_MARGIN_SOTCK = 8 + + QUERY_CATEGORY_NEW_STOCKS = 12 + QUERY_CATEGORY_NEW_STOCKS_QUOTA = 13 + QUERY_CATEGORY_NEW_STOCK_NUMBER = 14 + QUERY_CATEGORY_NEW_STOCK_HIT = 15
+ + +
[docs]class TDXBroker(QA_Broker): + def __init__(self, endpoint="http://127.0.0.1:10092/api", encoding="utf-8", enc_key=None, enc_iv=None): + + self._endpoint = endpoint + self._encoding = "utf-8" + if enc_key == None or enc_iv == None: + self._transport_enc = False + self._transport_enc_key = None + self._transport_enc_iv = None + self._cipher = None + else: + self._transport_enc = True + self._transport_enc_key = enc_key + self._transport_enc_iv = enc_iv + backend = default_backend() + self._cipher = Cipher(algorithms.AES( + enc_key), modes.CBC(enc_iv), backend=backend) + + self._session = requests.Session() + +
[docs] def call(self, func, params=None): + + json_obj = { + "func": func + } + + if params is not None: + json_obj["params"] = params + + if self._transport_enc: + data_to_send = self.encrypt(json_obj) + response = self._session.post(self._endpoint, data=data_to_send) + else: + response = self._session.post(self._endpoint, json=json_obj) + response.encoding = self._encoding + text = response.text + + if self._transport_enc: + decoded_text = self.decrypt(text) + log.debug(decoded_text) + return json.loads(decoded_text) + else: + return json.loads(text)
+ +
[docs] def encrypt(self, source_obj): + encrypter = self._cipher.encryptor() + source = json.dumps(source_obj) + source = source.encode(self._encoding) + need_to_padding = 16 - (len(source) % 16) + if need_to_padding > 0: + source = source + b'\x00' * need_to_padding + enc_data = encrypter.update(source) + encrypter.finalize() + b64_enc_data = base64.encodebytes(enc_data) + return urllib.parse.quote(b64_enc_data)
+ +
[docs] def decrypt(self, source): + decrypter = self._cipher.decryptor() + source = urllib.parse.unquote(source) + source = base64.decodebytes(source.encode("utf-8")) + data_bytes = decrypter.update(source) + decrypter.finalize() + return data_bytes.rstrip(b"\x00").decode(self._encoding)
+ +
[docs] def data_to_df(self, result): + if 'data' in result: + data = result['data'] + return pd.DataFrame(data=data)
+ + #------ functions + +
[docs] def ping(self): + + return self.call("ping", {})
+ +
[docs] def logon(self, ip, port, version, yyb_id, account_id, trade_account, jy_passwrod, tx_password): + return self.call("logon", { + "ip": ip, + "port": port, + "version": version, + "yyb_id": yyb_id, + "account_no": account_id, + "trade_account": trade_account, + "jy_password": jy_passwrod, + "tx_password": tx_password + })
+ +
[docs] def logoff(self, client_id): + return self.call("logoff", { + "client_id": client_id + })
+ +
[docs] def query_data(self, client_id, category): + return self.call("query_data", { + "client_id": client_id, + "category": category + })
+ +
[docs] def send_order(self, client_id, category, price_type, gddm, zqdm, price, quantity): + return self.call("send_order", { + 'client_id': client_id, + 'category': category, + 'price_type': price_type, + 'gddm': gddm, + 'zqdm': zqdm, + 'price': price, + 'quantity': quantity + })
+ +
[docs] def cancel_order(self, client_id, exchange_id, hth): + return self.call("cancel_order", { + 'client_id': client_id, + 'exchange_id': exchange_id, + 'hth': hth + })
+ +
[docs] def get_quote(self, client_id, code): + return self.call("get_quote", { + 'client_id': client_id, + 'code': code, + })
+ +
[docs] def repay(self, client_id, amount): + return self.call("repay", { + 'client_id': client_id, + 'amount': amount + })
+ +
[docs] def receive_order(self, event): + """ + 0 限价委托; 上海限价委托 / 深圳限价委托 + 1 市价委托(深圳对方最优价格) + 2 市价委托(深圳本方最优价格) + 3 市价委托(深圳即时成交剩余撤销) + 4 市价委托(上海五档即成剩撤 / 深圳五档即成剩撤) + 5 市价委托(深圳全额成交或撤销) + 6 市价委托(上海五档即成转限价) + """ + return self.send_order(event.client_id, event.category, event.price_type,event.gddm,event.zqdm,event.price,event.quantity)
+ #client_id, category, price_type, gddm, zqdm, price, quantity + +
[docs] def run(self,event): + pass
+ + +if __name__ == "__main__": + import os + api = TDXBroker(endpoint="http://10.11.5.175:10092/api", + enc_key=b"4f1cf3fec4c84c84", enc_iv=b"0c78abc083b011e7") + #api = TdxTradeApi(endpoint="http://10.11.5.175:10092/api") + print("---Ping---") + result = api.ping() + print(result) + + print("---登入---") + acc = os.getenv("TDX_ACCOUNT", "") + password = os.getenv("TDX_PASS", "") + result = api.logon("202.108.253.186", 7708, + "8.23", 32, + acc, acc, password, "") + + print(result) + + if result["success"]: + client_id = result["data"]["client_id"] + + for i in (0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15): + print("---查询信息 cate=%d--" % i) + print(api.data_to_df(api.query_data(client_id, i))) + + print("---查询报价---") + print(api.data_to_df(api.get_quote(client_id, '600315'))) + + print("---登出---") + print(api.logoff(client_id)) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QASU/main.html b/_build/html/_modules/QUANTAXIS/QASU/main.html new file mode 100644 index 000000000..cb47d1884 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QASU/main.html @@ -0,0 +1,282 @@ + + + + + + + + QUANTAXIS.QASU.main — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QASU.main

+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from QUANTAXIS.QASU import save_tdx as stdx
+from QUANTAXIS.QASU import save_tdx_file as tdx_file
+from QUANTAXIS.QASU import save_tushare as sts
+from QUANTAXIS.QAUtil import DATABASE
+
+
+
+
+
[docs]def QA_SU_save_stock_info(engine, client=DATABASE): + """save stock info + + Arguments: + engine {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + engine = select_save_engine(engine) + engine.QA_SU_save_stock_info(client=client)
+ + +
[docs]def QA_SU_save_stock_list(engine, client=DATABASE): + """save stock_list + + Arguments: + engine {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + engine = select_save_engine(engine) + engine.QA_SU_save_stock_list(client=client)
+ + +
[docs]def QA_SU_save_stock_day(engine, client=DATABASE): + """save stock_day + + Arguments: + engine {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + engine = select_save_engine(engine) + engine.QA_SU_save_stock_day(client=client)
+ + +
[docs]def QA_SU_save_stock_min(engine, client=DATABASE): + """save stock_min + + Arguments: + engine {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + engine = select_save_engine(engine) + engine.QA_SU_save_stock_min(client=client)
+ + +
[docs]def QA_SU_save_index_day(engine, client=DATABASE): + """save index_day + + Arguments: + engine {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + engine = select_save_engine(engine) + engine.QA_SU_save_index_day(client=client)
+ + +
[docs]def QA_SU_save_index_min(engine, client=DATABASE): + """save index_min + + Arguments: + engine {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + engine = select_save_engine(engine) + engine.QA_SU_save_index_min(client=client)
+ + +
[docs]def QA_SU_save_etf_day(engine, client=DATABASE): + """save etf_day + + Arguments: + engine {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + engine = select_save_engine(engine) + engine.QA_SU_save_etf_day(client=client)
+ + +
[docs]def QA_SU_save_etf_min(engine, client=DATABASE): + """save etf_min + + Arguments: + engine {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + engine = select_save_engine(engine) + engine.QA_SU_save_etf_min(client=client)
+ + +
[docs]def QA_SU_save_stock_xdxr(engine, client=DATABASE): + """save stock_xdxr + + Arguments: + engine {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + engine = select_save_engine(engine) + engine.QA_SU_save_stock_xdxr(client=client)
+ +
[docs]def QA_SU_save_stock_block(engine, client=DATABASE): + """save stock_block + + Arguments: + engine {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + engine = select_save_engine(engine) + engine.QA_SU_save_stock_block(client=client)
+ + + +
[docs]def select_save_engine(engine): + """select save_engine + + Arguments: + engine {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + + if engine in ['tushare', 'ts', 'Tushare']: + return sts + elif engine in ['tdx']: + return stdx
+ + + + +
[docs]def QA_SU_save_stock_min_5(file_dir, client=DATABASE): + """save stock_min5 + + Arguments: + file_dir {[type]} -- [description] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + + Returns: + [type] -- [description] + """ + + return tdx_file.QA_save_tdx_to_mongo(file_dir, client)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QASU/save_account.html b/_build/html/_modules/QUANTAXIS/QASU/save_account.html new file mode 100644 index 000000000..ec7187747 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QASU/save_account.html @@ -0,0 +1,137 @@ + + + + + + + + QUANTAXIS.QASU.save_account — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QASU.save_account

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from QUANTAXIS.QAUtil import DATABASE
+
+"""对于账户的增删改查(QAACCOUNT/QAUSER/QAPORTFOLIO)
+"""
+
+
+
[docs]def save_account(message, collection=DATABASE.account): + """save account + + Arguments: + message {[type]} -- [description] + + Keyword Arguments: + collection {[type]} -- [description] (default: {DATABASE}) + """ + + collection.save(message)
+ + + +
[docs]def update_account(mes, collection=DATABASE.account): + """update the account with account message + + Arguments: + mes {[type]} -- [description] + + Keyword Arguments: + collection {[type]} -- [description] (default: {DATABASE}) + """ + + collection.find_one_and_update({'account_cookie': mes['account_cookie']})
+ + +
[docs]def save_riskanalysis(message,collection=DATABASE.risk): + collection.save(message)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QASU/save_backtest.html b/_build/html/_modules/QUANTAXIS/QASU/save_backtest.html new file mode 100644 index 000000000..81896c589 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QASU/save_backtest.html @@ -0,0 +1,164 @@ + + + + + + + + QUANTAXIS.QASU.save_backtest — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QASU.save_backtest

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import csv
+import os
+
+from QUANTAXIS.QAUtil import QA_util_log_expection
+
+
+"""适用于老代码的回测
+现在已经废弃
+"""
+
+
+
[docs]def QA_SU_save_account_message(message, client): + coll = client.quantaxis.backtest_history + try: + coll.insert({ + 'time_stamp': message['body']['date_stamp'], + "cookie": message['header']['cookie'], + 'user': message['header']['session']['user'], + 'strategy': message['header']['session']['strategy'], + 'cash': message['body']['account']['cash'], + 'hold': message['body']['account']['hold'], + 'history': message['body']['account']['history'], + 'assets': message['body']['account']['assets'], + 'detail': message['body']['account']['detail'] + }) + except: + QA_util_log_expection('error in saving backtest account')
+ + +
[docs]def QA_SU_save_backtest_message(message, client): + __coll = client.quantaxis.backtest_info + + __coll.insert(message)
+ + +
[docs]def QA_SU_save_account_to_csv(message, path=os.getcwd()): + + __file_name_1 = '{}backtest-ca&history-{}.csv'.format( + path, str(message['header']['cookie'])) + with open(__file_name_1, 'w', newline='') as C: + csvwriter = csv.writer(C) + csvwriter.writerow(['date', 'code', 'price', 'towards', 'amount', + 'order_id', 'trade_id', 'commission_fee', 'cash', 'assets']) + for i in range(0, max(len(message['body']['account']['cash']), len(message['body']['account']['assets']))): + try: + message['body']['account']['history'][i].append( + message['body']['account']['cash'][i]) + message['body']['account']['history'][i].append( + message['body']['account']['assets'][i]) + csvwriter.writerow(message['body']['account']['history'][i]) + except: + pass
+ + +
[docs]def QA_SU_save_pnl_to_csv(detail, cookie): + __file_name_2 = 'backtest-pnl--' + \ + str(cookie) + '.csv' + with open(__file_name_2, 'w', newline='') as E: + csvwriter_1 = csv.writer(E) + csvwriter_1.writerow(detail.columns) + for item in detail: + csvwriter_1.writerow(item)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QASU/save_local.html b/_build/html/_modules/QUANTAXIS/QASU/save_local.html new file mode 100644 index 000000000..777de6cbd --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QASU/save_local.html @@ -0,0 +1,127 @@ + + + + + + + + QUANTAXIS.QASU.save_local — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QASU.save_local

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import os
+import sys
+
+#QUNATAXIS_DIR='{}{}{}'.format( os.path.expanduser('~'), os.sep, '.quantaxis')
+
+path = os.path.expanduser('~')
+qa_path = '{}{}{}'.format(path, os.sep, '.quantaxis')
+setting_path = '{}{}{}'.format(qa_path, os.sep, '.setting')
+cache_path = '{}{}{}'.format(qa_path, os.sep, '.cache')
+
+
+
[docs]def make_cache(): + pass
+ + +
[docs]def make_dir(): + path = os.path.expanduser('~') + qa_path = '{}{}{}'.format(path, os.sep, '.quantaxis') + os.makedirs(qa_path, exist_ok=True) + setting_path = '{}{}{}'.format(qa_path, os.sep, '.setting') + cache_path = '{}{}{}'.format(qa_path, os.sep, '.cache') + downloads_path = '{}{}{}'.format(qa_path, os.sep, 'downloads') + os.makedirs(setting_path, exist_ok=True) + os.makedirs(cache_path, exist_ok=True) + os.makedirs(downloads_path, exist_ok=True)
+ +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QASU/save_tdx.html b/_build/html/_modules/QUANTAXIS/QASU/save_tdx.html new file mode 100644 index 000000000..9906364ae --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QASU/save_tdx.html @@ -0,0 +1,648 @@ + + + + + + + + QUANTAXIS.QASU.save_tdx — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QASU.save_tdx

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import concurrent
+import datetime
+from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
+
+import pandas as pd
+import pymongo
+
+from QUANTAXIS.QAFetch import QA_fetch_get_stock_block
+from QUANTAXIS.QAFetch.QATdx import (QA_fetch_get_index_day,
+                                     QA_fetch_get_index_min,
+                                     QA_fetch_get_stock_day,
+                                     QA_fetch_get_stock_info,
+                                     QA_fetch_get_stock_list,
+                                     QA_fetch_get_stock_min,
+                                     QA_fetch_get_stock_transaction,
+                                     QA_fetch_get_stock_xdxr, select_best_ip)
+from QUANTAXIS.QAFetch.QATushare import QA_fetch_get_stock_time_to_market
+from QUANTAXIS.QAUtil import (DATABASE, QA_util_get_next_day,
+                              QA_util_get_real_date, QA_util_log_info,
+                              QA_util_to_json_from_pandas, trade_date_sse)
+
+# ip=select_best_ip()
+
+
+
[docs]def now_time(): + return str(QA_util_get_real_date(str(datetime.date.today() - datetime.timedelta(days=1)), trade_date_sse, -1)) + \ + ' 17:00:00' if datetime.datetime.now().hour < 15 else str(QA_util_get_real_date( + str(datetime.date.today()), trade_date_sse, -1)) + ' 15:00:00'
+ + +
[docs]def QA_SU_save_stock_day(client=DATABASE): + """save stock_day + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + stock_list = QA_fetch_get_stock_time_to_market() + coll_stock_day = client.stock_day + coll_stock_day.create_index( + [("code", pymongo.ASCENDING), ("date_stamp", pymongo.ASCENDING)]) + err = [] + + def __saving_work(code, coll_stock_day): + try: + QA_util_log_info( + '##JOB01 Now Saving STOCK_DAY==== %s' % (str(code))) + + ref = coll_stock_day.find({'code': str(code)[0:6]}) + end_date = str(now_time())[0:10] + if ref.count() > 0: + # 加入这个判断的原因是因为如果股票是刚上市的 数据库会没有数据 所以会有负索引问题出现 + + start_date = ref[ref.count() - 1]['date'] + + QA_util_log_info(' UPDATE_STOCK_DAY \n Trying updating %s from %s to %s' % + (code, start_date, end_date)) + if start_date != end_date: + coll_stock_day.insert_many( + QA_util_to_json_from_pandas( + QA_fetch_get_stock_day(str(code), QA_util_get_next_day(start_date), end_date, '00'))) + else: + start_date = '1990-01-01' + QA_util_log_info(' UPDATE_STOCK_DAY \n Trying updating %s from %s to %s' % + (code, start_date, end_date)) + if start_date != end_date: + coll_stock_day.insert_many( + QA_util_to_json_from_pandas( + QA_fetch_get_stock_day(str(code), start_date, end_date, '00'))) + except: + err.append(str(code)) + for item in range(len(stock_list)): + QA_util_log_info('The %s of Total %s' % + (item, len(stock_list))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(item / len(stock_list) * 100))[0:4] + '%') + + __saving_work(stock_list.index[item], coll_stock_day) + if len(err) < 1: + QA_util_log_info('SUCCESS') + else: + QA_util_log_info('ERROR CODE \n ') + QA_util_log_info(err)
+ + +
[docs]def QA_SU_save_stock_xdxr(client=DATABASE): + """[summary] + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + client.drop_collection('stock_xdxr') + stock_list = QA_fetch_get_stock_time_to_market() + coll = client.stock_xdxr + coll.create_index([('code', pymongo.ASCENDING), + ('date', pymongo.ASCENDING)]) + err = [] + + def __saving_work(code, coll): + QA_util_log_info('##JOB02 Now Saving XDXR INFO ==== %s' % (str(code))) + try: + coll.insert_many( + QA_util_to_json_from_pandas( + QA_fetch_get_stock_xdxr(str(code)))) + + except: + + err.append(str(code)) + for i_ in range(len(stock_list)): + QA_util_log_info('The %s of Total %s' % (i_, len(stock_list))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(i_ / len(stock_list) * 100))[0:4] + '%') + __saving_work(stock_list.index[i_], coll) + if len(err) < 1: + QA_util_log_info('SUCCESS') + else: + + try_code = err + err = [] + QA_util_log_info('Try to get stock xdxr info in erro list! \n') + for i__ in range(len(try_code)): + QA_util_log_info('The %s of Total %s' % (i__, len(try_code))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(i__ / len(try_code) * 100))[0:4] + '%') + __saving_work(try_code[i__], coll) + if len(err) < 1: + QA_util_log_info('SUCCESS') + else: + QA_util_log_info('ERROR CODE \n ') + QA_util_log_info(err)
+ + +
[docs]def QA_SU_save_stock_min(client=DATABASE): + """save stock_min + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + stock_list = QA_fetch_get_stock_time_to_market() + coll = client.stock_min + coll.create_index([('code', pymongo.ASCENDING), ('time_stamp', + pymongo.ASCENDING), ('date_stamp', pymongo.ASCENDING)]) + err = [] + + def __saving_work(code, coll): + QA_util_log_info('##JOB03 Now Saving STOCK_MIN ==== %s' % (str(code))) + try: + for type in ['1min', '5min', '15min', '30min', '60min']: + ref_ = coll.find( + {'code': str(code)[0:6], 'type': type}) + end_time = str(now_time())[0:19] + if ref_.count() > 0: + start_time = ref_[ref_.count() - 1]['datetime'] + + QA_util_log_info( + '##JOB03.%s Now Saving %s from %s to %s ==%s ' % (['1min', '5min', '15min', '30min', '60min'].index(type), str(code), start_time, end_time, type)) + if start_time != end_time: + __data = QA_fetch_get_stock_min( + str(code), start_time, end_time, type) + if len(__data) > 1: + coll.insert_many( + QA_util_to_json_from_pandas(__data)[1::]) + else: + start_time = '2015-01-01' + QA_util_log_info( + '##JOB03.%s Now Saving %s from %s to %s ==%s ' % (['1min', '5min', '15min', '30min', '60min'].index(type), str(code), start_time, end_time, type)) + if start_time != end_time: + __data = QA_fetch_get_stock_min( + str(code), start_time, end_time, type) + if len(__data) > 1: + coll.insert_many( + QA_util_to_json_from_pandas(__data)) + except Exception as e: + QA_util_log_info(e) + + err.append(code) + + executor = ThreadPoolExecutor(max_workers=4) + #executor.map((__saving_work, stock_list.index[i_], coll),URLS) + res = {executor.submit( + __saving_work, stock_list.index[i_], coll) for i_ in range(len(stock_list))} + count = 0 + for i_ in concurrent.futures.as_completed(res): + QA_util_log_info('The %s of Total %s' % (count, len(stock_list))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(count / len(stock_list) * 100))[0:4] + '%') + count = count + 1 + if len(err) < 1: + QA_util_log_info('SUCCESS') + else: + QA_util_log_info('ERROR CODE \n ') + QA_util_log_info(err)
+ + +
[docs]def QA_SU_save_index_day(client=DATABASE): + """save index_day + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + __index_list = QA_fetch_get_stock_list('index') + coll = client.index_day + coll.create_index([('code', pymongo.ASCENDING), + ('date_stamp', pymongo.ASCENDING)]) + err = [] + + def __saving_work(code, coll): + + try: + ref_ = coll.find({'code': str(code)[0:6]}) + end_time = str(now_time())[0:10] + if ref_.count() > 0: + start_time = ref_[ref_.count() - 1]['date'] + + QA_util_log_info('##JOB04 Now Saving INDEX_DAY==== \n Trying updating %s from %s to %s' % + (code, start_time, end_time)) + + if start_time != end_time: + coll.insert_many( + QA_util_to_json_from_pandas( + QA_fetch_get_index_day(str(code), QA_util_get_next_day(start_time), end_time))) + else: + start_time = '1990-01-01' + QA_util_log_info('##JOB04 Now Saving INDEX_DAY==== \n Trying updating %s from %s to %s' % + (code, start_time, end_time)) + coll.insert_many( + QA_util_to_json_from_pandas( + QA_fetch_get_index_day(str(code), start_time, end_time))) + except Exception as e: + QA_util_log_info(e) + err.append(str(code)) + for i_ in range(len(__index_list)): + #__saving_work('000001') + QA_util_log_info('The %s of Total %s' % (i_, len(__index_list))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(i_ / len(__index_list) * 100))[0:4] + '%') + __saving_work(__index_list.index[i_][0], coll) + if len(err) < 1: + QA_util_log_info('SUCCESS') + else: + QA_util_log_info('ERROR CODE \n ') + QA_util_log_info(err)
+ + +
[docs]def QA_SU_save_index_min(client=DATABASE): + """save index_min + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + __index_list = QA_fetch_get_stock_list('index') + coll = client.index_min + coll.create_index([('code', pymongo.ASCENDING), ('time_stamp', + pymongo.ASCENDING), ('date_stamp', pymongo.ASCENDING)]) + err = [] + + def __saving_work(code, coll): + + QA_util_log_info('##JOB05 Now Saving Index_MIN ==== %s' % (str(code))) + try: + + for type in ['1min', '5min', '15min', '30min', '60min']: + ref_ = coll.find( + {'code': str(code)[0:6], 'type': type}) + end_time = str(now_time())[0:19] + if ref_.count() > 0: + start_time = ref_[ref_.count() - 1]['datetime'] + + QA_util_log_info( + '##JOB05.%s Now Saving %s from %s to %s ==%s ' % (['1min', '5min', '15min', '30min', '60min'].index(type), str(code), start_time, end_time, type)) + if start_time != end_time: + __data = QA_fetch_get_index_min( + str(code), start_time, end_time, type) + if len(__data) > 1: + coll.insert_many( + QA_util_to_json_from_pandas(__data[1::])) + else: + start_time = '2015-01-01' + QA_util_log_info( + '##JOB05.%s Now Saving %s from %s to %s ==%s ' % (['1min', '5min', '15min', '30min', '60min'].index(type), str(code), start_time, end_time, type)) + if start_time != end_time: + __data = QA_fetch_get_index_min( + str(code), start_time, end_time, type) + if len(__data) > 1: + coll.insert_many( + QA_util_to_json_from_pandas(__data)) + except: + err.append(code) + + executor = ThreadPoolExecutor(max_workers=4) + + res = {executor.submit( + __saving_work, __index_list.index[i_][0], coll) for i_ in range(len(__index_list))} # multi index ./. + count = 0 + for i_ in concurrent.futures.as_completed(res): + QA_util_log_info('The %s of Total %s' % (count, len(__index_list))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(count / len(__index_list) * 100))[0:4] + '%') + count = count + 1 + if len(err) < 1: + QA_util_log_info('SUCCESS') + else: + QA_util_log_info('ERROR CODE \n ') + QA_util_log_info(err)
+ + +
[docs]def QA_SU_save_etf_day(client=DATABASE): + """save etf_day + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + __index_list = QA_fetch_get_stock_list('etf') + coll = client.index_day + coll.create_index([('code', pymongo.ASCENDING), + ('date_stamp', pymongo.ASCENDING)]) + err = [] + + def __saving_work(code, coll): + + try: + + ref_ = coll.find({'code': str(code)[0:6]}) + end_time = str(now_time())[0:10] + if ref_.count() > 0: + start_time = ref_[ref_.count() - 1]['date'] + + QA_util_log_info('##JOB06 Now Saving ETF_DAY==== \n Trying updating %s from %s to %s' % + (code, start_time, end_time)) + + if start_time != end_time: + coll.insert_many( + QA_util_to_json_from_pandas( + QA_fetch_get_index_day(str(code), QA_util_get_next_day(start_time), end_time))) + else: + start_time = '1990-01-01' + QA_util_log_info('##JOB06 Now Saving ETF_DAY==== \n Trying updating %s from %s to %s' % + (code, start_time, end_time)) + + if start_time != end_time: + coll.insert_many( + QA_util_to_json_from_pandas( + QA_fetch_get_index_day(str(code), start_time, end_time))) + except: + err.append(str(code)) + for i_ in range(len(__index_list)): + #__saving_work('000001') + QA_util_log_info('The %s of Total %s' % (i_, len(__index_list))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(i_ / len(__index_list) * 100))[0:4] + '%') + __saving_work(__index_list.index[i_][0], coll) + if len(err) < 1: + QA_util_log_info('SUCCESS') + else: + QA_util_log_info('ERROR CODE \n ') + QA_util_log_info(err)
+ + +
[docs]def QA_SU_save_etf_min(client=DATABASE): + """save etf_min + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + __index_list = QA_fetch_get_stock_list('etf') + coll = client.index_min + coll.create_index([('code', pymongo.ASCENDING), ('time_stamp', + pymongo.ASCENDING), ('date_stamp', pymongo.ASCENDING)]) + err = [] + + def __saving_work(code, coll): + + QA_util_log_info('##JOB07 Now Saving ETF_MIN ==== %s' % (str(code))) + try: + + for type in ['1min', '5min', '15min', '30min', '60min']: + ref_ = coll.find( + {'code': str(code)[0:6], 'type': type}) + end_time = str(now_time())[0:19] + if ref_.count() > 0: + start_time = ref_[ref_.count() - 1]['datetime'] + + QA_util_log_info( + '##JOB07.%s Now Saving %s from %s to %s ==%s ' % (['1min', '5min', '15min', '30min', '60min'].index(type), str(code), start_time, end_time, type)) + if start_time != end_time: + __data = QA_fetch_get_index_min( + str(code), start_time, end_time, type) + if len(__data) > 1: + coll.insert_many( + QA_util_to_json_from_pandas(__data[1::])) + else: + start_time = '2015-01-01' + QA_util_log_info( + '##JOB07.%s Now Saving %s from %s to %s ==%s ' % (['1min', '5min', '15min', '30min', '60min'].index(type), str(code), start_time, end_time, type)) + if start_time != end_time: + __data = QA_fetch_get_index_min( + str(code), start_time, end_time, type) + if len(__data) > 1: + coll.insert_many( + QA_util_to_json_from_pandas(__data)) + except: + err.append(code) + + executor = ThreadPoolExecutor(max_workers=4) + + res = {executor.submit( + __saving_work, __index_list.index[i_][0], coll) for i_ in range(len(__index_list))} # multi index ./. + count = 0 + for i_ in concurrent.futures.as_completed(res): + QA_util_log_info('The %s of Total %s' % (count, len(__index_list))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(count / len(__index_list) * 100))[0:4] + '%') + count = count + 1 + if len(err) < 1: + QA_util_log_info('SUCCESS') + else: + QA_util_log_info('ERROR CODE \n ') + QA_util_log_info(err)
+ + +
[docs]def QA_SU_save_stock_list(client=DATABASE): + """save stock_list + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + client.drop_collection('stock_list') + coll = client.stock_list + coll.create_index('code') + err = [] + + try: + QA_util_log_info('##JOB08 Now Saving STOCK_LIST ====') + coll.insert_many(QA_util_to_json_from_pandas( + QA_fetch_get_stock_list())) + except: + pass
+ + +
[docs]def QA_SU_save_stock_block(client=DATABASE): + """save stock_block + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + client.drop_collection('stock_block') + coll = client.stock_block + coll.create_index('code') + err = [] + try: + QA_util_log_info('##JOB09 Now Saving STOCK_BlOCK ====') + coll.insert_many(QA_util_to_json_from_pandas( + QA_fetch_get_stock_block('tdx'))) + coll.insert_many(QA_util_to_json_from_pandas( + QA_fetch_get_stock_block('ths'))) + except: + pass
+ + +
[docs]def QA_SU_save_stock_info(client=DATABASE): + """save stock_info + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + client.drop_collection('stock_info') + stock_list = QA_fetch_get_stock_time_to_market() + coll = client.stock_info + coll.create_index('code') + err = [] + + def __saving_work(code, coll): + QA_util_log_info( + '##JOB010 Now Saving STOCK INFO ==== %s' % (str(code))) + try: + coll.insert_many( + QA_util_to_json_from_pandas( + QA_fetch_get_stock_info(str(code)))) + + except: + err.append(str(code)) + for i_ in range(len(stock_list)): + #__saving_work('000001') + QA_util_log_info('The %s of Total %s' % (i_, len(stock_list))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(i_ / len(stock_list) * 100))[0:4] + '%') + __saving_work(stock_list.index[i_], coll) + if len(err) < 1: + QA_util_log_info('SUCCESS') + else: + QA_util_log_info('ERROR CODE \n ') + QA_util_log_info(err)
+ + +
[docs]def QA_SU_save_stock_transaction(client=DATABASE): + """save stock_transaction + + Keyword Arguments: + client {[type]} -- [description] (default: {DATABASE}) + """ + + stock_list = QA_fetch_get_stock_time_to_market() + coll = client.stock_transaction + coll.create_index('code') + err = [] + + def __saving_work(code): + QA_util_log_info( + '##JOB10 Now Saving STOCK_TRANSACTION ==== %s' % (str(code))) + try: + coll.insert_many( + QA_util_to_json_from_pandas( + QA_fetch_get_stock_transaction(str(code), str(stock_list[code]), str(now_time())[0:10]))) + except: + err.append(str(code)) + for i_ in range(len(stock_list)): + #__saving_work('000001') + QA_util_log_info('The %s of Total %s' % (i_, len(stock_list))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(i_ / len(stock_list) * 100))[0:4] + '%') + __saving_work(stock_list.index[i_]) + if len(err) < 1: + QA_util_log_info('SUCCESS') + else: + QA_util_log_info('ERROR CODE \n ') + QA_util_log_info(err)
+ + +if __name__ == '__main__': + # QA_SU_save_stock_day() + # QA_SU_save_stock_xdxr() + # QA_SU_save_stock_min() + # QA_SU_save_stock_transaction() + # QA_SU_save_index_day() + # QA_SU_save_stock_list() + # QA_SU_save_index_min() + pass +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QASU/save_tdx_file.html b/_build/html/_modules/QUANTAXIS/QASU/save_tdx_file.html new file mode 100644 index 000000000..1c4342c4d --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QASU/save_tdx_file.html @@ -0,0 +1,153 @@ + + + + + + + + QUANTAXIS.QASU.save_tdx_file — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QASU.save_tdx_file

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import json
+import os
+
+from pytdx.reader import TdxMinBarReader
+
+from QUANTAXIS.QAUtil import (DATABASE, QA_util_date_stamp, QA_util_log_info,
+                              QA_util_time_stamp)
+
+
+
[docs]def QA_save_tdx_to_mongo(file_dir, client=DATABASE): + """save file + + Arguments: + file_dir {str:direction} -- 文件的地址 + + Keyword Arguments: + client {Mongodb:Connection} -- Mongo Connection (default: {DATABASE}) + """ + + reader = TdxMinBarReader() + __coll = client.stock_min_five + for a, v, files in os.walk(file_dir): + + for file in files: + + if (str(file)[0:2] == 'sh' and int(str(file)[2]) == 6) or \ + (str(file)[0:2] == 'sz' and int(str(file)[2]) == 0) or \ + (str(file)[0:2] == 'sz' and int(str(file)[2]) == 3): + + QA_util_log_info('Now_saving ' + str(file) + [2:8] + '\'s 5 min tick') + fname = file_dir + os.sep + file + df = reader.get_df(fname) + df['code'] = str(file)[2:8] + df['market'] = str(file)[0:2] + df['datetime'] = [str(x) for x in list(df.index)] + df['date'] = [str(x)[0:10] for x in list(df.index)] + df['time_stamp'] = df['datetime'].apply( + lambda x: QA_util_time_stamp(x)) + df['date_stamp'] = df['date'].apply( + lambda x: QA_util_date_stamp(x)) + data_json = json.loads(df.to_json(orient='records')) + __coll.insert_many(data_json)
+ + +if __name__ == '__main__': + file_dir = ['C:\\users\\yutiansut\\desktop\\sh5fz', + 'C:\\users\\yutiansut\\desktop\\sz5fz'] + for item in file_dir: + QA_save_tdx_to_mongo(item) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QASU/save_tushare.html b/_build/html/_modules/QUANTAXIS/QASU/save_tushare.html new file mode 100644 index 000000000..152567f3a --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QASU/save_tushare.html @@ -0,0 +1,221 @@ + + + + + + + + QUANTAXIS.QASU.save_tushare — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QASU.save_tushare

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import datetime
+import json
+import re
+import time
+
+import tushare as ts
+
+from QUANTAXIS.QAFetch.QATushare import (QA_fetch_get_stock_day,
+                                         QA_fetch_get_stock_info,
+                                         QA_fetch_get_stock_list,
+                                         QA_fetch_get_trade_date)
+from QUANTAXIS.QAUtil import (QA_util_date_stamp, QA_util_log_info,
+                              QA_util_time_stamp, QA_util_to_json_from_pandas,
+                              trade_date_sse)
+from QUANTAXIS.QAUtil.QASetting import DATABASE
+
+
+
[docs]def QA_save_stock_day_all(client=DATABASE): + df = ts.get_stock_basics() + __coll = client.stock_day + __coll.ensure_index('code') + + def saving_work(i): + QA_util_log_info('Now Saving ==== %s' % (i)) + try: + data_json = QA_fetch_get_stock_day( + i, start='1990-01-01') + + __coll.insert_many(data_json) + except: + QA_util_log_info('error in saving ==== %s' % str(i)) + + for i_ in range(len(df.index)): + QA_util_log_info('The %s of Total %s' % (i_, len(df.index))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(i_ / len(df.index) * 100))[0:4] + '%') + saving_work(df.index[i_]) + + saving_work('hs300') + saving_work('sz50')
+ + +
[docs]def QA_SU_save_stock_list(client=DATABASE): + data = QA_fetch_get_stock_list() + date = str(datetime.date.today()) + date_stamp = QA_util_date_stamp(date) + coll = client.stock_list + coll.insert({'date': date, 'date_stamp': date_stamp, + 'stock': {'code': data}})
+ + +
[docs]def QA_SU_save_trade_date_all(client=DATABASE): + data = QA_fetch_get_trade_date('', '') + coll = client.trade_date + coll.insert_many(data)
+ + +
[docs]def QA_SU_save_stock_info(client=DATABASE): + data = QA_fetch_get_stock_info('all') + coll = client.stock_info + coll.insert_many(data)
+ + +
[docs]def QA_save_stock_day_all_bfq(client=DATABASE): + df = ts.get_stock_basics() + + __coll = client.stock_day_bfq + __coll.ensure_index('code') + + def saving_work(i): + QA_util_log_info('Now Saving ==== %s' % (i)) + try: + data_json = QA_fetch_get_stock_day( + i, start='1990-01-01', if_fq='00') + + __coll.insert_many(data_json) + except: + QA_util_log_info('error in saving ==== %s' % str(i)) + + for i_ in range(len(df.index)): + QA_util_log_info('The %s of Total %s' % (i_, len(df.index))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(i_ / len(df.index) * 100))[0:4] + '%') + saving_work(df.index[i_]) + + saving_work('hs300') + saving_work('sz50')
+ + +
[docs]def QA_save_stock_day_with_fqfactor(client=DATABASE): + df = ts.get_stock_basics() + + __coll = client.stock_day + __coll.ensure_index('code') + + def saving_work(i): + QA_util_log_info('Now Saving ==== %s' % (i)) + try: + data_hfq = QA_fetch_get_stock_day( + i, start='1990-01-01', if_fq='02', type_='pd') + data_json = QA_util_to_json_from_pandas(data_hfq) + __coll.insert_many(data_json) + except: + QA_util_log_info('error in saving ==== %s' % str(i)) + for i_ in range(len(df.index)): + QA_util_log_info('The %s of Total %s' % (i_, len(df.index))) + QA_util_log_info('DOWNLOAD PROGRESS %s ' % str( + float(i_ / len(df.index) * 100))[0:4] + '%') + saving_work(df.index[i_]) + + saving_work('hs300') + saving_work('sz50') + + QA_util_log_info('Saving Process has been done !') + return 0
+ + +if __name__ == '__main__': + QA_save_stock_day_with_fqfactor() +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QASU/user.html b/_build/html/_modules/QUANTAXIS/QASU/user.html new file mode 100644 index 000000000..1447c32e6 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QASU/user.html @@ -0,0 +1,126 @@ + + + + + + + + QUANTAXIS.QASU.user — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QASU.user

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from QUANTAXIS.QAUtil.QALogs import QA_util_log_info
+
+
+
[docs]def QA_user_sign_in(name, password, client): + coll = client.quantaxis.user_list + cursor=coll.find({'username': name, 'password': password}) + if (cursor.count() > 0): + QA_util_log_info('success login! your username is:' + str(name)) + return cursor + else: + QA_util_log_info('Failed to login,please check your password ') + return None
+ + +
[docs]def QA_user_sign_up(name, password, client): + coll = client.quantaxis.user_list + if (coll.find({'username': name}).count() > 0): + QA_util_log_info('user name is already exist') + return False + else: + coll.insert({'username': name, 'password': password}) + QA_util_log_info('Success sign in! please login ') + return True
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QABar.html b/_build/html/_modules/QUANTAXIS/QAUtil/QABar.html new file mode 100644 index 000000000..1acbddb98 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QABar.html @@ -0,0 +1,230 @@ + + + + + + + + QUANTAXIS.QAUtil.QABar — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QABar

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import datetime
+import math
+
+import numpy as np
+import pandas as pd
+
+from QUANTAXIS.QAUtil.QADate_trade import (QA_util_date_gap,
+                                           QA_util_get_real_datelist,
+                                           QA_util_get_trade_range,
+                                           QA_util_if_trade, trade_date_sse)
+
+
+
[docs]def QA_util_make_min_index(day, type_='1min'): + """创建股票分钟线的index + + Arguments: + day {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + if QA_util_if_trade(day) is True: + return pd.date_range(str(day) + ' 09:30:00', str(day) + ' 11:30:00', freq=type_, closed='right').append( + pd.date_range(str(day) + ' 13:00:00', str(day) + ' 15:00:00', freq=type_, closed='right')) + else: + return pd.DataFrame(['No trade'])
+ + +
[docs]def QA_util_make_hour_index(day, type_='1h'): + """创建股票的小时线的index + + Arguments: + day {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + if QA_util_if_trade(day) is True: + return pd.date_range(str(day) + ' 09:30:00', str(day) + ' 11:30:00', freq=type_, closed='right').append( + pd.date_range(str(day) + ' 13:00:00', str(day) + ' 15:00:00', freq=type_, closed='right')) + else: + return pd.DataFrame(['No trade'])
+ + +
[docs]def QA_util_time_gap(time, gap, methods, type_): + '分钟线回测的时候的gap' + min_len = int(240 / int(str(type_).split('min')[0])) + day_gap = math.ceil(gap / min_len) + + if methods in ['>', 'gt']: + data = pd.concat([pd.DataFrame(QA_util_make_min_index(day, type_)) for day in trade_date_sse[trade_date_sse.index(str(datetime.datetime.strptime( + time, '%Y-%m-%d %H:%M:%S').date())):trade_date_sse.index(str(datetime.datetime.strptime(time, '%Y-%m-%d %H:%M:%S').date())) + day_gap + 1]]).reset_index() + return np.asarray(data[data[0] > time].head(gap)[0].apply(lambda x: str(x))).tolist()[-1] + elif methods in ['>=', 'gte']: + data = pd.concat([pd.DataFrame(QA_util_make_min_index(day, type_)) for day in trade_date_sse[trade_date_sse.index(str(datetime.datetime.strptime( + time, '%Y-%m-%d %H:%M:%S').date())):trade_date_sse.index(str(datetime.datetime.strptime(time, '%Y-%m-%d %H:%M:%S').date())) + day_gap + 1]]).reset_index() + + return np.asarray(data[data[0] >= time].head(gap)[0].apply(lambda x: str(x))).tolist()[-1] + elif methods in ['<', 'lt']: + data = pd.concat([pd.DataFrame(QA_util_make_min_index(day, type_)) for day in trade_date_sse[trade_date_sse.index(str(datetime.datetime.strptime( + time, '%Y-%m-%d %H:%M:%S').date())) - day_gap:trade_date_sse.index(str(datetime.datetime.strptime(time, '%Y-%m-%d %H:%M:%S').date())) + 1]]).reset_index() + + return np.asarray(data[data[0] < time].tail(gap)[0].apply(lambda x: str(x))).tolist()[0] + elif methods in ['<=', 'lte']: + data = pd.concat([pd.DataFrame(QA_util_make_min_index(day, type_)) for day in trade_date_sse[trade_date_sse.index(str(datetime.datetime.strptime( + time, '%Y-%m-%d %H:%M:%S').date())) - day_gap:trade_date_sse.index(str(datetime.datetime.strptime(time, '%Y-%m-%d %H:%M:%S').date())) + 1]]).reset_index() + + return np.asarray(data[data[0] <= time].tail(gap)[0].apply(lambda x: str(x))).tolist()[0] + elif methods in ['==', '=', 'eq']: + return time
+ + +""" +期货交易所交易时间: + +(一)大连、上海、郑州交易所 + +集合竞价申报时间:08:55—08:59 +集合竞价撮合时间:08:59—09:00 +正常开盘交易时间:09:00-11:30 (小节休息10:15-10:30) +13:30-15:00 + +提示:客户下单时间为集合竞价时间和正常交易时间。在8:59—9:00竞价结束时间和交易所小节休息时间(上午10:15-10:30)下单,交易系统将不接受指令,并视之为废单。(时间以交易所时钟报时为准) + +(二)上期所夜盘 + +集合竞价申报时间:20:55—20:59 +集合竞价撮合时间:20:59—21:00 +正常开盘交易时间:21:00-02:30 (黄金、白银) +21:00-01:00 (铜、铝、铅、锌、镍、锡) +21:00-23:00(螺纹钢、热轧卷板、石油沥青、天然橡胶) + +提示:法定节假日的前一日没有夜盘交易。 + +(三)大商所夜盘 + +集合竞价申报时间:20:55—20:59 +集合竞价撮合时间:20:59—21:00 +正常开盘交易时间:21:00—23:30 (豆一、豆二、豆油、豆粕、焦煤、焦炭、棕榈油、铁矿石) + +提示:法定节假日的前一日没有夜盘交易。 + +(四)郑商所夜盘 + +集合竞价申报时间:20:55—20:59 +集合竞价撮合时间:20:59—21:00 +正常开盘交易时间:21:00-23:30 (白糖、棉花、菜粕、甲醇、PTA、菜籽油、玻璃、动力煤) + +提示:法定节假日的前一日没有夜盘交易。 + +(五)中金所 + +股指:集合竞价时间:9:25—9:30 +正常开盘交易时间:9:30-11:30(第一节);13:00-15:00(第二节) + +国债: +集合竞价时间:9:10-9:15 +正常开盘交易时间:9:15-11:30(第一节);13:00-15:15(第二节) +最后交易日交易时间:9:15-11:30 + + +""" + + +if __name__ == '__main__': + pass +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QACfg.html b/_build/html/_modules/QUANTAXIS/QAUtil/QACfg.html new file mode 100644 index 000000000..d0098ac57 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QACfg.html @@ -0,0 +1,132 @@ + + + + + + + + QUANTAXIS.QAUtil.QACfg — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QACfg

+#coding :utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from configparser import ConfigParser
+
+
+
[docs]def QA_util_cfg_initial(CONFIG_FILE): + """[summary] + + Arguments: + CONFIG_FILE {[type]} -- [description] + """ + + pass
+ + +
[docs]def QA_util_get_cfg(__file_path, __file_name): + """[summary] + + Arguments: + __file_path {[type]} -- [description] + __file_name {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + __setting_file = ConfigParser() + try: + return __setting_file.read(__file_path + __file_name) + except: + return 'wrong'
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QACode.html b/_build/html/_modules/QUANTAXIS/QAUtil/QACode.html new file mode 100644 index 000000000..035f41e99 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QACode.html @@ -0,0 +1,123 @@ + + + + + + + + QUANTAXIS.QAUtil.QACode — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QACode

+#coding :utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""
+该文件主要是负责一些对于code名称的处理
+"""
+
+
+
[docs]def QA_util_code_tostr(code): + """ + 将所有沪深股票从数字转化到6位的代码 + + 因为有时候在csv等转换的时候,诸如 000001的股票会变成office强制转化成数字1 + + """ + return '00000{}'.format(str(code)[0:6])[-6:]
+ + +
[docs]def QA_util_code_tolist(code): + if isinstance(code, str): + return [QA_util_code_tostr(code)] + + elif isinstance(code, list): + return [QA_util_code_tostr(item) for item in code]
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QACsv.html b/_build/html/_modules/QUANTAXIS/QAUtil/QACsv.html new file mode 100644 index 000000000..0ca630ee5 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QACsv.html @@ -0,0 +1,141 @@ + + + + + + + + QUANTAXIS.QAUtil.QACsv — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QACsv

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import csv
+
+
+
[docs]def QA_util_save_csv(data, name, column=None, location=None): + # 重写了一下保存的模式 + # 增加了对于可迭代对象的判断 2017/8/10 + """ + QA_util_save_csv(data,name,column,location) + + 将list保存成csv + 第一个参数是list + 第二个参数是要保存的名字 + 第三个参数是行的名称(可选) + 第四个是保存位置(可选) + + @yutiansut + """ + assert isinstance(data, list) + if location is None: + path = './' + str(name) + '.csv' + else: + path = location + str(name) + '.csv' + with open(path, 'w', newline='') as f: + csvwriter = csv.writer(f) + if column is None: + pass + else: + csvwriter.writerow(column) + + for item in data: + + if isinstance(item, list): + csvwriter.writerow(item) + else: + csvwriter.writerow([item])
+ + +if __name__ == '__main__': + QA_util_save_csv(['a', 'v', 2, 3], 'test') + QA_util_save_csv([['a', 'v', 2, 3]], 'test2') +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QADate.html b/_build/html/_modules/QUANTAXIS/QAUtil/QADate.html new file mode 100644 index 000000000..037d9956d --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QADate.html @@ -0,0 +1,440 @@ + + + + + + + + QUANTAXIS.QAUtil.QADate — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QADate

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import datetime
+import threading
+import time
+
+from QUANTAXIS.QAUtil.QALogs import QA_util_log_info
+
+
+
[docs]def QA_util_time_now(): + """[summary] + + Returns: + [type] -- [description] + """ + + return datetime.datetime.now()
+ + +
[docs]def QA_util_date_today(): + """[summary] + + Returns: + [type] -- [description] + """ + + return datetime.date.today()
+ + +
[docs]def QA_util_date_str2int(date): + """[summary] + + Arguments: + date {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + return int(str(date)[0:4] + str(date)[5:7] + str(date)[8:10])
+ + +
[docs]def QA_util_date_int2str(date): + """[summary] + + Arguments: + date {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + return str(str(date)[0:4] + '-' + str(date)[4:6] + '-' + str(date)[6:8])
+ + +
[docs]def QA_util_to_datetime(time): + """[summary] + + Arguments: + time {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + if len(str(time)) == 10: + _time = '{} 00:00:00'.format(time) + elif len(str(time)) == 19: + _time = str(time) + else: + QA_util_log_info('WRONG DATETIME FORMAT {}'.format(time)) + return datetime.datetime.strptime(_time, '%Y-%m-%d %H:%M:%S')
+ + +
[docs]def QA_util_date_stamp(date): + """[summary] + + Arguments: + date {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + datestr = str(date)[0:10] + date = time.mktime(time.strptime(datestr, '%Y-%m-%d')) + return date
+ + +
[docs]def QA_util_time_stamp(time_): + ''' + 数据格式最好是%Y-%m-%d %H:%M:%S 中间要有空格 + ''' + if len(str(time_)) == 10: + # yyyy-mm-dd格式 + return time.mktime(time.strptime(time_, '%Y-%m-%d')) + elif len(str(time_)) == 16: + # yyyy-mm-dd hh:mm格式 + return time.mktime(time.strptime(time_, '%Y-%m-%d %H:%M')) + else: + timestr = str(time_)[0:19] + return time.mktime(time.strptime(timestr, '%Y-%m-%d %H:%M:%S'))
+ + +
[docs]def QA_util_stamp2datetime(timestamp): + """ + datestamp转datetime + + pandas转出来的timestamp是13位整数 要/1000 + + """ + try: + return datetime.datetime.fromtimestamp(timestamp) + except Exception as e: + return datetime.datetime.fromtimestamp(timestamp / 1000)
+ + +
[docs]def QA_util_ms_stamp(ms): + """[summary] + + Arguments: + ms {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + return ms
+ + +
[docs]def QA_util_date_valid(date): + """[summary] + + Arguments: + date {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + try: + + time.strptime(date, "%Y-%m-%d") + return True + except: + return False
+ + +
[docs]def QA_util_realtime(strtime, client): + """[summary] + + Arguments: + strtime {[type]} -- [description] + client {[type]} -- [description] + """ + + time_stamp = QA_util_date_stamp(strtime) + coll = client.quantaxis.trade_date + temp_str = coll.find_one({'date_stamp': {"$gte": time_stamp}}) + time_real = temp_str['date'] + time_id = temp_str['num'] + return {'time_real': time_real, 'id': time_id}
+ + +
[docs]def QA_util_id2date(idx, client): + """[summary] + + Arguments: + idx {[type]} -- [description] + client {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + coll = client.quantaxis.trade_date + temp_str = coll.find_one({'num': idx}) + return temp_str['date']
+ + +
[docs]def QA_util_is_trade(date, code, client): + """判断是否是交易日 + + Arguments: + date {[type]} -- [description] + code {[type]} -- [description] + client {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + coll = client.quantaxis.stock_day + date = str(date)[0:10] + is_trade = coll.find_one({'code': code, 'date': date}) + try: + len(is_trade) + return True + except: + return False
+ + +
[docs]def QA_util_get_date_index(date, trade_list): + """返回在trade_list中的index位置 + + Arguments: + date {[type]} -- [description] + trade_list {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + return trade_list.index(date)
+ + +
[docs]def QA_util_get_index_date(id, trade_list): + return trade_list[id]
+ + +
[docs]def QA_util_select_hours(time=None, gt=None, lt=None, gte=None, lte=None): + 'quantaxis的时间选择函数,约定时间的范围,比如早上9点到11点' + if time is None: + __realtime = datetime.datetime.now() + else: + __realtime = time + + fun_list = [] + if gt != None: + fun_list.append('>') + if lt != None: + fun_list.append('<') + if gte != None: + fun_list.append('>=') + if lte != None: + fun_list.append('<=') + + assert len(fun_list) > 0 + true_list = [] + try: + for item in fun_list: + if item == '>': + if __realtime.strftime('%H') > gt: + true_list.append(0) + else: + true_list.append(1) + elif item == '<': + if __realtime.strftime('%H') < lt: + true_list.append(0) + else: + true_list.append(1) + elif item == '>=': + if __realtime.strftime('%H') >= gte: + true_list.append(0) + else: + true_list.append(1) + elif item == '<=': + if __realtime.strftime('%H') <= lte: + true_list.append(0) + else: + true_list.append(1) + + except: + return Exception + if sum(true_list) > 0: + return False + else: + return True
+ + +
[docs]def QA_util_select_min(time=None, gt=None, lt=None, gte=None, lte=None): + 'quantaxis的时间选择函数,约定时间的范围,比如30分到59分' + if time is None: + __realtime = datetime.datetime.now() + else: + __realtime = time + + fun_list = [] + if gt != None: + fun_list.append('>') + if lt != None: + fun_list.append('<') + if gte != None: + fun_list.append('>=') + if lte != None: + fun_list.append('<=') + + assert len(fun_list) > 0 + true_list = [] + try: + for item in fun_list: + if item == '>': + if __realtime.strftime('%M') > gt: + true_list.append(0) + else: + true_list.append(1) + elif item == '<': + if __realtime.strftime('%M') < lt: + true_list.append(0) + else: + true_list.append(1) + elif item == '>=': + if __realtime.strftime('%M') >= gte: + true_list.append(0) + else: + true_list.append(1) + elif item == '<=': + if __realtime.strftime('%M') <= lte: + true_list.append(0) + else: + true_list.append(1) + + except: + return Exception + if sum(true_list) > 0: + return False + else: + return True
+ + +
[docs]def QA_util_time_delay(time_=0): + '这是一个用于复用/比如说@装饰器的延时函数\ + 使用threading里面的延时,为了是不阻塞进程\ + 有时候,同时发进去两个函数,第一个函数需要延时\ + 第二个不需要的话,用sleep就会阻塞掉第二个进程' + def _exec(func): + threading.Timer(time_, func) + return _exec
+ + +
[docs]def QA_util_calc_time(func, *args, **kwargs): + '耗时长度的装饰器' + _time = datetime.datetime.now() + func(*args, **kwargs) + print(datetime.datetime.now() - _time)
+ # return datetime.datetime.now() - _time + + +if __name__ == '__main__': + print(QA_util_time_stamp('2017-01-01 10:25:08')) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QADate_trade.html b/_build/html/_modules/QUANTAXIS/QAUtil/QADate_trade.html new file mode 100644 index 000000000..484580f09 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QADate_trade.html @@ -0,0 +1,242 @@ + + + + + + + + QUANTAXIS.QAUtil.QADate_trade — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QADate_trade

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import datetime
+
+from QUANTAXIS.QAUtil.QAParameter import MARKET_TYPE
+
+trade_date_sse = ['1990-12-19', '1990-12-20', '1990-12-21', '1990-12-24', '1990-12-25', '1990-12-26', '1990-12-27', '1990-12-28', '1990-12-31', '1991-01-02', '1991-01-03', '1991-01-04', '1991-01-07', '1991-01-08', '1991-01-09', '1991-01-10', '1991-01-11', '1991-01-14', '1991-01-15', '1991-01-16', '1991-01-17', '1991-01-18', '1991-01-21', '1991-01-22', '1991-01-23', '1991-01-24', '1991-01-25', '1991-01-28', '1991-01-29', '1991-01-30', '1991-01-31', '1991-02-01', '1991-02-04', '1991-02-05', '1991-02-06', '1991-02-07', '1991-02-08', '1991-02-11', '1991-02-12', '1991-02-13', '1991-02-14', '1991-02-19', '1991-02-20', '1991-02-21', '1991-02-22', '1991-02-25', '1991-02-26', '1991-02-27', '1991-02-28', '1991-03-01', '1991-03-04', '1991-03-05', '1991-03-06', '1991-03-07', '1991-03-08', '1991-03-11', '1991-03-12', '1991-03-13', '1991-03-14', '1991-03-15', '1991-03-18', '1991-03-19', '1991-03-20', '1991-03-21', '1991-03-22', '1991-03-25', '1991-03-26', '1991-03-27', '1991-03-28', '1991-03-29', '1991-04-01', '1991-04-02', '1991-04-03', '1991-04-04', '1991-04-05', '1991-04-08', '1991-04-09', '1991-04-10', '1991-04-11', '1991-04-12', '1991-04-15', '1991-04-16', '1991-04-17', '1991-04-18', '1991-04-19', '1991-04-22', '1991-04-23', '1991-04-24', '1991-04-25', '1991-04-26', '1991-04-29', '1991-04-30', '1991-05-02', '1991-05-03', '1991-05-06', '1991-05-07', '1991-05-08', '1991-05-09', '1991-05-10', '1991-05-13', '1991-05-14', '1991-05-15', '1991-05-16', '1991-05-17', '1991-05-20', '1991-05-21', '1991-05-22', '1991-05-23', '1991-05-24', '1991-05-27', '1991-05-28', '1991-05-29', '1991-05-30', '1991-05-31', '1991-06-03', '1991-06-04', '1991-06-05', '1991-06-06', '1991-06-07', '1991-06-10', '1991-06-11', '1991-06-12', '1991-06-13', '1991-06-14', '1991-06-17', '1991-06-18', '1991-06-19', '1991-06-20', '1991-06-21', '1991-06-24', '1991-06-25', '1991-06-26', '1991-06-27', '1991-06-28', '1991-07-01', '1991-07-02', '1991-07-03', '1991-07-04', '1991-07-05', '1991-07-08', '1991-07-09', '1991-07-10', '1991-07-11', '1991-07-12', '1991-07-15', '1991-07-16', '1991-07-17', '1991-07-18', '1991-07-19', '1991-07-22', '1991-07-23', '1991-07-24', '1991-07-25', '1991-07-26', '1991-07-29', '1991-07-30', '1991-07-31', '1991-08-01', '1991-08-02', '1991-08-05', '1991-08-06', '1991-08-07', '1991-08-08', '1991-08-09', '1991-08-12', '1991-08-13', '1991-08-14', '1991-08-15', '1991-08-16', '1991-08-19', '1991-08-20', '1991-08-21', '1991-08-22', '1991-08-23', '1991-08-26', '1991-08-27', '1991-08-28', '1991-08-29', '1991-08-30', '1991-09-02', '1991-09-03', '1991-09-04', '1991-09-05', '1991-09-06', '1991-09-09', '1991-09-10', '1991-09-11', '1991-09-12', '1991-09-13', '1991-09-16', '1991-09-17', '1991-09-18', '1991-09-19', '1991-09-20', '1991-09-23', '1991-09-24', '1991-09-25', '1991-09-26', '1991-09-27', '1991-09-30', '1991-10-03', '1991-10-04', '1991-10-07', '1991-10-08', '1991-10-09', '1991-10-10', '1991-10-11', '1991-10-14', '1991-10-15', '1991-10-16', '1991-10-17', '1991-10-18', '1991-10-21', '1991-10-22', '1991-10-23', '1991-10-24', '1991-10-25', '1991-10-28', '1991-10-29', '1991-10-30', '1991-10-31', '1991-11-01', '1991-11-04', '1991-11-05', '1991-11-06', '1991-11-07', '1991-11-08', '1991-11-11', '1991-11-12', '1991-11-13', '1991-11-14', '1991-11-15', '1991-11-18', '1991-11-19', '1991-11-20', '1991-11-21', '1991-11-22', '1991-11-25', '1991-11-26', '1991-11-27', '1991-11-28', '1991-11-29', '1991-12-02', '1991-12-03', '1991-12-04', '1991-12-05', '1991-12-06', '1991-12-09', '1991-12-10', '1991-12-11', '1991-12-12', '1991-12-13', '1991-12-16', '1991-12-17', '1991-12-18', '1991-12-19', '1991-12-20', '1991-12-23', '1991-12-24', '1991-12-25', '1991-12-26', '1991-12-27', '1991-12-30', '1991-12-31', '1992-01-02', '1992-01-03', '1992-01-06', '1992-01-07', '1992-01-08', '1992-01-09', '1992-01-10', '1992-01-13', '1992-01-14', '1992-01-15', '1992-01-16', '1992-01-17', '1992-01-20', '1992-01-21', '1992-01-22', '1992-01-23', '1992-01-24', '1992-01-27', '1992-01-28', '1992-01-29', '1992-01-30', '1992-01-31', '1992-02-03', '1992-02-07', '1992-02-10', '1992-02-11', '1992-02-12', '1992-02-13', '1992-02-14', '1992-02-17', '1992-02-18', '1992-02-19', '1992-02-20', '1992-02-21', '1992-02-24', '1992-02-25', '1992-02-26', '1992-02-27', '1992-02-28', '1992-03-02', '1992-03-03', '1992-03-04', '1992-03-05', '1992-03-06', '1992-03-09', '1992-03-10', '1992-03-11', '1992-03-12', '1992-03-13', '1992-03-16', '1992-03-17', '1992-03-18', '1992-03-19', '1992-03-20', '1992-03-23', '1992-03-24', '1992-03-25', '1992-03-26', '1992-03-27', '1992-03-30', '1992-03-31', '1992-04-01', '1992-04-02', '1992-04-03', '1992-04-06', '1992-04-07', '1992-04-08', '1992-04-09', '1992-04-10', '1992-04-13', '1992-04-14', '1992-04-15', '1992-04-16', '1992-04-17', '1992-04-20', '1992-04-21', '1992-04-22', '1992-04-23', '1992-04-24', '1992-04-27', '1992-04-28', '1992-04-29', '1992-04-30', '1992-05-04', '1992-05-05', '1992-05-06', '1992-05-07', '1992-05-08', '1992-05-11', '1992-05-12', '1992-05-13', '1992-05-14', '1992-05-15', '1992-05-18', '1992-05-19', '1992-05-20', '1992-05-21', '1992-05-22', '1992-05-25', '1992-05-26', '1992-05-27', '1992-05-28', '1992-05-29', '1992-06-01', '1992-06-02', '1992-06-03', '1992-06-04', '1992-06-05', '1992-06-08', '1992-06-09', '1992-06-10', '1992-06-11', '1992-06-12', '1992-06-15', '1992-06-16', '1992-06-17', '1992-06-18', '1992-06-19', '1992-06-22', '1992-06-23', '1992-06-24', '1992-06-25', '1992-06-26', '1992-06-29', '1992-06-30', '1992-07-01', '1992-07-02', '1992-07-03', '1992-07-06', '1992-07-07', '1992-07-08', '1992-07-09', '1992-07-10', '1992-07-13', '1992-07-14', '1992-07-15', '1992-07-16', '1992-07-17', '1992-07-20', '1992-07-21', '1992-07-22', '1992-07-23', '1992-07-24', '1992-07-27', '1992-07-28', '1992-07-29', '1992-07-30', '1992-07-31', '1992-08-03', '1992-08-04', '1992-08-05', '1992-08-06', '1992-08-07', '1992-08-10', '1992-08-11', '1992-08-12', '1992-08-13', '1992-08-14', '1992-08-17', '1992-08-18', '1992-08-19', '1992-08-20', '1992-08-21', '1992-08-24', '1992-08-25', '1992-08-26', '1992-08-27', '1992-08-28', '1992-08-31', '1992-09-01', '1992-09-02', '1992-09-03', '1992-09-04', '1992-09-07', '1992-09-08', '1992-09-09', '1992-09-10', '1992-09-11', '1992-09-14', '1992-09-15', '1992-09-16', '1992-09-17', '1992-09-18', '1992-09-21', '1992-09-22', '1992-09-23', '1992-09-24', '1992-09-25', '1992-09-28', '1992-09-29', '1992-09-30', '1992-10-05', '1992-10-06', '1992-10-07', '1992-10-08', '1992-10-09', '1992-10-12', '1992-10-13', '1992-10-14', '1992-10-15', '1992-10-16', '1992-10-19', '1992-10-20', '1992-10-21', '1992-10-22', '1992-10-23', '1992-10-26', '1992-10-27', '1992-10-28', '1992-10-29', '1992-10-30', '1992-11-02', '1992-11-03', '1992-11-04', '1992-11-05', '1992-11-06', '1992-11-09', '1992-11-10', '1992-11-11', '1992-11-12', '1992-11-13', '1992-11-16', '1992-11-17', '1992-11-18', '1992-11-19', '1992-11-20', '1992-11-23', '1992-11-24', '1992-11-25', '1992-11-26', '1992-11-27', '1992-11-30', '1992-12-01', '1992-12-02', '1992-12-03', '1992-12-04', '1992-12-07', '1992-12-08', '1992-12-09', '1992-12-10', '1992-12-11', '1992-12-14', '1992-12-15', '1992-12-16', '1992-12-17', '1992-12-18', '1992-12-21', '1992-12-22', '1992-12-23', '1992-12-24', '1992-12-25', '1992-12-28', '1992-12-29', '1992-12-30', '1992-12-31', '1993-01-04', '1993-01-05', '1993-01-06', '1993-01-07', '1993-01-08', '1993-01-11', '1993-01-12', '1993-01-13', '1993-01-14', '1993-01-15', '1993-01-18', '1993-01-19', '1993-01-20', '1993-01-21', '1993-01-22', '1993-01-27', '1993-01-28', '1993-01-29', '1993-02-01', '1993-02-02', '1993-02-03', '1993-02-04', '1993-02-05', '1993-02-08', '1993-02-09', '1993-02-10', '1993-02-11', '1993-02-12', '1993-02-15', '1993-02-16', '1993-02-17', '1993-02-18', '1993-02-19', '1993-02-22', '1993-02-23', '1993-02-24', '1993-02-25', '1993-02-26', '1993-03-01', '1993-03-02', '1993-03-03', '1993-03-04', '1993-03-05', '1993-03-08', '1993-03-09', '1993-03-10', '1993-03-11', '1993-03-12', '1993-03-15', '1993-03-16', '1993-03-17', '1993-03-18', '1993-03-19', '1993-03-22', '1993-03-23', '1993-03-24', '1993-03-25', '1993-03-26', '1993-03-29', '1993-03-30', '1993-03-31', '1993-04-01', '1993-04-02', '1993-04-05', '1993-04-06', '1993-04-07', '1993-04-08', '1993-04-09', '1993-04-12', '1993-04-13', '1993-04-14', '1993-04-15', '1993-04-16', '1993-04-19', '1993-04-20', '1993-04-21', '1993-04-22', '1993-04-23', '1993-04-26', '1993-04-27', '1993-04-28', '1993-04-29', '1993-04-30', '1993-05-03', '1993-05-04', '1993-05-05', '1993-05-06', '1993-05-07', '1993-05-10', '1993-05-11', '1993-05-12', '1993-05-13', '1993-05-14', '1993-05-17', '1993-05-18', '1993-05-19', '1993-05-20', '1993-05-21', '1993-05-24', '1993-05-25', '1993-05-26', '1993-05-27', '1993-05-28', '1993-05-31', '1993-06-01', '1993-06-02', '1993-06-03', '1993-06-04', '1993-06-07', '1993-06-08', '1993-06-09', '1993-06-10', '1993-06-11', '1993-06-14', '1993-06-15', '1993-06-16', '1993-06-17', '1993-06-18', '1993-06-21', '1993-06-22', '1993-06-23', '1993-06-24', '1993-06-25', '1993-06-28', '1993-06-29', '1993-06-30', '1993-07-01', '1993-07-02', '1993-07-05', '1993-07-06', '1993-07-07', '1993-07-08', '1993-07-09', '1993-07-12', '1993-07-13', '1993-07-14', '1993-07-15', '1993-07-16', '1993-07-19', '1993-07-20', '1993-07-21', '1993-07-22', '1993-07-23', '1993-07-26', '1993-07-27', '1993-07-28', '1993-07-29', '1993-07-30', '1993-08-02', '1993-08-03', '1993-08-04', '1993-08-05', '1993-08-06', '1993-08-09', '1993-08-10', '1993-08-11', '1993-08-12', '1993-08-13', '1993-08-16', '1993-08-17', '1993-08-18', '1993-08-19', '1993-08-20', '1993-08-23', '1993-08-24', '1993-08-25', '1993-08-26', '1993-08-27', '1993-08-30', '1993-08-31', '1993-09-01', '1993-09-02', '1993-09-03', '1993-09-06', '1993-09-07', '1993-09-08', '1993-09-09', '1993-09-10', '1993-09-13', '1993-09-14', '1993-09-15', '1993-09-16', '1993-09-17', '1993-09-20', '1993-09-21', '1993-09-22', '1993-09-23', '1993-09-24', '1993-09-27', '1993-09-28', '1993-09-29', '1993-09-30', '1993-10-04', '1993-10-05', '1993-10-06', '1993-10-07', '1993-10-08', '1993-10-11', '1993-10-12', '1993-10-13', '1993-10-14', '1993-10-15', '1993-10-18', '1993-10-19', '1993-10-20', '1993-10-21', '1993-10-22', '1993-10-25', '1993-10-26', '1993-10-27', '1993-10-28', '1993-10-29', '1993-11-01', '1993-11-02', '1993-11-03', '1993-11-04', '1993-11-05', '1993-11-08', '1993-11-09', '1993-11-10', '1993-11-11', '1993-11-12', '1993-11-15', '1993-11-16', '1993-11-17', '1993-11-18', '1993-11-19', '1993-11-22', '1993-11-23', '1993-11-24', '1993-11-25', '1993-11-26', '1993-11-29', '1993-11-30', '1993-12-01', '1993-12-02', '1993-12-03', '1993-12-06', '1993-12-07', '1993-12-08', '1993-12-09', '1993-12-10', '1993-12-13', '1993-12-14', '1993-12-15', '1993-12-16', '1993-12-17', '1993-12-20', '1993-12-21', '1993-12-22', '1993-12-23', '1993-12-24', '1993-12-27', '1993-12-28', '1993-12-29', '1993-12-30', '1993-12-31', '1994-01-03', '1994-01-04', '1994-01-05', '1994-01-06', '1994-01-07', '1994-01-10', '1994-01-11', '1994-01-12', '1994-01-13', '1994-01-14', '1994-01-17', '1994-01-18', '1994-01-19', '1994-01-20', '1994-01-21', '1994-01-24', '1994-01-25', '1994-01-26', '1994-01-27', '1994-01-28', '1994-01-31', '1994-02-01', '1994-02-02', '1994-02-03', '1994-02-04', '1994-02-14', '1994-02-15', '1994-02-16', '1994-02-17', '1994-02-18', '1994-02-21', '1994-02-22', '1994-02-23', '1994-02-24', '1994-02-25', '1994-02-28', '1994-03-01', '1994-03-02', '1994-03-03', '1994-03-04', '1994-03-07', '1994-03-08', '1994-03-09', '1994-03-10', '1994-03-11', '1994-03-14', '1994-03-15', '1994-03-16', '1994-03-17', '1994-03-18', '1994-03-21', '1994-03-22', '1994-03-23', '1994-03-24', '1994-03-25', '1994-03-28', '1994-03-29', '1994-03-30', '1994-03-31', '1994-04-01', '1994-04-04', '1994-04-05', '1994-04-06', '1994-04-07', '1994-04-08', '1994-04-11', '1994-04-12', '1994-04-13', '1994-04-14', '1994-04-15', '1994-04-18', '1994-04-19', '1994-04-20', '1994-04-21', '1994-04-22', '1994-04-25', '1994-04-26', '1994-04-27', '1994-04-28', '1994-04-29', '1994-05-03', '1994-05-04', '1994-05-05', '1994-05-06', '1994-05-09', '1994-05-10', '1994-05-11', '1994-05-12', '1994-05-13', '1994-05-16', '1994-05-17', '1994-05-18', '1994-05-19', '1994-05-20', '1994-05-23', '1994-05-24', '1994-05-25', '1994-05-26', '1994-05-27', '1994-05-30', '1994-05-31', '1994-06-01', '1994-06-02', '1994-06-03', '1994-06-06', '1994-06-07', '1994-06-08', '1994-06-09', '1994-06-10', '1994-06-13', '1994-06-14', '1994-06-15', '1994-06-16', '1994-06-17', '1994-06-20', '1994-06-21', '1994-06-22', '1994-06-23', '1994-06-24', '1994-06-27', '1994-06-28', '1994-06-29', '1994-06-30', '1994-07-01', '1994-07-04', '1994-07-05', '1994-07-06', '1994-07-07', '1994-07-08', '1994-07-11', '1994-07-12', '1994-07-13', '1994-07-14', '1994-07-15', '1994-07-18', '1994-07-19', '1994-07-20', '1994-07-21', '1994-07-22', '1994-07-25', '1994-07-26', '1994-07-27', '1994-07-28', '1994-07-29', '1994-08-01', '1994-08-02', '1994-08-03', '1994-08-04', '1994-08-05', '1994-08-08', '1994-08-09', '1994-08-10', '1994-08-11', '1994-08-12', '1994-08-15', '1994-08-16', '1994-08-17', '1994-08-18', '1994-08-19', '1994-08-22', '1994-08-23', '1994-08-24', '1994-08-25', '1994-08-26', '1994-08-29', '1994-08-30', '1994-08-31', '1994-09-01', '1994-09-02', '1994-09-05', '1994-09-06', '1994-09-07', '1994-09-08', '1994-09-09', '1994-09-12', '1994-09-13', '1994-09-14', '1994-09-15', '1994-09-16', '1994-09-19', '1994-09-20', '1994-09-21', '1994-09-22', '1994-09-23', '1994-09-26', '1994-09-27', '1994-09-28', '1994-09-29', '1994-09-30', '1994-10-05', '1994-10-06', '1994-10-07', '1994-10-10', '1994-10-11', '1994-10-12', '1994-10-13', '1994-10-14', '1994-10-17', '1994-10-18', '1994-10-19', '1994-10-20', '1994-10-21', '1994-10-24', '1994-10-25', '1994-10-26', '1994-10-27', '1994-10-28', '1994-10-31', '1994-11-01', '1994-11-02', '1994-11-03', '1994-11-04', '1994-11-07', '1994-11-08', '1994-11-09', '1994-11-10', '1994-11-11', '1994-11-14', '1994-11-15', '1994-11-16', '1994-11-17', '1994-11-18', '1994-11-21', '1994-11-22', '1994-11-23', '1994-11-24', '1994-11-25', '1994-11-28', '1994-11-29', '1994-11-30', '1994-12-01', '1994-12-02', '1994-12-05', '1994-12-06', '1994-12-07', '1994-12-08', '1994-12-09', '1994-12-12', '1994-12-13', '1994-12-14', '1994-12-15', '1994-12-16', '1994-12-19', '1994-12-20', '1994-12-21', '1994-12-22', '1994-12-23', '1994-12-26', '1994-12-27', '1994-12-28', '1994-12-29', '1994-12-30', '1995-01-03', '1995-01-04', '1995-01-05', '1995-01-06', '1995-01-09', '1995-01-10', '1995-01-11', '1995-01-12', '1995-01-13', '1995-01-16', '1995-01-17', '1995-01-18', '1995-01-19', '1995-01-20', '1995-01-23', '1995-01-24', '1995-01-25', '1995-01-26', '1995-01-27', '1995-02-06', '1995-02-07', '1995-02-08', '1995-02-09', '1995-02-10', '1995-02-13', '1995-02-14', '1995-02-15', '1995-02-16', '1995-02-17', '1995-02-20', '1995-02-21', '1995-02-22', '1995-02-23', '1995-02-24', '1995-02-27', '1995-02-28', '1995-03-01', '1995-03-02', '1995-03-03', '1995-03-06', '1995-03-07', '1995-03-08', '1995-03-09', '1995-03-10', '1995-03-13', '1995-03-14', '1995-03-15', '1995-03-16', '1995-03-17', '1995-03-20', '1995-03-21', '1995-03-22', '1995-03-23', '1995-03-24', '1995-03-27', '1995-03-28', '1995-03-29', '1995-03-30', '1995-03-31', '1995-04-03', '1995-04-04', '1995-04-05', '1995-04-06', '1995-04-07', '1995-04-10', '1995-04-11', '1995-04-12', '1995-04-13', '1995-04-14', '1995-04-17', '1995-04-18', '1995-04-19', '1995-04-20', '1995-04-21', '1995-04-24', '1995-04-25', '1995-04-26', '1995-04-27', '1995-04-28', '1995-05-02', '1995-05-03', '1995-05-04', '1995-05-05', '1995-05-08', '1995-05-09', '1995-05-10', '1995-05-11', '1995-05-12', '1995-05-15', '1995-05-16', '1995-05-17', '1995-05-18', '1995-05-19', '1995-05-22', '1995-05-23', '1995-05-24', '1995-05-25', '1995-05-26', '1995-05-29', '1995-05-30', '1995-05-31', '1995-06-01', '1995-06-02', '1995-06-05', '1995-06-06', '1995-06-07', '1995-06-08', '1995-06-09', '1995-06-12', '1995-06-13', '1995-06-14', '1995-06-15', '1995-06-16', '1995-06-19', '1995-06-20', '1995-06-21', '1995-06-22', '1995-06-23', '1995-06-26', '1995-06-27', '1995-06-28', '1995-06-29', '1995-06-30', '1995-07-03', '1995-07-04', '1995-07-05', '1995-07-06', '1995-07-07', '1995-07-10', '1995-07-11', '1995-07-12', '1995-07-13', '1995-07-14', '1995-07-17', '1995-07-18', '1995-07-19', '1995-07-20', '1995-07-21', '1995-07-24', '1995-07-25', '1995-07-26', '1995-07-27', '1995-07-28', '1995-07-31', '1995-08-01', '1995-08-02', '1995-08-03', '1995-08-04', '1995-08-07', '1995-08-08', '1995-08-09', '1995-08-10', '1995-08-11', '1995-08-14', '1995-08-15', '1995-08-16', '1995-08-17', '1995-08-18', '1995-08-21', '1995-08-22', '1995-08-23', '1995-08-24', '1995-08-25', '1995-08-28', '1995-08-29', '1995-08-30', '1995-08-31', '1995-09-01', '1995-09-04', '1995-09-05', '1995-09-06', '1995-09-07', '1995-09-08', '1995-09-11', '1995-09-12', '1995-09-13', '1995-09-14', '1995-09-15', '1995-09-18', '1995-09-19', '1995-09-20', '1995-09-21', '1995-09-22', '1995-09-25', '1995-09-26', '1995-09-27', '1995-09-28', '1995-09-29', '1995-10-04', '1995-10-05', '1995-10-06', '1995-10-09', '1995-10-10', '1995-10-11', '1995-10-12', '1995-10-13', '1995-10-16', '1995-10-17', '1995-10-18', '1995-10-19', '1995-10-20', '1995-10-23', '1995-10-24', '1995-10-25', '1995-10-26', '1995-10-27', '1995-10-30', '1995-10-31', '1995-11-01', '1995-11-02', '1995-11-03', '1995-11-06', '1995-11-07', '1995-11-08', '1995-11-09', '1995-11-10', '1995-11-13', '1995-11-14', '1995-11-15', '1995-11-16', '1995-11-17', '1995-11-20', '1995-11-21', '1995-11-22', '1995-11-23', '1995-11-24', '1995-11-27', '1995-11-28', '1995-11-29', '1995-11-30', '1995-12-01', '1995-12-04', '1995-12-05', '1995-12-06', '1995-12-07', '1995-12-08', '1995-12-11', '1995-12-12', '1995-12-13', '1995-12-14', '1995-12-15', '1995-12-18', '1995-12-19', '1995-12-20', '1995-12-21', '1995-12-22', '1995-12-25', '1995-12-26', '1995-12-27', '1995-12-28', '1995-12-29', '1996-01-02', '1996-01-03', '1996-01-04', '1996-01-05', '1996-01-08', '1996-01-09', '1996-01-10', '1996-01-11', '1996-01-12', '1996-01-15', '1996-01-16', '1996-01-17', '1996-01-18', '1996-01-19', '1996-01-22', '1996-01-23', '1996-01-24', '1996-01-25', '1996-01-26', '1996-01-29', '1996-01-30', '1996-01-31', '1996-02-01', '1996-02-02', '1996-02-05', '1996-02-06', '1996-02-07', '1996-02-08', '1996-02-09', '1996-02-12', '1996-02-13', '1996-02-14', '1996-02-15', '1996-02-16', '1996-03-04', '1996-03-05', '1996-03-06', '1996-03-07', '1996-03-08', '1996-03-11', '1996-03-12', '1996-03-13', '1996-03-14', '1996-03-15', '1996-03-18', '1996-03-19', '1996-03-20', '1996-03-21', '1996-03-22', '1996-03-25', '1996-03-26', '1996-03-27', '1996-03-28', '1996-03-29', '1996-04-01', '1996-04-02', '1996-04-03', '1996-04-04', '1996-04-05', '1996-04-08', '1996-04-09', '1996-04-10', '1996-04-11', '1996-04-12', '1996-04-15', '1996-04-16', '1996-04-17', '1996-04-18', '1996-04-19', '1996-04-22', '1996-04-23', '1996-04-24', '1996-04-25', '1996-04-26', '1996-04-29', '1996-04-30', '1996-05-02', '1996-05-03', '1996-05-06', '1996-05-07', '1996-05-08', '1996-05-09', '1996-05-10', '1996-05-13', '1996-05-14', '1996-05-15', '1996-05-16', '1996-05-17', '1996-05-20', '1996-05-21', '1996-05-22', '1996-05-23', '1996-05-24', '1996-05-27', '1996-05-28', '1996-05-29', '1996-05-30', '1996-05-31', '1996-06-03', '1996-06-04', '1996-06-05', '1996-06-06', '1996-06-07', '1996-06-10', '1996-06-11', '1996-06-12', '1996-06-13', '1996-06-14', '1996-06-17', '1996-06-18', '1996-06-19', '1996-06-20', '1996-06-21', '1996-06-24', '1996-06-25', '1996-06-26', '1996-06-27', '1996-06-28', '1996-07-01', '1996-07-02', '1996-07-03', '1996-07-04', '1996-07-05', '1996-07-08', '1996-07-09', '1996-07-10', '1996-07-11', '1996-07-12', '1996-07-15', '1996-07-16', '1996-07-17', '1996-07-18', '1996-07-19', '1996-07-22', '1996-07-23', '1996-07-24', '1996-07-25', '1996-07-26', '1996-07-29', '1996-07-30', '1996-07-31', '1996-08-01', '1996-08-02', '1996-08-05', '1996-08-06', '1996-08-07', '1996-08-08', '1996-08-09', '1996-08-12', '1996-08-13', '1996-08-14', '1996-08-15', '1996-08-16', '1996-08-19', '1996-08-20', '1996-08-21', '1996-08-22', '1996-08-23', '1996-08-26', '1996-08-27', '1996-08-28', '1996-08-29', '1996-08-30', '1996-09-02', '1996-09-03', '1996-09-04', '1996-09-05', '1996-09-06', '1996-09-09', '1996-09-10', '1996-09-11', '1996-09-12', '1996-09-13', '1996-09-16', '1996-09-17', '1996-09-18', '1996-09-19', '1996-09-20', '1996-09-23', '1996-09-24', '1996-09-25', '1996-09-26', '1996-09-27', '1996-10-03', '1996-10-04', '1996-10-07', '1996-10-08', '1996-10-09', '1996-10-10', '1996-10-11', '1996-10-14', '1996-10-15', '1996-10-16', '1996-10-17', '1996-10-18', '1996-10-21', '1996-10-22', '1996-10-23', '1996-10-24', '1996-10-25', '1996-10-28', '1996-10-29', '1996-10-30', '1996-10-31', '1996-11-01', '1996-11-04', '1996-11-05', '1996-11-06', '1996-11-07', '1996-11-08', '1996-11-11', '1996-11-12', '1996-11-13', '1996-11-14', '1996-11-15', '1996-11-18', '1996-11-19', '1996-11-20', '1996-11-21', '1996-11-22', '1996-11-25', '1996-11-26', '1996-11-27', '1996-11-28', '1996-11-29', '1996-12-02', '1996-12-03', '1996-12-04', '1996-12-05', '1996-12-06', '1996-12-09', '1996-12-10', '1996-12-11', '1996-12-12', '1996-12-13', '1996-12-16', '1996-12-17', '1996-12-18', '1996-12-19', '1996-12-20', '1996-12-23', '1996-12-24', '1996-12-25', '1996-12-26', '1996-12-27', '1996-12-30', '1996-12-31', '1997-01-02', '1997-01-03', '1997-01-06', '1997-01-07', '1997-01-08', '1997-01-09', '1997-01-10', '1997-01-13', '1997-01-14', '1997-01-15', '1997-01-16', '1997-01-17', '1997-01-20', '1997-01-21', '1997-01-22', '1997-01-23', '1997-01-24', '1997-01-27', '1997-01-28', '1997-01-29', '1997-01-30', '1997-01-31', '1997-02-17', '1997-02-18', '1997-02-19', '1997-02-20', '1997-02-21', '1997-02-24', '1997-02-25', '1997-02-26', '1997-02-27', '1997-02-28', '1997-03-03', '1997-03-04', '1997-03-05', '1997-03-06', '1997-03-07', '1997-03-10', '1997-03-11', '1997-03-12', '1997-03-13', '1997-03-14', '1997-03-17', '1997-03-18', '1997-03-19', '1997-03-20', '1997-03-21', '1997-03-24', '1997-03-25', '1997-03-26', '1997-03-27', '1997-03-28', '1997-03-31', '1997-04-01', '1997-04-02', '1997-04-03', '1997-04-04', '1997-04-07', '1997-04-08', '1997-04-09', '1997-04-10', '1997-04-11', '1997-04-14', '1997-04-15', '1997-04-16', '1997-04-17', '1997-04-18', '1997-04-21', '1997-04-22', '1997-04-23', '1997-04-24', '1997-04-25', '1997-04-28', '1997-04-29', '1997-04-30', '1997-05-05', '1997-05-06', '1997-05-07', '1997-05-08', '1997-05-09', '1997-05-12', '1997-05-13', '1997-05-14', '1997-05-15', '1997-05-16', '1997-05-19', '1997-05-20', '1997-05-21', '1997-05-22', '1997-05-23', '1997-05-26', '1997-05-27', '1997-05-28', '1997-05-29', '1997-05-30', '1997-06-02', '1997-06-03', '1997-06-04', '1997-06-05', '1997-06-06', '1997-06-09', '1997-06-10', '1997-06-11', '1997-06-12', '1997-06-13', '1997-06-16', '1997-06-17', '1997-06-18', '1997-06-19', '1997-06-20', '1997-06-23', '1997-06-24', '1997-06-25', '1997-06-26', '1997-06-27', '1997-07-02', '1997-07-03', '1997-07-04', '1997-07-07', '1997-07-08', '1997-07-09', '1997-07-10', '1997-07-11', '1997-07-14', '1997-07-15', '1997-07-16', '1997-07-17', '1997-07-18', '1997-07-21', '1997-07-22', '1997-07-23', '1997-07-24', '1997-07-25', '1997-07-28', '1997-07-29', '1997-07-30', '1997-07-31', '1997-08-01', '1997-08-04', '1997-08-05', '1997-08-06', '1997-08-07', '1997-08-08', '1997-08-11', '1997-08-12', '1997-08-13', '1997-08-14', '1997-08-15', '1997-08-18', '1997-08-19', '1997-08-20', '1997-08-21', '1997-08-22', '1997-08-25', '1997-08-26', '1997-08-27', '1997-08-28', '1997-08-29', '1997-09-01', '1997-09-02', '1997-09-03', '1997-09-04', '1997-09-05', '1997-09-08', '1997-09-09', '1997-09-10', '1997-09-11', '1997-09-12', '1997-09-15', '1997-09-16', '1997-09-17', '1997-09-18', '1997-09-19', '1997-09-22', '1997-09-23', '1997-09-24', '1997-09-25', '1997-09-26', '1997-09-29', '1997-09-30', '1997-10-06', '1997-10-07', '1997-10-08', '1997-10-09', '1997-10-10', '1997-10-13', '1997-10-14', '1997-10-15', '1997-10-16', '1997-10-17', '1997-10-20', '1997-10-21', '1997-10-22', '1997-10-23', '1997-10-24', '1997-10-27', '1997-10-28', '1997-10-29', '1997-10-30', '1997-10-31', '1997-11-03', '1997-11-04', '1997-11-05', '1997-11-06', '1997-11-07', '1997-11-10', '1997-11-11', '1997-11-12', '1997-11-13', '1997-11-14', '1997-11-17', '1997-11-18', '1997-11-19', '1997-11-20', '1997-11-21', '1997-11-24', '1997-11-25', '1997-11-26', '1997-11-27', '1997-11-28', '1997-12-01', '1997-12-02', '1997-12-03', '1997-12-04', '1997-12-05', '1997-12-08', '1997-12-09', '1997-12-10', '1997-12-11', '1997-12-12', '1997-12-15', '1997-12-16', '1997-12-17', '1997-12-18', '1997-12-19', '1997-12-22', '1997-12-23', '1997-12-24', '1997-12-25', '1997-12-26', '1997-12-29', '1997-12-30', '1997-12-31', '1998-01-05', '1998-01-06', '1998-01-07', '1998-01-08', '1998-01-09', '1998-01-12', '1998-01-13', '1998-01-14', '1998-01-15', '1998-01-16', '1998-01-19', '1998-01-20', '1998-01-21', '1998-01-22', '1998-01-23', '1998-02-09', '1998-02-10', '1998-02-11', '1998-02-12', '1998-02-13', '1998-02-16', '1998-02-17', '1998-02-18', '1998-02-19', '1998-02-20', '1998-02-23', '1998-02-24', '1998-02-25', '1998-02-26', '1998-02-27', '1998-03-02', '1998-03-03', '1998-03-04', '1998-03-05', '1998-03-06', '1998-03-09', '1998-03-10', '1998-03-11', '1998-03-12', '1998-03-13', '1998-03-16', '1998-03-17', '1998-03-18', '1998-03-19', '1998-03-20', '1998-03-23', '1998-03-24', '1998-03-25', '1998-03-26', '1998-03-27', '1998-03-30', '1998-03-31', '1998-04-01', '1998-04-02', '1998-04-03', '1998-04-06', '1998-04-07', '1998-04-08', '1998-04-09', '1998-04-10', '1998-04-13', '1998-04-14', '1998-04-15', '1998-04-16', '1998-04-17', '1998-04-20', '1998-04-21', '1998-04-22', '1998-04-23', '1998-04-24', '1998-04-27', '1998-04-28', '1998-04-29', '1998-04-30', '1998-05-04', '1998-05-05', '1998-05-06', '1998-05-07', '1998-05-08', '1998-05-11', '1998-05-12', '1998-05-13', '1998-05-14', '1998-05-15', '1998-05-18', '1998-05-19', '1998-05-20', '1998-05-21', '1998-05-22', '1998-05-25', '1998-05-26', '1998-05-27', '1998-05-28', '1998-05-29', '1998-06-01', '1998-06-02', '1998-06-03', '1998-06-04', '1998-06-05', '1998-06-08', '1998-06-09', '1998-06-10', '1998-06-11', '1998-06-12', '1998-06-15', '1998-06-16', '1998-06-17', '1998-06-18', '1998-06-19', '1998-06-22', '1998-06-23', '1998-06-24', '1998-06-25', '1998-06-26', '1998-06-29', '1998-06-30', '1998-07-01', '1998-07-02', '1998-07-03', '1998-07-06', '1998-07-07', '1998-07-08', '1998-07-09', '1998-07-10', '1998-07-13', '1998-07-14', '1998-07-15', '1998-07-16', '1998-07-17', '1998-07-20', '1998-07-21', '1998-07-22', '1998-07-23', '1998-07-24', '1998-07-27', '1998-07-28', '1998-07-29', '1998-07-30', '1998-07-31', '1998-08-03', '1998-08-04', '1998-08-05', '1998-08-06', '1998-08-07', '1998-08-10', '1998-08-11', '1998-08-12', '1998-08-13', '1998-08-14', '1998-08-17', '1998-08-18', '1998-08-19', '1998-08-20', '1998-08-21', '1998-08-24', '1998-08-25', '1998-08-26', '1998-08-27', '1998-08-28', '1998-08-31', '1998-09-01', '1998-09-02', '1998-09-03', '1998-09-04', '1998-09-07', '1998-09-08', '1998-09-09', '1998-09-10', '1998-09-11', '1998-09-14', '1998-09-15', '1998-09-16', '1998-09-17', '1998-09-18', '1998-09-21', '1998-09-22', '1998-09-23', '1998-09-24', '1998-09-25', '1998-09-28', '1998-09-29', '1998-09-30', '1998-10-05', '1998-10-06', '1998-10-07', '1998-10-08', '1998-10-09', '1998-10-12', '1998-10-13', '1998-10-14', '1998-10-15', '1998-10-16', '1998-10-19', '1998-10-20', '1998-10-21', '1998-10-22', '1998-10-23', '1998-10-26', '1998-10-27', '1998-10-28', '1998-10-29', '1998-10-30', '1998-11-02', '1998-11-03', '1998-11-04', '1998-11-05', '1998-11-06', '1998-11-09', '1998-11-10', '1998-11-11', '1998-11-12', '1998-11-13', '1998-11-16', '1998-11-17', '1998-11-18', '1998-11-19', '1998-11-20', '1998-11-23', '1998-11-24', '1998-11-25', '1998-11-26', '1998-11-27', '1998-11-30', '1998-12-01', '1998-12-02', '1998-12-03', '1998-12-04', '1998-12-07', '1998-12-08', '1998-12-09', '1998-12-10', '1998-12-11', '1998-12-14', '1998-12-15', '1998-12-16', '1998-12-17', '1998-12-18', '1998-12-21', '1998-12-22', '1998-12-23', '1998-12-24', '1998-12-25', '1998-12-28', '1998-12-29', '1998-12-30', '1998-12-31', '1999-01-04', '1999-01-05', '1999-01-06', '1999-01-07', '1999-01-08', '1999-01-11', '1999-01-12', '1999-01-13', '1999-01-14', '1999-01-15', '1999-01-18', '1999-01-19', '1999-01-20', '1999-01-21', '1999-01-22', '1999-01-25', '1999-01-26', '1999-01-27', '1999-01-28', '1999-01-29', '1999-02-01', '1999-02-02', '1999-02-03', '1999-02-04', '1999-02-05', '1999-02-08', '1999-02-09', '1999-03-01', '1999-03-02', '1999-03-03', '1999-03-04', '1999-03-05', '1999-03-08', '1999-03-09', '1999-03-10', '1999-03-11', '1999-03-12', '1999-03-15', '1999-03-16', '1999-03-17', '1999-03-18', '1999-03-19', '1999-03-22', '1999-03-23', '1999-03-24', '1999-03-25', '1999-03-26', '1999-03-29', '1999-03-30', '1999-03-31', '1999-04-01', '1999-04-02', '1999-04-05', '1999-04-06', '1999-04-07', '1999-04-08', '1999-04-09', '1999-04-12', '1999-04-13', '1999-04-14', '1999-04-15', '1999-04-16', '1999-04-19', '1999-04-20', '1999-04-21', '1999-04-22', '1999-04-23', '1999-04-26', '1999-04-27', '1999-04-28', '1999-04-29', '1999-04-30', '1999-05-04', '1999-05-05', '1999-05-06', '1999-05-07', '1999-05-10', '1999-05-11', '1999-05-12', '1999-05-13', '1999-05-14', '1999-05-17', '1999-05-18', '1999-05-19', '1999-05-20', '1999-05-21', '1999-05-24', '1999-05-25', '1999-05-26', '1999-05-27', '1999-05-28', '1999-05-31', '1999-06-01', '1999-06-02', '1999-06-03', '1999-06-04', '1999-06-07', '1999-06-08', '1999-06-09', '1999-06-10', '1999-06-11', '1999-06-14', '1999-06-15', '1999-06-16', '1999-06-17', '1999-06-18', '1999-06-21', '1999-06-22', '1999-06-23', '1999-06-24', '1999-06-25', '1999-06-28', '1999-06-29', '1999-06-30', '1999-07-01', '1999-07-02', '1999-07-05', '1999-07-06', '1999-07-07', '1999-07-08', '1999-07-09', '1999-07-12', '1999-07-13', '1999-07-14', '1999-07-15', '1999-07-16', '1999-07-19', '1999-07-20', '1999-07-21', '1999-07-22', '1999-07-23', '1999-07-26', '1999-07-27', '1999-07-28', '1999-07-29', '1999-07-30', '1999-08-02', '1999-08-03', '1999-08-04', '1999-08-05', '1999-08-06', '1999-08-09', '1999-08-10', '1999-08-11', '1999-08-12', '1999-08-13', '1999-08-16', '1999-08-17', '1999-08-18', '1999-08-19', '1999-08-20', '1999-08-23', '1999-08-24', '1999-08-25', '1999-08-26', '1999-08-27', '1999-08-30', '1999-08-31', '1999-09-01', '1999-09-02', '1999-09-03', '1999-09-06', '1999-09-07', '1999-09-08', '1999-09-09', '1999-09-10', '1999-09-13', '1999-09-14', '1999-09-15', '1999-09-16', '1999-09-17', '1999-09-20', '1999-09-21', '1999-09-22', '1999-09-23', '1999-09-24', '1999-09-27', '1999-09-28', '1999-09-29', '1999-09-30', '1999-10-08', '1999-10-11', '1999-10-12', '1999-10-13', '1999-10-14', '1999-10-15', '1999-10-18', '1999-10-19', '1999-10-20', '1999-10-21', '1999-10-22', '1999-10-25', '1999-10-26', '1999-10-27', '1999-10-28', '1999-10-29', '1999-11-01', '1999-11-02', '1999-11-03', '1999-11-04', '1999-11-05', '1999-11-08', '1999-11-09', '1999-11-10', '1999-11-11', '1999-11-12', '1999-11-15', '1999-11-16', '1999-11-17', '1999-11-18', '1999-11-19', '1999-11-22', '1999-11-23', '1999-11-24', '1999-11-25', '1999-11-26', '1999-11-29', '1999-11-30', '1999-12-01', '1999-12-02', '1999-12-03', '1999-12-06', '1999-12-07', '1999-12-08', '1999-12-09', '1999-12-10', '1999-12-13', '1999-12-14', '1999-12-15', '1999-12-16', '1999-12-17', '1999-12-21', '1999-12-22', '1999-12-23', '1999-12-24', '1999-12-27', '1999-12-28', '1999-12-29', '1999-12-30', '2000-01-04', '2000-01-05', '2000-01-06', '2000-01-07', '2000-01-10', '2000-01-11', '2000-01-12', '2000-01-13', '2000-01-14', '2000-01-17', '2000-01-18', '2000-01-19', '2000-01-20', '2000-01-21', '2000-01-24', '2000-01-25', '2000-01-26', '2000-01-27', '2000-01-28', '2000-02-14', '2000-02-15', '2000-02-16', '2000-02-17', '2000-02-18', '2000-02-21', '2000-02-22', '2000-02-23', '2000-02-24', '2000-02-25', '2000-02-28', '2000-02-29', '2000-03-01', '2000-03-02', '2000-03-03', '2000-03-06', '2000-03-07', '2000-03-08', '2000-03-09', '2000-03-10', '2000-03-13', '2000-03-14', '2000-03-15', '2000-03-16', '2000-03-17', '2000-03-20', '2000-03-21', '2000-03-22', '2000-03-23', '2000-03-24', '2000-03-27', '2000-03-28', '2000-03-29', '2000-03-30', '2000-03-31', '2000-04-03', '2000-04-04', '2000-04-05', '2000-04-06', '2000-04-07', '2000-04-10', '2000-04-11', '2000-04-12', '2000-04-13', '2000-04-14', '2000-04-17', '2000-04-18', '2000-04-19', '2000-04-20', '2000-04-21', '2000-04-24', '2000-04-25', '2000-04-26', '2000-04-27', '2000-04-28', '2000-05-08', '2000-05-09', '2000-05-10', '2000-05-11', '2000-05-12', '2000-05-15', '2000-05-16', '2000-05-17', '2000-05-18', '2000-05-19', '2000-05-22', '2000-05-23', '2000-05-24', '2000-05-25', '2000-05-26', '2000-05-29', '2000-05-30', '2000-05-31', '2000-06-01', '2000-06-02', '2000-06-05', '2000-06-06', '2000-06-07', '2000-06-08', '2000-06-09', '2000-06-12', '2000-06-13', '2000-06-14', '2000-06-15', '2000-06-16', '2000-06-19', '2000-06-20', '2000-06-21', '2000-06-22', '2000-06-23', '2000-06-26', '2000-06-27', '2000-06-28', '2000-06-29', '2000-06-30', '2000-07-03', '2000-07-04', '2000-07-05', '2000-07-06', '2000-07-07', '2000-07-10', '2000-07-11', '2000-07-12', '2000-07-13', '2000-07-14', '2000-07-17', '2000-07-18', '2000-07-19', '2000-07-20', '2000-07-21', '2000-07-24', '2000-07-25', '2000-07-26', '2000-07-27', '2000-07-28', '2000-07-31', '2000-08-01', '2000-08-02', '2000-08-03', '2000-08-04', '2000-08-07', '2000-08-08', '2000-08-09', '2000-08-10', '2000-08-11', '2000-08-14', '2000-08-15', '2000-08-16', '2000-08-17', '2000-08-18', '2000-08-21', '2000-08-22', '2000-08-23', '2000-08-24', '2000-08-25', '2000-08-28', '2000-08-29', '2000-08-30', '2000-08-31', '2000-09-01', '2000-09-04', '2000-09-05', '2000-09-06', '2000-09-07', '2000-09-08', '2000-09-11', '2000-09-12', '2000-09-13', '2000-09-14', '2000-09-15', '2000-09-18', '2000-09-19', '2000-09-20', '2000-09-21', '2000-09-22', '2000-09-25', '2000-09-26', '2000-09-27', '2000-09-28', '2000-09-29', '2000-10-09', '2000-10-10', '2000-10-11', '2000-10-12', '2000-10-13', '2000-10-16', '2000-10-17', '2000-10-18', '2000-10-19', '2000-10-20', '2000-10-23', '2000-10-24', '2000-10-25', '2000-10-26', '2000-10-27', '2000-10-30', '2000-10-31', '2000-11-01', '2000-11-02', '2000-11-03', '2000-11-06', '2000-11-07', '2000-11-08', '2000-11-09', '2000-11-10', '2000-11-13', '2000-11-14', '2000-11-15', '2000-11-16', '2000-11-17', '2000-11-20', '2000-11-21', '2000-11-22', '2000-11-23', '2000-11-24', '2000-11-27', '2000-11-28', '2000-11-29', '2000-11-30', '2000-12-01', '2000-12-04', '2000-12-05', '2000-12-06', '2000-12-07', '2000-12-08', '2000-12-11', '2000-12-12', '2000-12-13', '2000-12-14', '2000-12-15', '2000-12-18', '2000-12-19', '2000-12-20', '2000-12-21', '2000-12-22', '2000-12-25', '2000-12-26', '2000-12-27', '2000-12-28', '2000-12-29', '2001-01-02', '2001-01-03', '2001-01-04', '2001-01-05', '2001-01-08', '2001-01-09', '2001-01-10', '2001-01-11', '2001-01-12', '2001-01-15', '2001-01-16', '2001-01-17', '2001-01-18', '2001-01-19', '2001-02-05', '2001-02-06', '2001-02-07', '2001-02-08', '2001-02-09', '2001-02-12', '2001-02-13', '2001-02-14', '2001-02-15', '2001-02-16', '2001-02-19', '2001-02-20', '2001-02-21', '2001-02-22', '2001-02-23', '2001-02-26', '2001-02-27', '2001-02-28', '2001-03-01', '2001-03-02', '2001-03-05', '2001-03-06', '2001-03-07', '2001-03-08', '2001-03-09', '2001-03-12', '2001-03-13', '2001-03-14', '2001-03-15', '2001-03-16', '2001-03-19', '2001-03-20', '2001-03-21', '2001-03-22', '2001-03-23', '2001-03-26', '2001-03-27', '2001-03-28', '2001-03-29', '2001-03-30', '2001-04-02', '2001-04-03', '2001-04-04', '2001-04-05', '2001-04-06', '2001-04-09', '2001-04-10', '2001-04-11', '2001-04-12', '2001-04-13', '2001-04-16', '2001-04-17', '2001-04-18', '2001-04-19', '2001-04-20', '2001-04-23', '2001-04-24', '2001-04-25', '2001-04-26', '2001-04-27', '2001-04-30', '2001-05-08', '2001-05-09', '2001-05-10', '2001-05-11', '2001-05-14', '2001-05-15', '2001-05-16', '2001-05-17', '2001-05-18', '2001-05-21', '2001-05-22', '2001-05-23', '2001-05-24', '2001-05-25', '2001-05-28', '2001-05-29', '2001-05-30', '2001-05-31', '2001-06-01', '2001-06-04', '2001-06-05', '2001-06-06', '2001-06-07', '2001-06-08', '2001-06-11', '2001-06-12', '2001-06-13', '2001-06-14', '2001-06-15', '2001-06-18', '2001-06-19', '2001-06-20', '2001-06-21', '2001-06-22', '2001-06-25', '2001-06-26', '2001-06-27', '2001-06-28', '2001-06-29', '2001-07-02', '2001-07-03', '2001-07-04', '2001-07-05', '2001-07-06', '2001-07-09', '2001-07-10', '2001-07-11', '2001-07-12', '2001-07-13', '2001-07-16', '2001-07-17', '2001-07-18', '2001-07-19', '2001-07-20', '2001-07-23', '2001-07-24', '2001-07-25', '2001-07-26', '2001-07-27', '2001-07-30', '2001-07-31', '2001-08-01', '2001-08-02', '2001-08-03', '2001-08-06', '2001-08-07', '2001-08-08', '2001-08-09', '2001-08-10', '2001-08-13', '2001-08-14', '2001-08-15', '2001-08-16', '2001-08-17', '2001-08-20', '2001-08-21', '2001-08-22', '2001-08-23', '2001-08-24', '2001-08-27', '2001-08-28', '2001-08-29', '2001-08-30', '2001-08-31', '2001-09-03', '2001-09-04', '2001-09-05', '2001-09-06', '2001-09-07', '2001-09-10', '2001-09-11', '2001-09-12', '2001-09-13', '2001-09-14', '2001-09-17', '2001-09-18', '2001-09-19', '2001-09-20', '2001-09-21', '2001-09-24', '2001-09-25', '2001-09-26', '2001-09-27', '2001-09-28', '2001-10-08', '2001-10-09', '2001-10-10', '2001-10-11', '2001-10-12', '2001-10-15', '2001-10-16', '2001-10-17', '2001-10-18', '2001-10-19', '2001-10-22', '2001-10-23', '2001-10-24', '2001-10-25', '2001-10-26', '2001-10-29', '2001-10-30', '2001-10-31', '2001-11-01', '2001-11-02', '2001-11-05', '2001-11-06', '2001-11-07', '2001-11-08', '2001-11-09', '2001-11-12', '2001-11-13', '2001-11-14', '2001-11-15', '2001-11-16', '2001-11-19', '2001-11-20', '2001-11-21', '2001-11-22', '2001-11-23', '2001-11-26', '2001-11-27', '2001-11-28', '2001-11-29', '2001-11-30', '2001-12-03', '2001-12-04', '2001-12-05', '2001-12-06', '2001-12-07', '2001-12-10', '2001-12-11', '2001-12-12', '2001-12-13', '2001-12-14', '2001-12-17', '2001-12-18', '2001-12-19', '2001-12-20', '2001-12-21', '2001-12-24', '2001-12-25', '2001-12-26', '2001-12-27', '2001-12-28', '2001-12-31', '2002-01-04', '2002-01-07', '2002-01-08', '2002-01-09', '2002-01-10', '2002-01-11', '2002-01-14', '2002-01-15', '2002-01-16', '2002-01-17', '2002-01-18', '2002-01-21', '2002-01-22', '2002-01-23', '2002-01-24', '2002-01-25', '2002-01-28', '2002-01-29', '2002-01-30', '2002-01-31', '2002-02-01', '2002-02-04', '2002-02-05', '2002-02-06', '2002-02-07', '2002-02-08', '2002-02-25', '2002-02-26', '2002-02-27', '2002-02-28', '2002-03-01', '2002-03-04', '2002-03-05', '2002-03-06', '2002-03-07', '2002-03-08', '2002-03-11', '2002-03-12', '2002-03-13', '2002-03-14', '2002-03-15', '2002-03-18', '2002-03-19', '2002-03-20', '2002-03-21', '2002-03-22', '2002-03-25', '2002-03-26', '2002-03-27', '2002-03-28', '2002-03-29', '2002-04-01', '2002-04-02', '2002-04-03', '2002-04-04', '2002-04-05', '2002-04-08', '2002-04-09', '2002-04-10', '2002-04-11', '2002-04-12', '2002-04-15', '2002-04-16', '2002-04-17', '2002-04-18', '2002-04-19', '2002-04-22', '2002-04-23', '2002-04-24', '2002-04-25', '2002-04-26', '2002-04-29', '2002-04-30', '2002-05-08', '2002-05-09', '2002-05-10', '2002-05-13', '2002-05-14', '2002-05-15', '2002-05-16', '2002-05-17', '2002-05-20', '2002-05-21', '2002-05-22', '2002-05-23', '2002-05-24', '2002-05-27', '2002-05-28', '2002-05-29', '2002-05-30', '2002-05-31', '2002-06-03', '2002-06-04', '2002-06-05', '2002-06-06', '2002-06-07', '2002-06-10', '2002-06-11', '2002-06-12', '2002-06-13', '2002-06-14', '2002-06-17', '2002-06-18', '2002-06-19', '2002-06-20', '2002-06-21', '2002-06-24', '2002-06-25', '2002-06-26', '2002-06-27', '2002-06-28', '2002-07-01', '2002-07-02', '2002-07-03', '2002-07-04', '2002-07-05', '2002-07-08', '2002-07-09', '2002-07-10', '2002-07-11', '2002-07-12', '2002-07-15', '2002-07-16', '2002-07-17', '2002-07-18', '2002-07-19', '2002-07-22', '2002-07-23', '2002-07-24', '2002-07-25', '2002-07-26', '2002-07-29', '2002-07-30', '2002-07-31', '2002-08-01', '2002-08-02', '2002-08-05', '2002-08-06', '2002-08-07', '2002-08-08', '2002-08-09', '2002-08-12', '2002-08-13', '2002-08-14', '2002-08-15', '2002-08-16', '2002-08-19', '2002-08-20', '2002-08-21', '2002-08-22', '2002-08-23', '2002-08-26', '2002-08-27', '2002-08-28', '2002-08-29', '2002-08-30', '2002-09-02', '2002-09-03', '2002-09-04', '2002-09-05', '2002-09-06', '2002-09-09', '2002-09-10', '2002-09-11', '2002-09-12', '2002-09-13', '2002-09-16', '2002-09-17', '2002-09-18', '2002-09-19', '2002-09-20', '2002-09-23', '2002-09-24', '2002-09-25', '2002-09-26', '2002-09-27', '2002-10-08', '2002-10-09', '2002-10-10', '2002-10-11', '2002-10-14', '2002-10-15', '2002-10-16', '2002-10-17', '2002-10-18', '2002-10-21', '2002-10-22', '2002-10-23', '2002-10-24', '2002-10-25', '2002-10-28', '2002-10-29', '2002-10-30', '2002-10-31', '2002-11-01', '2002-11-04', '2002-11-05', '2002-11-06', '2002-11-07', '2002-11-08', '2002-11-11', '2002-11-12', '2002-11-13', '2002-11-14', '2002-11-15', '2002-11-18', '2002-11-19', '2002-11-20', '2002-11-21', '2002-11-22', '2002-11-25', '2002-11-26', '2002-11-27', '2002-11-28', '2002-11-29', '2002-12-02', '2002-12-03', '2002-12-04', '2002-12-05', '2002-12-06', '2002-12-09', '2002-12-10', '2002-12-11', '2002-12-12', '2002-12-13', '2002-12-16', '2002-12-17', '2002-12-18', '2002-12-19', '2002-12-20', '2002-12-23', '2002-12-24', '2002-12-25', '2002-12-26', '2002-12-27', '2002-12-30', '2002-12-31', '2003-01-02', '2003-01-03', '2003-01-06', '2003-01-07', '2003-01-08', '2003-01-09', '2003-01-10', '2003-01-13', '2003-01-14', '2003-01-15', '2003-01-16', '2003-01-17', '2003-01-20', '2003-01-21', '2003-01-22', '2003-01-23', '2003-01-24', '2003-01-27', '2003-01-28', '2003-01-29', '2003-02-10', '2003-02-11', '2003-02-12', '2003-02-13', '2003-02-14', '2003-02-17', '2003-02-18', '2003-02-19', '2003-02-20', '2003-02-21', '2003-02-24', '2003-02-25', '2003-02-26', '2003-02-27', '2003-02-28', '2003-03-03', '2003-03-04', '2003-03-05', '2003-03-06', '2003-03-07', '2003-03-10', '2003-03-11', '2003-03-12', '2003-03-13', '2003-03-14', '2003-03-17', '2003-03-18', '2003-03-19', '2003-03-20', '2003-03-21', '2003-03-24', '2003-03-25', '2003-03-26', '2003-03-27', '2003-03-28', '2003-03-31', '2003-04-01', '2003-04-02', '2003-04-03', '2003-04-04', '2003-04-07', '2003-04-08', '2003-04-09', '2003-04-10', '2003-04-11', '2003-04-14', '2003-04-15', '2003-04-16', '2003-04-17', '2003-04-18', '2003-04-21', '2003-04-22', '2003-04-23', '2003-04-24', '2003-04-25', '2003-04-28', '2003-04-29', '2003-04-30', '2003-05-12', '2003-05-13', '2003-05-14', '2003-05-15', '2003-05-16', '2003-05-19', '2003-05-20', '2003-05-21', '2003-05-22', '2003-05-23', '2003-05-26', '2003-05-27', '2003-05-28', '2003-05-29', '2003-05-30', '2003-06-02', '2003-06-03', '2003-06-04', '2003-06-05', '2003-06-06', '2003-06-09', '2003-06-10', '2003-06-11', '2003-06-12', '2003-06-13', '2003-06-16', '2003-06-17', '2003-06-18', '2003-06-19', '2003-06-20', '2003-06-23', '2003-06-24', '2003-06-25', '2003-06-26', '2003-06-27', '2003-06-30', '2003-07-01', '2003-07-02', '2003-07-03', '2003-07-04', '2003-07-07', '2003-07-08', '2003-07-09', '2003-07-10', '2003-07-11', '2003-07-14', '2003-07-15', '2003-07-16', '2003-07-17', '2003-07-18', '2003-07-21', '2003-07-22', '2003-07-23', '2003-07-24', '2003-07-25', '2003-07-28', '2003-07-29', '2003-07-30', '2003-07-31', '2003-08-01', '2003-08-04', '2003-08-05', '2003-08-06', '2003-08-07', '2003-08-08', '2003-08-11', '2003-08-12', '2003-08-13', '2003-08-14', '2003-08-15', '2003-08-18', '2003-08-19', '2003-08-20', '2003-08-21', '2003-08-22', '2003-08-25', '2003-08-26', '2003-08-27', '2003-08-28', '2003-08-29', '2003-09-01', '2003-09-02', '2003-09-03', '2003-09-04', '2003-09-05', '2003-09-08', '2003-09-09', '2003-09-10', '2003-09-11', '2003-09-12', '2003-09-15', '2003-09-16', '2003-09-17', '2003-09-18', '2003-09-19', '2003-09-22', '2003-09-23', '2003-09-24', '2003-09-25', '2003-09-26', '2003-09-29', '2003-09-30', '2003-10-08', '2003-10-09', '2003-10-10', '2003-10-13', '2003-10-14', '2003-10-15', '2003-10-16', '2003-10-17', '2003-10-20', '2003-10-21', '2003-10-22', '2003-10-23', '2003-10-24', '2003-10-27', '2003-10-28', '2003-10-29', '2003-10-30', '2003-10-31', '2003-11-03', '2003-11-04', '2003-11-05', '2003-11-06', '2003-11-07', '2003-11-10', '2003-11-11', '2003-11-12', '2003-11-13', '2003-11-14', '2003-11-17', '2003-11-18', '2003-11-19', '2003-11-20', '2003-11-21', '2003-11-24', '2003-11-25', '2003-11-26', '2003-11-27', '2003-11-28', '2003-12-01', '2003-12-02', '2003-12-03', '2003-12-04', '2003-12-05', '2003-12-08', '2003-12-09', '2003-12-10', '2003-12-11', '2003-12-12', '2003-12-15', '2003-12-16', '2003-12-17', '2003-12-18', '2003-12-19', '2003-12-22', '2003-12-23', '2003-12-24', '2003-12-25', '2003-12-26', '2003-12-29', '2003-12-30', '2003-12-31', '2004-01-02', '2004-01-05', '2004-01-06', '2004-01-07', '2004-01-08', '2004-01-09', '2004-01-12', '2004-01-13', '2004-01-14', '2004-01-15', '2004-01-16', '2004-01-29', '2004-01-30', '2004-02-02', '2004-02-03', '2004-02-04', '2004-02-05', '2004-02-06', '2004-02-09', '2004-02-10', '2004-02-11', '2004-02-12', '2004-02-13', '2004-02-16', '2004-02-17', '2004-02-18', '2004-02-19', '2004-02-20', '2004-02-23', '2004-02-24', '2004-02-25', '2004-02-26', '2004-02-27', '2004-03-01', '2004-03-02', '2004-03-03', '2004-03-04', '2004-03-05', '2004-03-08', '2004-03-09', '2004-03-10', '2004-03-11', '2004-03-12', '2004-03-15', '2004-03-16', '2004-03-17', '2004-03-18', '2004-03-19', '2004-03-22', '2004-03-23', '2004-03-24', '2004-03-25', '2004-03-26', '2004-03-29', '2004-03-30', '2004-03-31', '2004-04-01', '2004-04-02', '2004-04-05', '2004-04-06', '2004-04-07', '2004-04-08', '2004-04-09', '2004-04-12', '2004-04-13', '2004-04-14', '2004-04-15', '2004-04-16', '2004-04-19', '2004-04-20', '2004-04-21', '2004-04-22', '2004-04-23', '2004-04-26', '2004-04-27', '2004-04-28', '2004-04-29', '2004-04-30', '2004-05-10', '2004-05-11', '2004-05-12', '2004-05-13', '2004-05-14', '2004-05-17', '2004-05-18', '2004-05-19', '2004-05-20', '2004-05-21', '2004-05-24', '2004-05-25', '2004-05-26', '2004-05-27', '2004-05-28', '2004-05-31',
+                  '2004-06-01', '2004-06-02', '2004-06-03', '2004-06-04', '2004-06-07', '2004-06-08', '2004-06-09', '2004-06-10', '2004-06-11', '2004-06-14', '2004-06-15', '2004-06-16', '2004-06-17', '2004-06-18', '2004-06-21', '2004-06-22', '2004-06-23', '2004-06-24', '2004-06-25', '2004-06-28', '2004-06-29', '2004-06-30', '2004-07-01', '2004-07-02', '2004-07-05', '2004-07-06', '2004-07-07', '2004-07-08', '2004-07-09', '2004-07-12', '2004-07-13', '2004-07-14', '2004-07-15', '2004-07-16', '2004-07-19', '2004-07-20', '2004-07-21', '2004-07-22', '2004-07-23', '2004-07-26', '2004-07-27', '2004-07-28', '2004-07-29', '2004-07-30', '2004-08-02', '2004-08-03', '2004-08-04', '2004-08-05', '2004-08-06', '2004-08-09', '2004-08-10', '2004-08-11', '2004-08-12', '2004-08-13', '2004-08-16', '2004-08-17', '2004-08-18', '2004-08-19', '2004-08-20', '2004-08-23', '2004-08-24', '2004-08-25', '2004-08-26', '2004-08-27', '2004-08-30', '2004-08-31', '2004-09-01', '2004-09-02', '2004-09-03', '2004-09-06', '2004-09-07', '2004-09-08', '2004-09-09', '2004-09-10', '2004-09-13', '2004-09-14', '2004-09-15', '2004-09-16', '2004-09-17', '2004-09-20', '2004-09-21', '2004-09-22', '2004-09-23', '2004-09-24', '2004-09-27', '2004-09-28', '2004-09-29', '2004-09-30', '2004-10-08', '2004-10-11', '2004-10-12', '2004-10-13', '2004-10-14', '2004-10-15', '2004-10-18', '2004-10-19', '2004-10-20', '2004-10-21', '2004-10-22', '2004-10-25', '2004-10-26', '2004-10-27', '2004-10-28', '2004-10-29', '2004-11-01', '2004-11-02', '2004-11-03', '2004-11-04', '2004-11-05', '2004-11-08', '2004-11-09', '2004-11-10', '2004-11-11', '2004-11-12', '2004-11-15', '2004-11-16', '2004-11-17', '2004-11-18', '2004-11-19', '2004-11-22', '2004-11-23', '2004-11-24', '2004-11-25', '2004-11-26', '2004-11-29', '2004-11-30', '2004-12-01', '2004-12-02', '2004-12-03', '2004-12-06', '2004-12-07', '2004-12-08', '2004-12-09', '2004-12-10', '2004-12-13', '2004-12-14', '2004-12-15', '2004-12-16', '2004-12-17', '2004-12-20', '2004-12-21', '2004-12-22', '2004-12-23', '2004-12-24', '2004-12-27', '2004-12-28', '2004-12-29', '2004-12-30', '2004-12-31', '2005-01-04', '2005-01-05', '2005-01-06', '2005-01-07', '2005-01-10', '2005-01-11', '2005-01-12', '2005-01-13', '2005-01-14', '2005-01-17', '2005-01-18', '2005-01-19', '2005-01-20', '2005-01-21', '2005-01-24', '2005-01-25', '2005-01-26', '2005-01-27', '2005-01-28', '2005-01-31', '2005-02-01', '2005-02-02', '2005-02-03', '2005-02-04', '2005-02-16', '2005-02-17', '2005-02-18', '2005-02-21', '2005-02-22', '2005-02-23', '2005-02-24', '2005-02-25', '2005-02-28', '2005-03-01', '2005-03-02', '2005-03-03', '2005-03-04', '2005-03-07', '2005-03-08', '2005-03-09', '2005-03-10', '2005-03-11', '2005-03-14', '2005-03-15', '2005-03-16', '2005-03-17', '2005-03-18', '2005-03-21', '2005-03-22', '2005-03-23', '2005-03-24', '2005-03-25', '2005-03-28', '2005-03-29', '2005-03-30', '2005-03-31', '2005-04-01', '2005-04-04', '2005-04-05', '2005-04-06', '2005-04-07', '2005-04-08', '2005-04-11', '2005-04-12', '2005-04-13', '2005-04-14', '2005-04-15', '2005-04-18', '2005-04-19', '2005-04-20', '2005-04-21', '2005-04-22', '2005-04-25', '2005-04-26', '2005-04-27', '2005-04-28', '2005-04-29', '2005-05-09', '2005-05-10', '2005-05-11', '2005-05-12', '2005-05-13', '2005-05-16', '2005-05-17', '2005-05-18', '2005-05-19', '2005-05-20', '2005-05-23', '2005-05-24', '2005-05-25', '2005-05-26', '2005-05-27', '2005-05-30', '2005-05-31', '2005-06-01', '2005-06-02', '2005-06-03', '2005-06-06', '2005-06-07', '2005-06-08', '2005-06-09', '2005-06-10', '2005-06-13', '2005-06-14', '2005-06-15', '2005-06-16', '2005-06-17', '2005-06-20', '2005-06-21', '2005-06-22', '2005-06-23', '2005-06-24', '2005-06-27', '2005-06-28', '2005-06-29', '2005-06-30', '2005-07-01', '2005-07-04', '2005-07-05', '2005-07-06', '2005-07-07', '2005-07-08', '2005-07-11', '2005-07-12', '2005-07-13', '2005-07-14', '2005-07-15', '2005-07-18', '2005-07-19', '2005-07-20', '2005-07-21', '2005-07-22', '2005-07-25', '2005-07-26', '2005-07-27', '2005-07-28', '2005-07-29', '2005-08-01', '2005-08-02', '2005-08-03', '2005-08-04', '2005-08-05', '2005-08-08', '2005-08-09', '2005-08-10', '2005-08-11', '2005-08-12', '2005-08-15', '2005-08-16', '2005-08-17', '2005-08-18', '2005-08-19', '2005-08-22', '2005-08-23', '2005-08-24', '2005-08-25', '2005-08-26', '2005-08-29', '2005-08-30', '2005-08-31', '2005-09-01', '2005-09-02', '2005-09-05', '2005-09-06', '2005-09-07', '2005-09-08', '2005-09-09', '2005-09-12', '2005-09-13', '2005-09-14', '2005-09-15', '2005-09-16', '2005-09-19', '2005-09-20', '2005-09-21', '2005-09-22', '2005-09-23', '2005-09-26', '2005-09-27', '2005-09-28', '2005-09-29', '2005-09-30', '2005-10-10', '2005-10-11', '2005-10-12', '2005-10-13', '2005-10-14', '2005-10-17', '2005-10-18', '2005-10-19', '2005-10-20', '2005-10-21', '2005-10-24', '2005-10-25', '2005-10-26', '2005-10-27', '2005-10-28', '2005-10-31', '2005-11-01', '2005-11-02', '2005-11-03', '2005-11-04', '2005-11-07', '2005-11-08', '2005-11-09', '2005-11-10', '2005-11-11', '2005-11-14', '2005-11-15', '2005-11-16', '2005-11-17', '2005-11-18', '2005-11-21', '2005-11-22', '2005-11-23', '2005-11-24', '2005-11-25', '2005-11-28', '2005-11-29', '2005-11-30', '2005-12-01', '2005-12-02', '2005-12-05', '2005-12-06', '2005-12-07', '2005-12-08', '2005-12-09', '2005-12-12', '2005-12-13', '2005-12-14', '2005-12-15', '2005-12-16', '2005-12-19', '2005-12-20', '2005-12-21', '2005-12-22', '2005-12-23', '2005-12-26', '2005-12-27', '2005-12-28', '2005-12-29', '2005-12-30', '2006-01-04', '2006-01-05', '2006-01-06', '2006-01-09', '2006-01-10', '2006-01-11', '2006-01-12', '2006-01-13', '2006-01-16', '2006-01-17', '2006-01-18', '2006-01-19', '2006-01-20', '2006-01-23', '2006-01-24', '2006-01-25', '2006-02-06', '2006-02-07', '2006-02-08', '2006-02-09', '2006-02-10', '2006-02-13', '2006-02-14', '2006-02-15', '2006-02-16', '2006-02-17', '2006-02-20', '2006-02-21', '2006-02-22', '2006-02-23', '2006-02-24', '2006-02-27', '2006-02-28', '2006-03-01', '2006-03-02', '2006-03-03', '2006-03-06', '2006-03-07', '2006-03-08', '2006-03-09', '2006-03-10', '2006-03-13', '2006-03-14', '2006-03-15', '2006-03-16', '2006-03-17', '2006-03-20', '2006-03-21', '2006-03-22', '2006-03-23', '2006-03-24', '2006-03-27', '2006-03-28', '2006-03-29', '2006-03-30', '2006-03-31', '2006-04-03', '2006-04-04', '2006-04-05', '2006-04-06', '2006-04-07', '2006-04-10', '2006-04-11', '2006-04-12', '2006-04-13', '2006-04-14', '2006-04-17', '2006-04-18', '2006-04-19', '2006-04-20', '2006-04-21', '2006-04-24', '2006-04-25', '2006-04-26', '2006-04-27', '2006-04-28', '2006-05-08', '2006-05-09', '2006-05-10', '2006-05-11', '2006-05-12', '2006-05-15', '2006-05-16', '2006-05-17', '2006-05-18', '2006-05-19', '2006-05-22', '2006-05-23', '2006-05-24', '2006-05-25', '2006-05-26', '2006-05-29', '2006-05-30', '2006-05-31', '2006-06-01', '2006-06-02', '2006-06-05', '2006-06-06', '2006-06-07', '2006-06-08', '2006-06-09', '2006-06-12', '2006-06-13', '2006-06-14', '2006-06-15', '2006-06-16', '2006-06-19', '2006-06-20', '2006-06-21', '2006-06-22', '2006-06-23', '2006-06-26', '2006-06-27', '2006-06-28', '2006-06-29', '2006-06-30', '2006-07-03', '2006-07-04', '2006-07-05', '2006-07-06', '2006-07-07', '2006-07-10', '2006-07-11', '2006-07-12', '2006-07-13', '2006-07-14', '2006-07-17', '2006-07-18', '2006-07-19', '2006-07-20', '2006-07-21', '2006-07-24', '2006-07-25', '2006-07-26', '2006-07-27', '2006-07-28', '2006-07-31', '2006-08-01', '2006-08-02', '2006-08-03', '2006-08-04', '2006-08-07', '2006-08-08', '2006-08-09', '2006-08-10', '2006-08-11', '2006-08-14', '2006-08-15', '2006-08-16', '2006-08-17', '2006-08-18', '2006-08-21', '2006-08-22', '2006-08-23', '2006-08-24', '2006-08-25', '2006-08-28', '2006-08-29', '2006-08-30', '2006-08-31', '2006-09-01', '2006-09-04', '2006-09-05', '2006-09-06', '2006-09-07', '2006-09-08', '2006-09-11', '2006-09-12', '2006-09-13', '2006-09-14', '2006-09-15', '2006-09-18', '2006-09-19', '2006-09-20', '2006-09-21', '2006-09-22', '2006-09-25', '2006-09-26', '2006-09-27', '2006-09-28', '2006-09-29', '2006-10-09', '2006-10-10', '2006-10-11', '2006-10-12', '2006-10-13', '2006-10-16', '2006-10-17', '2006-10-18', '2006-10-19', '2006-10-20', '2006-10-23', '2006-10-24', '2006-10-25', '2006-10-26', '2006-10-27', '2006-10-30', '2006-10-31', '2006-11-01', '2006-11-02', '2006-11-03', '2006-11-06', '2006-11-07', '2006-11-08', '2006-11-09', '2006-11-10', '2006-11-13', '2006-11-14', '2006-11-15', '2006-11-16', '2006-11-17', '2006-11-20', '2006-11-21', '2006-11-22', '2006-11-23', '2006-11-24', '2006-11-27', '2006-11-28', '2006-11-29', '2006-11-30', '2006-12-01', '2006-12-04', '2006-12-05', '2006-12-06', '2006-12-07', '2006-12-08', '2006-12-11', '2006-12-12', '2006-12-13', '2006-12-14', '2006-12-15', '2006-12-18', '2006-12-19', '2006-12-20', '2006-12-21', '2006-12-22', '2006-12-25', '2006-12-26', '2006-12-27', '2006-12-28', '2006-12-29', '2007-01-04', '2007-01-05', '2007-01-08', '2007-01-09', '2007-01-10', '2007-01-11', '2007-01-12', '2007-01-15', '2007-01-16', '2007-01-17', '2007-01-18', '2007-01-19', '2007-01-22', '2007-01-23', '2007-01-24', '2007-01-25', '2007-01-26', '2007-01-29', '2007-01-30', '2007-01-31', '2007-02-01', '2007-02-02', '2007-02-05', '2007-02-06', '2007-02-07', '2007-02-08', '2007-02-09', '2007-02-12', '2007-02-13', '2007-02-14', '2007-02-15', '2007-02-16', '2007-02-26', '2007-02-27', '2007-02-28', '2007-03-01', '2007-03-02', '2007-03-05', '2007-03-06', '2007-03-07', '2007-03-08', '2007-03-09', '2007-03-12', '2007-03-13', '2007-03-14', '2007-03-15', '2007-03-16', '2007-03-19', '2007-03-20', '2007-03-21', '2007-03-22', '2007-03-23', '2007-03-26', '2007-03-27', '2007-03-28', '2007-03-29', '2007-03-30', '2007-04-02', '2007-04-03', '2007-04-04', '2007-04-05', '2007-04-06', '2007-04-09', '2007-04-10', '2007-04-11', '2007-04-12', '2007-04-13', '2007-04-16', '2007-04-17', '2007-04-18', '2007-04-19', '2007-04-20', '2007-04-23', '2007-04-24', '2007-04-25', '2007-04-26', '2007-04-27', '2007-04-30', '2007-05-08', '2007-05-09', '2007-05-10', '2007-05-11', '2007-05-14', '2007-05-15', '2007-05-16', '2007-05-17', '2007-05-18', '2007-05-21', '2007-05-22', '2007-05-23', '2007-05-24', '2007-05-25', '2007-05-28', '2007-05-29', '2007-05-30', '2007-05-31', '2007-06-01', '2007-06-04', '2007-06-05', '2007-06-06', '2007-06-07', '2007-06-08', '2007-06-11', '2007-06-12', '2007-06-13', '2007-06-14', '2007-06-15', '2007-06-18', '2007-06-19', '2007-06-20', '2007-06-21', '2007-06-22', '2007-06-25', '2007-06-26', '2007-06-27', '2007-06-28', '2007-06-29', '2007-07-02', '2007-07-03', '2007-07-04', '2007-07-05', '2007-07-06', '2007-07-09', '2007-07-10', '2007-07-11', '2007-07-12', '2007-07-13', '2007-07-16', '2007-07-17', '2007-07-18', '2007-07-19', '2007-07-20', '2007-07-23', '2007-07-24', '2007-07-25', '2007-07-26', '2007-07-27', '2007-07-30', '2007-07-31', '2007-08-01', '2007-08-02', '2007-08-03', '2007-08-06', '2007-08-07', '2007-08-08', '2007-08-09', '2007-08-10', '2007-08-13', '2007-08-14', '2007-08-15', '2007-08-16', '2007-08-17', '2007-08-20', '2007-08-21', '2007-08-22', '2007-08-23', '2007-08-24', '2007-08-27', '2007-08-28', '2007-08-29', '2007-08-30', '2007-08-31', '2007-09-03', '2007-09-04', '2007-09-05', '2007-09-06', '2007-09-07', '2007-09-10', '2007-09-11', '2007-09-12', '2007-09-13', '2007-09-14', '2007-09-17', '2007-09-18', '2007-09-19', '2007-09-20', '2007-09-21', '2007-09-24', '2007-09-25', '2007-09-26', '2007-09-27', '2007-09-28', '2007-10-08', '2007-10-09', '2007-10-10', '2007-10-11', '2007-10-12', '2007-10-15', '2007-10-16', '2007-10-17', '2007-10-18', '2007-10-19', '2007-10-22', '2007-10-23', '2007-10-24', '2007-10-25', '2007-10-26', '2007-10-29', '2007-10-30', '2007-10-31', '2007-11-01', '2007-11-02', '2007-11-05', '2007-11-06', '2007-11-07', '2007-11-08', '2007-11-09', '2007-11-12', '2007-11-13', '2007-11-14', '2007-11-15', '2007-11-16', '2007-11-19', '2007-11-20', '2007-11-21', '2007-11-22', '2007-11-23', '2007-11-26', '2007-11-27', '2007-11-28', '2007-11-29', '2007-11-30', '2007-12-03', '2007-12-04', '2007-12-05', '2007-12-06', '2007-12-07', '2007-12-10', '2007-12-11', '2007-12-12', '2007-12-13', '2007-12-14', '2007-12-17', '2007-12-18', '2007-12-19', '2007-12-20', '2007-12-21', '2007-12-24', '2007-12-25', '2007-12-26', '2007-12-27', '2007-12-28', '2008-01-02', '2008-01-03', '2008-01-04', '2008-01-07', '2008-01-08', '2008-01-09', '2008-01-10', '2008-01-11', '2008-01-14', '2008-01-15', '2008-01-16', '2008-01-17', '2008-01-18', '2008-01-21', '2008-01-22', '2008-01-23', '2008-01-24', '2008-01-25', '2008-01-28', '2008-01-29', '2008-01-30', '2008-01-31', '2008-02-01', '2008-02-04', '2008-02-05', '2008-02-13', '2008-02-14', '2008-02-15', '2008-02-18', '2008-02-19', '2008-02-20', '2008-02-21', '2008-02-22', '2008-02-25', '2008-02-26', '2008-02-27', '2008-02-28', '2008-02-29', '2008-03-03', '2008-03-04', '2008-03-05', '2008-03-06', '2008-03-07', '2008-03-10', '2008-03-11', '2008-03-12', '2008-03-13', '2008-03-14', '2008-03-17', '2008-03-18', '2008-03-19', '2008-03-20', '2008-03-21', '2008-03-24', '2008-03-25', '2008-03-26', '2008-03-27', '2008-03-28', '2008-03-31', '2008-04-01', '2008-04-02', '2008-04-03', '2008-04-07', '2008-04-08', '2008-04-09', '2008-04-10', '2008-04-11', '2008-04-14', '2008-04-15', '2008-04-16', '2008-04-17', '2008-04-18', '2008-04-21', '2008-04-22', '2008-04-23', '2008-04-24', '2008-04-25', '2008-04-28', '2008-04-29', '2008-04-30', '2008-05-05', '2008-05-06', '2008-05-07', '2008-05-08', '2008-05-09', '2008-05-12', '2008-05-13', '2008-05-14', '2008-05-15', '2008-05-16', '2008-05-19', '2008-05-20', '2008-05-21', '2008-05-22', '2008-05-23', '2008-05-26', '2008-05-27', '2008-05-28', '2008-05-29', '2008-05-30', '2008-06-02', '2008-06-03', '2008-06-04', '2008-06-05', '2008-06-06', '2008-06-10', '2008-06-11', '2008-06-12', '2008-06-13', '2008-06-16', '2008-06-17', '2008-06-18', '2008-06-19', '2008-06-20', '2008-06-23', '2008-06-24', '2008-06-25', '2008-06-26', '2008-06-27', '2008-06-30', '2008-07-01', '2008-07-02', '2008-07-03', '2008-07-04', '2008-07-07', '2008-07-08', '2008-07-09', '2008-07-10', '2008-07-11', '2008-07-14', '2008-07-15', '2008-07-16', '2008-07-17', '2008-07-18', '2008-07-21', '2008-07-22', '2008-07-23', '2008-07-24', '2008-07-25', '2008-07-28', '2008-07-29', '2008-07-30', '2008-07-31', '2008-08-01', '2008-08-04', '2008-08-05', '2008-08-06', '2008-08-07', '2008-08-08', '2008-08-11', '2008-08-12', '2008-08-13', '2008-08-14', '2008-08-15', '2008-08-18', '2008-08-19', '2008-08-20', '2008-08-21', '2008-08-22', '2008-08-25', '2008-08-26', '2008-08-27', '2008-08-28', '2008-08-29', '2008-09-01', '2008-09-02', '2008-09-03', '2008-09-04', '2008-09-05', '2008-09-08', '2008-09-09', '2008-09-10', '2008-09-11', '2008-09-12', '2008-09-16', '2008-09-17', '2008-09-18', '2008-09-19', '2008-09-22', '2008-09-23', '2008-09-24', '2008-09-25', '2008-09-26', '2008-10-06', '2008-10-07', '2008-10-08', '2008-10-09', '2008-10-10', '2008-10-13', '2008-10-14', '2008-10-15', '2008-10-16', '2008-10-17', '2008-10-20', '2008-10-21', '2008-10-22', '2008-10-23', '2008-10-24', '2008-10-27', '2008-10-28', '2008-10-29', '2008-10-30', '2008-10-31', '2008-11-03', '2008-11-04', '2008-11-05', '2008-11-06', '2008-11-07', '2008-11-10', '2008-11-11', '2008-11-12', '2008-11-13', '2008-11-14', '2008-11-17', '2008-11-18', '2008-11-19', '2008-11-20', '2008-11-21', '2008-11-24', '2008-11-25', '2008-11-26', '2008-11-27', '2008-11-28', '2008-12-01', '2008-12-02', '2008-12-03', '2008-12-04', '2008-12-05', '2008-12-08', '2008-12-09', '2008-12-10', '2008-12-11', '2008-12-12', '2008-12-15', '2008-12-16', '2008-12-17', '2008-12-18', '2008-12-19', '2008-12-22', '2008-12-23', '2008-12-24', '2008-12-25', '2008-12-26', '2008-12-29', '2008-12-30', '2008-12-31', '2009-01-05', '2009-01-06', '2009-01-07', '2009-01-08', '2009-01-09', '2009-01-12', '2009-01-13', '2009-01-14', '2009-01-15', '2009-01-16', '2009-01-19', '2009-01-20', '2009-01-21', '2009-01-22', '2009-01-23', '2009-02-02', '2009-02-03', '2009-02-04', '2009-02-05', '2009-02-06', '2009-02-09', '2009-02-10', '2009-02-11', '2009-02-12', '2009-02-13', '2009-02-16', '2009-02-17', '2009-02-18', '2009-02-19', '2009-02-20', '2009-02-23', '2009-02-24', '2009-02-25', '2009-02-26', '2009-02-27', '2009-03-02', '2009-03-03', '2009-03-04', '2009-03-05', '2009-03-06', '2009-03-09', '2009-03-10', '2009-03-11', '2009-03-12', '2009-03-13', '2009-03-16', '2009-03-17', '2009-03-18', '2009-03-19', '2009-03-20', '2009-03-23', '2009-03-24', '2009-03-25', '2009-03-26', '2009-03-27', '2009-03-30', '2009-03-31', '2009-04-01', '2009-04-02', '2009-04-03', '2009-04-07', '2009-04-08', '2009-04-09', '2009-04-10', '2009-04-13', '2009-04-14', '2009-04-15', '2009-04-16', '2009-04-17', '2009-04-20', '2009-04-21', '2009-04-22', '2009-04-23', '2009-04-24', '2009-04-27', '2009-04-28', '2009-04-29', '2009-04-30', '2009-05-04', '2009-05-05', '2009-05-06', '2009-05-07', '2009-05-08', '2009-05-11', '2009-05-12', '2009-05-13', '2009-05-14', '2009-05-15', '2009-05-18', '2009-05-19', '2009-05-20', '2009-05-21', '2009-05-22', '2009-05-25', '2009-05-26', '2009-05-27', '2009-06-01', '2009-06-02', '2009-06-03', '2009-06-04', '2009-06-05', '2009-06-08', '2009-06-09', '2009-06-10', '2009-06-11', '2009-06-12', '2009-06-15', '2009-06-16', '2009-06-17', '2009-06-18', '2009-06-19', '2009-06-22', '2009-06-23', '2009-06-24', '2009-06-25', '2009-06-26', '2009-06-29', '2009-06-30', '2009-07-01', '2009-07-02', '2009-07-03', '2009-07-06', '2009-07-07', '2009-07-08', '2009-07-09', '2009-07-10', '2009-07-13', '2009-07-14', '2009-07-15', '2009-07-16', '2009-07-17', '2009-07-20', '2009-07-21', '2009-07-22', '2009-07-23', '2009-07-24', '2009-07-27', '2009-07-28', '2009-07-29', '2009-07-30', '2009-07-31', '2009-08-03', '2009-08-04', '2009-08-05', '2009-08-06', '2009-08-07', '2009-08-10', '2009-08-11', '2009-08-12', '2009-08-13', '2009-08-14', '2009-08-17', '2009-08-18', '2009-08-19', '2009-08-20', '2009-08-21', '2009-08-24', '2009-08-25', '2009-08-26', '2009-08-27', '2009-08-28', '2009-08-31', '2009-09-01', '2009-09-02', '2009-09-03', '2009-09-04', '2009-09-07', '2009-09-08', '2009-09-09', '2009-09-10', '2009-09-11', '2009-09-14', '2009-09-15', '2009-09-16', '2009-09-17', '2009-09-18', '2009-09-21', '2009-09-22', '2009-09-23', '2009-09-24', '2009-09-25', '2009-09-28', '2009-09-29', '2009-09-30', '2009-10-09', '2009-10-12', '2009-10-13', '2009-10-14', '2009-10-15', '2009-10-16', '2009-10-19', '2009-10-20', '2009-10-21', '2009-10-22', '2009-10-23', '2009-10-26', '2009-10-27', '2009-10-28', '2009-10-29', '2009-10-30', '2009-11-02', '2009-11-03', '2009-11-04', '2009-11-05', '2009-11-06', '2009-11-09', '2009-11-10', '2009-11-11', '2009-11-12', '2009-11-13', '2009-11-16', '2009-11-17', '2009-11-18', '2009-11-19', '2009-11-20', '2009-11-23', '2009-11-24', '2009-11-25', '2009-11-26', '2009-11-27', '2009-11-30', '2009-12-01', '2009-12-02', '2009-12-03', '2009-12-04', '2009-12-07', '2009-12-08', '2009-12-09', '2009-12-10', '2009-12-11', '2009-12-14', '2009-12-15', '2009-12-16', '2009-12-17', '2009-12-18', '2009-12-21', '2009-12-22', '2009-12-23', '2009-12-24', '2009-12-25', '2009-12-28', '2009-12-29', '2009-12-30', '2009-12-31', '2010-01-04', '2010-01-05', '2010-01-06', '2010-01-07', '2010-01-08', '2010-01-11', '2010-01-12', '2010-01-13', '2010-01-14', '2010-01-15', '2010-01-18', '2010-01-19', '2010-01-20', '2010-01-21', '2010-01-22', '2010-01-25', '2010-01-26', '2010-01-27', '2010-01-28', '2010-01-29', '2010-02-01', '2010-02-02', '2010-02-03', '2010-02-04', '2010-02-05', '2010-02-08', '2010-02-09', '2010-02-10', '2010-02-11', '2010-02-12', '2010-02-22', '2010-02-23', '2010-02-24', '2010-02-25', '2010-02-26', '2010-03-01', '2010-03-02', '2010-03-03', '2010-03-04', '2010-03-05', '2010-03-08', '2010-03-09', '2010-03-10', '2010-03-11', '2010-03-12', '2010-03-15', '2010-03-16', '2010-03-17', '2010-03-18', '2010-03-19', '2010-03-22', '2010-03-23', '2010-03-24', '2010-03-25', '2010-03-26', '2010-03-29', '2010-03-30', '2010-03-31', '2010-04-01', '2010-04-02', '2010-04-06', '2010-04-07', '2010-04-08', '2010-04-09', '2010-04-12', '2010-04-13', '2010-04-14', '2010-04-15', '2010-04-16', '2010-04-19', '2010-04-20', '2010-04-21', '2010-04-22', '2010-04-23', '2010-04-26', '2010-04-27', '2010-04-28', '2010-04-29', '2010-04-30', '2010-05-04', '2010-05-05', '2010-05-06', '2010-05-07', '2010-05-10', '2010-05-11', '2010-05-12', '2010-05-13', '2010-05-14', '2010-05-17', '2010-05-18', '2010-05-19', '2010-05-20', '2010-05-21', '2010-05-24', '2010-05-25', '2010-05-26', '2010-05-27', '2010-05-28', '2010-05-31', '2010-06-01', '2010-06-02', '2010-06-03', '2010-06-04', '2010-06-07', '2010-06-08', '2010-06-09', '2010-06-10', '2010-06-11', '2010-06-17', '2010-06-18', '2010-06-21', '2010-06-22', '2010-06-23', '2010-06-24', '2010-06-25', '2010-06-28', '2010-06-29', '2010-06-30', '2010-07-01', '2010-07-02', '2010-07-05', '2010-07-06', '2010-07-07', '2010-07-08', '2010-07-09', '2010-07-12', '2010-07-13', '2010-07-14', '2010-07-15', '2010-07-16', '2010-07-19', '2010-07-20', '2010-07-21', '2010-07-22', '2010-07-23', '2010-07-26', '2010-07-27', '2010-07-28', '2010-07-29', '2010-07-30', '2010-08-02', '2010-08-03', '2010-08-04', '2010-08-05', '2010-08-06', '2010-08-09', '2010-08-10', '2010-08-11', '2010-08-12', '2010-08-13', '2010-08-16', '2010-08-17', '2010-08-18', '2010-08-19', '2010-08-20', '2010-08-23', '2010-08-24', '2010-08-25', '2010-08-26', '2010-08-27', '2010-08-30', '2010-08-31', '2010-09-01', '2010-09-02', '2010-09-03', '2010-09-06', '2010-09-07', '2010-09-08', '2010-09-09', '2010-09-10', '2010-09-13', '2010-09-14', '2010-09-15', '2010-09-16', '2010-09-17', '2010-09-20', '2010-09-21', '2010-09-27', '2010-09-28', '2010-09-29', '2010-09-30', '2010-10-08', '2010-10-11', '2010-10-12', '2010-10-13', '2010-10-14', '2010-10-15', '2010-10-18', '2010-10-19', '2010-10-20', '2010-10-21', '2010-10-22', '2010-10-25', '2010-10-26', '2010-10-27', '2010-10-28', '2010-10-29', '2010-11-01', '2010-11-02', '2010-11-03', '2010-11-04', '2010-11-05', '2010-11-08', '2010-11-09', '2010-11-10', '2010-11-11', '2010-11-12', '2010-11-15', '2010-11-16', '2010-11-17', '2010-11-18', '2010-11-19', '2010-11-22', '2010-11-23', '2010-11-24', '2010-11-25', '2010-11-26', '2010-11-29', '2010-11-30', '2010-12-01', '2010-12-02', '2010-12-03', '2010-12-06', '2010-12-07', '2010-12-08', '2010-12-09', '2010-12-10', '2010-12-13', '2010-12-14', '2010-12-15', '2010-12-16', '2010-12-17', '2010-12-20', '2010-12-21', '2010-12-22', '2010-12-23', '2010-12-24', '2010-12-27', '2010-12-28', '2010-12-29', '2010-12-30', '2010-12-31', '2011-01-04', '2011-01-05', '2011-01-06', '2011-01-07', '2011-01-10', '2011-01-11', '2011-01-12', '2011-01-13', '2011-01-14', '2011-01-17', '2011-01-18', '2011-01-19', '2011-01-20', '2011-01-21', '2011-01-24', '2011-01-25', '2011-01-26', '2011-01-27', '2011-01-28', '2011-01-31', '2011-02-01', '2011-02-09', '2011-02-10', '2011-02-11', '2011-02-14', '2011-02-15', '2011-02-16', '2011-02-17', '2011-02-18', '2011-02-21', '2011-02-22', '2011-02-23', '2011-02-24', '2011-02-25', '2011-02-28', '2011-03-01', '2011-03-02', '2011-03-03', '2011-03-04', '2011-03-07', '2011-03-08', '2011-03-09', '2011-03-10', '2011-03-11', '2011-03-14', '2011-03-15', '2011-03-16', '2011-03-17', '2011-03-18', '2011-03-21', '2011-03-22', '2011-03-23', '2011-03-24', '2011-03-25', '2011-03-28', '2011-03-29', '2011-03-30', '2011-03-31', '2011-04-01', '2011-04-06', '2011-04-07', '2011-04-08', '2011-04-11', '2011-04-12', '2011-04-13', '2011-04-14', '2011-04-15', '2011-04-18', '2011-04-19', '2011-04-20', '2011-04-21', '2011-04-22', '2011-04-25', '2011-04-26', '2011-04-27', '2011-04-28', '2011-04-29', '2011-05-03', '2011-05-04', '2011-05-05', '2011-05-06', '2011-05-09', '2011-05-10', '2011-05-11', '2011-05-12', '2011-05-13', '2011-05-16', '2011-05-17', '2011-05-18', '2011-05-19', '2011-05-20', '2011-05-23', '2011-05-24', '2011-05-25', '2011-05-26', '2011-05-27', '2011-05-30', '2011-05-31', '2011-06-01', '2011-06-02', '2011-06-03', '2011-06-07', '2011-06-08', '2011-06-09', '2011-06-10', '2011-06-13', '2011-06-14', '2011-06-15', '2011-06-16', '2011-06-17', '2011-06-20', '2011-06-21', '2011-06-22', '2011-06-23', '2011-06-24', '2011-06-27', '2011-06-28', '2011-06-29', '2011-06-30', '2011-07-01', '2011-07-04', '2011-07-05', '2011-07-06', '2011-07-07', '2011-07-08', '2011-07-11', '2011-07-12', '2011-07-13', '2011-07-14', '2011-07-15', '2011-07-18', '2011-07-19', '2011-07-20', '2011-07-21', '2011-07-22', '2011-07-25', '2011-07-26', '2011-07-27', '2011-07-28', '2011-07-29', '2011-08-01', '2011-08-02', '2011-08-03', '2011-08-04', '2011-08-05', '2011-08-08', '2011-08-09', '2011-08-10', '2011-08-11', '2011-08-12', '2011-08-15', '2011-08-16', '2011-08-17', '2011-08-18', '2011-08-19', '2011-08-22', '2011-08-23', '2011-08-24', '2011-08-25', '2011-08-26', '2011-08-29', '2011-08-30', '2011-08-31', '2011-09-01', '2011-09-02', '2011-09-05', '2011-09-06', '2011-09-07', '2011-09-08', '2011-09-09', '2011-09-13', '2011-09-14', '2011-09-15', '2011-09-16', '2011-09-19', '2011-09-20', '2011-09-21', '2011-09-22', '2011-09-23', '2011-09-26', '2011-09-27', '2011-09-28', '2011-09-29', '2011-09-30', '2011-10-10', '2011-10-11', '2011-10-12', '2011-10-13', '2011-10-14', '2011-10-17', '2011-10-18', '2011-10-19', '2011-10-20', '2011-10-21', '2011-10-24', '2011-10-25', '2011-10-26', '2011-10-27', '2011-10-28', '2011-10-31', '2011-11-01', '2011-11-02', '2011-11-03', '2011-11-04', '2011-11-07', '2011-11-08', '2011-11-09', '2011-11-10', '2011-11-11', '2011-11-14', '2011-11-15', '2011-11-16', '2011-11-17', '2011-11-18', '2011-11-21', '2011-11-22', '2011-11-23', '2011-11-24', '2011-11-25', '2011-11-28', '2011-11-29', '2011-11-30', '2011-12-01', '2011-12-02', '2011-12-05', '2011-12-06', '2011-12-07', '2011-12-08', '2011-12-09', '2011-12-12', '2011-12-13', '2011-12-14', '2011-12-15', '2011-12-16', '2011-12-19', '2011-12-20', '2011-12-21', '2011-12-22', '2011-12-23', '2011-12-26', '2011-12-27', '2011-12-28', '2011-12-29', '2011-12-30', '2012-01-04', '2012-01-05', '2012-01-06', '2012-01-09', '2012-01-10', '2012-01-11', '2012-01-12', '2012-01-13', '2012-01-16', '2012-01-17', '2012-01-18', '2012-01-19', '2012-01-20', '2012-01-30', '2012-01-31', '2012-02-01', '2012-02-02', '2012-02-03', '2012-02-06', '2012-02-07', '2012-02-08', '2012-02-09', '2012-02-10', '2012-02-13', '2012-02-14', '2012-02-15', '2012-02-16', '2012-02-17', '2012-02-20', '2012-02-21', '2012-02-22', '2012-02-23', '2012-02-24', '2012-02-27', '2012-02-28', '2012-02-29', '2012-03-01', '2012-03-02', '2012-03-05', '2012-03-06', '2012-03-07', '2012-03-08', '2012-03-09', '2012-03-12', '2012-03-13', '2012-03-14', '2012-03-15', '2012-03-16', '2012-03-19', '2012-03-20', '2012-03-21', '2012-03-22', '2012-03-23', '2012-03-26', '2012-03-27', '2012-03-28', '2012-03-29', '2012-03-30', '2012-04-05', '2012-04-06', '2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12', '2012-04-13', '2012-04-16', '2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20', '2012-04-23', '2012-04-24', '2012-04-25', '2012-04-26', '2012-04-27', '2012-05-02', '2012-05-03', '2012-05-04', '2012-05-07', '2012-05-08', '2012-05-09', '2012-05-10', '2012-05-11', '2012-05-14', '2012-05-15', '2012-05-16', '2012-05-17', '2012-05-18', '2012-05-21', '2012-05-22', '2012-05-23', '2012-05-24', '2012-05-25', '2012-05-28', '2012-05-29', '2012-05-30', '2012-05-31', '2012-06-01', '2012-06-04', '2012-06-05', '2012-06-06', '2012-06-07', '2012-06-08', '2012-06-11', '2012-06-12', '2012-06-13', '2012-06-14', '2012-06-15', '2012-06-18', '2012-06-19', '2012-06-20', '2012-06-21', '2012-06-25', '2012-06-26', '2012-06-27', '2012-06-28', '2012-06-29', '2012-07-02', '2012-07-03', '2012-07-04', '2012-07-05', '2012-07-06', '2012-07-09', '2012-07-10', '2012-07-11', '2012-07-12', '2012-07-13', '2012-07-16', '2012-07-17', '2012-07-18', '2012-07-19', '2012-07-20', '2012-07-23', '2012-07-24', '2012-07-25', '2012-07-26', '2012-07-27', '2012-07-30', '2012-07-31', '2012-08-01', '2012-08-02', '2012-08-03', '2012-08-06', '2012-08-07', '2012-08-08', '2012-08-09', '2012-08-10', '2012-08-13', '2012-08-14', '2012-08-15', '2012-08-16', '2012-08-17', '2012-08-20', '2012-08-21', '2012-08-22', '2012-08-23', '2012-08-24', '2012-08-27', '2012-08-28', '2012-08-29', '2012-08-30', '2012-08-31', '2012-09-03', '2012-09-04', '2012-09-05', '2012-09-06', '2012-09-07', '2012-09-10', '2012-09-11', '2012-09-12', '2012-09-13', '2012-09-14', '2012-09-17', '2012-09-18', '2012-09-19', '2012-09-20', '2012-09-21', '2012-09-24', '2012-09-25', '2012-09-26', '2012-09-27', '2012-09-28', '2012-10-08', '2012-10-09', '2012-10-10', '2012-10-11', '2012-10-12', '2012-10-15', '2012-10-16', '2012-10-17', '2012-10-18', '2012-10-19', '2012-10-22', '2012-10-23', '2012-10-24', '2012-10-25', '2012-10-26', '2012-10-29', '2012-10-30', '2012-10-31', '2012-11-01', '2012-11-02', '2012-11-05', '2012-11-06', '2012-11-07', '2012-11-08', '2012-11-09', '2012-11-12', '2012-11-13', '2012-11-14', '2012-11-15', '2012-11-16', '2012-11-19', '2012-11-20', '2012-11-21', '2012-11-22', '2012-11-23', '2012-11-26', '2012-11-27', '2012-11-28', '2012-11-29', '2012-11-30', '2012-12-03', '2012-12-04', '2012-12-05', '2012-12-06', '2012-12-07', '2012-12-10', '2012-12-11', '2012-12-12', '2012-12-13', '2012-12-14', '2012-12-17', '2012-12-18', '2012-12-19', '2012-12-20', '2012-12-21', '2012-12-24', '2012-12-25', '2012-12-26', '2012-12-27', '2012-12-28', '2012-12-31', '2013-01-04', '2013-01-07', '2013-01-08', '2013-01-09', '2013-01-10', '2013-01-11', '2013-01-14', '2013-01-15', '2013-01-16', '2013-01-17', '2013-01-18', '2013-01-21', '2013-01-22', '2013-01-23', '2013-01-24', '2013-01-25', '2013-01-28', '2013-01-29', '2013-01-30', '2013-01-31', '2013-02-01', '2013-02-04', '2013-02-05', '2013-02-06', '2013-02-07', '2013-02-08', '2013-02-18', '2013-02-19', '2013-02-20', '2013-02-21', '2013-02-22', '2013-02-25', '2013-02-26', '2013-02-27', '2013-02-28', '2013-03-01', '2013-03-04', '2013-03-05', '2013-03-06', '2013-03-07', '2013-03-08', '2013-03-11', '2013-03-12', '2013-03-13', '2013-03-14', '2013-03-15', '2013-03-18', '2013-03-19', '2013-03-20', '2013-03-21', '2013-03-22', '2013-03-25', '2013-03-26', '2013-03-27', '2013-03-28', '2013-03-29', '2013-04-01', '2013-04-02', '2013-04-03', '2013-04-08', '2013-04-09', '2013-04-10', '2013-04-11', '2013-04-12', '2013-04-15', '2013-04-16', '2013-04-17', '2013-04-18', '2013-04-19', '2013-04-22', '2013-04-23', '2013-04-24', '2013-04-25', '2013-04-26', '2013-05-02', '2013-05-03', '2013-05-06', '2013-05-07', '2013-05-08', '2013-05-09', '2013-05-10', '2013-05-13', '2013-05-14', '2013-05-15', '2013-05-16', '2013-05-17', '2013-05-20', '2013-05-21', '2013-05-22', '2013-05-23', '2013-05-24', '2013-05-27', '2013-05-28', '2013-05-29', '2013-05-30', '2013-05-31', '2013-06-03', '2013-06-04', '2013-06-05', '2013-06-06', '2013-06-07', '2013-06-13', '2013-06-14', '2013-06-17', '2013-06-18', '2013-06-19', '2013-06-20', '2013-06-21', '2013-06-24', '2013-06-25', '2013-06-26', '2013-06-27', '2013-06-28', '2013-07-01', '2013-07-02', '2013-07-03', '2013-07-04', '2013-07-05', '2013-07-08', '2013-07-09', '2013-07-10', '2013-07-11', '2013-07-12', '2013-07-15', '2013-07-16', '2013-07-17', '2013-07-18', '2013-07-19', '2013-07-22', '2013-07-23', '2013-07-24', '2013-07-25', '2013-07-26', '2013-07-29', '2013-07-30', '2013-07-31', '2013-08-01', '2013-08-02', '2013-08-05', '2013-08-06', '2013-08-07', '2013-08-08', '2013-08-09', '2013-08-12', '2013-08-13', '2013-08-14', '2013-08-15', '2013-08-16', '2013-08-19', '2013-08-20', '2013-08-21', '2013-08-22', '2013-08-23', '2013-08-26', '2013-08-27', '2013-08-28', '2013-08-29', '2013-08-30', '2013-09-02', '2013-09-03', '2013-09-04', '2013-09-05', '2013-09-06', '2013-09-09', '2013-09-10', '2013-09-11', '2013-09-12', '2013-09-13', '2013-09-16', '2013-09-17', '2013-09-18', '2013-09-23', '2013-09-24', '2013-09-25', '2013-09-26', '2013-09-27', '2013-09-30', '2013-10-08', '2013-10-09', '2013-10-10', '2013-10-11', '2013-10-14', '2013-10-15', '2013-10-16', '2013-10-17', '2013-10-18', '2013-10-21', '2013-10-22', '2013-10-23', '2013-10-24', '2013-10-25', '2013-10-28', '2013-10-29', '2013-10-30', '2013-10-31', '2013-11-01', '2013-11-04', '2013-11-05', '2013-11-06', '2013-11-07', '2013-11-08', '2013-11-11', '2013-11-12', '2013-11-13', '2013-11-14', '2013-11-15', '2013-11-18', '2013-11-19', '2013-11-20', '2013-11-21', '2013-11-22', '2013-11-25', '2013-11-26', '2013-11-27', '2013-11-28', '2013-11-29', '2013-12-02', '2013-12-03', '2013-12-04', '2013-12-05', '2013-12-06', '2013-12-09', '2013-12-10', '2013-12-11', '2013-12-12', '2013-12-13', '2013-12-16', '2013-12-17', '2013-12-18', '2013-12-19', '2013-12-20', '2013-12-23', '2013-12-24', '2013-12-25', '2013-12-26', '2013-12-27', '2013-12-30', '2013-12-31', '2014-01-02', '2014-01-03', '2014-01-06', '2014-01-07', '2014-01-08', '2014-01-09', '2014-01-10', '2014-01-13', '2014-01-14', '2014-01-15', '2014-01-16', '2014-01-17', '2014-01-20', '2014-01-21', '2014-01-22', '2014-01-23', '2014-01-24', '2014-01-27', '2014-01-28', '2014-01-29', '2014-01-30', '2014-02-07', '2014-02-10', '2014-02-11', '2014-02-12', '2014-02-13', '2014-02-14', '2014-02-17', '2014-02-18', '2014-02-19', '2014-02-20', '2014-02-21', '2014-02-24', '2014-02-25', '2014-02-26', '2014-02-27', '2014-02-28', '2014-03-03', '2014-03-04', '2014-03-05', '2014-03-06', '2014-03-07', '2014-03-10', '2014-03-11', '2014-03-12', '2014-03-13', '2014-03-14', '2014-03-17', '2014-03-18', '2014-03-19', '2014-03-20', '2014-03-21', '2014-03-24', '2014-03-25', '2014-03-26', '2014-03-27', '2014-03-28', '2014-03-31', '2014-04-01', '2014-04-02', '2014-04-03', '2014-04-04', '2014-04-08', '2014-04-09', '2014-04-10', '2014-04-11', '2014-04-14', '2014-04-15', '2014-04-16', '2014-04-17', '2014-04-18', '2014-04-21', '2014-04-22', '2014-04-23', '2014-04-24', '2014-04-25', '2014-04-28', '2014-04-29', '2014-04-30', '2014-05-05', '2014-05-06', '2014-05-07', '2014-05-08', '2014-05-09', '2014-05-12', '2014-05-13', '2014-05-14', '2014-05-15', '2014-05-16', '2014-05-19', '2014-05-20', '2014-05-21', '2014-05-22', '2014-05-23', '2014-05-26', '2014-05-27', '2014-05-28', '2014-05-29', '2014-05-30', '2014-06-03', '2014-06-04', '2014-06-05', '2014-06-06', '2014-06-09', '2014-06-10', '2014-06-11', '2014-06-12', '2014-06-13', '2014-06-16', '2014-06-17', '2014-06-18', '2014-06-19', '2014-06-20', '2014-06-23', '2014-06-24', '2014-06-25', '2014-06-26', '2014-06-27', '2014-06-30', '2014-07-01', '2014-07-02', '2014-07-03', '2014-07-04', '2014-07-07', '2014-07-08', '2014-07-09', '2014-07-10', '2014-07-11', '2014-07-14', '2014-07-15', '2014-07-16', '2014-07-17', '2014-07-18', '2014-07-21', '2014-07-22', '2014-07-23', '2014-07-24', '2014-07-25', '2014-07-28', '2014-07-29', '2014-07-30', '2014-07-31', '2014-08-01', '2014-08-04', '2014-08-05', '2014-08-06', '2014-08-07', '2014-08-08', '2014-08-11', '2014-08-12', '2014-08-13', '2014-08-14', '2014-08-15', '2014-08-18', '2014-08-19', '2014-08-20', '2014-08-21', '2014-08-22', '2014-08-25', '2014-08-26', '2014-08-27', '2014-08-28', '2014-08-29', '2014-09-01', '2014-09-02', '2014-09-03', '2014-09-04', '2014-09-05', '2014-09-09', '2014-09-10', '2014-09-11', '2014-09-12', '2014-09-15', '2014-09-16', '2014-09-17', '2014-09-18', '2014-09-19', '2014-09-22', '2014-09-23', '2014-09-24', '2014-09-25', '2014-09-26', '2014-09-29', '2014-09-30', '2014-10-08', '2014-10-09', '2014-10-10', '2014-10-13', '2014-10-14', '2014-10-15', '2014-10-16', '2014-10-17', '2014-10-20', '2014-10-21', '2014-10-22', '2014-10-23', '2014-10-24', '2014-10-27', '2014-10-28', '2014-10-29', '2014-10-30', '2014-10-31', '2014-11-03', '2014-11-04', '2014-11-05', '2014-11-06', '2014-11-07', '2014-11-10', '2014-11-11', '2014-11-12', '2014-11-13', '2014-11-14', '2014-11-17', '2014-11-18', '2014-11-19', '2014-11-20', '2014-11-21', '2014-11-24', '2014-11-25', '2014-11-26', '2014-11-27', '2014-11-28', '2014-12-01', '2014-12-02', '2014-12-03', '2014-12-04', '2014-12-05', '2014-12-08', '2014-12-09', '2014-12-10', '2014-12-11', '2014-12-12', '2014-12-15', '2014-12-16', '2014-12-17', '2014-12-18', '2014-12-19', '2014-12-22', '2014-12-23', '2014-12-24', '2014-12-25', '2014-12-26', '2014-12-29', '2014-12-30', '2014-12-31', '2015-01-05', '2015-01-06', '2015-01-07', '2015-01-08', '2015-01-09', '2015-01-12', '2015-01-13', '2015-01-14', '2015-01-15', '2015-01-16', '2015-01-19', '2015-01-20', '2015-01-21', '2015-01-22', '2015-01-23', '2015-01-26', '2015-01-27', '2015-01-28', '2015-01-29', '2015-01-30', '2015-02-02', '2015-02-03', '2015-02-04', '2015-02-05', '2015-02-06', '2015-02-09', '2015-02-10', '2015-02-11', '2015-02-12', '2015-02-13', '2015-02-16', '2015-02-17', '2015-02-25', '2015-02-26', '2015-02-27', '2015-03-02', '2015-03-03', '2015-03-04', '2015-03-05', '2015-03-06', '2015-03-09', '2015-03-10', '2015-03-11', '2015-03-12', '2015-03-13', '2015-03-16', '2015-03-17', '2015-03-18', '2015-03-19', '2015-03-20', '2015-03-23', '2015-03-24', '2015-03-25', '2015-03-26', '2015-03-27', '2015-03-30', '2015-03-31', '2015-04-01', '2015-04-02', '2015-04-03', '2015-04-07', '2015-04-08', '2015-04-09', '2015-04-10', '2015-04-13', '2015-04-14', '2015-04-15', '2015-04-16', '2015-04-17', '2015-04-20', '2015-04-21', '2015-04-22', '2015-04-23', '2015-04-24', '2015-04-27', '2015-04-28', '2015-04-29', '2015-04-30', '2015-05-04', '2015-05-05', '2015-05-06', '2015-05-07', '2015-05-08', '2015-05-11', '2015-05-12', '2015-05-13', '2015-05-14', '2015-05-15', '2015-05-18', '2015-05-19', '2015-05-20', '2015-05-21', '2015-05-22', '2015-05-25', '2015-05-26', '2015-05-27', '2015-05-28', '2015-05-29', '2015-06-01', '2015-06-02', '2015-06-03', '2015-06-04', '2015-06-05', '2015-06-08', '2015-06-09', '2015-06-10', '2015-06-11', '2015-06-12', '2015-06-15', '2015-06-16', '2015-06-17', '2015-06-18', '2015-06-19', '2015-06-23', '2015-06-24', '2015-06-25', '2015-06-26', '2015-06-29', '2015-06-30', '2015-07-01', '2015-07-02', '2015-07-03', '2015-07-06', '2015-07-07', '2015-07-08', '2015-07-09', '2015-07-10', '2015-07-13', '2015-07-14', '2015-07-15', '2015-07-16', '2015-07-17', '2015-07-20', '2015-07-21', '2015-07-22', '2015-07-23', '2015-07-24', '2015-07-27', '2015-07-28', '2015-07-29', '2015-07-30', '2015-07-31', '2015-08-03', '2015-08-04', '2015-08-05', '2015-08-06', '2015-08-07', '2015-08-10', '2015-08-11', '2015-08-12', '2015-08-13', '2015-08-14', '2015-08-17', '2015-08-18', '2015-08-19', '2015-08-20', '2015-08-21', '2015-08-24', '2015-08-25', '2015-08-26', '2015-08-27', '2015-08-28', '2015-08-31', '2015-09-01', '2015-09-02', '2015-09-07', '2015-09-08', '2015-09-09', '2015-09-10', '2015-09-11', '2015-09-14', '2015-09-15', '2015-09-16', '2015-09-17', '2015-09-18', '2015-09-21', '2015-09-22', '2015-09-23', '2015-09-24', '2015-09-25', '2015-09-28', '2015-09-29', '2015-09-30', '2015-10-08', '2015-10-09', '2015-10-12', '2015-10-13', '2015-10-14', '2015-10-15', '2015-10-16', '2015-10-19', '2015-10-20', '2015-10-21', '2015-10-22', '2015-10-23', '2015-10-26', '2015-10-27', '2015-10-28', '2015-10-29', '2015-10-30', '2015-11-02', '2015-11-03', '2015-11-04', '2015-11-05', '2015-11-06', '2015-11-09', '2015-11-10', '2015-11-11', '2015-11-12', '2015-11-13', '2015-11-16', '2015-11-17', '2015-11-18', '2015-11-19', '2015-11-20', '2015-11-23', '2015-11-24', '2015-11-25', '2015-11-26', '2015-11-27', '2015-11-30', '2015-12-01', '2015-12-02', '2015-12-03', '2015-12-04', '2015-12-07', '2015-12-08', '2015-12-09', '2015-12-10', '2015-12-11', '2015-12-14', '2015-12-15', '2015-12-16', '2015-12-17', '2015-12-18', '2015-12-21', '2015-12-22', '2015-12-23', '2015-12-24', '2015-12-25', '2015-12-28', '2015-12-29', '2015-12-30', '2015-12-31', '2016-01-04', '2016-01-05', '2016-01-06', '2016-01-07', '2016-01-08', '2016-01-11', '2016-01-12', '2016-01-13', '2016-01-14', '2016-01-15', '2016-01-18', '2016-01-19', '2016-01-20', '2016-01-21', '2016-01-22', '2016-01-25', '2016-01-26', '2016-01-27', '2016-01-28', '2016-01-29', '2016-02-01', '2016-02-02', '2016-02-03', '2016-02-04', '2016-02-05', '2016-02-15', '2016-02-16', '2016-02-17', '2016-02-18', '2016-02-19', '2016-02-22', '2016-02-23', '2016-02-24', '2016-02-25', '2016-02-26', '2016-02-29', '2016-03-01', '2016-03-02', '2016-03-03', '2016-03-04', '2016-03-07', '2016-03-08', '2016-03-09', '2016-03-10', '2016-03-11', '2016-03-14', '2016-03-15', '2016-03-16', '2016-03-17', '2016-03-18', '2016-03-21', '2016-03-22', '2016-03-23', '2016-03-24', '2016-03-25', '2016-03-28', '2016-03-29', '2016-03-30', '2016-03-31', '2016-04-01', '2016-04-05', '2016-04-06', '2016-04-07', '2016-04-08', '2016-04-11', '2016-04-12', '2016-04-13', '2016-04-14', '2016-04-15', '2016-04-18', '2016-04-19', '2016-04-20', '2016-04-21', '2016-04-22', '2016-04-25', '2016-04-26', '2016-04-27', '2016-04-28', '2016-04-29', '2016-05-03', '2016-05-04', '2016-05-05', '2016-05-06', '2016-05-09', '2016-05-10', '2016-05-11', '2016-05-12', '2016-05-13', '2016-05-16', '2016-05-17', '2016-05-18', '2016-05-19', '2016-05-20', '2016-05-23', '2016-05-24', '2016-05-25', '2016-05-26', '2016-05-27', '2016-05-30', '2016-05-31', '2016-06-01', '2016-06-02', '2016-06-03', '2016-06-06', '2016-06-07', '2016-06-08', '2016-06-13', '2016-06-14', '2016-06-15', '2016-06-16', '2016-06-17', '2016-06-20', '2016-06-21', '2016-06-22', '2016-06-23', '2016-06-24', '2016-06-27', '2016-06-28', '2016-06-29', '2016-06-30', '2016-07-01', '2016-07-04', '2016-07-05', '2016-07-06', '2016-07-07', '2016-07-08', '2016-07-11', '2016-07-12', '2016-07-13', '2016-07-14', '2016-07-15', '2016-07-18', '2016-07-19', '2016-07-20', '2016-07-21', '2016-07-22', '2016-07-25', '2016-07-26', '2016-07-27', '2016-07-28', '2016-07-29', '2016-08-01', '2016-08-02', '2016-08-03', '2016-08-04', '2016-08-05', '2016-08-08', '2016-08-09', '2016-08-10', '2016-08-11', '2016-08-12', '2016-08-15', '2016-08-16', '2016-08-17', '2016-08-18', '2016-08-19', '2016-08-22', '2016-08-23', '2016-08-24', '2016-08-25', '2016-08-26', '2016-08-29', '2016-08-30', '2016-08-31', '2016-09-01', '2016-09-02', '2016-09-05', '2016-09-06', '2016-09-07', '2016-09-08', '2016-09-09', '2016-09-12', '2016-09-13', '2016-09-14', '2016-09-19', '2016-09-20', '2016-09-21', '2016-09-22', '2016-09-23', '2016-09-26', '2016-09-27', '2016-09-28', '2016-09-29', '2016-09-30', '2016-10-10', '2016-10-11', '2016-10-12', '2016-10-13', '2016-10-14', '2016-10-17', '2016-10-18', '2016-10-19', '2016-10-20', '2016-10-21', '2016-10-24', '2016-10-25', '2016-10-26', '2016-10-27', '2016-10-28', '2016-10-31', '2016-11-01', '2016-11-02', '2016-11-03', '2016-11-04', '2016-11-07', '2016-11-08', '2016-11-09', '2016-11-10', '2016-11-11', '2016-11-14', '2016-11-15', '2016-11-16', '2016-11-17', '2016-11-18', '2016-11-21', '2016-11-22', '2016-11-23', '2016-11-24', '2016-11-25', '2016-11-28', '2016-11-29', '2016-11-30', '2016-12-01', '2016-12-02', '2016-12-05', '2016-12-06', '2016-12-07', '2016-12-08', '2016-12-09', '2016-12-12', '2016-12-13', '2016-12-14', '2016-12-15', '2016-12-16', '2016-12-19', '2016-12-20', '2016-12-21', '2016-12-22', '2016-12-23', '2016-12-26', '2016-12-27', '2016-12-28', '2016-12-29', '2016-12-30', '2017-01-03', '2017-01-04', '2017-01-05', '2017-01-06', '2017-01-09', '2017-01-10', '2017-01-11', '2017-01-12', '2017-01-13', '2017-01-16', '2017-01-17', '2017-01-18', '2017-01-19', '2017-01-20', '2017-01-23', '2017-01-24', '2017-01-25', '2017-01-26', '2017-02-03', '2017-02-06', '2017-02-07', '2017-02-08', '2017-02-09', '2017-02-10', '2017-02-13', '2017-02-14', '2017-02-15', '2017-02-16', '2017-02-17', '2017-02-20', '2017-02-21', '2017-02-22', '2017-02-23', '2017-02-24', '2017-02-27', '2017-02-28', '2017-03-01', '2017-03-02', '2017-03-03', '2017-03-06', '2017-03-07', '2017-03-08', '2017-03-09', '2017-03-10', '2017-03-13', '2017-03-14', '2017-03-15', '2017-03-16', '2017-03-17', '2017-03-20', '2017-03-21', '2017-03-22', '2017-03-23', '2017-03-24', '2017-03-27', '2017-03-28', '2017-03-29', '2017-03-30', '2017-03-31', '2017-04-05', '2017-04-06', '2017-04-07', '2017-04-10', '2017-04-11', '2017-04-12', '2017-04-13', '2017-04-14', '2017-04-17', '2017-04-18', '2017-04-19', '2017-04-20', '2017-04-21', '2017-04-24', '2017-04-25', '2017-04-26', '2017-04-27', '2017-04-28', '2017-05-02', '2017-05-03', '2017-05-04', '2017-05-05', '2017-05-08', '2017-05-09', '2017-05-10', '2017-05-11', '2017-05-12', '2017-05-15', '2017-05-16', '2017-05-17', '2017-05-18', '2017-05-19', '2017-05-22', '2017-05-23', '2017-05-24', '2017-05-25', '2017-05-26', '2017-05-31', '2017-06-01', '2017-06-02', '2017-06-05', '2017-06-06', '2017-06-07', '2017-06-08', '2017-06-09', '2017-06-12', '2017-06-13', '2017-06-14', '2017-06-15', '2017-06-16', '2017-06-19', '2017-06-20', '2017-06-21', '2017-06-22', '2017-06-23', '2017-06-26', '2017-06-27', '2017-06-28', '2017-06-29', '2017-06-30', '2017-07-03', '2017-07-04', '2017-07-05', '2017-07-06', '2017-07-07', '2017-07-10', '2017-07-11', '2017-07-12', '2017-07-13', '2017-07-14', '2017-07-17', '2017-07-18', '2017-07-19', '2017-07-20', '2017-07-21', '2017-07-24', '2017-07-25', '2017-07-26', '2017-07-27', '2017-07-28', '2017-07-31', '2017-08-01', '2017-08-02', '2017-08-03', '2017-08-04', '2017-08-07', '2017-08-08', '2017-08-09', '2017-08-10', '2017-08-11', '2017-08-14', '2017-08-15', '2017-08-16', '2017-08-17', '2017-08-18', '2017-08-21', '2017-08-22', '2017-08-23', '2017-08-24', '2017-08-25', '2017-08-28', '2017-08-29', '2017-08-30', '2017-08-31', '2017-09-01', '2017-09-04', '2017-09-05', '2017-09-06', '2017-09-07', '2017-09-08', '2017-09-11', '2017-09-12', '2017-09-13', '2017-09-14', '2017-09-15', '2017-09-18', '2017-09-19', '2017-09-20', '2017-09-21', '2017-09-22', '2017-09-25', '2017-09-26', '2017-09-27', '2017-09-28', '2017-09-29', '2017-10-09', '2017-10-10', '2017-10-11', '2017-10-12', '2017-10-13', '2017-10-16', '2017-10-17', '2017-10-18', '2017-10-19', '2017-10-20', '2017-10-23', '2017-10-24', '2017-10-25', '2017-10-26', '2017-10-27', '2017-10-30', '2017-10-31', '2017-11-01', '2017-11-02', '2017-11-03', '2017-11-06', '2017-11-07', '2017-11-08', '2017-11-09', '2017-11-10', '2017-11-13', '2017-11-14', '2017-11-15', '2017-11-16', '2017-11-17', '2017-11-20', '2017-11-21', '2017-11-22', '2017-11-23', '2017-11-24', '2017-11-27', '2017-11-28', '2017-11-29', '2017-11-30', '2017-12-01', '2017-12-04', '2017-12-05', '2017-12-06', '2017-12-07', '2017-12-08', '2017-12-11', '2017-12-12', '2017-12-13', '2017-12-14', '2017-12-15', '2017-12-18', '2017-12-19', '2017-12-20', '2017-12-21', '2017-12-22', '2017-12-25', '2017-12-26', '2017-12-27', '2017-12-28', '2017-12-29', '2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05', '2018-01-08', '2018-01-09', '2018-01-10', '2018-01-11', '2018-01-12', '2018-01-15', '2018-01-16', '2018-01-17', '2018-01-18', '2018-01-19', '2018-01-22', '2018-01-23', '2018-01-24', '2018-01-25', '2018-01-26', '2018-01-29', '2018-01-30', '2018-01-31', '2018-02-01', '2018-02-02', '2018-02-05', '2018-02-06', '2018-02-07', '2018-02-08', '2018-02-09', '2018-02-12', '2018-02-13', '2018-02-14', '2018-02-22', '2018-02-23', '2018-02-26', '2018-02-27', '2018-02-28', '2018-03-01', '2018-03-02', '2018-03-05', '2018-03-06', '2018-03-07', '2018-03-08', '2018-03-09', '2018-03-12', '2018-03-13', '2018-03-14', '2018-03-15', '2018-03-16', '2018-03-19', '2018-03-20', '2018-03-21', '2018-03-22', '2018-03-23', '2018-03-26', '2018-03-27', '2018-03-28', '2018-03-29', '2018-03-30', '2018-04-02', '2018-04-03', '2018-04-04', '2018-04-09', '2018-04-10', '2018-04-11', '2018-04-12', '2018-04-13', '2018-04-16', '2018-04-17', '2018-04-18', '2018-04-19', '2018-04-20', '2018-04-23', '2018-04-24', '2018-04-25', '2018-04-26', '2018-04-27', '2018-05-02', '2018-05-03', '2018-05-04', '2018-05-07', '2018-05-08', '2018-05-09', '2018-05-10', '2018-05-11', '2018-05-14', '2018-05-15', '2018-05-16', '2018-05-17', '2018-05-18', '2018-05-21', '2018-05-22', '2018-05-23', '2018-05-24', '2018-05-25', '2018-05-28', '2018-05-29', '2018-05-30', '2018-05-31', '2018-06-01', '2018-06-04', '2018-06-05', '2018-06-06', '2018-06-07', '2018-06-08', '2018-06-11', '2018-06-12', '2018-06-13', '2018-06-14', '2018-06-15', '2018-06-19', '2018-06-20', '2018-06-21', '2018-06-22', '2018-06-25', '2018-06-26', '2018-06-27', '2018-06-28', '2018-06-29', '2018-07-02', '2018-07-03', '2018-07-04', '2018-07-05', '2018-07-06', '2018-07-09', '2018-07-10', '2018-07-11', '2018-07-12', '2018-07-13', '2018-07-16', '2018-07-17', '2018-07-18', '2018-07-19', '2018-07-20', '2018-07-23', '2018-07-24', '2018-07-25', '2018-07-26', '2018-07-27', '2018-07-30', '2018-07-31', '2018-08-01', '2018-08-02', '2018-08-03', '2018-08-06', '2018-08-07', '2018-08-08', '2018-08-09', '2018-08-10', '2018-08-13', '2018-08-14', '2018-08-15', '2018-08-16', '2018-08-17', '2018-08-20', '2018-08-21', '2018-08-22', '2018-08-23', '2018-08-24', '2018-08-27', '2018-08-28', '2018-08-29', '2018-08-30', '2018-08-31', '2018-09-03', '2018-09-04', '2018-09-05', '2018-09-06', '2018-09-07', '2018-09-10', '2018-09-11', '2018-09-12', '2018-09-13', '2018-09-14', '2018-09-17', '2018-09-18', '2018-09-19', '2018-09-20', '2018-09-21', '2018-09-25', '2018-09-26', '2018-09-27', '2018-09-28', '2018-10-08', '2018-10-09', '2018-10-10', '2018-10-11', '2018-10-12', '2018-10-15', '2018-10-16', '2018-10-17', '2018-10-18', '2018-10-19', '2018-10-22', '2018-10-23', '2018-10-24', '2018-10-25', '2018-10-26', '2018-10-29', '2018-10-30', '2018-10-31', '2018-11-01', '2018-11-02', '2018-11-05', '2018-11-06', '2018-11-07', '2018-11-08', '2018-11-09', '2018-11-12', '2018-11-13', '2018-11-14', '2018-11-15', '2018-11-16', '2018-11-19', '2018-11-20', '2018-11-21', '2018-11-22', '2018-11-23', '2018-11-26', '2018-11-27', '2018-11-28', '2018-11-29', '2018-11-30', '2018-12-03', '2018-12-04', '2018-12-05', '2018-12-06', '2018-12-07', '2018-12-10', '2018-12-11', '2018-12-12', '2018-12-13', '2018-12-14', '2018-12-17', '2018-12-18', '2018-12-19', '2018-12-20', '2018-12-21', '2018-12-24', '2018-12-25', '2018-12-26', '2018-12-27', '2018-12-28', '2018-12-31']
+
+
[docs]def QA_util_if_trade(day): + '日期是否交易' + if day in trade_date_sse: + return True + else: + return False
+ + +
[docs]def QA_util_if_tradetime(_time,market=MARKET_TYPE.STOCK_CN,code=None): + '时间是否交易' + _time = datetime.datetime.strptime(str(_time)[0:19], '%Y-%m-%d %H:%M:%S') + if market is MARKET_TYPE.STOCK_CN: + if QA_util_if_trade(str(_time.date())[0:10]): + if _time.hour in [10, 13, 14]: + return True + elif _time.hour in [9] and _time.minute >= 30: + return True + elif _time.hour in [11] and _time.minute <= 30: + return True + else: + return False + else: + return False + elif market is MARKET_TYPE.FUTURE_CN: + # 暂时用螺纹 + if code[0:2] in ['rb','RB']: + if QA_util_if_trade(str(_time.date())[0:10]): + if _time.hour in [9, 10, 14, 21, 22]: + return True + elif _time.hour in [13] and _time.minute >= 30: + return True + elif _time.hour in [11] and _time.minute <= 30: + return True + else: + return False + else: + return False
+ +
[docs]def QA_util_get_next_day(date,n=1): + """ + 得到下一个(n)交易日 + """ + return QA_util_date_gap(date,n,'gt')
+ +
[docs]def QA_util_get_last_day(date,n=1): + """ + 得到上一个(n)交易日 + """ + return QA_util_date_gap(date,n,'lt')
+ +
[docs]def QA_util_get_real_date(date, trade_list=trade_date_sse, towards=-1): + """ + 获取真实的交易日期,其中,第三个参数towards是表示向前/向后推 + towards=1 日期向后迭代 + towards=-1 日期向前迭代 + @ yutiansut + + """ + if towards == 1: + while date not in trade_list: + date = str(datetime.datetime.strptime( + str(date)[0:10], '%Y-%m-%d') + datetime.timedelta(days=1))[0:10] + else: + return str(date)[0:10] + elif towards == -1: + while date not in trade_list: + date = str(datetime.datetime.strptime( + str(date)[0:10], '%Y-%m-%d') - datetime.timedelta(days=1))[0:10] + else: + return str(date)[0:10]
+ + +
[docs]def QA_util_get_real_datelist(start, end): + """ + 取数据的真实区间,返回的时候用 start,end=QA_util_get_real_datelist + @yutiansut + 2017/8/10 + + 当start end中间没有交易日 返回None, None + @yutiansut/ 2017-12-19 + """ + real_start = QA_util_get_real_date(start, trade_date_sse, 1) + real_end = QA_util_get_real_date(end, trade_date_sse, -1) + if trade_date_sse.index(real_start) > trade_date_sse.index(real_end): + return None, None + else: + return (real_start, real_end)
+ + +
[docs]def QA_util_get_trade_range(start, end): + '给出交易具体时间' + start, end = QA_util_get_real_datelist(start, end) + if start is not None: + return trade_date_sse[trade_date_sse.index(start):trade_date_sse.index(end) + 1:1] + else: + return None
+ + +
[docs]def QA_util_get_trade_gap(start, end): + '返回start_day到end_day中间有多少个交易天 算首尾' + start, end = QA_util_get_real_datelist(start, end) + if start is not None: + return trade_date_sse.index(end) + 1 - trade_date_sse.index(start) + else: + return 0
+ + +
[docs]def QA_util_date_gap(date, gap, methods): + """[summary] + + Arguments: + date {[type]} -- [description] + gap {[type]} -- [description] + methods {[type]} -- [description] + + Returns: + [type] -- [description] + """ + + try: + if methods in ['>', 'gt']: + return trade_date_sse[trade_date_sse.index(date) + gap] + elif methods in ['>=', 'gte']: + return trade_date_sse[trade_date_sse.index(date) + gap - 1] + elif methods in ['<', 'lt']: + return trade_date_sse[trade_date_sse.index(date) - gap] + elif methods in ['<=', 'lte']: + return trade_date_sse[trade_date_sse.index(date) - gap + 1] + elif methods in ['==', '=', 'eq']: + return date + + except: + return 'wrong date'
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QADict.html b/_build/html/_modules/QUANTAXIS/QAUtil/QADict.html new file mode 100644 index 000000000..7a0c0305f --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QADict.html @@ -0,0 +1,120 @@ + + + + + + + + QUANTAXIS.QAUtil.QADict — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QADict

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+
[docs]def QA_util_dict_remove_key(dicts, key): + """ + 输入一个dict 返回删除后的 + """ + + if isinstance(key, list): + for item in key: + try: + dicts.pop(item) + except: + pass + else: + try: + dicts.pop(key) + except: + pass + return dicts
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QAList.html b/_build/html/_modules/QUANTAXIS/QAUtil/QAList.html new file mode 100644 index 000000000..d17cea7a2 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QAList.html @@ -0,0 +1,115 @@ + + + + + + + + QUANTAXIS.QAUtil.QAList — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QAList

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import numpy as np
+
+
+
[docs]def QA_util_multi_demension_list(row_, col_=0): + # row_ 是行, col_ 是列 + """ + 如果需要创建一个[[],[]], 那就用 row_=2,col=0 + 其他时候,返回的都是[[None]] + """ + return [[None for col in range(col_)] for row in range(row_)]
+ + +
[docs]def QA_util_diff_list(datastruct): + return (np.array(datastruct[1:]) - np.array(datastruct[:-1])).tolist()
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QALogs.html b/_build/html/_modules/QUANTAXIS/QAUtil/QALogs.html new file mode 100644 index 000000000..828790986 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QALogs.html @@ -0,0 +1,161 @@ + + + + + + + + QUANTAXIS.QAUtil.QALogs — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QALogs

+# Coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""
+QUANTAXIS Log Module
+@yutiansut
+
+QA_util_log_x is under [QAStandard#0.0.2@602-x] Protocol
+QA_util_log_info()
+QA_util_log_debug()
+QA_util_log_expection()
+"""
+
+import datetime
+
+from zenlog import logging
+
+logging.basicConfig(level=logging.DEBUG,
+                    format='%(asctime)s QUANTAXIS>>> %(message)s',
+                    datefmt='%H:%M:%S',
+                    filename='quantaxis-' +
+                    str(datetime.datetime.now().strftime(
+                        '%Y-%m-%d-%H-%M-%S')) + '-.log',
+                    filemode='w')
+console = logging.StreamHandler()
+console.setLevel(logging.INFO)
+formatter = logging.Formatter('QUANTAXIS>> %(message)s')
+console.setFormatter(formatter)
+logging.getLogger('').addHandler(console)
+
+
+logging.info('start QUANTAXIS')
+
+
+
[docs]def QA_util_log_debug(logs): + """ + QUANTAXIS Log Module + @yutiansut + + QA_util_log_x is under [QAStandard#0.0.2@602-x] Protocol + """ + logging.debug(logs)
+ + +
[docs]def QA_util_log_info(logs): + """ + QUANTAXIS Log Module + @yutiansut + + QA_util_log_x is under [QAStandard#0.0.2@602-x] Protocol + """ + logging.info(logs)
+ + +
[docs]def QA_util_log_expection(logs): + """ + QUANTAXIS Log Module + @yutiansut + + QA_util_log_x is under [QAStandard#0.0.2@602-x] Protocol + """ + logging.exception(logs)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QAMail.html b/_build/html/_modules/QUANTAXIS/QAUtil/QAMail.html new file mode 100644 index 000000000..315e53f5f --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QAMail.html @@ -0,0 +1,131 @@ + + + + + + + + QUANTAXIS.QAUtil.QAMail — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QAMail

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from email import encoders
+from email.header import Header
+from email.mime.text import MIMEText
+from email.utils import parseaddr, formataddr
+import smtplib
+
+
+
[docs]def QA_util_send_mail(msg, title, from_user, from_password, to_addr, smtp): + """邮件发送 + + Arguments: + msg {[type]} -- [description] + title {[type]} -- [description] + from_user {[type]} -- [description] + from_password {[type]} -- [description] + to_addr {[type]} -- [description] + smtp {[type]} -- [description] + """ + + msg = MIMEText(msg, 'plain', 'utf-8') + msg['Subject'] = Header(title, 'utf-8').encode() + + server = smtplib.SMTP(smtp, 25) # SMTP协议默认端口是25 + server.set_debuglevel(1) + server.login(from_user, from_password) + server.sendmail(from_user, [to_addr], msg.as_string())
+ + + +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QAMongo.html b/_build/html/_modules/QUANTAXIS/QAUtil/QAMongo.html new file mode 100644 index 000000000..12435d639 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QAMongo.html @@ -0,0 +1,147 @@ + + + + + + + + QUANTAXIS.QAUtil.QAMongo — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QAMongo

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import subprocess
+
+import pandas as pd
+
+from QUANTAXIS.QAUtil.QASetting import DATABASE
+from QUANTAXIS.QAUtil.QALogs import QA_util_log_info
+
+
+
[docs]def QA_util_mongo_initial(db=DATABASE): + + db.drop_collection('stock_day') + db.drop_collection('stock_list') + db.drop_collection('stock_info') + db.drop_collection('trade_date') + db.drop_collection('stock_min') + db.drop_collection('stock_transaction') + db.drop_collection('stock_xdxr')
+ + + + + +
[docs]def QA_util_mongo_status(db=DATABASE): + QA_util_log_info(db.collection_names()) + QA_util_log_info(db.last_status()) + QA_util_log_info(subprocess.call('mongostat', shell=True))
+ + +
[docs]def QA_util_mongo_infos(db=DATABASE): + + data_struct = [] + + for item in db.collection_names(): + value = [] + value.append(item) + value.append(eval('db.' + str(item) + '.find({}).count()')) + value.append(list(eval('db.' + str(item) + '.find_one()').keys())) + data_struct.append(value) + return pd.DataFrame(data_struct, columns=['collection_name', 'counts', 'columns']).set_index('collection_name')
+ + +if __name__ == '__main__': + print(QA_util_mongo_infos()) + QA_util_mongo_status() +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QAParameter.html b/_build/html/_modules/QUANTAXIS/QAUtil/QAParameter.html new file mode 100644 index 000000000..facda7b25 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QAParameter.html @@ -0,0 +1,423 @@ + + + + + + + + QUANTAXIS.QAUtil.QAParameter — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QAParameter

+# -* coding: utf-8 -*-
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+"""
+这里定义的是一些常用常量
+"""
+
+
+
[docs]class ORDER_DIRECTION(): + """订单的买卖方向 + + BUY 股票 买入 + SELL 股票 卖出 + BUY_OPEN 期货 多开 + BUY_CLOSE 期货 空平(多头平旧仓) + SELL_OPEN 期货 空开 + SELL_CLOSE 期货 多平(空头平旧仓) + + + """ + + BUY = 1 + SELL = -1 + BUY_OPEN = 1 + BUY_CLOSE = 1 + SELL_OPEN = -1 + SELL_CLOSE = -1
+ + +
[docs]class ORDER_MODEL(): + """订单的成交模式 + + LIMIT 限价模式 + MARKET 市价单 # 目前市价单在回测中是bar的开盘价 /实盘里面是五档剩余最优成交价 + CLOSE 收盘单 # 及在bar的收盘时的价格 + NEXT_OPEN 下一个bar的开盘价成交 + STRICT 严格订单 不推荐/仅限回测/是在当前bar的最高价买入/当前bar的最低价卖出 + + @yutiansut/2017-12-18 + """ + + LIMIT = 'limit' # 限价 + MARKET = 'market' # 市价/在回测里是下个bar的开盘价买入/实盘就是五档剩余最优成交价 + CLOSE = 'close' # 当前bar的收盘价买入 + NEXT_OPEN = 'next_open' # 下个bar的开盘价买入 + STRICT = 'strict' # 严格模式/不推荐(仅限回测测试用)
+ + +
[docs]class ORDER_STATUS(): + """订单状态 + + status1xx 订单待生成 + status3xx 初始化订单 临时扣除资产(可用现金/可卖股份) + status3xx 订单存活(等待交易) + status2xx 订单完全交易/未完全交易 + status4xx 主动撤单 + status500 订单死亡(每日结算) 恢复临时资产 + + 200 委托成功,完全交易 + 203 委托成功,未完全成功 + 300 刚创建订单的时候 + 400 已撤单 + 500 服务器撤单/每日结算 + + 订单生成(100) -- 进入待成交队列(300) -- 完全成交(200) -- 每日结算(500)-- 死亡 + 订单生成(100) -- 进入待成交队列(300) -- 部分成交(203) -- 未成交(300) -- 每日结算(500) -- 死亡 + 订单生成(100) -- 进入待成交队列(300) -- 主动撤单(400) -- 每日结算(500) -- 死亡 + """ + + NEW = 100 + SUCCESS_ALL = 200 + SUCCESS_PART = 203 + QUEUED = 300 # queued 用于表示在order_queue中 实际表达的意思是订单存活 待成交 + CANCEL_ALL = 400 + SETTLED = 500
+ + +
[docs]class AMOUNT_MODEL(): + """订单的成交量 + + by_price是按固定成交总额下单,动态计算成交量 + by_amount 按固定成家量下单 + """ + + BY_PRICE = 'by_price' + BY_AMOUNT = 'by_amount'
+ + +
[docs]class RUNNING_ENVIRONMENT(): + """执行环境 + + 回测 + 模拟 + 实盘 + 随机(按算法/分布随机生成行情)/仅用于训练测试 + """ + + BACKETEST = 'backtest' + SIMULATION = 'simulation' + REAL = 'real' + RANODM = 'random'
+ + +
[docs]class TRADE_STATUS(): + """交易状态返回值 + + 涨跌停限制: 202 + 成功交易 : 200 + 当天无交易数据: 500 + 订单失败(比如买卖价格超过涨跌停价格范围,交易量过大等等):400 + """ + + SUCCESS = 200 + PRICE_LIMIT = 202 + NO_MARKET_DATA = 500 + FAILED = 400
+ + +
[docs]class MARKET_ERROR(): + ACCOUNT_EXIST = 'Account has already exist'
+ + +
[docs]class MARKET_TYPE(): + """市场种类 + + 日线 尾数01 + 分钟线 尾数02 + tick 尾数03 + + 市场: + 股票 0 + 指数/基金 1 + 期货 2 + 港股 3 + 美股 4 + 比特币/加密货币市场 5 + """ + STOCK_CN = 'stock_cn' # 中国A股 + STOCK_HK = 'stock_hk' # 港股 + STOCK_US = 'stock_us' # 美股 + FUTURE_CN = 'future_cn' # 国内期货 + OPTION_CN = 'option_cn' # 国内期权 + STOCKOPTION_CN = 'stockoption_cn' # 个股期权 + # BITCOIN = 'bitcoin' # 比特币 + CRYPTOCURRENCY = 'cryptocurrency' # 加密货币(衍生货币) + INDEX_CN = 'index_cn' # 中国指数 + FUND_CN = 'fund_cn' # 中国基金 + BOND_CN = 'bond_cn' # 中国债券
+ + +
[docs]class BROKER_TYPE(): + """执行环境 + + 回测 + 模拟 + 实盘 + 随机(按算法/分布随机生成行情)/仅用于训练测试 + """ + + BACKETEST = 'backtest' + SIMULATION = 'simulation' + REAL = 'real' + RANODM = 'random'
+ + +
[docs]class EVENT_TYPE(): + BROKER_EVENT = 'broker_event' + ACCOUNT_EVENT = 'account_event' + MARKET_EVENT = 'market_event' + TRADE_EVENT = 'trade_event' + ENGINE_EVENT = 'engine_event' + ORDER_EVENT = 'order_event'
+ + +
[docs]class MARKET_EVENT(): + """交易前置事件""" + QUERY_ORDER = 'query_order' + QUERY_ASSETS = 'query_assets' + QUERY_ACCOUNT = 'query_account' + QUERY_CASH = 'query_cash' + QUERY_DATA = 'query_data'
+ + +
[docs]class ENGINE_EVENT(): + """引擎事件""" + MARKET_INIT = 'market_init' + UPCOMING_DATA = 'upcoming_data' + BAR_SETTLE = 'bar_settle' + DAILY_SETTLE = 'daily_settle' + UPDATE = 'update'
+ + +
[docs]class ACCOUNT_EVENT(): + """账户事件""" + UPDATE = 'account_update' + SETTLE = 'account_settle' + MAKE_ORDER = 'account_make_order'
+ + +
[docs]class BROKER_EVENT(): + """BROKER事件 + BROKER + 有加载数据的任务 load data + 撮合成交的任务 broker_trade + + + """ + LOAD_DATA = 'load_data' + TRADE = 'broker_trade' + SETTLE = 'broker_settle' + DAILY_SETTLE = 'broker_dailysettle' + RECEIVE_ORDER = 'receive_order'
+ + +
[docs]class ORDER_EVENT(): + """订单事件 + + 创建订单 create + 交易 trade + 撤单 cancel + + """ + CREATE = 'create' + TRADE = 'trade' + CANCEL = 'cancel'
+ + +
[docs]class FREQUENCE(): + """查询的级别 + + [description] + """ + + YEAR = 'year' # 年bar + QUARTER = 'quarter' # 季度bar + MONTH = 'month' # 月bar + WEEK = 'week' # 周bar + DAY = 'day' # 日bar + ONE_MIN = '1min' # 1min bar + FIVE_MIN = '5min' # 5min bar + FIFTEEN_MIN = '15min' # 15min bar + THIRTY_MIN = '30min' # 30min bar + HOUR = '60min' # 60min bar + SIXTY_MIN = '60min' # 60min bar + CURRENT = 'current' # 当前bar + TICK = 'tick' # transaction
+ + +
[docs]class CURRENCY_TYPE(): + """货币种类""" + RMB = 'rmb' # 人民币 + USD = 'usd' # 美元 + EUR = 'eur' # 欧元 + HKD = 'hkd' # 港币 + GBP = 'GBP' # 英镑 + BTC = 'btc' # 比特币 + JPY = 'jpy' # 日元 + AUD = 'aud' # 澳元 + CAD = 'cad' # 加拿大元
+ + +
[docs]class DATASOURCE(): + """数据来源 + """ + + WIND = 'wind' # wind金融终端 + TDB = 'tdb' # wind tdb + THS = 'ths' # 同花顺网页 + TUSHARE = 'tushare' # tushare + TDX = 'tdx' # 通达信 + MONGO = 'mongo' # 本地/远程Mongodb + EASTMONEY = 'eastmoney' # 东方财富网 + CHOICE = 'choice' # choice金融终端 + CCXT = 'ccxt' # github/ccxt 虚拟货币 + LOCALFILE = 'localfile' # 本地文件
+ + +
[docs]class OUTPUT_FORMAT(): + """输出格式 + """ + + DATASTRUCT = 'datastruct' + DATAFRAME = 'dataframe' + SERIES = 'series' + NDARRAY = 'ndarray' + LIST = 'list' + JSON = 'json'
+ + +DATABASE_TABLE = { + (MARKET_TYPE.STOCK_CN, FREQUENCE.DAY): 'stock_day', + (MARKET_TYPE.STOCK_CN, FREQUENCE.ONE_MIN): 'stock_min', + (MARKET_TYPE.STOCK_CN, FREQUENCE.FIVE_MIN): 'stock_min', + (MARKET_TYPE.STOCK_CN, FREQUENCE.FIFTEEN_MIN): 'stock_min', + (MARKET_TYPE.STOCK_CN, FREQUENCE.THIRTY_MIN): 'stock_min', + (MARKET_TYPE.STOCK_CN, FREQUENCE.SIXTY_MIN): 'stock_min', + (MARKET_TYPE.STOCK_CN, FREQUENCE.HOUR): 'stock_min', + (MARKET_TYPE.STOCK_CN, FREQUENCE.TICK): 'stock_transaction', + (MARKET_TYPE.INDEX_CN, FREQUENCE.DAY): 'index_day', + (MARKET_TYPE.INDEX_CN, FREQUENCE.ONE_MIN): 'index_min', + (MARKET_TYPE.INDEX_CN, FREQUENCE.FIVE_MIN): 'index_min', + (MARKET_TYPE.INDEX_CN, FREQUENCE.FIFTEEN_MIN): 'index_min', + (MARKET_TYPE.INDEX_CN, FREQUENCE.THIRTY_MIN): 'index_min', + (MARKET_TYPE.INDEX_CN, FREQUENCE.SIXTY_MIN): 'index_min', + (MARKET_TYPE.INDEX_CN, FREQUENCE.HOUR): 'index_min', + (MARKET_TYPE.INDEX_CN, FREQUENCE.TICK): 'index_transaction', + (MARKET_TYPE.FUND_CN, FREQUENCE.DAY): 'index_day', + (MARKET_TYPE.FUND_CN, FREQUENCE.ONE_MIN): 'index_min', + (MARKET_TYPE.FUND_CN, FREQUENCE.FIVE_MIN): 'index_min', + (MARKET_TYPE.FUND_CN, FREQUENCE.FIFTEEN_MIN): 'index_min', + (MARKET_TYPE.FUND_CN, FREQUENCE.THIRTY_MIN): 'index_min', + (MARKET_TYPE.FUND_CN, FREQUENCE.SIXTY_MIN): 'index_min', + (MARKET_TYPE.FUND_CN, FREQUENCE.HOUR): 'index_min', + (MARKET_TYPE.FUND_CN, FREQUENCE.TICK): 'index_transaction', + (MARKET_TYPE.FUTURE_CN, FREQUENCE.DAY): 'future_day', + (MARKET_TYPE.FUTURE_CN, FREQUENCE.ONE_MIN): 'future_min', + (MARKET_TYPE.FUTURE_CN, FREQUENCE.FIVE_MIN): 'future_min', + (MARKET_TYPE.FUTURE_CN, FREQUENCE.FIFTEEN_MIN): 'future_min', + (MARKET_TYPE.FUTURE_CN, FREQUENCE.THIRTY_MIN): 'future_min', + (MARKET_TYPE.FUTURE_CN, FREQUENCE.SIXTY_MIN): 'future_min', + (MARKET_TYPE.FUTURE_CN, FREQUENCE.HOUR): 'future_min', + (MARKET_TYPE.FUTURE_CN, FREQUENCE.TICK): 'future_transaction' +} +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QAPlot.html b/_build/html/_modules/QUANTAXIS/QAUtil/QAPlot.html new file mode 100644 index 000000000..eeb8a7855 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QAPlot.html @@ -0,0 +1,170 @@ + + + + + + + + QUANTAXIS.QAUtil.QAPlot — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QAPlot

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+import os
+import webbrowser
+
+from pyecharts import Kline
+
+from QUANTAXIS.QAUtil.QALogs import QA_util_log_info
+
+
+"""
+0.5.1预计新增内容:
+
+
+维护一个画图方法,之后可能会做成抽象基类
+
+
+主要是画DataStruct的k线图, DataStruct加指标的图,以及回测框架的回测结果的图
+"""
+
+
+
[docs]def plot_datastruct(_quotation_base, code=None): + if code is None: + path_name = '.' + os.sep + 'QA_' + _quotation_base.type + \ + '_codepackage_' + _quotation_base.if_fq + '.html' + kline = Kline('CodePackage_' + _quotation_base.if_fq + '_' + _quotation_base.type, + width=1360, height=700, page_title='QUANTAXIS') + + data_splits = _quotation_base.splits() + + for i_ in range(len(data_splits)): + data = [] + axis = [] + for dates, row in data_splits[i_].data.iterrows(): + open, high, low, close = row[1:5] + datas = [open, close, low, high] + axis.append(dates[0]) + data.append(datas) + + kline.add(_quotation_base.code[i_], axis, data, mark_point=[ + "max", "min"], is_datazoom_show=True, datazoom_orient='horizontal') + kline.render(path_name) + webbrowser.open(path_name) + QA_util_log_info('The Pic has been saved to your path: %s' % path_name) + else: + data = [] + axis = [] + for dates, row in _quotation_base.select_code(code).data.iterrows(): + open, high, low, close = row[1:5] + datas = [open, close, low, high] + axis.append(dates[0]) + data.append(datas) + + path_name = '.' + os.sep + 'QA_' + _quotation_base.type + \ + '_' + code + '_' + _quotation_base.if_fq + '.html' + kline = Kline(code + '__' + _quotation_base.if_fq + '__' + _quotation_base.type, + width=1360, height=700, page_title='QUANTAXIS') + kline.add(code, axis, data, mark_point=[ + "max", "min"], is_datazoom_show=True, datazoom_orient='horizontal') + kline.render(path_name) + webbrowser.open(path_name) + QA_util_log_info('The Pic has been saved to your path: %s' % path_name)
+ + +
[docs]def QA_plot_save_html(pic_handle, path, if_open_web): + pic_handle.render(path) + if if_open_web: + webbrowser.open(path) + else: + pass + QA_util_log_info('The Pic has been saved to your path: %s' % path)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QARandom.html b/_build/html/_modules/QUANTAXIS/QAUtil/QARandom.html new file mode 100644 index 000000000..99f094890 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QARandom.html @@ -0,0 +1,121 @@ + + + + + + + + QUANTAXIS.QAUtil.QARandom — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QARandom

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import random
+
+
+
[docs]def QA_util_random_with_topic(topic='Acc', lens=8): + """ + 生成account随机值 + + Acc+4数字id+4位大小写随机 + + """ + _list = [chr(i) for i in range(65, 91)] + [chr(i) + for i in range(97, 123)] + [str(i) for i in range(10)] + + num = random.sample(_list, lens) + return '{}_{}'.format(topic, ''.join(num))
+ + +if __name__ == '__main__': + print(QA_util_random_with_topic(input())) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QASetting.html b/_build/html/_modules/QUANTAXIS/QAUtil/QASetting.html new file mode 100644 index 000000000..0cdebd46d --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QASetting.html @@ -0,0 +1,159 @@ + + + + + + + + QUANTAXIS.QAUtil.QASetting — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QASetting

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from QUANTAXIS.QASU.user import QA_user_sign_in
+from QUANTAXIS.QAUtil.QASql import QA_util_sql_mongo_setting
+
+
+
[docs]class QA_Setting(): + def __init__(self, ip='127.0.0.1', port=27017): + self.ip = ip + self.port = port + self.username = None + self.password = None + + @property + def client(self): + return QA_util_sql_mongo_setting(self.ip, self.port) + +
[docs] def change(self, ip, port): + self.ip = ip + self.port = port + global DATABASE + DATABASE = self.client.quantaxis + return self
+ +
[docs] def login(self, user_name, password): + user = QA_user_sign_in(user_name, password, self.client) + if user is not None: + self.user_name = user_name + self.password = password + self.user = user + return self.user + else: + return False
+ + +DATABASE = QA_Setting().client.quantaxis + + +info_ip_list = [{'ip': '101.227.73.20', 'port': 7709}, {'ip': '101.227.77.254', 'port': 7709}, {'ip': '114.80.63.12', 'port': 7709}, {'ip': '114.80.63.35', 'port': 7709}, {'ip': '115.238.56.198', 'port': 7709}, {'ip': '115.238.90.165', 'port': 7709}, {'ip': '124.160.88.183', 'port': 7709}, {'ip': '60.28.23.80', 'port': 7709}, {'ip': '14.215.128.18', 'port': 7709}, {'ip': '180.153.18.170', 'port': 7709}, { + 'ip': '180.153.18.171', 'port': 7709}, {'ip': '180.153.39.51', 'port': 7709}, {'ip': '202.108.253.130', 'port': 7709}, {'ip': '202.108.253.131', 'port': 7709}, {'ip': '218.108.47.69', 'port': 7709}, {'ip': '218.108.98.244', 'port': 7709}, {'ip': '218.75.126.9', 'port': 7709}, {'ip': '221.231.141.60', 'port': 7709}, {'ip': '59.173.18.140', 'port': 7709}, {'ip': '60.12.136.250', 'port': 7709}] + + +stock_ip_list = [{'ip': '218.75.126.9', 'port': 7709}, {'ip': '115.238.90.165', 'port': 7709}, {'ip': '124.160.88.183', 'port': 7709}, {'ip': '60.12.136.250', 'port': 7709}, {'ip': '218.108.98.244', 'port': 7709}, {'ip': '218.108.47.69', 'port': 7709}, {'ip': '180.153.39.51', 'port': 7709}, {'ip': '121.14.2.7', 'port': 7709}, {'ip': '60.28.29.69', 'port': 7709}, {'ip': '180.153.18.170', 'port': 7709}, {'ip': '180.153.18.171', 'port': 7709}, {'ip': '180.153.18.17', 'port': 7709}, { + 'ip': '61.135.142.73', 'port': 7709}, {'ip': '115.238.56.198', 'port': 7709}, {'ip': '60.191.117.167', 'port': 7709}, {'ip': 'hq.cjis.cn', 'port': 7709}, {'ip': '59.173.18.69', 'port': 7709}, {'ip': 'sztdx.gtjas.com', 'port': 7709}, {'ip': 'jstdx.gtjas.com', 'port': 7709}, {'ip': 'shtdx.gtjas.com', 'port': 7709}, {'ip': '218.9.148.108', 'port': 7709}, {'ip': '61.153.144.179', 'port': 7709}, {'ip': '61.153.209.138', 'port': 7709}, {'ip': '61.153.209.139', 'port': 7709}, {'ip': 'hq1.daton.com.cn', 'port': 7709}] + +future_ip_list = [{'ip': '112.74.214.43', 'port': 7727}, + {'ip': '59.175.238.38', 'port': 7727}, + {'ip': '124.74.236.94', 'port': 7721}, + {'ip': '218.80.248.229', 'port': 7721}, + {'ip': '124.74.236.94', 'port': 7721}, + {'ip': '58.246.109.27', 'port': 7721} + ] + + +""" +['121.14.110.210', '119.147.212.76', '113.105.73.86', '119.147.171.211', '119.147.164.57', '119.147.164.58', '61.49.50.180', '61.49.50.181', +'61.135.142.85', '61.135.149.181', '114.80.80.210', '222.73.49.15', '221.194.181.176'] +""" +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QASql.html b/_build/html/_modules/QUANTAXIS/QAUtil/QASql.html new file mode 100644 index 000000000..68cd27795 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QASql.html @@ -0,0 +1,129 @@ + + + + + + + + QUANTAXIS.QAUtil.QASql — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QASql

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import pymongo
+from motor.motor_asyncio import AsyncIOMotorClient
+
+from QUANTAXIS.QAUtil.QALogs import QA_util_log_info
+
+
+
[docs]def QA_util_sql_mongo_setting(ip='127.0.0.1', port=27017): + client = pymongo.MongoClient(ip, int(port)) + #QA_util_log_info('ip:{},port:{}'.format(str(ip), str(port))) + return client
+ +# async + + +
[docs]def QA_util_sql_async_mongo_setting(ip='127.0.0.1', port=27017): + client = AsyncIOMotorClient(ip, int(port)) + QA_util_log_info('ip:{},port{}'.format(str(ip), str(port))) + return client
+ + +QA_util_sql_mongo_sort_ASCENDING = pymongo.ASCENDING +QA_util_sql_mongo_sort_DESCENDING = pymongo.DESCENDING + +if __name__ == '__main__': + # test async_mongo + client = QA_util_sql_async_mongo_setting().quantaxis.stock_day + print(client) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QAText.html b/_build/html/_modules/QUANTAXIS/QAUtil/QAText.html new file mode 100644 index 000000000..7accaa118 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QAText.html @@ -0,0 +1,124 @@ + + + + + + + + QUANTAXIS.QAUtil.QAText — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QAText

+# coding=utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+"""
+这里主要是一些关于文本的代码
+
+文本分词
+模糊查询
+正则匹配
+"""
+
+import jieba
+import re
+import fuzzyfinder
+
+# TODO: stock_list中有股票的中文/stock_block中有版块的中文 需要将他们做一些模糊查询
+
+
+
+
[docs]def split_word(input_text,cutall=False): + """ + 使用jieba分词 将输入的语句分词 + """ + + return jieba.cut(input_text,cut_all=cutall)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QATransform.html b/_build/html/_modules/QUANTAXIS/QAUtil/QATransform.html new file mode 100644 index 000000000..b91b153ee --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QATransform.html @@ -0,0 +1,145 @@ + + + + + + + + QUANTAXIS.QAUtil.QATransform — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QATransform

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import csv
+import json
+
+import numpy as np
+import pandas as pd
+
+
+
[docs]def QA_util_to_json_from_pandas(data): + """需要对于datetime 和date 进行转换, 以免直接被变成了时间戳""" + if 'datetime' in data.columns: + data.datetime = data.datetime.apply(str) + if 'date' in data.columns: + data.date = data.date.apply(str) + return json.loads(data.to_json(orient='records'))
+ + +
[docs]def QA_util_to_json_from_numpy(data): + pass
+ + +
[docs]def QA_util_to_json_from_list(data): + pass
+ + +
[docs]def QA_util_to_list_from_pandas(data): + return np.asarray(data).tolist()
+ + +
[docs]def QA_util_to_list_from_numpy(data): + return data.tolist()
+ + +
[docs]def QA_util_to_pandas_from_json(data): + + if isinstance(data, dict): + return pd.DataFrame(data=[data, ]) + else: + return pd.DataFrame(data=[{'value': data}])
+ + +
[docs]def QA_util_to_pandas_from_list(data): + if isinstance(data, list): + return pd.DataFrame(data=data)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAUtil/QAWeb.html b/_build/html/_modules/QUANTAXIS/QAUtil/QAWeb.html new file mode 100644 index 000000000..192246807 --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAUtil/QAWeb.html @@ -0,0 +1,142 @@ + + + + + + + + QUANTAXIS.QAUtil.QAWeb — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAUtil.QAWeb

+# coding:utf-8
+#
+# The MIT License (MIT)
+#
+# Copyright (c) 2016-2018 yutiansut/QUANTAXIS
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import datetime
+from subprocess import PIPE, Popen
+
+
+
[docs]def QA_util_web_ping(url): + ms_list = [] + p = Popen(["ping", url], + stdin=PIPE, stdout=PIPE, stderr=PIPE, + shell=True) + out = p.stdout.read() + list_ = str(out).split('=') + # print(list) + for item in list_: + if 'ms' in item: + ms_list.append(int(item.split('ms')[0])) + + if len(ms_list) < 1: + # Bad Request: + ms_list.append(9999999) + return ms_list[-1]
+ + +
[docs]class QA_Util_web_pool(): + def __init__(self): + pass + +
[docs] def hot_update(self): + pass
+ +
[docs] def dynamic_optimics(self): + pass
+ +
[docs] def task_queue(self): + pass
+ + +if __name__ == "__main__": + print(datetime.datetime.now()) + print(QA_util_web_ping('www.baidu.com')) + print(datetime.datetime.now()) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/QUANTAXIS/QAWeb/chain.html b/_build/html/_modules/QUANTAXIS/QAWeb/chain.html new file mode 100644 index 000000000..5665fe56a --- /dev/null +++ b/_build/html/_modules/QUANTAXIS/QAWeb/chain.html @@ -0,0 +1,358 @@ + + + + + + + + QUANTAXIS.QAWeb.chain — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for QUANTAXIS.QAWeb.chain

+import hashlib
+import json
+from time import time
+from typing import Any, Dict, List, Optional
+from urllib.parse import urlparse
+from uuid import uuid4
+
+import requests
+from flask import Flask, jsonify, request
+
+#from https://github.com/xilibi2003/blockchain/blob/master/blockchain.py
+
+
+
[docs]class Blockchain: + def __init__(self): + self.current_transactions = [] + self.chain = [] + self.nodes = set() + + # 创建创世块 + self.new_block(previous_hash='1', proof=100) + +
[docs] def register_node(self, address: str) -> None: + """ + Add a new node to the list of nodes + :param address: Address of node. Eg. 'http://192.168.0.5:5000' + """ + + parsed_url = urlparse(address) + self.nodes.add(parsed_url.netloc)
+ +
[docs] def valid_chain(self, chain: List[Dict[str, Any]]) -> bool: + """ + Determine if a given blockchain is valid + :param chain: A blockchain + :return: True if valid, False if not + """ + + last_block = chain[0] + current_index = 1 + + while current_index < len(chain): + block = chain[current_index] + print(f'{last_block}') + print(f'{block}') + print("\n-----------\n") + # Check that the hash of the block is correct + if block['previous_hash'] != self.hash(last_block): + return False + + # Check that the Proof of Work is correct + if not self.valid_proof(last_block['proof'], block['proof']): + return False + + last_block = block + current_index += 1 + + return True
+ +
[docs] def resolve_conflicts(self) -> bool: + """ + 共识算法解决冲突 + 使用网络中最长的链. + :return: 如果链被取代返回 True, 否则为False + """ + + neighbours = self.nodes + new_chain = None + + # We're only looking for chains longer than ours + max_length = len(self.chain) + + # Grab and verify the chains from all the nodes in our network + for node in neighbours: + response = requests.get(f'http://{node}/chain') + + if response.status_code == 200: + length = response.json()['length'] + chain = response.json()['chain'] + + # Check if the length is longer and the chain is valid + if length > max_length and self.valid_chain(chain): + max_length = length + new_chain = chain + + # Replace our chain if we discovered a new, valid chain longer than ours + if new_chain: + self.chain = new_chain + return True + + return False
+ +
[docs] def new_block(self, proof: int, previous_hash: Optional[str]) -> Dict[str, Any]: + """ + 生成新块 + :param proof: The proof given by the Proof of Work algorithm + :param previous_hash: Hash of previous Block + :return: New Block + """ + + block = { + 'index': len(self.chain) + 1, + 'timestamp': time(), + 'transactions': self.current_transactions, + 'proof': proof, + 'previous_hash': previous_hash or self.hash(self.chain[-1]), + } + + # Reset the current list of transactions + self.current_transactions = [] + + self.chain.append(block) + return block
+ +
[docs] def new_transaction(self, sender: str, recipient: str, amount: int) -> int: + """ + 生成新交易信息,信息将加入到下一个待挖的区块中 + :param sender: Address of the Sender + :param recipient: Address of the Recipient + :param amount: Amount + :return: The index of the Block that will hold this transaction + """ + self.current_transactions.append({ + 'sender': sender, + 'recipient': recipient, + 'amount': amount, + }) + + return self.last_block['index'] + 1
+ + @property + def last_block(self) -> Dict[str, Any]: + return self.chain[-1] + +
[docs] @staticmethod + def hash(block: Dict[str, Any]) -> str: + """ + 生成块的 SHA-256 hash值 + :param block: Block + """ + + # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes + block_string = json.dumps(block, sort_keys=True).encode() + return hashlib.sha256(block_string).hexdigest()
+ +
[docs] def proof_of_work(self, last_proof: int) -> int: + """ + 简单的工作量证明: + - 查找一个 p' 使得 hash(pp') 以4个0开头 + - p 是上一个块的证明, p' 是当前的证明 + """ + + proof = 0 + while self.valid_proof(last_proof, proof) is False: + proof += 1 + + return proof
+ +
[docs] @staticmethod + def valid_proof(last_proof: int, proof: int) -> bool: + """ + 验证证明: 是否hash(last_proof, proof)以4个0开头 + :param last_proof: Previous Proof + :param proof: Current Proof + :return: True if correct, False if not. + """ + + guess = f'{last_proof}{proof}'.encode() + guess_hash = hashlib.sha256(guess).hexdigest() + return guess_hash[:4] == "0000"
+ + +# Instantiate the Node +app = Flask(__name__) + +# Generate a globally unique address for this node +node_identifier = str(uuid4()).replace('-', '') + +# Instantiate the Blockchain +blockchain = Blockchain() + + +
[docs]@app.route('/mine', methods=['GET']) +def mine(): + # We run the proof of work algorithm to get the next proof... + last_block = blockchain.last_block + last_proof = last_block['proof'] + proof = blockchain.proof_of_work(last_proof) + + # 给工作量证明的节点提供奖励. + # 发送者为 "0" 表明是新挖出的币 + blockchain.new_transaction( + sender="0", + recipient=node_identifier, + amount=1, + ) + + # Forge the new Block by adding it to the chain + block = blockchain.new_block(proof, None) + + response = { + 'message': "New Block Forged", + 'index': block['index'], + 'transactions': block['transactions'], + 'proof': block['proof'], + 'previous_hash': block['previous_hash'], + } + return jsonify(response), 200
+ + +
[docs]@app.route('/transactions/new', methods=['POST']) +def new_transaction(): + values = request.get_json() + + # 检查POST数据 + required = ['sender', 'recipient', 'amount'] + if not all(k in values for k in required): + return 'Missing values', 400 + + # Create a new Transaction + index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount']) + + response = {'message': f'Transaction will be added to Block {index}'} + return jsonify(response), 201
+ + +
[docs]@app.route('/chain', methods=['GET']) +def full_chain(): + response = { + 'chain': blockchain.chain, + 'length': len(blockchain.chain), + } + return jsonify(response), 200
+ + +
[docs]@app.route('/nodes/register', methods=['POST']) +def register_nodes(): + values = request.get_json() + + nodes = values.get('nodes') + if nodes is None: + return "Error: Please supply a valid list of nodes", 400 + + for node in nodes: + blockchain.register_node(node) + + response = { + 'message': 'New nodes have been added', + 'total_nodes': list(blockchain.nodes), + } + return jsonify(response), 201
+ + +
[docs]@app.route('/nodes/resolve', methods=['GET']) +def consensus(): + replaced = blockchain.resolve_conflicts() + + if replaced: + response = { + 'message': 'Our chain was replaced', + 'new_chain': blockchain.chain + } + else: + response = { + 'message': 'Our chain is authoritative', + 'chain': blockchain.chain + } + + return jsonify(response), 200
+ + +if __name__ == '__main__': + from argparse import ArgumentParser + + parser = ArgumentParser() + parser.add_argument('-p', '--port', default=5000, type=int, help='port to listen on') + args = parser.parse_args() + port = args.port + + app.run(host='127.0.0.1', port=port) +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/index.html b/_build/html/_modules/index.html new file mode 100644 index 000000000..f3224bdf8 --- /dev/null +++ b/_build/html/_modules/index.html @@ -0,0 +1,158 @@ + + + + + + + + Overview: module code — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

All modules for which code is available

+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_modules/sqlalchemy/orm/attributes.html b/_build/html/_modules/sqlalchemy/orm/attributes.html new file mode 100644 index 000000000..a04f3cb0d --- /dev/null +++ b/_build/html/_modules/sqlalchemy/orm/attributes.html @@ -0,0 +1,1774 @@ + + + + + + + + sqlalchemy.orm.attributes — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for sqlalchemy.orm.attributes

+# orm/attributes.py
+# Copyright (C) 2005-2018 the SQLAlchemy authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of SQLAlchemy and is released under
+# the MIT License: http://www.opensource.org/licenses/mit-license.php
+
+"""Defines instrumentation for class attributes and their interaction
+with instances.
+
+This module is usually not directly visible to user applications, but
+defines a large part of the ORM's interactivity.
+
+
+"""
+
+import operator
+from .. import util, event, inspection
+from . import interfaces, collections, exc as orm_exc
+
+from .base import instance_state, instance_dict, manager_of_class
+
+from .base import PASSIVE_NO_RESULT, ATTR_WAS_SET, ATTR_EMPTY, NO_VALUE,\
+    NEVER_SET, NO_CHANGE, CALLABLES_OK, SQL_OK, RELATED_OBJECT_OK,\
+    INIT_OK, NON_PERSISTENT_OK, LOAD_AGAINST_COMMITTED, PASSIVE_OFF,\
+    PASSIVE_RETURN_NEVER_SET, PASSIVE_NO_INITIALIZE, PASSIVE_NO_FETCH,\
+    PASSIVE_NO_FETCH_RELATED, PASSIVE_ONLY_PERSISTENT, NO_AUTOFLUSH
+from .base import state_str, instance_str
+
+
+@inspection._self_inspects
+class QueryableAttribute(interfaces._MappedAttribute,
+                         interfaces.InspectionAttr,
+                         interfaces.PropComparator):
+    """Base class for :term:`descriptor` objects that intercept
+    attribute events on behalf of a :class:`.MapperProperty`
+    object.  The actual :class:`.MapperProperty` is accessible
+    via the :attr:`.QueryableAttribute.property`
+    attribute.
+
+
+    .. seealso::
+
+        :class:`.InstrumentedAttribute`
+
+        :class:`.MapperProperty`
+
+        :attr:`.Mapper.all_orm_descriptors`
+
+        :attr:`.Mapper.attrs`
+    """
+
+    is_attribute = True
+
+    def __init__(self, class_, key, impl=None,
+                 comparator=None, parententity=None,
+                 of_type=None):
+        self.class_ = class_
+        self.key = key
+        self.impl = impl
+        self.comparator = comparator
+        self._parententity = parententity
+        self._of_type = of_type
+
+        manager = manager_of_class(class_)
+        # manager is None in the case of AliasedClass
+        if manager:
+            # propagate existing event listeners from
+            # immediate superclass
+            for base in manager._bases:
+                if key in base:
+                    self.dispatch._update(base[key].dispatch)
+
+    @util.memoized_property
+    def _supports_population(self):
+        return self.impl.supports_population
+
+    def get_history(self, instance, passive=PASSIVE_OFF):
+        return self.impl.get_history(instance_state(instance),
+                                     instance_dict(instance), passive)
+
+    def __selectable__(self):
+        # TODO: conditionally attach this method based on clause_element ?
+        return self
+
+    @util.memoized_property
+    def info(self):
+        """Return the 'info' dictionary for the underlying SQL element.
+
+        The behavior here is as follows:
+
+        * If the attribute is a column-mapped property, i.e.
+          :class:`.ColumnProperty`, which is mapped directly
+          to a schema-level :class:`.Column` object, this attribute
+          will return the :attr:`.SchemaItem.info` dictionary associated
+          with the core-level :class:`.Column` object.
+
+        * If the attribute is a :class:`.ColumnProperty` but is mapped to
+          any other kind of SQL expression other than a :class:`.Column`,
+          the attribute will refer to the :attr:`.MapperProperty.info`
+          dictionary associated directly with the :class:`.ColumnProperty`,
+          assuming the SQL expression itself does not have its own ``.info``
+          attribute (which should be the case, unless a user-defined SQL
+          construct has defined one).
+
+        * If the attribute refers to any other kind of
+          :class:`.MapperProperty`, including :class:`.RelationshipProperty`,
+          the attribute will refer to the :attr:`.MapperProperty.info`
+          dictionary associated with that :class:`.MapperProperty`.
+
+        * To access the :attr:`.MapperProperty.info` dictionary of the
+          :class:`.MapperProperty` unconditionally, including for a
+          :class:`.ColumnProperty` that's associated directly with a
+          :class:`.schema.Column`, the attribute can be referred to using
+          :attr:`.QueryableAttribute.property` attribute, as
+          ``MyClass.someattribute.property.info``.
+
+        .. versionadded:: 0.8.0
+
+        .. seealso::
+
+            :attr:`.SchemaItem.info`
+
+            :attr:`.MapperProperty.info`
+
+        """
+        return self.comparator.info
+
+    @util.memoized_property
+    def parent(self):
+        """Return an inspection instance representing the parent.
+
+        This will be either an instance of :class:`.Mapper`
+        or :class:`.AliasedInsp`, depending upon the nature
+        of the parent entity which this attribute is associated
+        with.
+
+        """
+        return inspection.inspect(self._parententity)
+
+    @property
+    def expression(self):
+        return self.comparator.__clause_element__()
+
+    def __clause_element__(self):
+        return self.comparator.__clause_element__()
+
+    def _query_clause_element(self):
+        """like __clause_element__(), but called specifically
+        by :class:`.Query` to allow special behavior."""
+
+        return self.comparator._query_clause_element()
+
+    def _bulk_update_tuples(self, value):
+        """Return setter tuples for a bulk UPDATE."""
+
+        return self.comparator._bulk_update_tuples(value)
+
+    def adapt_to_entity(self, adapt_to_entity):
+        assert not self._of_type
+        return self.__class__(adapt_to_entity.entity,
+                              self.key, impl=self.impl,
+                              comparator=self.comparator.adapt_to_entity(
+                                  adapt_to_entity),
+                              parententity=adapt_to_entity)
+
+    def of_type(self, cls):
+        return QueryableAttribute(
+            self.class_,
+            self.key,
+            self.impl,
+            self.comparator.of_type(cls),
+            self._parententity,
+            of_type=cls)
+
+    def label(self, name):
+        return self._query_clause_element().label(name)
+
+    def operate(self, op, *other, **kwargs):
+        return op(self.comparator, *other, **kwargs)
+
+    def reverse_operate(self, op, other, **kwargs):
+        return op(other, self.comparator, **kwargs)
+
+    def hasparent(self, state, optimistic=False):
+        return self.impl.hasparent(state, optimistic=optimistic) is not False
+
+    def __getattr__(self, key):
+        try:
+            return getattr(self.comparator, key)
+        except AttributeError:
+            raise AttributeError(
+                'Neither %r object nor %r object associated with %s '
+                'has an attribute %r' % (
+                    type(self).__name__,
+                    type(self.comparator).__name__,
+                    self,
+                    key)
+            )
+
+    def __str__(self):
+        return "%s.%s" % (self.class_.__name__, self.key)
+
+    @util.memoized_property
+    def property(self):
+        """Return the :class:`.MapperProperty` associated with this
+        :class:`.QueryableAttribute`.
+
+
+        Return values here will commonly be instances of
+        :class:`.ColumnProperty` or :class:`.RelationshipProperty`.
+
+
+        """
+        return self.comparator.property
+
+
+class InstrumentedAttribute(QueryableAttribute):
+    """Class bound instrumented attribute which adds basic
+    :term:`descriptor` methods.
+
+    See :class:`.QueryableAttribute` for a description of most features.
+
+
+    """
+
+    def __set__(self, instance, value):
+        self.impl.set(instance_state(instance),
+                      instance_dict(instance), value, None)
+
+    def __delete__(self, instance):
+        self.impl.delete(instance_state(instance), instance_dict(instance))
+
+    def __get__(self, instance, owner):
+        if instance is None:
+            return self
+
+        dict_ = instance_dict(instance)
+        if self._supports_population and self.key in dict_:
+            return dict_[self.key]
+        else:
+            return self.impl.get(instance_state(instance), dict_)
+
+
+def create_proxied_attribute(descriptor):
+    """Create an QueryableAttribute / user descriptor hybrid.
+
+    Returns a new QueryableAttribute type that delegates descriptor
+    behavior and getattr() to the given descriptor.
+    """
+
+    # TODO: can move this to descriptor_props if the need for this
+    # function is removed from ext/hybrid.py
+
+    class Proxy(QueryableAttribute):
+        """Presents the :class:`.QueryableAttribute` interface as a
+        proxy on top of a Python descriptor / :class:`.PropComparator`
+        combination.
+
+        """
+
+        def __init__(self, class_, key, descriptor,
+                     comparator,
+                     adapt_to_entity=None, doc=None,
+                     original_property=None):
+            self.class_ = class_
+            self.key = key
+            self.descriptor = descriptor
+            self.original_property = original_property
+            self._comparator = comparator
+            self._adapt_to_entity = adapt_to_entity
+            self.__doc__ = doc
+
+        @property
+        def property(self):
+            return self.comparator.property
+
+        @util.memoized_property
+        def comparator(self):
+            if util.callable(self._comparator):
+                self._comparator = self._comparator()
+            if self._adapt_to_entity:
+                self._comparator = self._comparator.adapt_to_entity(
+                    self._adapt_to_entity)
+            return self._comparator
+
+        def adapt_to_entity(self, adapt_to_entity):
+            return self.__class__(adapt_to_entity.entity,
+                                  self.key,
+                                  self.descriptor,
+                                  self._comparator,
+                                  adapt_to_entity)
+
+        def __get__(self, instance, owner):
+            if instance is None:
+                return self
+            else:
+                return self.descriptor.__get__(instance, owner)
+
+        def __str__(self):
+            return "%s.%s" % (self.class_.__name__, self.key)
+
+        def __getattr__(self, attribute):
+            """Delegate __getattr__ to the original descriptor and/or
+            comparator."""
+
+            try:
+                return getattr(descriptor, attribute)
+            except AttributeError:
+                try:
+                    return getattr(self.comparator, attribute)
+                except AttributeError:
+                    raise AttributeError(
+                        'Neither %r object nor %r object associated with %s '
+                        'has an attribute %r' % (
+                            type(descriptor).__name__,
+                            type(self.comparator).__name__,
+                            self,
+                            attribute)
+                    )
+
+    Proxy.__name__ = type(descriptor).__name__ + 'Proxy'
+
+    util.monkeypatch_proxied_specials(Proxy, type(descriptor),
+                                      name='descriptor',
+                                      from_instance=descriptor)
+    return Proxy
+
+OP_REMOVE = util.symbol("REMOVE")
+OP_APPEND = util.symbol("APPEND")
+OP_REPLACE = util.symbol("REPLACE")
+OP_BULK_REPLACE = util.symbol("BULK_REPLACE")
+OP_MODIFIED = util.symbol("MODIFIED")
+
+
+class Event(object):
+    """A token propagated throughout the course of a chain of attribute
+    events.
+
+    Serves as an indicator of the source of the event and also provides
+    a means of controlling propagation across a chain of attribute
+    operations.
+
+    The :class:`.Event` object is sent as the ``initiator`` argument
+    when dealing with events such as :meth:`.AttributeEvents.append`,
+    :meth:`.AttributeEvents.set`,
+    and :meth:`.AttributeEvents.remove`.
+
+    The :class:`.Event` object is currently interpreted by the backref
+    event handlers, and is used to control the propagation of operations
+    across two mutually-dependent attributes.
+
+    .. versionadded:: 0.9.0
+
+    :var impl: The :class:`.AttributeImpl` which is the current event
+     initiator.
+
+    :var op: The symbol :attr:`.OP_APPEND`, :attr:`.OP_REMOVE`,
+     :attr:`.OP_REPLACE`, or :attr:`.OP_BULK_REPLACE`, indicating the
+     source operation.
+
+    """
+
+    __slots__ = 'impl', 'op', 'parent_token'
+
+    def __init__(self, attribute_impl, op):
+        self.impl = attribute_impl
+        self.op = op
+        self.parent_token = self.impl.parent_token
+
+    def __eq__(self, other):
+        return isinstance(other, Event) and \
+            other.impl is self.impl and \
+            other.op == self.op
+
+    @property
+    def key(self):
+        return self.impl.key
+
+    def hasparent(self, state):
+        return self.impl.hasparent(state)
+
+
+class AttributeImpl(object):
+    """internal implementation for instrumented attributes."""
+
+    def __init__(self, class_, key,
+                 callable_, dispatch, trackparent=False, extension=None,
+                 compare_function=None, active_history=False,
+                 parent_token=None, expire_missing=True,
+                 send_modified_events=True, accepts_scalar_loader=None,
+                 **kwargs):
+        r"""Construct an AttributeImpl.
+
+        \class_
+          associated class
+
+        key
+          string name of the attribute
+
+        \callable_
+          optional function which generates a callable based on a parent
+          instance, which produces the "default" values for a scalar or
+          collection attribute when it's first accessed, if not present
+          already.
+
+        trackparent
+          if True, attempt to track if an instance has a parent attached
+          to it via this attribute.
+
+        extension
+          a single or list of AttributeExtension object(s) which will
+          receive set/delete/append/remove/etc. events.  Deprecated.
+          The event package is now used.
+
+        compare_function
+          a function that compares two values which are normally
+          assignable to this attribute.
+
+        active_history
+          indicates that get_history() should always return the "old" value,
+          even if it means executing a lazy callable upon attribute change.
+
+        parent_token
+          Usually references the MapperProperty, used as a key for
+          the hasparent() function to identify an "owning" attribute.
+          Allows multiple AttributeImpls to all match a single
+          owner attribute.
+
+        expire_missing
+          if False, don't add an "expiry" callable to this attribute
+          during state.expire_attributes(None), if no value is present
+          for this key.
+
+        send_modified_events
+          if False, the InstanceState._modified_event method will have no
+          effect; this means the attribute will never show up as changed in a
+          history entry.
+        """
+        self.class_ = class_
+        self.key = key
+        self.callable_ = callable_
+        self.dispatch = dispatch
+        self.trackparent = trackparent
+        self.parent_token = parent_token or self
+        self.send_modified_events = send_modified_events
+        if compare_function is None:
+            self.is_equal = operator.eq
+        else:
+            self.is_equal = compare_function
+
+        if accepts_scalar_loader is not None:
+            self.accepts_scalar_loader = accepts_scalar_loader
+        else:
+            self.accepts_scalar_loader = self.default_accepts_scalar_loader
+
+        # TODO: pass in the manager here
+        # instead of doing a lookup
+        attr = manager_of_class(class_)[key]
+
+        for ext in util.to_list(extension or []):
+            ext._adapt_listener(attr, ext)
+
+        if active_history:
+            self.dispatch._active_history = True
+
+        self.expire_missing = expire_missing
+        self._modified_token = Event(self, OP_MODIFIED)
+
+    __slots__ = (
+        'class_', 'key', 'callable_', 'dispatch', 'trackparent',
+        'parent_token', 'send_modified_events', 'is_equal', 'expire_missing',
+        '_modified_token', 'accepts_scalar_loader'
+    )
+
+    def __str__(self):
+        return "%s.%s" % (self.class_.__name__, self.key)
+
+    def _get_active_history(self):
+        """Backwards compat for impl.active_history"""
+
+        return self.dispatch._active_history
+
+    def _set_active_history(self, value):
+        self.dispatch._active_history = value
+
+    active_history = property(_get_active_history, _set_active_history)
+
+    def hasparent(self, state, optimistic=False):
+        """Return the boolean value of a `hasparent` flag attached to
+        the given state.
+
+        The `optimistic` flag determines what the default return value
+        should be if no `hasparent` flag can be located.
+
+        As this function is used to determine if an instance is an
+        *orphan*, instances that were loaded from storage should be
+        assumed to not be orphans, until a True/False value for this
+        flag is set.
+
+        An instance attribute that is loaded by a callable function
+        will also not have a `hasparent` flag.
+
+        """
+        msg = "This AttributeImpl is not configured to track parents."
+        assert self.trackparent, msg
+
+        return state.parents.get(id(self.parent_token), optimistic) \
+            is not False
+
+    def sethasparent(self, state, parent_state, value):
+        """Set a boolean flag on the given item corresponding to
+        whether or not it is attached to a parent object via the
+        attribute represented by this ``InstrumentedAttribute``.
+
+        """
+        msg = "This AttributeImpl is not configured to track parents."
+        assert self.trackparent, msg
+
+        id_ = id(self.parent_token)
+        if value:
+            state.parents[id_] = parent_state
+        else:
+            if id_ in state.parents:
+                last_parent = state.parents[id_]
+
+                if last_parent is not False and \
+                        last_parent.key != parent_state.key:
+
+                    if last_parent.obj() is None:
+                        raise orm_exc.StaleDataError(
+                            "Removing state %s from parent "
+                            "state %s along attribute '%s', "
+                            "but the parent record "
+                            "has gone stale, can't be sure this "
+                            "is the most recent parent." %
+                            (state_str(state),
+                             state_str(parent_state),
+                             self.key))
+
+                    return
+
+            state.parents[id_] = False
+
+    def get_history(self, state, dict_, passive=PASSIVE_OFF):
+        raise NotImplementedError()
+
+    def get_all_pending(self, state, dict_, passive=PASSIVE_NO_INITIALIZE):
+        """Return a list of tuples of (state, obj)
+        for all objects in this attribute's current state
+        + history.
+
+        Only applies to object-based attributes.
+
+        This is an inlining of existing functionality
+        which roughly corresponds to:
+
+            get_state_history(
+                        state,
+                        key,
+                        passive=PASSIVE_NO_INITIALIZE).sum()
+
+        """
+        raise NotImplementedError()
+
+    def initialize(self, state, dict_):
+        """Initialize the given state's attribute with an empty value."""
+
+        value = None
+        for fn in self.dispatch.init_scalar:
+            ret = fn(state, value, dict_)
+            if ret is not ATTR_EMPTY:
+                value = ret
+
+        return value
+
+    def get(self, state, dict_, passive=PASSIVE_OFF):
+        """Retrieve a value from the given object.
+        If a callable is assembled on this object's attribute, and
+        passive is False, the callable will be executed and the
+        resulting value will be set as the new value for this attribute.
+        """
+        if self.key in dict_:
+            return dict_[self.key]
+        else:
+            # if history present, don't load
+            key = self.key
+            if key not in state.committed_state or \
+                    state.committed_state[key] is NEVER_SET:
+                if not passive & CALLABLES_OK:
+                    return PASSIVE_NO_RESULT
+
+                if key in state.expired_attributes:
+                    value = state._load_expired(state, passive)
+                elif key in state.callables:
+                    callable_ = state.callables[key]
+                    value = callable_(state, passive)
+                elif self.callable_:
+                    value = self.callable_(state, passive)
+                else:
+                    value = ATTR_EMPTY
+
+                if value is PASSIVE_NO_RESULT or value is NEVER_SET:
+                    return value
+                elif value is ATTR_WAS_SET:
+                    try:
+                        return dict_[key]
+                    except KeyError:
+                        # TODO: no test coverage here.
+                        raise KeyError(
+                            "Deferred loader for attribute "
+                            "%r failed to populate "
+                            "correctly" % key)
+                elif value is not ATTR_EMPTY:
+                    return self.set_committed_value(state, dict_, value)
+
+            if not passive & INIT_OK:
+                return NEVER_SET
+            else:
+                # Return a new, empty value
+                return self.initialize(state, dict_)
+
+    def append(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
+        self.set(state, dict_, value, initiator, passive=passive)
+
+    def remove(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
+        self.set(state, dict_, None, initiator,
+                 passive=passive, check_old=value)
+
+    def pop(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
+        self.set(state, dict_, None, initiator,
+                 passive=passive, check_old=value, pop=True)
+
+    def set(self, state, dict_, value, initiator,
+            passive=PASSIVE_OFF, check_old=None, pop=False):
+        raise NotImplementedError()
+
+    def get_committed_value(self, state, dict_, passive=PASSIVE_OFF):
+        """return the unchanged value of this attribute"""
+
+        if self.key in state.committed_state:
+            value = state.committed_state[self.key]
+            if value in (NO_VALUE, NEVER_SET):
+                return None
+            else:
+                return value
+        else:
+            return self.get(state, dict_, passive=passive)
+
+    def set_committed_value(self, state, dict_, value):
+        """set an attribute value on the given instance and 'commit' it."""
+
+        dict_[self.key] = value
+        state._commit(dict_, [self.key])
+        return value
+
+
+class ScalarAttributeImpl(AttributeImpl):
+    """represents a scalar value-holding InstrumentedAttribute."""
+
+    default_accepts_scalar_loader = True
+    uses_objects = False
+    supports_population = True
+    collection = False
+    dynamic = False
+
+    __slots__ = '_replace_token', '_append_token', '_remove_token'
+
+    def __init__(self, *arg, **kw):
+        super(ScalarAttributeImpl, self).__init__(*arg, **kw)
+        self._replace_token = self._append_token = Event(self, OP_REPLACE)
+        self._remove_token = Event(self, OP_REMOVE)
+
+    def delete(self, state, dict_):
+
+        # TODO: catch key errors, convert to attributeerror?
+        if self.dispatch._active_history:
+            old = self.get(state, dict_, PASSIVE_RETURN_NEVER_SET)
+        else:
+            old = dict_.get(self.key, NO_VALUE)
+
+        if self.dispatch.remove:
+            self.fire_remove_event(state, dict_, old, self._remove_token)
+        state._modified_event(dict_, self, old)
+        del dict_[self.key]
+
+    def get_history(self, state, dict_, passive=PASSIVE_OFF):
+        if self.key in dict_:
+            return History.from_scalar_attribute(self, state, dict_[self.key])
+        else:
+            if passive & INIT_OK:
+                passive ^= INIT_OK
+            current = self.get(state, dict_, passive=passive)
+            if current is PASSIVE_NO_RESULT:
+                return HISTORY_BLANK
+            else:
+                return History.from_scalar_attribute(self, state, current)
+
+    def set(self, state, dict_, value, initiator,
+            passive=PASSIVE_OFF, check_old=None, pop=False):
+        if self.dispatch._active_history:
+            old = self.get(state, dict_, PASSIVE_RETURN_NEVER_SET)
+        else:
+            old = dict_.get(self.key, NO_VALUE)
+
+        if self.dispatch.set:
+            value = self.fire_replace_event(state, dict_,
+                                            value, old, initiator)
+        state._modified_event(dict_, self, old)
+        dict_[self.key] = value
+
+    def fire_replace_event(self, state, dict_, value, previous, initiator):
+        for fn in self.dispatch.set:
+            value = fn(
+                state, value, previous, initiator or self._replace_token)
+        return value
+
+    def fire_remove_event(self, state, dict_, value, initiator):
+        for fn in self.dispatch.remove:
+            fn(state, value, initiator or self._remove_token)
+
+    @property
+    def type(self):
+        self.property.columns[0].type
+
+
+class ScalarObjectAttributeImpl(ScalarAttributeImpl):
+    """represents a scalar-holding InstrumentedAttribute,
+       where the target object is also instrumented.
+
+       Adds events to delete/set operations.
+
+    """
+
+    default_accepts_scalar_loader = False
+    uses_objects = True
+    supports_population = True
+    collection = False
+
+    __slots__ = ()
+
+    def delete(self, state, dict_):
+        old = self.get(state, dict_)
+        self.fire_remove_event(state, dict_, old, self._remove_token)
+        del dict_[self.key]
+
+    def get_history(self, state, dict_, passive=PASSIVE_OFF):
+        if self.key in dict_:
+            return History.from_object_attribute(self, state, dict_[self.key])
+        else:
+            if passive & INIT_OK:
+                passive ^= INIT_OK
+            current = self.get(state, dict_, passive=passive)
+            if current is PASSIVE_NO_RESULT:
+                return HISTORY_BLANK
+            else:
+                return History.from_object_attribute(self, state, current)
+
+    def get_all_pending(self, state, dict_, passive=PASSIVE_NO_INITIALIZE):
+        if self.key in dict_:
+            current = dict_[self.key]
+        elif passive & CALLABLES_OK:
+            current = self.get(state, dict_, passive=passive)
+        else:
+            return []
+
+        # can't use __hash__(), can't use __eq__() here
+        if current is not None and \
+                current is not PASSIVE_NO_RESULT and \
+                current is not NEVER_SET:
+            ret = [(instance_state(current), current)]
+        else:
+            ret = [(None, None)]
+
+        if self.key in state.committed_state:
+            original = state.committed_state[self.key]
+            if original is not None and \
+                    original is not PASSIVE_NO_RESULT and \
+                    original is not NEVER_SET and \
+                    original is not current:
+
+                ret.append((instance_state(original), original))
+        return ret
+
+    def set(self, state, dict_, value, initiator,
+            passive=PASSIVE_OFF, check_old=None, pop=False):
+        """Set a value on the given InstanceState.
+
+        """
+        if self.dispatch._active_history:
+            old = self.get(
+                state, dict_,
+                passive=PASSIVE_ONLY_PERSISTENT |
+                NO_AUTOFLUSH | LOAD_AGAINST_COMMITTED)
+        else:
+            old = self.get(
+                state, dict_, passive=PASSIVE_NO_FETCH ^ INIT_OK |
+                LOAD_AGAINST_COMMITTED)
+
+        if check_old is not None and \
+                old is not PASSIVE_NO_RESULT and \
+                check_old is not old:
+            if pop:
+                return
+            else:
+                raise ValueError(
+                    "Object %s not associated with %s on attribute '%s'" % (
+                        instance_str(check_old),
+                        state_str(state),
+                        self.key
+                    ))
+
+        value = self.fire_replace_event(state, dict_, value, old, initiator)
+        dict_[self.key] = value
+
+    def fire_remove_event(self, state, dict_, value, initiator):
+        if self.trackparent and value is not None:
+            self.sethasparent(instance_state(value), state, False)
+
+        for fn in self.dispatch.remove:
+            fn(state, value, initiator or self._remove_token)
+
+        state._modified_event(dict_, self, value)
+
+    def fire_replace_event(self, state, dict_, value, previous, initiator):
+        if self.trackparent:
+            if (previous is not value and
+                    previous not in (None, PASSIVE_NO_RESULT, NEVER_SET)):
+                self.sethasparent(instance_state(previous), state, False)
+
+        for fn in self.dispatch.set:
+            value = fn(
+                state, value, previous, initiator or self._replace_token)
+
+        state._modified_event(dict_, self, previous)
+
+        if self.trackparent:
+            if value is not None:
+                self.sethasparent(instance_state(value), state, True)
+
+        return value
+
+
+class CollectionAttributeImpl(AttributeImpl):
+    """A collection-holding attribute that instruments changes in membership.
+
+    Only handles collections of instrumented objects.
+
+    InstrumentedCollectionAttribute holds an arbitrary, user-specified
+    container object (defaulting to a list) and brokers access to the
+    CollectionAdapter, a "view" onto that object that presents consistent bag
+    semantics to the orm layer independent of the user data implementation.
+
+    """
+    default_accepts_scalar_loader = False
+    uses_objects = True
+    supports_population = True
+    collection = True
+    dynamic = False
+
+    __slots__ = (
+        'copy', 'collection_factory', '_append_token', '_remove_token',
+        '_bulk_replace_token', '_duck_typed_as'
+    )
+
+    def __init__(self, class_, key, callable_, dispatch,
+                 typecallable=None, trackparent=False, extension=None,
+                 copy_function=None, compare_function=None, **kwargs):
+        super(CollectionAttributeImpl, self).__init__(
+            class_,
+            key,
+            callable_, dispatch,
+            trackparent=trackparent,
+            extension=extension,
+            compare_function=compare_function,
+            **kwargs)
+
+        if copy_function is None:
+            copy_function = self.__copy
+        self.copy = copy_function
+        self.collection_factory = typecallable
+        self._append_token = Event(self, OP_APPEND)
+        self._remove_token = Event(self, OP_REMOVE)
+        self._bulk_replace_token = Event(self, OP_BULK_REPLACE)
+        self._duck_typed_as = util.duck_type_collection(
+            self.collection_factory())
+
+        if getattr(self.collection_factory, "_sa_linker", None):
+
+            @event.listens_for(self, "init_collection")
+            def link(target, collection, collection_adapter):
+                collection._sa_linker(collection_adapter)
+
+            @event.listens_for(self, "dispose_collection")
+            def unlink(target, collection, collection_adapter):
+                collection._sa_linker(None)
+
+    def __copy(self, item):
+        return [y for y in collections.collection_adapter(item)]
+
+    def get_history(self, state, dict_, passive=PASSIVE_OFF):
+        current = self.get(state, dict_, passive=passive)
+        if current is PASSIVE_NO_RESULT:
+            return HISTORY_BLANK
+        else:
+            return History.from_collection(self, state, current)
+
+    def get_all_pending(self, state, dict_, passive=PASSIVE_NO_INITIALIZE):
+        # NOTE: passive is ignored here at the moment
+
+        if self.key not in dict_:
+            return []
+
+        current = dict_[self.key]
+        current = getattr(current, '_sa_adapter')
+
+        if self.key in state.committed_state:
+            original = state.committed_state[self.key]
+            if original not in (NO_VALUE, NEVER_SET):
+                current_states = [((c is not None) and
+                                   instance_state(c) or None, c)
+                                  for c in current]
+                original_states = [((c is not None) and
+                                    instance_state(c) or None, c)
+                                   for c in original]
+
+                current_set = dict(current_states)
+                original_set = dict(original_states)
+
+                return \
+                    [(s, o) for s, o in current_states
+                        if s not in original_set] + \
+                    [(s, o) for s, o in current_states
+                        if s in original_set] + \
+                    [(s, o) for s, o in original_states
+                        if s not in current_set]
+
+        return [(instance_state(o), o) for o in current]
+
+    def fire_append_event(self, state, dict_, value, initiator):
+        for fn in self.dispatch.append:
+            value = fn(
+                state, value, initiator or self._append_token)
+
+        state._modified_event(dict_, self, NEVER_SET, True)
+
+        if self.trackparent and value is not None:
+            self.sethasparent(instance_state(value), state, True)
+
+        return value
+
+    def fire_pre_remove_event(self, state, dict_, initiator):
+        state._modified_event(dict_, self, NEVER_SET, True)
+
+    def fire_remove_event(self, state, dict_, value, initiator):
+        if self.trackparent and value is not None:
+            self.sethasparent(instance_state(value), state, False)
+
+        for fn in self.dispatch.remove:
+            fn(state, value, initiator or self._remove_token)
+
+        state._modified_event(dict_, self, NEVER_SET, True)
+
+    def delete(self, state, dict_):
+        if self.key not in dict_:
+            return
+
+        state._modified_event(dict_, self, NEVER_SET, True)
+
+        collection = self.get_collection(state, state.dict)
+        collection.clear_with_event()
+        # TODO: catch key errors, convert to attributeerror?
+        del dict_[self.key]
+
+    def initialize(self, state, dict_):
+        """Initialize this attribute with an empty collection."""
+
+        _, user_data = self._initialize_collection(state)
+        dict_[self.key] = user_data
+        return user_data
+
+    def _initialize_collection(self, state):
+
+        adapter, collection = state.manager.initialize_collection(
+            self.key, state, self.collection_factory)
+
+        self.dispatch.init_collection(state, collection, adapter)
+
+        return adapter, collection
+
+    def append(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
+        collection = self.get_collection(state, dict_, passive=passive)
+        if collection is PASSIVE_NO_RESULT:
+            value = self.fire_append_event(state, dict_, value, initiator)
+            assert self.key not in dict_, \
+                "Collection was loaded during event handling."
+            state._get_pending_mutation(self.key).append(value)
+        else:
+            collection.append_with_event(value, initiator)
+
+    def remove(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
+        collection = self.get_collection(state, state.dict, passive=passive)
+        if collection is PASSIVE_NO_RESULT:
+            self.fire_remove_event(state, dict_, value, initiator)
+            assert self.key not in dict_, \
+                "Collection was loaded during event handling."
+            state._get_pending_mutation(self.key).remove(value)
+        else:
+            collection.remove_with_event(value, initiator)
+
+    def pop(self, state, dict_, value, initiator, passive=PASSIVE_OFF):
+        try:
+            # TODO: better solution here would be to add
+            # a "popper" role to collections.py to complement
+            # "remover".
+            self.remove(state, dict_, value, initiator, passive=passive)
+        except (ValueError, KeyError, IndexError):
+            pass
+
+    def set(self, state, dict_, value, initiator=None,
+            passive=PASSIVE_OFF, pop=False, _adapt=True):
+        iterable = orig_iterable = value
+
+        # pulling a new collection first so that an adaptation exception does
+        # not trigger a lazy load of the old collection.
+        new_collection, user_data = self._initialize_collection(state)
+        if _adapt:
+            if new_collection._converter is not None:
+                iterable = new_collection._converter(iterable)
+            else:
+                setting_type = util.duck_type_collection(iterable)
+                receiving_type = self._duck_typed_as
+
+                if setting_type is not receiving_type:
+                    given = iterable is None and 'None' or \
+                        iterable.__class__.__name__
+                    wanted = self._duck_typed_as.__name__
+                    raise TypeError(
+                        "Incompatible collection type: %s is not %s-like" % (
+                            given, wanted))
+
+                # If the object is an adapted collection, return the (iterable)
+                # adapter.
+                if hasattr(iterable, '_sa_iterator'):
+                    iterable = iterable._sa_iterator()
+                elif setting_type is dict:
+                    if util.py3k:
+                        iterable = iterable.values()
+                    else:
+                        iterable = getattr(
+                            iterable, 'itervalues', iterable.values)()
+                else:
+                    iterable = iter(iterable)
+        new_values = list(iterable)
+
+        evt = self._bulk_replace_token
+
+        self.dispatch.bulk_replace(state, new_values, evt)
+
+        old = self.get(state, dict_, passive=PASSIVE_ONLY_PERSISTENT)
+        if old is PASSIVE_NO_RESULT:
+            old = self.initialize(state, dict_)
+        elif old is orig_iterable:
+            # ignore re-assignment of the current collection, as happens
+            # implicitly with in-place operators (foo.collection |= other)
+            return
+
+        # place a copy of "old" in state.committed_state
+        state._modified_event(dict_, self, old, True)
+
+        old_collection = old._sa_adapter
+
+        dict_[self.key] = user_data
+
+        collections.bulk_replace(
+            new_values, old_collection, new_collection,
+            initiator=evt)
+
+        del old._sa_adapter
+        self.dispatch.dispose_collection(state, old, old_collection)
+
+    def _invalidate_collection(self, collection):
+        adapter = getattr(collection, '_sa_adapter')
+        adapter.invalidated = True
+
+    def set_committed_value(self, state, dict_, value):
+        """Set an attribute value on the given instance and 'commit' it."""
+
+        collection, user_data = self._initialize_collection(state)
+
+        if value:
+            collection.append_multiple_without_event(value)
+
+        state.dict[self.key] = user_data
+
+        state._commit(dict_, [self.key])
+
+        if self.key in state._pending_mutations:
+            # pending items exist.  issue a modified event,
+            # add/remove new items.
+            state._modified_event(dict_, self, user_data, True)
+
+            pending = state._pending_mutations.pop(self.key)
+            added = pending.added_items
+            removed = pending.deleted_items
+            for item in added:
+                collection.append_without_event(item)
+            for item in removed:
+                collection.remove_without_event(item)
+
+        return user_data
+
+    def get_collection(self, state, dict_,
+                       user_data=None, passive=PASSIVE_OFF):
+        """Retrieve the CollectionAdapter associated with the given state.
+
+        Creates a new CollectionAdapter if one does not exist.
+
+        """
+        if user_data is None:
+            user_data = self.get(state, dict_, passive=passive)
+            if user_data is PASSIVE_NO_RESULT:
+                return user_data
+
+        return getattr(user_data, '_sa_adapter')
+
+
+def backref_listeners(attribute, key, uselist):
+    """Apply listeners to synchronize a two-way relationship."""
+
+    # use easily recognizable names for stack traces.
+
+    # in the sections marked "tokens to test for a recursive loop",
+    # this is somewhat brittle and very performance-sensitive logic
+    # that is specific to how we might arrive at each event.  a marker
+    # that can target us directly to arguments being invoked against
+    # the impl might be simpler, but could interfere with other systems.
+
+    parent_token = attribute.impl.parent_token
+    parent_impl = attribute.impl
+
+    def _acceptable_key_err(child_state, initiator, child_impl):
+        raise ValueError(
+            "Bidirectional attribute conflict detected: "
+            'Passing object %s to attribute "%s" '
+            'triggers a modify event on attribute "%s" '
+            'via the backref "%s".' % (
+                state_str(child_state),
+                initiator.parent_token,
+                child_impl.parent_token,
+                attribute.impl.parent_token
+            )
+        )
+
+    def emit_backref_from_scalar_set_event(state, child, oldchild, initiator):
+        if oldchild is child:
+            return child
+        if oldchild is not None and \
+                oldchild is not PASSIVE_NO_RESULT and \
+                oldchild is not NEVER_SET:
+            # With lazy=None, there's no guarantee that the full collection is
+            # present when updating via a backref.
+            old_state, old_dict = instance_state(oldchild),\
+                instance_dict(oldchild)
+            impl = old_state.manager[key].impl
+
+            # tokens to test for a recursive loop.
+            if not impl.collection and not impl.dynamic:
+                check_recursive_token = impl._replace_token
+            else:
+                check_recursive_token = impl._remove_token
+
+            if initiator is not check_recursive_token:
+                impl.pop(old_state,
+                         old_dict,
+                         state.obj(),
+                         parent_impl._append_token,
+                         passive=PASSIVE_NO_FETCH)
+
+        if child is not None:
+            child_state, child_dict = instance_state(child),\
+                instance_dict(child)
+            child_impl = child_state.manager[key].impl
+
+            if initiator.parent_token is not parent_token and \
+                    initiator.parent_token is not child_impl.parent_token:
+                _acceptable_key_err(state, initiator, child_impl)
+
+            # tokens to test for a recursive loop.
+            check_append_token = child_impl._append_token
+            check_bulk_replace_token = child_impl._bulk_replace_token \
+                if child_impl.collection else None
+
+            if initiator is not check_append_token and \
+                    initiator is not check_bulk_replace_token:
+                child_impl.append(
+                    child_state,
+                    child_dict,
+                    state.obj(),
+                    initiator,
+                    passive=PASSIVE_NO_FETCH)
+        return child
+
+    def emit_backref_from_collection_append_event(state, child, initiator):
+        if child is None:
+            return
+
+        child_state, child_dict = instance_state(child), \
+            instance_dict(child)
+        child_impl = child_state.manager[key].impl
+
+        if initiator.parent_token is not parent_token and \
+                initiator.parent_token is not child_impl.parent_token:
+            _acceptable_key_err(state, initiator, child_impl)
+
+        # tokens to test for a recursive loop.
+        check_append_token = child_impl._append_token
+        check_bulk_replace_token = child_impl._bulk_replace_token \
+            if child_impl.collection else None
+
+        if initiator is not check_append_token and \
+                initiator is not check_bulk_replace_token:
+            child_impl.append(
+                child_state,
+                child_dict,
+                state.obj(),
+                initiator,
+                passive=PASSIVE_NO_FETCH)
+        return child
+
+    def emit_backref_from_collection_remove_event(state, child, initiator):
+        if child is not None:
+            child_state, child_dict = instance_state(child),\
+                instance_dict(child)
+            child_impl = child_state.manager[key].impl
+
+            # tokens to test for a recursive loop.
+            if not child_impl.collection and not child_impl.dynamic:
+                check_remove_token = child_impl._remove_token
+                check_replace_token = child_impl._replace_token
+            else:
+                check_remove_token = child_impl._remove_token
+                check_replace_token = child_impl._bulk_replace_token \
+                    if child_impl.collection else None
+
+            if initiator is not check_remove_token and \
+                    initiator is not check_replace_token:
+                child_impl.pop(
+                    child_state,
+                    child_dict,
+                    state.obj(),
+                    initiator,
+                    passive=PASSIVE_NO_FETCH)
+
+    if uselist:
+        event.listen(attribute, "append",
+                     emit_backref_from_collection_append_event,
+                     retval=True, raw=True)
+    else:
+        event.listen(attribute, "set",
+                     emit_backref_from_scalar_set_event,
+                     retval=True, raw=True)
+    # TODO: need coverage in test/orm/ of remove event
+    event.listen(attribute, "remove",
+                 emit_backref_from_collection_remove_event,
+                 retval=True, raw=True)
+
+_NO_HISTORY = util.symbol('NO_HISTORY')
+_NO_STATE_SYMBOLS = frozenset([
+    id(PASSIVE_NO_RESULT),
+    id(NO_VALUE),
+    id(NEVER_SET)])
+
+History = util.namedtuple("History", [
+    "added", "unchanged", "deleted"
+])
+
+
+class History(History):
+    """A 3-tuple of added, unchanged and deleted values,
+    representing the changes which have occurred on an instrumented
+    attribute.
+
+    The easiest way to get a :class:`.History` object for a particular
+    attribute on an object is to use the :func:`.inspect` function::
+
+        from sqlalchemy import inspect
+
+        hist = inspect(myobject).attrs.myattribute.history
+
+    Each tuple member is an iterable sequence:
+
+    * ``added`` - the collection of items added to the attribute (the first
+      tuple element).
+
+    * ``unchanged`` - the collection of items that have not changed on the
+      attribute (the second tuple element).
+
+    * ``deleted`` - the collection of items that have been removed from the
+      attribute (the third tuple element).
+
+    """
+
+    def __bool__(self):
+        return self != HISTORY_BLANK
+    __nonzero__ = __bool__
+
+    def empty(self):
+        """Return True if this :class:`.History` has no changes
+        and no existing, unchanged state.
+
+        """
+
+        return not bool(
+            (self.added or self.deleted)
+            or self.unchanged
+        )
+
+    def sum(self):
+        """Return a collection of added + unchanged + deleted."""
+
+        return (self.added or []) +\
+            (self.unchanged or []) +\
+            (self.deleted or [])
+
+    def non_deleted(self):
+        """Return a collection of added + unchanged."""
+
+        return (self.added or []) +\
+            (self.unchanged or [])
+
+    def non_added(self):
+        """Return a collection of unchanged + deleted."""
+
+        return (self.unchanged or []) +\
+            (self.deleted or [])
+
+    def has_changes(self):
+        """Return True if this :class:`.History` has changes."""
+
+        return bool(self.added or self.deleted)
+
+    def as_state(self):
+        return History(
+            [(c is not None)
+             and instance_state(c) or None
+             for c in self.added],
+            [(c is not None)
+             and instance_state(c) or None
+             for c in self.unchanged],
+            [(c is not None)
+             and instance_state(c) or None
+             for c in self.deleted],
+        )
+
+    @classmethod
+    def from_scalar_attribute(cls, attribute, state, current):
+        original = state.committed_state.get(attribute.key, _NO_HISTORY)
+
+        if original is _NO_HISTORY:
+            if current is NEVER_SET:
+                return cls((), (), ())
+            else:
+                return cls((), [current], ())
+        # don't let ClauseElement expressions here trip things up
+        elif attribute.is_equal(current, original) is True:
+            return cls((), [current], ())
+        else:
+            # current convention on native scalars is to not
+            # include information
+            # about missing previous value in "deleted", but
+            # we do include None, which helps in some primary
+            # key situations
+            if id(original) in _NO_STATE_SYMBOLS:
+                deleted = ()
+            else:
+                deleted = [original]
+            if current is NEVER_SET:
+                return cls((), (), deleted)
+            else:
+                return cls([current], (), deleted)
+
+    @classmethod
+    def from_object_attribute(cls, attribute, state, current):
+        original = state.committed_state.get(attribute.key, _NO_HISTORY)
+
+        if original is _NO_HISTORY:
+            if current is NO_VALUE or current is NEVER_SET:
+                return cls((), (), ())
+            else:
+                return cls((), [current], ())
+        elif current is original:
+            return cls((), [current], ())
+        else:
+            # current convention on related objects is to not
+            # include information
+            # about missing previous value in "deleted", and
+            # to also not include None - the dependency.py rules
+            # ignore the None in any case.
+            if id(original) in _NO_STATE_SYMBOLS or original is None:
+                deleted = ()
+            else:
+                deleted = [original]
+            if current is NO_VALUE or current is NEVER_SET:
+                return cls((), (), deleted)
+            else:
+                return cls([current], (), deleted)
+
+    @classmethod
+    def from_collection(cls, attribute, state, current):
+        original = state.committed_state.get(attribute.key, _NO_HISTORY)
+
+        if current is NO_VALUE or current is NEVER_SET:
+            return cls((), (), ())
+
+        current = getattr(current, '_sa_adapter')
+        if original in (NO_VALUE, NEVER_SET):
+            return cls(list(current), (), ())
+        elif original is _NO_HISTORY:
+            return cls((), list(current), ())
+        else:
+
+            current_states = [((c is not None) and instance_state(c)
+                               or None, c)
+                              for c in current
+                              ]
+            original_states = [((c is not None) and instance_state(c)
+                                or None, c)
+                               for c in original
+                               ]
+
+            current_set = dict(current_states)
+            original_set = dict(original_states)
+
+            return cls(
+                [o for s, o in current_states if s not in original_set],
+                [o for s, o in current_states if s in original_set],
+                [o for s, o in original_states if s not in current_set]
+            )
+
+HISTORY_BLANK = History(None, None, None)
+
+
+def get_history(obj, key, passive=PASSIVE_OFF):
+    """Return a :class:`.History` record for the given object
+    and attribute key.
+
+    :param obj: an object whose class is instrumented by the
+      attributes package.
+
+    :param key: string attribute name.
+
+    :param passive: indicates loading behavior for the attribute
+       if the value is not already present.   This is a
+       bitflag attribute, which defaults to the symbol
+       :attr:`.PASSIVE_OFF` indicating all necessary SQL
+       should be emitted.
+
+    """
+    if passive is True:
+        util.warn_deprecated("Passing True for 'passive' is deprecated. "
+                             "Use attributes.PASSIVE_NO_INITIALIZE")
+        passive = PASSIVE_NO_INITIALIZE
+    elif passive is False:
+        util.warn_deprecated("Passing False for 'passive' is "
+                             "deprecated.  Use attributes.PASSIVE_OFF")
+        passive = PASSIVE_OFF
+
+    return get_state_history(instance_state(obj), key, passive)
+
+
+def get_state_history(state, key, passive=PASSIVE_OFF):
+    return state.get_history(key, passive)
+
+
+def has_parent(cls, obj, key, optimistic=False):
+    """TODO"""
+    manager = manager_of_class(cls)
+    state = instance_state(obj)
+    return manager.has_parent(state, key, optimistic)
+
+
+def register_attribute(class_, key, **kw):
+    comparator = kw.pop('comparator', None)
+    parententity = kw.pop('parententity', None)
+    doc = kw.pop('doc', None)
+    desc = register_descriptor(class_, key,
+                               comparator, parententity, doc=doc)
+    register_attribute_impl(class_, key, **kw)
+    return desc
+
+
+def register_attribute_impl(class_, key,
+                            uselist=False, callable_=None,
+                            useobject=False,
+                            impl_class=None, backref=None, **kw):
+
+    manager = manager_of_class(class_)
+    if uselist:
+        factory = kw.pop('typecallable', None)
+        typecallable = manager.instrument_collection_class(
+            key, factory or list)
+    else:
+        typecallable = kw.pop('typecallable', None)
+
+    dispatch = manager[key].dispatch
+
+    if impl_class:
+        impl = impl_class(class_, key, typecallable, dispatch, **kw)
+    elif uselist:
+        impl = CollectionAttributeImpl(class_, key, callable_, dispatch,
+                                       typecallable=typecallable, **kw)
+    elif useobject:
+        impl = ScalarObjectAttributeImpl(class_, key, callable_,
+                                         dispatch, **kw)
+    else:
+        impl = ScalarAttributeImpl(class_, key, callable_, dispatch, **kw)
+
+    manager[key].impl = impl
+
+    if backref:
+        backref_listeners(manager[key], backref, uselist)
+
+    manager.post_configure_attribute(key)
+    return manager[key]
+
+
+def register_descriptor(class_, key, comparator=None,
+                        parententity=None, doc=None):
+    manager = manager_of_class(class_)
+
+    descriptor = InstrumentedAttribute(class_, key, comparator=comparator,
+                                       parententity=parententity)
+
+    descriptor.__doc__ = doc
+
+    manager.instrument_attribute(key, descriptor)
+    return descriptor
+
+
+def unregister_attribute(class_, key):
+    manager_of_class(class_).uninstrument_attribute(key)
+
+
+def init_collection(obj, key):
+    """Initialize a collection attribute and return the collection adapter.
+
+    This function is used to provide direct access to collection internals
+    for a previously unloaded attribute.  e.g.::
+
+        collection_adapter = init_collection(someobject, 'elements')
+        for elem in values:
+            collection_adapter.append_without_event(elem)
+
+    For an easier way to do the above, see
+    :func:`~sqlalchemy.orm.attributes.set_committed_value`.
+
+    obj is an instrumented object instance.  An InstanceState
+    is accepted directly for backwards compatibility but
+    this usage is deprecated.
+
+    """
+    state = instance_state(obj)
+    dict_ = state.dict
+    return init_state_collection(state, dict_, key)
+
+
+def init_state_collection(state, dict_, key):
+    """Initialize a collection attribute and return the collection adapter."""
+
+    attr = state.manager[key].impl
+    user_data = attr.initialize(state, dict_)
+    return attr.get_collection(state, dict_, user_data)
+
+
+def set_committed_value(instance, key, value):
+    """Set the value of an attribute with no history events.
+
+    Cancels any previous history present.  The value should be
+    a scalar value for scalar-holding attributes, or
+    an iterable for any collection-holding attribute.
+
+    This is the same underlying method used when a lazy loader
+    fires off and loads additional data from the database.
+    In particular, this method can be used by application code
+    which has loaded additional attributes or collections through
+    separate queries, which can then be attached to an instance
+    as though it were part of its original loaded state.
+
+    """
+    state, dict_ = instance_state(instance), instance_dict(instance)
+    state.manager[key].impl.set_committed_value(state, dict_, value)
+
+
+def set_attribute(instance, key, value, initiator=None):
+    """Set the value of an attribute, firing history events.
+
+    This function may be used regardless of instrumentation
+    applied directly to the class, i.e. no descriptors are required.
+    Custom attribute management schemes will need to make usage
+    of this method to establish attribute state as understood
+    by SQLAlchemy.
+
+    :param instance: the object that will be modified
+
+    :param key: string name of the attribute
+
+    :param value: value to assign
+
+    :param initiator: an instance of :class:`.Event` that would have
+     been propagated from a previous event listener.  This argument
+     is used when the :func:`.set_attribute` function is being used within
+     an existing event listening function where an :class:`.Event` object
+     is being supplied; the object may be used to track the origin of the
+     chain of events.
+
+     .. versionadded:: 1.2.3
+
+    """
+    state, dict_ = instance_state(instance), instance_dict(instance)
+    state.manager[key].impl.set(state, dict_, value, initiator)
+
+
+def get_attribute(instance, key):
+    """Get the value of an attribute, firing any callables required.
+
+    This function may be used regardless of instrumentation
+    applied directly to the class, i.e. no descriptors are required.
+    Custom attribute management schemes will need to make usage
+    of this method to make usage of attribute state as understood
+    by SQLAlchemy.
+
+    """
+    state, dict_ = instance_state(instance), instance_dict(instance)
+    return state.manager[key].impl.get(state, dict_)
+
+
+def del_attribute(instance, key):
+    """Delete the value of an attribute, firing history events.
+
+    This function may be used regardless of instrumentation
+    applied directly to the class, i.e. no descriptors are required.
+    Custom attribute management schemes will need to make usage
+    of this method to establish attribute state as understood
+    by SQLAlchemy.
+
+    """
+    state, dict_ = instance_state(instance), instance_dict(instance)
+    state.manager[key].impl.delete(state, dict_)
+
+
+def flag_modified(instance, key):
+    """Mark an attribute on an instance as 'modified'.
+
+    This sets the 'modified' flag on the instance and
+    establishes an unconditional change event for the given attribute.
+    The attribute must have a value present, else an
+    :class:`.InvalidRequestError` is raised.
+
+    To mark an object "dirty" without referring to any specific attribute
+    so that it is considered within a flush, use the
+    :func:`.attributes.flag_dirty` call.
+
+    .. seealso::
+
+        :func:`.attributes.flag_dirty`
+
+    """
+    state, dict_ = instance_state(instance), instance_dict(instance)
+    impl = state.manager[key].impl
+    impl.dispatch.modified(state, impl._modified_token)
+    state._modified_event(dict_, impl, NO_VALUE, is_userland=True)
+
+
+def flag_dirty(instance):
+    """Mark an instance as 'dirty' without any specific attribute mentioned.
+
+    This is a special operation that will allow the object to travel through
+    the flush process for interception by events such as
+    :meth:`.SessionEvents.before_flush`.   Note that no SQL will be emitted in
+    the flush process for an object that has no changes, even if marked dirty
+    via this method.  However, a :meth:`.SessionEvents.before_flush` handler
+    will be able to see the object in the :attr:`.Session.dirty` collection and
+    may establish changes on it, which will then be included in the SQL
+    emitted.
+
+    .. versionadded:: 1.2
+
+    .. seealso::
+
+        :func:`.attributes.flag_modified`
+
+    """
+
+    state, dict_ = instance_state(instance), instance_dict(instance)
+    state._modified_event(dict_, None, NO_VALUE, is_userland=True)
+
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/_sources/QUANTAXIS_Trade/README.rst.txt b/_build/html/_sources/QUANTAXIS_Trade/README.rst.txt new file mode 100644 index 000000000..fb977fc7d --- /dev/null +++ b/_build/html/_sources/QUANTAXIS_Trade/README.rst.txt @@ -0,0 +1,128 @@ +QUANTAXIS quantitative financial strategy framework +========================== + +QUANTAXIS quantitative framework to achieve the stock and futures market, the whole species back to the test.Through the distributed crawler for data capture, to build a response to the data cleaning and market push engine to build a multi-language open response frame. And build interactive visualization of clients and websites. + +.. image:: https://badge.waffle.io/yutiansut/QUANTAXIS.svg?label=ready&title=Ready + :target: https://waffle.io/yutiansut/QUANTAXIS + :alt: 'Stories in Ready' + + + +0.4.x Release Note +--------------------------------- + +QUANTAXIS Quantitative Financial Strategy Framework is a quantitative analysis solution for small and medium-sized strategy teams.We can quickly implement scene-oriented customization solutions with highly decoupled modularity and standardized protocols. QUANTAXIS is a progressive open Framework, you can according to their own needs, the introduction of their own data, analysis programs, visualization process, you can also RESTful interface, the rapid realization of multi-LAN / WAN collaboration. + +QUANTAXIS and many excellent domestic quantitative platform is the difference, QA more concerned about the user experience and the actual situation, for the user needs will be more optimized, so will pay more attention to openness, the introduction of custom convenience, and the team Collaborative details are handled, such as custom data introductions, custom policy chart comparison, custom risk and policy portfolio management, and so on. + +* Welcome group discussion: [group link] (https://jq.qq.com/?_wv=1027&k=4CEKGzn) + +* For more information, see https://github.com/yutiansut/QUANTAXIS/blob/0.4-beta/update_log.md + +* If you have any questions, you can send [issue] (https://github.com/yutiansut/QUANTAXIS/issues) on github, or contact us at QQ 279336410, QQ group 563280067 +============= + +More info on https://github.com/yutiansut/quantaxis + + +An EXAMPLE of QUANTAXIS BACKTEST like that below: + +.. code:: python + + + import QUANTAXIS as QA + from QUANTAXIS import QA_Backtest_stock_day as QB + + + """ + Written Before: + ===============QUANTAXIS BACKTEST STOCK_DAY's Constant + Constant: + QB.account.message + QB.account.cash + QB.account.hold + QB.account.history + QB.account.assets + QB.account.detail + QB.account.init_assest + + + + QB.strategy_stock_list + QB.strategy_start_date + QB.strategy_end_date + + + QB.today + + QB.benchmark_code + + + + + Function: + get the market data (based on gap): + QB.QA_backtest_get_market_data(QB,code,QB.today) + get the market data as you want: + QA.QA_fetch_stock_day(code,start,end,model) + + + Order : + QB.QA_backtest_send_order(QB, code,amount,towards,order: dict) + + order has three model: + 1.Limited order order['order_model']=0 or l,L + attention: this model should have a order['price'] key + order['price']=xxxx + + 2.Market order order['order_model']=1 or m,M,market,Market + 3.Strict model order['order_model']=2 or s,S + which is buy in the highest price or sell in the lowest price + + Query the hold amount + + QB.QA_backtest_hold_amount(QB,code) + + + """ + + + @QB.backtest_init + def init(): + # + QB.setting.QA_util_sql_mongo_ip='127.0.0.1' + + QB.account.init_assest=2500000 + QB.benchmark_code='hs300' + + QB.strategy_stock_list=['000001','000002','600010','601801','603111'] + QB.strategy_start_date='2017-03-01' + QB.strategy_end_date='2017-07-01' + + @QB.before_backtest + def before_backtest(): + global risk_position + QA.QA_util_log_info(QB.account.message) + + + + @QB.load_strategy + def strategy(): + #print(QB.account.message) + #print(QB.account.cash) + #input() + + for item in QB.strategy_stock_list: + QA.QA_util_log_info(QB.QA_backtest_get_market_data(QB,item,QB.today)) + if QB.QA_backtest_hold_amount(QB,item)==0: + QB.QA_backtest_send_order(QB,item,10000,1,{'order_model':'Market'}) + + + else: + #print(QB.QA_backtest_hold_amount(QB,item)) + QB.QA_backtest_send_order(QB,item,10000,-1,{'order_model':'Market'}) + + @QB.end_backtest + def after_backtest(): + pass \ No newline at end of file diff --git a/_build/html/_sources/README.rst.txt b/_build/html/_sources/README.rst.txt new file mode 100644 index 000000000..fb977fc7d --- /dev/null +++ b/_build/html/_sources/README.rst.txt @@ -0,0 +1,128 @@ +QUANTAXIS quantitative financial strategy framework +========================== + +QUANTAXIS quantitative framework to achieve the stock and futures market, the whole species back to the test.Through the distributed crawler for data capture, to build a response to the data cleaning and market push engine to build a multi-language open response frame. And build interactive visualization of clients and websites. + +.. image:: https://badge.waffle.io/yutiansut/QUANTAXIS.svg?label=ready&title=Ready + :target: https://waffle.io/yutiansut/QUANTAXIS + :alt: 'Stories in Ready' + + + +0.4.x Release Note +--------------------------------- + +QUANTAXIS Quantitative Financial Strategy Framework is a quantitative analysis solution for small and medium-sized strategy teams.We can quickly implement scene-oriented customization solutions with highly decoupled modularity and standardized protocols. QUANTAXIS is a progressive open Framework, you can according to their own needs, the introduction of their own data, analysis programs, visualization process, you can also RESTful interface, the rapid realization of multi-LAN / WAN collaboration. + +QUANTAXIS and many excellent domestic quantitative platform is the difference, QA more concerned about the user experience and the actual situation, for the user needs will be more optimized, so will pay more attention to openness, the introduction of custom convenience, and the team Collaborative details are handled, such as custom data introductions, custom policy chart comparison, custom risk and policy portfolio management, and so on. + +* Welcome group discussion: [group link] (https://jq.qq.com/?_wv=1027&k=4CEKGzn) + +* For more information, see https://github.com/yutiansut/QUANTAXIS/blob/0.4-beta/update_log.md + +* If you have any questions, you can send [issue] (https://github.com/yutiansut/QUANTAXIS/issues) on github, or contact us at QQ 279336410, QQ group 563280067 +============= + +More info on https://github.com/yutiansut/quantaxis + + +An EXAMPLE of QUANTAXIS BACKTEST like that below: + +.. code:: python + + + import QUANTAXIS as QA + from QUANTAXIS import QA_Backtest_stock_day as QB + + + """ + Written Before: + ===============QUANTAXIS BACKTEST STOCK_DAY's Constant + Constant: + QB.account.message + QB.account.cash + QB.account.hold + QB.account.history + QB.account.assets + QB.account.detail + QB.account.init_assest + + + + QB.strategy_stock_list + QB.strategy_start_date + QB.strategy_end_date + + + QB.today + + QB.benchmark_code + + + + + Function: + get the market data (based on gap): + QB.QA_backtest_get_market_data(QB,code,QB.today) + get the market data as you want: + QA.QA_fetch_stock_day(code,start,end,model) + + + Order : + QB.QA_backtest_send_order(QB, code,amount,towards,order: dict) + + order has three model: + 1.Limited order order['order_model']=0 or l,L + attention: this model should have a order['price'] key + order['price']=xxxx + + 2.Market order order['order_model']=1 or m,M,market,Market + 3.Strict model order['order_model']=2 or s,S + which is buy in the highest price or sell in the lowest price + + Query the hold amount + + QB.QA_backtest_hold_amount(QB,code) + + + """ + + + @QB.backtest_init + def init(): + # + QB.setting.QA_util_sql_mongo_ip='127.0.0.1' + + QB.account.init_assest=2500000 + QB.benchmark_code='hs300' + + QB.strategy_stock_list=['000001','000002','600010','601801','603111'] + QB.strategy_start_date='2017-03-01' + QB.strategy_end_date='2017-07-01' + + @QB.before_backtest + def before_backtest(): + global risk_position + QA.QA_util_log_info(QB.account.message) + + + + @QB.load_strategy + def strategy(): + #print(QB.account.message) + #print(QB.account.cash) + #input() + + for item in QB.strategy_stock_list: + QA.QA_util_log_info(QB.QA_backtest_get_market_data(QB,item,QB.today)) + if QB.QA_backtest_hold_amount(QB,item)==0: + QB.QA_backtest_send_order(QB,item,10000,1,{'order_model':'Market'}) + + + else: + #print(QB.QA_backtest_hold_amount(QB,item)) + QB.QA_backtest_send_order(QB,item,10000,-1,{'order_model':'Market'}) + + @QB.end_backtest + def after_backtest(): + pass \ No newline at end of file diff --git a/_build/html/_sources/index.rst.txt b/_build/html/_sources/index.rst.txt new file mode 100644 index 000000000..d69aefa6d --- /dev/null +++ b/_build/html/_sources/index.rst.txt @@ -0,0 +1,20 @@ +.. QUANTAXIS documentation master file, created by + sphinx-quickstart on Mon May 7 21:02:19 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to QUANTAXIS's documentation! +===================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/_build/html/_sources/source/QUANTAXIS.QAARP.rst.txt b/_build/html/_sources/source/QUANTAXIS.QAARP.rst.txt new file mode 100644 index 000000000..58da99219 --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QAARP.rst.txt @@ -0,0 +1,54 @@ +QUANTAXIS.QAARP package +======================= + +Submodules +---------- + +QUANTAXIS.QAARP.QAAccount module +-------------------------------- + +.. automodule:: QUANTAXIS.QAARP.QAAccount + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAARP.QAPortfolio module +---------------------------------- + +.. automodule:: QUANTAXIS.QAARP.QAPortfolio + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAARP.QARisk module +----------------------------- + +.. automodule:: QUANTAXIS.QAARP.QARisk + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAARP.QAStrategy module +--------------------------------- + +.. automodule:: QUANTAXIS.QAARP.QAStrategy + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAARP.QAUser module +----------------------------- + +.. automodule:: QUANTAXIS.QAARP.QAUser + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAARP + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QAAnalysis.rst.txt b/_build/html/_sources/source/QUANTAXIS.QAAnalysis.rst.txt new file mode 100644 index 000000000..eede2424f --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QAAnalysis.rst.txt @@ -0,0 +1,62 @@ +QUANTAXIS.QAAnalysis package +============================ + +Submodules +---------- + +QUANTAXIS.QAAnalysis.QAAnalysis\_block module +--------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_block + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAAnalysis.QAAnalysis\_dataframe module +------------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_dataframe + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAAnalysis.QAAnalysis\_machinelearning module +------------------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_machinelearning + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAAnalysis.QAAnalysis\_series module +---------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_series + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAAnalysis.QAAnalysis\_tick module +-------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_tick + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAAnalysis.QAAnalysis\_trade module +--------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_trade + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAAnalysis + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QABacktest.rst.txt b/_build/html/_sources/source/QUANTAXIS.QABacktest.rst.txt new file mode 100644 index 000000000..adcc84e69 --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QABacktest.rst.txt @@ -0,0 +1,46 @@ +QUANTAXIS.QABacktest package +============================ + +Submodules +---------- + +QUANTAXIS.QABacktest.QAAnalysis module +-------------------------------------- + +.. automodule:: QUANTAXIS.QABacktest.QAAnalysis + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QABacktest.QABacktest module +-------------------------------------- + +.. automodule:: QUANTAXIS.QABacktest.QABacktest + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QABacktest.QAResult module +------------------------------------ + +.. automodule:: QUANTAXIS.QABacktest.QAResult + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QABacktest.backtest\_setting module +--------------------------------------------- + +.. automodule:: QUANTAXIS.QABacktest.backtest_setting + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QABacktest + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QACmd.rst.txt b/_build/html/_sources/source/QUANTAXIS.QACmd.rst.txt new file mode 100644 index 000000000..fc5e3a217 --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QACmd.rst.txt @@ -0,0 +1,22 @@ +QUANTAXIS.QACmd package +======================= + +Submodules +---------- + +QUANTAXIS.QACmd.backtest module +------------------------------- + +.. automodule:: QUANTAXIS.QACmd.backtest + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QACmd + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QAData.proto.rst.txt b/_build/html/_sources/source/QUANTAXIS.QAData.proto.rst.txt new file mode 100644 index 000000000..4c0e1151b --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QAData.proto.rst.txt @@ -0,0 +1,38 @@ +QUANTAXIS.QAData.proto package +============================== + +Submodules +---------- + +QUANTAXIS.QAData.proto.order\_pb2 module +---------------------------------------- + +.. automodule:: QUANTAXIS.QAData.proto.order_pb2 + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.proto.stock\_day\_pb2 module +--------------------------------------------- + +.. automodule:: QUANTAXIS.QAData.proto.stock_day_pb2 + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.proto.stock\_min\_pb2 module +--------------------------------------------- + +.. automodule:: QUANTAXIS.QAData.proto.stock_min_pb2 + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAData.proto + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QAData.rst.txt b/_build/html/_sources/source/QUANTAXIS.QAData.rst.txt new file mode 100644 index 000000000..7721ce6ba --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QAData.rst.txt @@ -0,0 +1,93 @@ +QUANTAXIS.QAData package +======================== + +Subpackages +----------- + +.. toctree:: + + QUANTAXIS.QAData.proto + +Submodules +---------- + +QUANTAXIS.QAData.QADataStruct module +------------------------------------ + +.. automodule:: QUANTAXIS.QAData.QADataStruct + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.base\_datastruct module +---------------------------------------- + +.. automodule:: QUANTAXIS.QAData.base_datastruct + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.data\_fq module +-------------------------------- + +.. automodule:: QUANTAXIS.QAData.data_fq + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.data\_resample module +-------------------------------------- + +.. automodule:: QUANTAXIS.QAData.data_resample + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.dsmethods module +--------------------------------- + +.. automodule:: QUANTAXIS.QAData.dsmethods + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.fundamental module +----------------------------------- + +.. automodule:: QUANTAXIS.QAData.fundamental + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.realtimedata module +------------------------------------ + +.. automodule:: QUANTAXIS.QAData.realtimedata + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.schema module +------------------------------ + +.. automodule:: QUANTAXIS.QAData.schema + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.serialize module +--------------------------------- + +.. automodule:: QUANTAXIS.QAData.serialize + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAData + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QAEngine.rst.txt b/_build/html/_sources/source/QUANTAXIS.QAEngine.rst.txt new file mode 100644 index 000000000..7f85c330b --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QAEngine.rst.txt @@ -0,0 +1,38 @@ +QUANTAXIS.QAEngine package +========================== + +Submodules +---------- + +QUANTAXIS.QAEngine.QAEvent module +--------------------------------- + +.. automodule:: QUANTAXIS.QAEngine.QAEvent + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAEngine.QATask module +-------------------------------- + +.. automodule:: QUANTAXIS.QAEngine.QATask + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAEngine.QAThreadEngine module +---------------------------------------- + +.. automodule:: QUANTAXIS.QAEngine.QAThreadEngine + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAEngine + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QAFetch.rst.txt b/_build/html/_sources/source/QUANTAXIS.QAFetch.rst.txt new file mode 100644 index 000000000..7c41e5293 --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QAFetch.rst.txt @@ -0,0 +1,126 @@ +QUANTAXIS.QAFetch package +========================= + +Submodules +---------- + +QUANTAXIS.QAFetch.Fetcher module +-------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.Fetcher + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QACrawler module +---------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QACrawler + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAEastMoney module +------------------------------------ + +.. automodule:: QUANTAXIS.QAFetch.QAEastMoney + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAQuery module +-------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QAQuery + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAQuery\_Advance module +----------------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QAQuery_Advance + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QATdx module +------------------------------ + +.. automodule:: QUANTAXIS.QAFetch.QATdx + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QATdx\_adv module +----------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QATdx_adv + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAThs module +------------------------------ + +.. automodule:: QUANTAXIS.QAFetch.QAThs + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QATushare module +---------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QATushare + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAWind module +------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QAWind + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAfinancial module +------------------------------------ + +.. automodule:: QUANTAXIS.QAFetch.QAfinancial + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.base module +----------------------------- + +.. automodule:: QUANTAXIS.QAFetch.base + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.data\_list module +----------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.data_list + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.realtime module +--------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.realtime + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAFetch + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QAIndicator.rst.txt b/_build/html/_sources/source/QUANTAXIS.QAIndicator.rst.txt new file mode 100644 index 000000000..afb3be113 --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QAIndicator.rst.txt @@ -0,0 +1,30 @@ +QUANTAXIS.QAIndicator package +============================= + +Submodules +---------- + +QUANTAXIS.QAIndicator.base module +--------------------------------- + +.. automodule:: QUANTAXIS.QAIndicator.base + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAIndicator.indicators module +--------------------------------------- + +.. automodule:: QUANTAXIS.QAIndicator.indicators + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAIndicator + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QAMarket.rst.txt b/_build/html/_sources/source/QUANTAXIS.QAMarket.rst.txt new file mode 100644 index 000000000..5878c0e06 --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QAMarket.rst.txt @@ -0,0 +1,126 @@ +QUANTAXIS.QAMarket package +========================== + +Submodules +---------- + +QUANTAXIS.QAMarket.Broker\_Calender module +------------------------------------------ + +.. automodule:: QUANTAXIS.QAMarket.Broker_Calender + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QABacktestBroker module +------------------------------------------ + +.. automodule:: QUANTAXIS.QAMarket.QABacktestBroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QABroker module +---------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QABroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QADealer module +---------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QADealer + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QAMarket module +---------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QAMarket + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QAOrder module +--------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QAOrder + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QAOrderHandler module +---------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QAOrderHandler + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QARandomBroker module +---------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QARandomBroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QARealBroker module +-------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QARealBroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QASimulatedBroker module +------------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QASimulatedBroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QATrade module +--------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QATrade + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.shipaneBroker module +--------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.shipaneBroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.shipaneclient module +--------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.shipaneclient + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.tdxRealBroker module +--------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.tdxRealBroker + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAMarket + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QASU.rst.txt b/_build/html/_sources/source/QUANTAXIS.QASU.rst.txt new file mode 100644 index 000000000..5693f90fc --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QASU.rst.txt @@ -0,0 +1,78 @@ +QUANTAXIS.QASU package +====================== + +Submodules +---------- + +QUANTAXIS.QASU.main module +-------------------------- + +.. automodule:: QUANTAXIS.QASU.main + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_account module +----------------------------------- + +.. automodule:: QUANTAXIS.QASU.save_account + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_backtest module +------------------------------------ + +.. automodule:: QUANTAXIS.QASU.save_backtest + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_local module +--------------------------------- + +.. automodule:: QUANTAXIS.QASU.save_local + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_tdx module +------------------------------- + +.. automodule:: QUANTAXIS.QASU.save_tdx + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_tdx\_file module +------------------------------------- + +.. automodule:: QUANTAXIS.QASU.save_tdx_file + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_tushare module +----------------------------------- + +.. automodule:: QUANTAXIS.QASU.save_tushare + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.user module +-------------------------- + +.. automodule:: QUANTAXIS.QASU.user + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QASU + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QAUtil.rst.txt b/_build/html/_sources/source/QUANTAXIS.QAUtil.rst.txt new file mode 100644 index 000000000..0625c15d6 --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QAUtil.rst.txt @@ -0,0 +1,190 @@ +QUANTAXIS.QAUtil package +======================== + +Submodules +---------- + +QUANTAXIS.QAUtil.QAAuth module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QAAuth + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QABar module +----------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QABar + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QACfg module +----------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QACfg + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QACode module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QACode + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QACsv module +----------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QACsv + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QADate module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QADate + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QADate\_trade module +------------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QADate_trade + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QADict module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QADict + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAList module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QAList + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QALocalize module +---------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QALocalize + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QALogs module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QALogs + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAMail module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QAMail + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAMongo module +------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QAMongo + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAParameter module +----------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QAParameter + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAPlot module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QAPlot + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QARandom module +-------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QARandom + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QASetting module +--------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QASetting + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QASql module +----------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QASql + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAText module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QAText + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QATransform module +----------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QATransform + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAWeb module +----------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QAWeb + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.host module +---------------------------- + +.. automodule:: QUANTAXIS.QAUtil.host + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAUtil + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.QAWeb.rst.txt b/_build/html/_sources/source/QUANTAXIS.QAWeb.rst.txt new file mode 100644 index 000000000..7af3d790f --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.QAWeb.rst.txt @@ -0,0 +1,30 @@ +QUANTAXIS.QAWeb package +======================= + +Submodules +---------- + +QUANTAXIS.QAWeb.QA\_Web module +------------------------------ + +.. automodule:: QUANTAXIS.QAWeb.QA_Web + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAWeb.chain module +---------------------------- + +.. automodule:: QUANTAXIS.QAWeb.chain + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAWeb + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/QUANTAXIS.rst.txt b/_build/html/_sources/source/QUANTAXIS.rst.txt new file mode 100644 index 000000000..e5a40b09e --- /dev/null +++ b/_build/html/_sources/source/QUANTAXIS.rst.txt @@ -0,0 +1,28 @@ +QUANTAXIS package +================= + +Subpackages +----------- + +.. toctree:: + + QUANTAXIS.QAARP + QUANTAXIS.QAAnalysis + QUANTAXIS.QABacktest + QUANTAXIS.QACmd + QUANTAXIS.QAData + QUANTAXIS.QAEngine + QUANTAXIS.QAFetch + QUANTAXIS.QAIndicator + QUANTAXIS.QAMarket + QUANTAXIS.QASU + QUANTAXIS.QAUtil + QUANTAXIS.QAWeb + +Module contents +--------------- + +.. automodule:: QUANTAXIS + :members: + :undoc-members: + :show-inheritance: diff --git a/_build/html/_sources/source/modules.rst.txt b/_build/html/_sources/source/modules.rst.txt new file mode 100644 index 000000000..b09928062 --- /dev/null +++ b/_build/html/_sources/source/modules.rst.txt @@ -0,0 +1,7 @@ +QUANTAXIS +========= + +.. toctree:: + :maxdepth: 4 + + QUANTAXIS diff --git a/_build/html/_static/ajax-loader.gif b/_build/html/_static/ajax-loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..61faf8cab23993bd3e1560bff0668bd628642330 GIT binary patch literal 673 zcmZ?wbhEHb6krfw_{6~Q|Nno%(3)e{?)x>&1u}A`t?OF7Z|1gRivOgXi&7IyQd1Pl zGfOfQ60;I3a`F>X^fL3(@);C=vM_KlFfb_o=k{|A33hf2a5d61U}gjg=>Rd%XaNQW zW@Cw{|b%Y*pl8F?4B9 zlo4Fz*0kZGJabY|>}Okf0}CCg{u4`zEPY^pV?j2@h+|igy0+Kz6p;@SpM4s6)XEMg z#3Y4GX>Hjlml5ftdH$4x0JGdn8~MX(U~_^d!Hi)=HU{V%g+mi8#UGbE-*ao8f#h+S z2a0-5+vc7MU$e-NhmBjLIC1v|)9+Im8x1yacJ7{^tLX(ZhYi^rpmXm0`@ku9b53aN zEXH@Y3JaztblgpxbJt{AtE1ad1Ca>{v$rwwvK(>{m~Gf_=-Ro7Fk{#;i~+{{>QtvI yb2P8Zac~?~=sRA>$6{!(^3;ZP0TPFR(G_-UDU(8Jl0?(IXu$~#4A!880|o%~Al1tN literal 0 HcmV?d00001 diff --git a/_build/html/_static/alabaster.css b/_build/html/_static/alabaster.css new file mode 100644 index 000000000..be65b1374 --- /dev/null +++ b/_build/html/_static/alabaster.css @@ -0,0 +1,693 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif; + font-size: 17px; + background-color: #fff; + color: #000; + margin: 0; + padding: 0; +} + + +div.document { + width: 940px; + margin: 30px auto 0 auto; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 220px; +} + +div.sphinxsidebar { + width: 220px; + font-size: 14px; + line-height: 1.5; +} + +hr { + border: 1px solid #B1B4B6; +} + +div.body { + background-color: #fff; + color: #3E4349; + padding: 0 30px 0 30px; +} + +div.body > .section { + text-align: left; +} + +div.footer { + width: 940px; + margin: 20px auto 30px auto; + font-size: 14px; + color: #888; + text-align: right; +} + +div.footer a { + color: #888; +} + +p.caption { + font-family: inherit; + font-size: inherit; +} + + +div.relations { + display: none; +} + + +div.sphinxsidebar a { + color: #444; + text-decoration: none; + border-bottom: 1px dotted #999; +} + +div.sphinxsidebar a:hover { + border-bottom: 1px solid #999; +} + +div.sphinxsidebarwrapper { + padding: 18px 10px; +} + +div.sphinxsidebarwrapper p.logo { + padding: 0; + margin: -10px 0 0 0px; + text-align: center; +} + +div.sphinxsidebarwrapper h1.logo { + margin-top: -10px; + text-align: center; + margin-bottom: 5px; + text-align: left; +} + +div.sphinxsidebarwrapper h1.logo-name { + margin-top: 0px; +} + +div.sphinxsidebarwrapper p.blurb { + margin-top: 0; + font-style: normal; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: 'Garamond', 'Georgia', serif; + color: #444; + font-size: 24px; + font-weight: normal; + margin: 0 0 5px 0; + padding: 0; +} + +div.sphinxsidebar h4 { + font-size: 20px; +} + +div.sphinxsidebar h3 a { + color: #444; +} + +div.sphinxsidebar p.logo a, +div.sphinxsidebar h3 a, +div.sphinxsidebar p.logo a:hover, +div.sphinxsidebar h3 a:hover { + border: none; +} + +div.sphinxsidebar p { + color: #555; + margin: 10px 0; +} + +div.sphinxsidebar ul { + margin: 10px 0; + padding: 0; + color: #000; +} + +div.sphinxsidebar ul li.toctree-l1 > a { + font-size: 120%; +} + +div.sphinxsidebar ul li.toctree-l2 > a { + font-size: 110%; +} + +div.sphinxsidebar input { + border: 1px solid #CCC; + font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif; + font-size: 1em; +} + +div.sphinxsidebar hr { + border: none; + height: 1px; + color: #AAA; + background: #AAA; + + text-align: left; + margin-left: 0; + width: 50%; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #004B6B; + text-decoration: underline; +} + +a:hover { + color: #6D4100; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Garamond', 'Georgia', serif; + font-weight: normal; + margin: 30px 0px 10px 0px; + padding: 0; +} + +div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } +div.body h2 { font-size: 180%; } +div.body h3 { font-size: 150%; } +div.body h4 { font-size: 130%; } +div.body h5 { font-size: 100%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #DDD; + padding: 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + color: #444; + background: #EAEAEA; +} + +div.body p, div.body dd, div.body li { + line-height: 1.4em; +} + +div.admonition { + margin: 20px 0px; + padding: 10px 30px; + background-color: #EEE; + border: 1px solid #CCC; +} + +div.admonition tt.xref, div.admonition code.xref, div.admonition a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fafafa; +} + +div.admonition p.admonition-title { + font-family: 'Garamond', 'Georgia', serif; + font-weight: normal; + font-size: 24px; + margin: 0 0 10px 0; + padding: 0; + line-height: 1; +} + +div.admonition p.last { + margin-bottom: 0; +} + +div.highlight { + background-color: #fff; +} + +dt:target, .highlight { + background: #FAF3E8; +} + +div.warning { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.danger { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.error { + background-color: #FCC; + border: 1px solid #FAA; + -moz-box-shadow: 2px 2px 4px #D52C2C; + -webkit-box-shadow: 2px 2px 4px #D52C2C; + box-shadow: 2px 2px 4px #D52C2C; +} + +div.caution { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.attention { + background-color: #FCC; + border: 1px solid #FAA; +} + +div.important { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.note { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.tip { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.hint { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.seealso { + background-color: #EEE; + border: 1px solid #CCC; +} + +div.topic { + background-color: #EEE; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre, tt, code { + font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; + font-size: 0.9em; +} + +.hll { + background-color: #FFC; + margin: 0 -12px; + padding: 0 12px; + display: block; +} + +img.screenshot { +} + +tt.descname, tt.descclassname, code.descname, code.descclassname { + font-size: 0.95em; +} + +tt.descname, code.descname { + padding-right: 0.08em; +} + +img.screenshot { + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils { + border: 1px solid #888; + -moz-box-shadow: 2px 2px 4px #EEE; + -webkit-box-shadow: 2px 2px 4px #EEE; + box-shadow: 2px 2px 4px #EEE; +} + +table.docutils td, table.docutils th { + border: 1px solid #888; + padding: 0.25em 0.7em; +} + +table.field-list, table.footnote { + border: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +table.footnote { + margin: 15px 0; + width: 100%; + border: 1px solid #EEE; + background: #FDFDFD; + font-size: 0.9em; +} + +table.footnote + table.footnote { + margin-top: -15px; + border-top: none; +} + +table.field-list th { + padding: 0 0.8em 0 0; +} + +table.field-list td { + padding: 0; +} + +table.field-list p { + margin-bottom: 0.8em; +} + +/* Cloned from + * https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68 + */ +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +table.footnote td.label { + width: .1px; + padding: 0.3em 0 0.3em 0.5em; +} + +table.footnote td { + padding: 0.3em 0.5em; +} + +dl { + margin: 0; + padding: 0; +} + +dl dd { + margin-left: 30px; +} + +blockquote { + margin: 0 0 0 30px; + padding: 0; +} + +ul, ol { + /* Matches the 30px from the narrow-screen "li > ul" selector below */ + margin: 10px 0 10px 30px; + padding: 0; +} + +pre { + background: #EEE; + padding: 7px 30px; + margin: 15px 0px; + line-height: 1.3em; +} + +div.viewcode-block:target { + background: #ffd; +} + +dl pre, blockquote pre, li pre { + margin-left: 0; + padding-left: 30px; +} + +tt, code { + background-color: #ecf0f3; + color: #222; + /* padding: 1px 2px; */ +} + +tt.xref, code.xref, a tt { + background-color: #FBFBFB; + border-bottom: 1px solid #fff; +} + +a.reference { + text-decoration: none; + border-bottom: 1px dotted #004B6B; +} + +/* Don't put an underline on images */ +a.image-reference, a.image-reference:hover { + border-bottom: none; +} + +a.reference:hover { + border-bottom: 1px solid #6D4100; +} + +a.footnote-reference { + text-decoration: none; + font-size: 0.7em; + vertical-align: top; + border-bottom: 1px dotted #004B6B; +} + +a.footnote-reference:hover { + border-bottom: 1px solid #6D4100; +} + +a:hover tt, a:hover code { + background: #EEE; +} + + +@media screen and (max-width: 870px) { + + div.sphinxsidebar { + display: none; + } + + div.document { + width: 100%; + + } + + div.documentwrapper { + margin-left: 0; + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + } + + div.bodywrapper { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; + } + + ul { + margin-left: 0; + } + + li > ul { + /* Matches the 30px from the "ul, ol" selector above */ + margin-left: 30px; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .bodywrapper { + margin: 0; + } + + .footer { + width: auto; + } + + .github { + display: none; + } + + + +} + + + +@media screen and (max-width: 875px) { + + body { + margin: 0; + padding: 20px 30px; + } + + div.documentwrapper { + float: none; + background: #fff; + } + + div.sphinxsidebar { + display: block; + float: none; + width: 102.5%; + margin: 50px -30px -20px -30px; + padding: 10px 20px; + background: #333; + color: #FFF; + } + + div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, + div.sphinxsidebar h3 a { + color: #fff; + } + + div.sphinxsidebar a { + color: #AAA; + } + + div.sphinxsidebar p.logo { + display: none; + } + + div.document { + width: 100%; + margin: 0; + } + + div.footer { + display: none; + } + + div.bodywrapper { + margin: 0; + } + + div.body { + min-height: 0; + padding: 0; + } + + .rtd_doc_footer { + display: none; + } + + .document { + width: auto; + } + + .footer { + width: auto; + } + + .footer { + width: auto; + } + + .github { + display: none; + } +} + + +/* misc. */ + +.revsys-inline { + display: none!important; +} + +/* Make nested-list/multi-paragraph items look better in Releases changelog + * pages. Without this, docutils' magical list fuckery causes inconsistent + * formatting between different release sub-lists. + */ +div#changelog > div.section > ul > li > p:only-child { + margin-bottom: 0; +} + +/* Hide fugly table cell borders in ..bibliography:: directive output */ +table.docutils.citation, table.docutils.citation td, table.docutils.citation th { + border: none; + /* Below needed in some edge cases; if not applied, bottom shadows appear */ + -moz-box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; +} \ No newline at end of file diff --git a/_build/html/_static/basic.css b/_build/html/_static/basic.css new file mode 100644 index 000000000..19ced1057 --- /dev/null +++ b/_build/html/_static/basic.css @@ -0,0 +1,665 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li div.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px 7px 0 7px; + background-color: #ffe; + width: 40%; + float: right; +} + +p.sidebar-title { + font-weight: bold; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px 7px 0 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +dl { + margin-bottom: 15px; +} + +dd p { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; +} + +td.linenos pre { + padding: 5px 0px; + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + margin-left: 0.5em; +} + +table.highlighttable td { + padding: 0 0.5em 0 0.5em; +} + +div.code-block-caption { + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +div.code-block-caption + div > div.highlight > pre { + margin-top: 0; +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + padding: 1em 1em 0; +} + +div.literal-block-wrapper div.highlight { + margin: 0; +} + +code.descname { + background-color: transparent; + font-weight: bold; + font-size: 1.2em; +} + +code.descclassname { + background-color: transparent; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: relative; + left: 0px; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_build/html/_static/comment-bright.png b/_build/html/_static/comment-bright.png new file mode 100644 index 0000000000000000000000000000000000000000..15e27edb12ac25701ac0ac21b97b52bb4e45415e GIT binary patch literal 756 zcmVgfIX78 z$8Pzv({A~p%??+>KickCb#0FM1rYN=mBmQ&Nwp<#JXUhU;{|)}%&s>suq6lXw*~s{ zvHx}3C%<;wE5CH!BR{p5@ml9ws}y)=QN-kL2?#`S5d*6j zk`h<}j1>tD$b?4D^N9w}-k)bxXxFg>+#kme^xx#qg6FI-%iv2U{0h(Y)cs%5a|m%Pn_K3X_bDJ>EH#(Fb73Z zfUt2Q3B>N+ot3qb*DqbTZpFIn4a!#_R-}{?-~Hs=xSS6p&$sZ-k1zDdtqU`Y@`#qL z&zv-~)Q#JCU(dI)Hf;$CEnK=6CK50}q7~wdbI->?E07bJ0R;!GSQTs5Am`#;*WHjvHRvY?&$Lm-vq1a_BzocI^ULXV!lbMd%|^B#fY;XX)n<&R^L z=84u1e_3ziq;Hz-*k5~zwY3*oDKt0;bM@M@@89;@m*4RFgvvM_4;5LB!@OB@^WbVT zjl{t;a8_>od-~P4 m{5|DvB&z#xT;*OnJqG}gk~_7HcNkCr0000W zanA~u9RIXo;n7c96&U)YLgs-FGlx~*_c{Jgvesu1E5(8YEf&5wF=YFPcRe@1=MJmi zag(L*xc2r0(slpcN!vC5CUju;vHJkHc*&70_n2OZsK%O~A=!+YIw z7zLLl7~Z+~RgWOQ=MI6$#0pvpu$Q43 zP@36QAmu6!_9NPM?o<1_!+stoVRRZbW9#SPe!n;#A_6m8f}|xN1;H{`0RoXQ2LM47 zt(g;iZ6|pCb@h2xk&(}S3=EVBUO0e90m2Lp5CB<(SPIaB;n4))3JB87Or#XPOPcum z?<^(g+m9}VNn4Y&B`g8h{t_$+RB1%HKRY6fjtd-<7&EsU;vs0GM(Lmbhi%Gwcfs0FTF}T zL{_M6Go&E0Eg8FuB*(Yn+Z*RVTBE@10eIOb3El^MhO`GabDll(V0&FlJi2k^;q8af zkENdk2}x2)_KVp`5OAwXZM;dG0?M-S)xE1IKDi6BY@5%Or?#aZ9$gcX)dPZ&wA1a< z$rFXHPn|TBf`e?>Are8sKtKrKcjF$i^lp!zkL?C|y^vlHr1HXeVJd;1I~g&Ob-q)& z(fn7s-KI}G{wnKzg_U5G(V%bX6uk zIa+<@>rdmZYd!9Y=C0cuchrbIjuRB_Wq{-RXlic?flu1*_ux}x%(HDH&nT`k^xCeC ziHi1!ChH*sQ6|UqJpTTzX$aw8e(UfcS^f;6yBWd+(1-70zU(rtxtqR%j z-lsH|CKQJXqD{+F7V0OTv8@{~(wp(`oIP^ZykMWgR>&|RsklFMCnOo&Bd{le} zV5F6424Qzl;o2G%oVvmHgRDP9!=rK8fy^!yV8y*4p=??uIRrrr0?>O!(z*g5AvL2!4z0{sq%vhG*Po}`a<6%kTK5TNhtC8}rXNu&h^QH4A&Sk~Autm*s~45(H7+0bi^MraaRVzr05hQ3iK?j` zR#U@^i0WhkIHTg29u~|ypU?sXCQEQgXfObPW;+0YAF;|5XyaMAEM0sQ@4-xCZe=0e z7r$ofiAxn@O5#RodD8rh5D@nKQ;?lcf@tg4o+Wp44aMl~c47azN_(im0N)7OqdPBC zGw;353_o$DqGRDhuhU$Eaj!@m000000NkvXXu0mjfjZ7Z_ literal 0 HcmV?d00001 diff --git a/_build/html/_static/custom.css b/_build/html/_static/custom.css new file mode 100644 index 000000000..2a924f1d6 --- /dev/null +++ b/_build/html/_static/custom.css @@ -0,0 +1 @@ +/* This file intentionally left blank. */ diff --git a/_build/html/_static/doctools.js b/_build/html/_static/doctools.js new file mode 100644 index 000000000..0c15c0099 --- /dev/null +++ b/_build/html/_static/doctools.js @@ -0,0 +1,311 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + */ +jQuery.urldecode = function(x) { + return decodeURIComponent(x).replace(/\+/g, ' '); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var bbox = span.getBBox(); + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + var parentOfText = node.parentNode.parentNode; + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keyup(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box or textarea + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); \ No newline at end of file diff --git a/_build/html/_static/documentation_options.js b/_build/html/_static/documentation_options.js new file mode 100644 index 000000000..3fbeb656f --- /dev/null +++ b/_build/html/_static/documentation_options.js @@ -0,0 +1,9 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: '', + VERSION: '1.0', + LANGUAGE: 'python', + COLLAPSE_INDEX: false, + FILE_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt' +}; \ No newline at end of file diff --git a/_build/html/_static/down-pressed.png b/_build/html/_static/down-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..5756c8cad8854722893dc70b9eb4bb0400343a39 GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`OFdm2Ln;`PZ^+1>KjR?B@S0W7 z%OS_REiHONoJ6{+Ks@6k3590|7k9F+ddB6!zw3#&!aw#S`x}3V3&=A(a#84O-&F7T z^k3tZB;&iR9siw0|F|E|DAL<8r-F4!1H-;1{e*~yAKZN5f0|Ei6yUmR#Is)EM(Po_ zi`qJR6|P<~+)N+kSDgL7AjdIC_!O7Q?eGb+L+qOjm{~LLinM4NHn7U%HcK%uoMYO5 VJ~8zD2B3o(JYD@<);T3K0RV0%P>BEl literal 0 HcmV?d00001 diff --git a/_build/html/_static/down.png b/_build/html/_static/down.png new file mode 100644 index 0000000000000000000000000000000000000000..1b3bdad2ceffae91cee61b32f3295f9bbe646e48 GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6CVIL!hEy=F?b*7pIY7kW{q%Rg zx!yQ<9v8bmJwa`TQk7YSw}WVQ()mRdQ;TC;* literal 0 HcmV?d00001 diff --git a/_build/html/_static/file.png b/_build/html/_static/file.png new file mode 100644 index 0000000000000000000000000000000000000000..a858a410e4faa62ce324d814e4b816fff83a6fb3 GIT binary patch literal 286 zcmV+(0pb3MP)s`hMrGg#P~ix$^RISR_I47Y|r1 z_CyJOe}D1){SET-^Amu_i71Lt6eYfZjRyw@I6OQAIXXHDfiX^GbOlHe=Ae4>0m)d(f|Me07*qoM6N<$f}vM^LjV8( literal 0 HcmV?d00001 diff --git a/_build/html/_static/jquery-3.2.1.js b/_build/html/_static/jquery-3.2.1.js new file mode 100644 index 000000000..d2d8ca479 --- /dev/null +++ b/_build/html/_static/jquery-3.2.1.js @@ -0,0 +1,10253 @@ +/*! + * jQuery JavaScript Library v3.2.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2017-03-20T18:59Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var document = window.document; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + + + + function DOMEval( code, doc ) { + doc = doc || document; + + var script = doc.createElement( "script" ); + + script.text = code; + doc.head.appendChild( script ).parentNode.removeChild( script ); + } +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.2.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android <=4.0 only + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + + if ( copyIsArray ) { + copyIsArray = false; + clone = src && Array.isArray( src ) ? src : []; + + } else { + clone = src && jQuery.isPlainObject( src ) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isFunction: function( obj ) { + return jQuery.type( obj ) === "function"; + }, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + + // As of jQuery 3.0, isNumeric is limited to + // strings and numbers (primitives or objects) + // that can be coerced to finite numbers (gh-2662) + var type = jQuery.type( obj ); + return ( type === "number" || type === "string" ) && + + // parseFloat NaNs numeric-cast false positives ("") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + !isNaN( obj - parseFloat( obj ) ); + }, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + + /* eslint-disable no-unused-vars */ + // See https://github.com/eslint/eslint/issues/6125 + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + DOMEval( code ); + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE <=9 - 11, Edge 12 - 13 + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // Support: Android <=4.0 only + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.3 + * https://sizzlejs.com/ + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2016-08-08 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + disabledAncestor = addCombinator( + function( elem ) { + return elem.disabled === true && ("form" in elem || "label" in elem); + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + + // ID selector + if ( (m = match[1]) ) { + + // Document context + if ( nodeType === 9 ) { + if ( (elem = context.getElementById( m )) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && (elem = newContext.getElementById( m )) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( (m = match[3]) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !compilerCache[ selector + " " ] && + (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + + if ( nodeType !== 1 ) { + newContext = context; + newSelector = selector; + + // qSA looks outside Element context, which is not what we want + // Thanks to Andrew Dupont for this workaround technique + // Support: IE <=8 + // Exclude object elements + } else if ( context.nodeName.toLowerCase() !== "object" ) { + + // Capture the context ID, setting it first if necessary + if ( (nid = context.getAttribute( "id" )) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", (nid = expando) ); + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[i] = "#" + nid + " " + toSelector( groups[i] ); + } + newSelector = groups.join( "," ); + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement("fieldset"); + + try { + return !!fn( el ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + disabledAncestor( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9-11, Edge + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + if ( preferredDoc !== document && + (subWindow = document.defaultView) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( el ) { + el.className = "i"; + return !el.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( el ) { + el.appendChild( document.createComment("") ); + return !el.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + }); + + // ID filter and find + if ( support.getById ) { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( (elem = elems[i++]) ) { + node = elem.getAttributeNode("id"); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( document.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( el ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement("input"); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll(":enabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll(":disabled").length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( el ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === document ? -1 : + b === document ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + !compilerCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return (sel + "").replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + // Use previously-cached element index if available + if ( useCache ) { + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || (node[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + (outerCache[ node.uniqueID ] = {}); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {}); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( (oldCache = uniqueCache[ key ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context === document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + if ( !context && elem.ownerDocument !== document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context || document, xml) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( el ) { + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement("fieldset") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( el ) { + return el.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Simple selector that can be filtered directly, removing non-Elements + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + // Complex selector, compare the two sets, removing non-Elements + qualifier = jQuery.filter( qualifier, elements ); + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1; + } ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( nodeName( elem, "iframe" ) ) { + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( jQuery.isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && jQuery.isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( jQuery.isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + jQuery.isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ jQuery.camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ jQuery.camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( jQuery.camelCase ); + } else { + key = jQuery.camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + jQuery.contains( elem.ownerDocument, elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + +var swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, + scale = 1, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + do { + + // If previous iteration zeroed out, double until we get *something*. + // Use string for doubling so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + initialInUnit = initialInUnit / scale; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // Break the loop if scale is unchanged or perfect, or if we've just had enough. + } while ( + scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations + ); + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i ); + +var rscriptType = ( /^$|\/(?:java|ecma)script/i ); + + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // Support: IE <=9 only + option: [ 1, "" ], + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +// Support: IE <=9 only +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +} )(); +var documentElement = document.documentElement; + + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 only +// See #13393 for more info +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = {}; + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + // Make a writable jQuery.Event from the native event object + var event = jQuery.event.fix( nativeEvent ); + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: jQuery.isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + /* eslint-disable max-len */ + + // See https://github.com/eslint/eslint/issues/3229 + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, + + /* eslint-enable */ + + // Support: IE <=10 - 11, Edge 12 - 13 + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( ">tbody", elem )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.access( src ); + pdataCur = dataPriv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && jQuery.contains( node.ownerDocument, node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html.replace( rxhtmlTag, "<$1>" ); + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rmargin = ( /^margin/ ); + +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + div.style.cssText = + "box-sizing:border-box;" + + "position:relative;display:block;" + + "margin:auto;border:1px;padding:1px;" + + "top:1%;width:50%"; + div.innerHTML = ""; + documentElement.appendChild( container ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = divStyle.marginLeft === "2px"; + boxSizingReliableVal = divStyle.width === "4px"; + + // Support: Android 4.0 - 4.3 only + // Some styles come back with percentage values, even though they shouldn't + div.style.marginRight = "50%"; + pixelMarginRightVal = divStyle.marginRight === "4px"; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + + "padding:0;margin-top:1px;position:absolute"; + container.appendChild( div ); + + jQuery.extend( support, { + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelMarginRight: function() { + computeStyleTests(); + return pixelMarginRightVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + + cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style; + +// Return a css property mapped to a potentially vendor prefixed property +function vendorPropName( name ) { + + // Shortcut for names that are not vendor prefixed + if ( name in emptyStyle ) { + return name; + } + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a property mapped along what jQuery.cssProps suggests or to +// a vendor prefixed property. +function finalPropName( name ) { + var ret = jQuery.cssProps[ name ]; + if ( !ret ) { + ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name; + } + return ret; +} + +function setPositiveNumber( elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i, + val = 0; + + // If we already have the right measurement, avoid augmentation + if ( extra === ( isBorderBox ? "border" : "content" ) ) { + i = 4; + + // Otherwise initialize for horizontal or vertical properties + } else { + i = name === "width" ? 1 : 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // At this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + + // At this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // At this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with computed style + var valueIsBorderBox, + styles = getStyles( elem ), + val = curCSS( elem, name, styles ), + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test( val ) ) { + return val; + } + + // Check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && + ( support.boxSizingReliable() || val === elem.style[ name ] ); + + // Fall back to offsetWidth/Height when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + if ( val === "auto" ) { + val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ]; + } + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + + // Use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + "float": "cssFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + if ( type === "number" ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = jQuery.camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + } ) : + getWidthOrHeight( elem, name, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = extra && getStyles( elem ), + subtract = extra && augmentWidthOrHeight( + elem, + name, + extra, + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + styles + ); + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ name ] = value; + value = jQuery.css( elem, name ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && + ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || + jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = jQuery.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 13 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( jQuery.isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + jQuery.proxy( result.stop, result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( jQuery.isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( typeof value === "string" && value ) { + classes = value.match( rnothtmlwhite ) || []; + + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( jQuery.isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + if ( typeof value === "string" && value ) { + classes = value.match( rnothtmlwhite ) || []; + + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( type === "string" ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = value.match( rnothtmlwhite ) || []; + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, isFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup contextmenu" ).split( " " ), + function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; +} ); + +jQuery.fn.extend( { + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +} ); + + + + +support.focusin = "onfocusin" in window; + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = jQuery.now(); + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = jQuery.isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( jQuery.isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 13 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available, append data to url + if ( s.data ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + + +jQuery._evalUrl = function( url ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + "throws": true + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( jQuery.isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + +
+
+
+
+ + +

Index

+ +
+ A + | B + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | O + | P + | Q + | R + | S + | T + | U + | V + | W + | Y + +
+

A

+ + + +
+ +

B

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + + +
+ +

K

+ + + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

O

+ + + +
+ +

P

+ + + +
+ +

Q

+ + + +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ +

W

+ + + +
+ +

Y

+ + +
+ + + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/index.html b/_build/html/index.html new file mode 100644 index 000000000..e56272e33 --- /dev/null +++ b/_build/html/index.html @@ -0,0 +1,104 @@ + + + + + + + + Welcome to QUANTAXIS's documentation! — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

Welcome to QUANTAXIS's documentation!

+
+
+
+
+

Indices and tables

+ +
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/objects.inv b/_build/html/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..7b1db6829c4ed30bb4167d57b92b6943f01a5270 GIT binary patch literal 8445 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 literal 0 HcmV?d00001 diff --git a/_build/html/py-modindex.html b/_build/html/py-modindex.html new file mode 100644 index 000000000..723005d03 --- /dev/null +++ b/_build/html/py-modindex.html @@ -0,0 +1,616 @@ + + + + + + + + Python Module Index — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + +

Python Module Index

+ +
+ q +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ q
+ QUANTAXIS +
    + QUANTAXIS.QAAnalysis +
    + QUANTAXIS.QAAnalysis.QAAnalysis_block +
    + QUANTAXIS.QAAnalysis.QAAnalysis_dataframe +
    + QUANTAXIS.QAAnalysis.QAAnalysis_machinelearning +
    + QUANTAXIS.QAAnalysis.QAAnalysis_series +
    + QUANTAXIS.QAAnalysis.QAAnalysis_tick +
    + QUANTAXIS.QAAnalysis.QAAnalysis_trade +
    + QUANTAXIS.QAARP +
    + QUANTAXIS.QAARP.QAAccount +
    + QUANTAXIS.QAARP.QAPortfolio +
    + QUANTAXIS.QAARP.QARisk +
    + QUANTAXIS.QAARP.QAStrategy +
    + QUANTAXIS.QAARP.QAUser +
    + QUANTAXIS.QABacktest +
    + QUANTAXIS.QABacktest.backtest_setting +
    + QUANTAXIS.QABacktest.QAAnalysis +
    + QUANTAXIS.QABacktest.QABacktest +
    + QUANTAXIS.QABacktest.QAResult +
    + QUANTAXIS.QACmd +
    + QUANTAXIS.QACmd.backtest +
    + QUANTAXIS.QAData +
    + QUANTAXIS.QAData.base_datastruct +
    + QUANTAXIS.QAData.data_fq +
    + QUANTAXIS.QAData.data_resample +
    + QUANTAXIS.QAData.dsmethods +
    + QUANTAXIS.QAData.proto +
    + QUANTAXIS.QAData.proto.order_pb2 +
    + QUANTAXIS.QAData.proto.stock_day_pb2 +
    + QUANTAXIS.QAData.proto.stock_min_pb2 +
    + QUANTAXIS.QAData.QADataStruct +
    + QUANTAXIS.QAData.realtimedata +
    + QUANTAXIS.QAData.schema +
    + QUANTAXIS.QAData.serialize +
    + QUANTAXIS.QAEngine +
    + QUANTAXIS.QAEngine.QAEvent +
    + QUANTAXIS.QAEngine.QATask +
    + QUANTAXIS.QAEngine.QAThreadEngine +
    + QUANTAXIS.QAFetch +
    + QUANTAXIS.QAFetch.base +
    + QUANTAXIS.QAFetch.data_list +
    + QUANTAXIS.QAFetch.Fetcher +
    + QUANTAXIS.QAFetch.QACrawler +
    + QUANTAXIS.QAFetch.QAEastMoney +
    + QUANTAXIS.QAFetch.QAfinancial +
    + QUANTAXIS.QAFetch.QAQuery +
    + QUANTAXIS.QAFetch.QAQuery_Advance +
    + QUANTAXIS.QAFetch.QATdx +
    + QUANTAXIS.QAFetch.QATdx_adv +
    + QUANTAXIS.QAFetch.QAThs +
    + QUANTAXIS.QAFetch.QATushare +
    + QUANTAXIS.QAFetch.QAWind +
    + QUANTAXIS.QAFetch.realtime +
    + QUANTAXIS.QAIndicator +
    + QUANTAXIS.QAIndicator.base +
    + QUANTAXIS.QAIndicator.indicators +
    + QUANTAXIS.QAMarket +
    + QUANTAXIS.QAMarket.QABacktestBroker +
    + QUANTAXIS.QAMarket.QABroker +
    + QUANTAXIS.QAMarket.QADealer +
    + QUANTAXIS.QAMarket.QAMarket +
    + QUANTAXIS.QAMarket.QAOrder +
    + QUANTAXIS.QAMarket.QAOrderHandler +
    + QUANTAXIS.QAMarket.QARandomBroker +
    + QUANTAXIS.QAMarket.QARealBroker +
    + QUANTAXIS.QAMarket.QASimulatedBroker +
    + QUANTAXIS.QAMarket.QATrade +
    + QUANTAXIS.QAMarket.shipaneBroker +
    + QUANTAXIS.QAMarket.shipaneclient +
    + QUANTAXIS.QAMarket.tdxRealBroker +
    + QUANTAXIS.QASU +
    + QUANTAXIS.QASU.main +
    + QUANTAXIS.QASU.save_account +
    + QUANTAXIS.QASU.save_backtest +
    + QUANTAXIS.QASU.save_local +
    + QUANTAXIS.QASU.save_tdx +
    + QUANTAXIS.QASU.save_tdx_file +
    + QUANTAXIS.QASU.save_tushare +
    + QUANTAXIS.QASU.user +
    + QUANTAXIS.QAUtil +
    + QUANTAXIS.QAUtil.host +
    + QUANTAXIS.QAUtil.QAAuth +
    + QUANTAXIS.QAUtil.QABar +
    + QUANTAXIS.QAUtil.QACfg +
    + QUANTAXIS.QAUtil.QACode +
    + QUANTAXIS.QAUtil.QACsv +
    + QUANTAXIS.QAUtil.QADate +
    + QUANTAXIS.QAUtil.QADate_trade +
    + QUANTAXIS.QAUtil.QADict +
    + QUANTAXIS.QAUtil.QAList +
    + QUANTAXIS.QAUtil.QALocalize +
    + QUANTAXIS.QAUtil.QALogs +
    + QUANTAXIS.QAUtil.QAMail +
    + QUANTAXIS.QAUtil.QAMongo +
    + QUANTAXIS.QAUtil.QAParameter +
    + QUANTAXIS.QAUtil.QAPlot +
    + QUANTAXIS.QAUtil.QARandom +
    + QUANTAXIS.QAUtil.QASetting +
    + QUANTAXIS.QAUtil.QASql +
    + QUANTAXIS.QAUtil.QAText +
    + QUANTAXIS.QAUtil.QATransform +
    + QUANTAXIS.QAUtil.QAWeb +
    + QUANTAXIS.QAWeb +
    + QUANTAXIS.QAWeb.chain +
    + QUANTAXIS.QAWeb.QA_Web +
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/search.html b/_build/html/search.html new file mode 100644 index 000000000..dfde4c01e --- /dev/null +++ b/_build/html/search.html @@ -0,0 +1,93 @@ + + + + + + + + Search — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +

Search

+
+ +

+ Please activate JavaScript to enable the search + functionality. +

+
+

+ From here you can search these documents. Enter your search + words into the box below and click "search". Note that the search + function will automatically search for all of the words. Pages + containing fewer words won't appear in the result list. +

+
+ + + +
+ +
+ +
+ +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/searchindex.js b/_build/html/searchindex.js new file mode 100644 index 000000000..cee5e214e --- /dev/null +++ b/_build/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["QUANTAXIS_Trade/README","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/api","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/building-testing","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/css-classes-reference","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/index","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/language-contribution","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/language-guide","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/language-requests","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/line-numbers","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/reference","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/release-process","QUANTAXIS_Webkit/web/node_modules/highlight.js/docs/style-guide","README","index","source/QUANTAXIS","source/QUANTAXIS.QAARP","source/QUANTAXIS.QAAnalysis","source/QUANTAXIS.QABacktest","source/QUANTAXIS.QACmd","source/QUANTAXIS.QAData","source/QUANTAXIS.QAData.proto","source/QUANTAXIS.QAEngine","source/QUANTAXIS.QAFetch","source/QUANTAXIS.QAIndicator","source/QUANTAXIS.QAMarket","source/QUANTAXIS.QASU","source/QUANTAXIS.QAUtil","source/QUANTAXIS.QAWeb","source/modules"],envversion:53,filenames:["QUANTAXIS_Trade\\README.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\api.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\building-testing.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\css-classes-reference.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\index.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\language-contribution.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\language-guide.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\language-requests.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\line-numbers.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\reference.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\release-process.rst","QUANTAXIS_Webkit\\web\\node_modules\\highlight.js\\docs\\style-guide.rst","README.rst","index.rst","source\\QUANTAXIS.rst","source\\QUANTAXIS.QAARP.rst","source\\QUANTAXIS.QAAnalysis.rst","source\\QUANTAXIS.QABacktest.rst","source\\QUANTAXIS.QACmd.rst","source\\QUANTAXIS.QAData.rst","source\\QUANTAXIS.QAData.proto.rst","source\\QUANTAXIS.QAEngine.rst","source\\QUANTAXIS.QAFetch.rst","source\\QUANTAXIS.QAIndicator.rst","source\\QUANTAXIS.QAMarket.rst","source\\QUANTAXIS.QASU.rst","source\\QUANTAXIS.QAUtil.rst","source\\QUANTAXIS.QAWeb.rst","source\\modules.rst"],objects:{"":{QUANTAXIS:[14,0,0,"-"]},"QUANTAXIS.QAARP":{QAAccount:[15,0,0,"-"],QAPortfolio:[15,0,0,"-"],QARisk:[15,0,0,"-"],QAStrategy:[15,0,0,"-"],QAUser:[15,0,0,"-"]},"QUANTAXIS.QAARP.QAAccount":{Account_handler:[15,1,1,""],QA_Account:[15,1,1,""]},"QUANTAXIS.QAARP.QAAccount.Account_handler":{get_account:[15,2,1,""]},"QUANTAXIS.QAARP.QAAccount.QA_Account":{cash_table:[15,3,1,""],change_cash:[15,2,1,""],code:[15,3,1,""],current_time:[15,3,1,""],daily_cash:[15,3,1,""],daily_hold:[15,3,1,""],end_date:[15,3,1,""],from_message:[15,2,1,""],history_table:[15,3,1,""],hold:[15,3,1,""],latest_cash:[15,3,1,""],message:[15,3,1,""],on_bar:[15,2,1,""],on_tick:[15,2,1,""],receive_deal:[15,2,1,""],reset_assets:[15,2,1,""],run:[15,2,1,""],save:[15,2,1,""],send_order:[15,2,1,""],settle:[15,2,1,""],start_date:[15,3,1,""],table:[15,3,1,""],trade:[15,3,1,""]},"QUANTAXIS.QAARP.QAPortfolio":{QA_Portfolio:[15,1,1,""],QA_PortfolioView:[15,1,1,""],QA_TEST_MAKEPortfolio:[15,1,1,""]},"QUANTAXIS.QAARP.QAPortfolio.QA_Portfolio":{add_account:[15,2,1,""],cookie_mangement:[15,2,1,""],get_account:[15,2,1,""],get_cash:[15,2,1,""],get_portfolio:[15,2,1,""],new_account:[15,2,1,""],pull:[15,2,1,""],push:[15,2,1,""],table:[15,3,1,""]},"QUANTAXIS.QAARP.QAPortfolio.QA_PortfolioView":{account_cookie:[15,3,1,""],accounts:[15,3,1,""],code:[15,3,1,""],daily_cash:[15,3,1,""],daily_hold:[15,3,1,""],end_date:[15,3,1,""],init_assets:[15,3,1,""],start_date:[15,3,1,""]},"QUANTAXIS.QAARP.QAPortfolio.QA_TEST_MAKEPortfolio":{make_portfolio:[15,2,1,""]},"QUANTAXIS.QAARP.QARisk":{QA_Performance:[15,1,1,""],QA_Risk:[15,1,1,""]},"QUANTAXIS.QAARP.QARisk.QA_Performance":{abnormal_active:[15,2,1,""],accumulate_return:[15,3,1,""],brinson:[15,2,1,""],hold:[15,2,1,""],prefer:[15,3,1,""],save:[15,2,1,""],style:[15,3,1,""]},"QUANTAXIS.QAARP.QARisk.QA_Risk":{alpha:[15,3,1,""],annualize_return:[15,3,1,""],benchmark_annualize_return:[15,3,1,""],benchmark_assets:[15,3,1,""],benchmark_data:[15,3,1,""],benchmark_profitpct:[15,3,1,""],beta:[15,3,1,""],calc_alpha:[15,2,1,""],calc_annualize_return:[15,2,1,""],calc_beta:[15,2,1,""],calc_profit:[15,2,1,""],calc_profitpctchange:[15,2,1,""],calc_sharpe:[15,2,1,""],calmar:[15,3,1,""],max_dropback:[15,3,1,""],message:[15,3,1,""],profit:[15,3,1,""],profit_pct:[15,3,1,""],save:[15,2,1,""],set_benchmark:[15,2,1,""],sharpe:[15,3,1,""],sortino:[15,3,1,""],volatility:[15,3,1,""]},"QUANTAXIS.QAARP.QAStrategy":{QA_Strategy:[15,1,1,""]},"QUANTAXIS.QAARP.QAUser":{QA_User:[15,1,1,""]},"QUANTAXIS.QAARP.QAUser.QA_User":{client:[15,2,1,""],connect_database:[15,2,1,""],generate_simpleaccount:[15,2,1,""],get_portfolio:[15,2,1,""],login:[15,2,1,""],new_portfolio:[15,2,1,""],register_account:[15,2,1,""],table:[15,3,1,""]},"QUANTAXIS.QAAnalysis":{QAAnalysis_block:[16,0,0,"-"],QAAnalysis_dataframe:[16,0,0,"-"],QAAnalysis_machinelearning:[16,0,0,"-"],QAAnalysis_series:[16,0,0,"-"],QAAnalysis_tick:[16,0,0,"-"],QAAnalysis_trade:[16,0,0,"-"]},"QUANTAXIS.QAAnalysis.QAAnalysis_block":{QAAnalysis_block:[16,1,1,""],QAAnalysis_codewithblock:[16,1,1,""],get_gap_trade:[16,4,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_block.QAAnalysis_block":{block_pcg:[16,2,1,""],block_price:[16,2,1,""],block_turnover:[16,2,1,""],market_data:[16,2,1,""],month_data:[16,3,1,""],res:[16,2,1,""],stock_info:[16,2,1,""],stock_turnover:[16,2,1,""],week_data:[16,3,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_dataframe":{QAAnalysis_stock:[16,1,1,""],shadow:[16,1,1,""],shadow_calc:[16,4,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_dataframe.QAAnalysis_stock":{add_func:[16,3,1,""],amplitude:[16,3,1,""],close:[16,3,1,""],date:[16,3,1,""],datetime:[16,3,1,""],day_pct_change:[16,3,1,""],high:[16,3,1,""],index:[16,3,1,""],kurtosis:[16,3,1,""],low:[16,3,1,""],mad:[16,3,1,""],max:[16,3,1,""],mean:[16,3,1,""],mean_harmonic:[16,3,1,""],min:[16,3,1,""],mode:[16,3,1,""],open:[16,3,1,""],pct_change:[16,3,1,""],price:[16,3,1,""],price_diff:[16,3,1,""],pstdev:[16,3,1,""],pvariance:[16,3,1,""],skewnewss:[16,3,1,""],stdev:[16,3,1,""],variance:[16,3,1,""],vol:[16,3,1,""],volume:[16,3,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_dataframe.shadow":{shadow_panel:[16,2,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_machinelearning":{QAAnalysis_Machine_Learning:[16,1,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_machinelearning.QAAnalysis_Machine_Learning":{cross_valid:[16,2,1,""],data_co:[16,2,1,""],load_data:[16,2,1,""],load_modules:[16,2,1,""],training:[16,2,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_series":{QAAnalysis_Series_slope:[16,4,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_tick":{QAAnalysis_Transaction:[16,1,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_tick.QAAnalysis_Transaction":{get_data:[16,2,1,""],get_stock_info:[16,2,1,""],winner:[16,2,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_trade":{QAAnalysis_trade:[16,1,1,""]},"QUANTAXIS.QAAnalysis.QAAnalysis_trade.QAAnalysis_trade":{import_trade:[16,2,1,""],make_deal:[16,2,1,""]},"QUANTAXIS.QABacktest":{QAAnalysis:[17,0,0,"-"],QABacktest:[17,0,0,"-"],QAResult:[17,0,0,"-"],backtest_setting:[17,0,0,"-"]},"QUANTAXIS.QABacktest.QAAnalysis":{QA_backtest_analysis_backtest:[17,4,1,""],QA_backtest_calc_alpha:[17,4,1,""],QA_backtest_calc_assets:[17,4,1,""],QA_backtest_calc_benchmark:[17,4,1,""],QA_backtest_calc_beta:[17,4,1,""],QA_backtest_calc_dropback_max:[17,4,1,""],QA_backtest_calc_profit:[17,4,1,""],QA_backtest_calc_profit_matrix:[17,4,1,""],QA_backtest_calc_profit_per_year:[17,4,1,""],QA_backtest_calc_sharpe:[17,4,1,""],QA_backtest_calc_trade_date:[17,4,1,""],QA_backtest_calc_volatility:[17,4,1,""],QA_backtest_calc_win_rate:[17,4,1,""],calc_every_pnl:[17,4,1,""],calc_trade_time:[17,4,1,""]},"QUANTAXIS.QABacktest.QABacktest":{BACKTEST_FRAMEWORK:[17,1,1,""],QA_Backtest:[17,1,1,""]},"QUANTAXIS.QABacktest.QABacktest.QA_Backtest":{after_success:[17,2,1,""],run:[17,2,1,""],start_market:[17,2,1,""],stop:[17,2,1,""]},"QUANTAXIS.QABacktest.QAResult":{backtest_result_analyzer:[17,1,1,""]},"QUANTAXIS.QABacktest.QAResult.backtest_result_analyzer":{codes:[17,3,1,""],detail:[17,3,1,""],get_loss_trade:[17,2,1,""],get_profit_trade:[17,2,1,""],get_stock_tradedetail:[17,2,1,""],get_stock_tradehistory:[17,2,1,""],get_trade_before_and_after_pnl:[17,2,1,""],get_trade_marketdata:[17,2,1,""],history:[17,3,1,""]},"QUANTAXIS.QABacktest.backtest_setting":{backtest_setting:[17,1,1,""]},"QUANTAXIS.QABacktest.backtest_setting.backtest_setting":{absoult_path:[17,3,1,""],database_uri:[17,3,1,""],dirs:[17,3,1,""]},"QUANTAXIS.QACmd":{CLI:[18,1,1,""],QA_cmd:[18,4,1,""],backtest:[18,0,0,"-"],sourcecpy:[18,4,1,""]},"QUANTAXIS.QACmd.CLI":{do_clean:[18,2,1,""],do_drop_database:[18,2,1,""],do_examples:[18,2,1,""],do_exit:[18,2,1,""],do_fn:[18,2,1,""],do_help:[18,2,1,""],do_quit:[18,2,1,""],do_save:[18,2,1,""],do_shell:[18,2,1,""],do_version:[18,2,1,""],help:[18,2,1,""],help_clean:[18,2,1,""],help_drop_database:[18,2,1,""],help_examples:[18,2,1,""],help_exit:[18,2,1,""],help_quit:[18,2,1,""],help_save:[18,2,1,""],help_version:[18,2,1,""]},"QUANTAXIS.QAData":{QADataStruct:[19,0,0,"-"],base_datastruct:[19,0,0,"-"],data_fq:[19,0,0,"-"],data_resample:[19,0,0,"-"],dsmethods:[19,0,0,"-"],proto:[20,0,0,"-"],realtimedata:[19,0,0,"-"],schema:[19,0,0,"-"],serialize:[19,0,0,"-"]},"QUANTAXIS.QAData.QADataStruct":{QA_DataStruct_Future_day:[19,1,1,""],QA_DataStruct_Future_min:[19,1,1,""],QA_DataStruct_Index_day:[19,1,1,""],QA_DataStruct_Index_min:[19,1,1,""],QA_DataStruct_Security_list:[19,1,1,""],QA_DataStruct_Stock_block:[19,1,1,""],QA_DataStruct_Stock_day:[19,1,1,""],QA_DataStruct_Stock_min:[19,1,1,""],QA_DataStruct_Stock_realtime:[19,1,1,""],QA_DataStruct_Stock_realtime_series:[19,1,1,""],QA_DataStruct_Stock_transaction:[19,1,1,""]},"QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Security_list":{code:[19,3,1,""],get_etf:[19,2,1,""],get_index:[19,2,1,""],get_stock:[19,2,1,""],name:[19,3,1,""]},"QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_block":{block_name:[19,3,1,""],code:[19,3,1,""],get_block:[19,2,1,""],get_code:[19,2,1,""],get_price:[19,2,1,""],getdtype:[19,2,1,""],len:[19,3,1,""],show:[19,2,1,""]},"QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_day":{high_limit:[19,3,1,""],low_limit:[19,3,1,""],next_day_high_limit:[19,3,1,""],next_day_low_limit:[19,3,1,""],preclose:[19,3,1,""],price_chg:[19,3,1,""],to_hfq:[19,2,1,""],to_qfq:[19,2,1,""]},"QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_min":{high_limit:[19,3,1,""],low_limit:[19,3,1,""],to_hfq:[19,2,1,""],to_qfq:[19,2,1,""]},"QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_realtime":{ab_board:[19,3,1,""],serialize:[19,2,1,""]},"QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_transaction":{amount:[19,3,1,""],buyorsell:[19,3,1,""],date:[19,3,1,""],datetime:[19,3,1,""],get_big_orders:[19,2,1,""],get_medium_order:[19,2,1,""],get_small_order:[19,2,1,""],get_time:[19,2,1,""],index:[19,3,1,""],order:[19,3,1,""],price:[19,3,1,""],resample:[19,2,1,""],time:[19,3,1,""],vol:[19,3,1,""],volume:[19,3,1,""]},"QUANTAXIS.QAData.data_fq":{QA_data_get_hfq:[19,4,1,""],QA_data_get_qfq:[19,4,1,""],QA_data_make_hfq:[19,4,1,""],QA_data_make_qfq:[19,4,1,""],QA_data_stock_to_fq:[19,4,1,""]},"QUANTAXIS.QAData.data_resample":{QA_data_tick_resample:[19,4,1,""]},"QUANTAXIS.QAData.dsmethods":{concat:[19,4,1,""],from_tushare:[19,4,1,""]},"QUANTAXIS.QAData.proto":{order_pb2:[20,0,0,"-"],stock_day_pb2:[20,0,0,"-"],stock_min_pb2:[20,0,0,"-"]},"QUANTAXIS.QAData.schema":{Shares:[19,1,1,""],full:[19,1,1,""],fundamental:[19,1,1,""]},"QUANTAXIS.QAData.schema.Shares":{circulation:[19,3,1,""],effective_date:[19,3,1,""],shares:[19,3,1,""],sid:[19,3,1,""]},"QUANTAXIS.QAData.schema.full":{adratio:[19,3,1,""],arturndays:[19,3,1,""],arturnover:[19,3,1,""],bips:[19,3,1,""],business_income:[19,3,1,""],bvps:[19,3,1,""],cashflowratio:[19,3,1,""],cashratio:[19,3,1,""],cf_liabilities:[19,3,1,""],cf_nm:[19,3,1,""],cf_sales:[19,3,1,""],code:[19,3,1,""],currentasset_days:[19,3,1,""],currentasset_turnover:[19,3,1,""],currentratio:[19,3,1,""],distrib:[19,3,1,""],epcf:[19,3,1,""],eps:[19,3,1,""],eps_yoy:[19,3,1,""],epsg:[19,3,1,""],gross_profit_rate:[19,3,1,""],icratio:[19,3,1,""],inventory_days:[19,3,1,""],inventory_turnover:[19,3,1,""],mbrg:[19,3,1,""],name:[19,3,1,""],nav:[19,3,1,""],net_profit_ratio:[19,3,1,""],net_profits:[19,3,1,""],nprg:[19,3,1,""],profits_yoy:[19,3,1,""],quarter:[19,3,1,""],quickratio:[19,3,1,""],rateofreturn:[19,3,1,""],report_date:[19,3,1,""],roe:[19,3,1,""],seg:[19,3,1,""],sheqratio:[19,3,1,""],targ:[19,3,1,""],trade_date:[19,3,1,""]},"QUANTAXIS.QAData.schema.fundamental":{adratio:[19,3,1,""],arturndays:[19,3,1,""],arturnover:[19,3,1,""],bips:[19,3,1,""],business_income:[19,3,1,""],bvps:[19,3,1,""],cashflowratio:[19,3,1,""],cashratio:[19,3,1,""],cf_liabilities:[19,3,1,""],cf_nm:[19,3,1,""],cf_sales:[19,3,1,""],code:[19,3,1,""],currentasset_days:[19,3,1,""],currentasset_turnover:[19,3,1,""],currentratio:[19,3,1,""],distrib:[19,3,1,""],epcf:[19,3,1,""],eps:[19,3,1,""],eps_yoy:[19,3,1,""],epsg:[19,3,1,""],gross_profit_rate:[19,3,1,""],icratio:[19,3,1,""],inventory_days:[19,3,1,""],inventory_turnover:[19,3,1,""],mbrg:[19,3,1,""],name:[19,3,1,""],nav:[19,3,1,""],net_profit_ratio:[19,3,1,""],net_profits:[19,3,1,""],nprg:[19,3,1,""],profits_yoy:[19,3,1,""],quarter:[19,3,1,""],quickratio:[19,3,1,""],rateofreturn:[19,3,1,""],report_date:[19,3,1,""],roe:[19,3,1,""],seg:[19,3,1,""],sheqratio:[19,3,1,""],targ:[19,3,1,""]},"QUANTAXIS.QAEngine":{QAEvent:[21,0,0,"-"],QATask:[21,0,0,"-"],QAThreadEngine:[21,0,0,"-"]},"QUANTAXIS.QAEngine.QAEvent":{QA_Event:[21,1,1,""],QA_Worker:[21,1,1,""]},"QUANTAXIS.QAEngine.QAEvent.QA_Worker":{run:[21,2,1,""]},"QUANTAXIS.QAEngine.QATask":{QA_Task:[21,1,1,""]},"QUANTAXIS.QAEngine.QATask.QA_Task":{"do":[21,2,1,""],result:[21,3,1,""]},"QUANTAXIS.QAEngine.QAThreadEngine":{QA_Engine:[21,1,1,""],QA_Thread:[21,1,1,""]},"QUANTAXIS.QAEngine.QAThreadEngine.QA_Engine":{clear:[21,2,1,""],create_kernal:[21,2,1,""],join:[21,2,1,""],kernel_num:[21,3,1,""],pause:[21,2,1,""],register_kernal:[21,2,1,""],resume:[21,2,1,""],run:[21,2,1,""],run_job:[21,2,1,""],start_kernal:[21,2,1,""],stop:[21,2,1,""],stop_all:[21,2,1,""],stop_kernal:[21,2,1,""]},"QUANTAXIS.QAEngine.QAThreadEngine.QA_Thread":{get:[21,2,1,""],get_nowait:[21,2,1,""],pause:[21,2,1,""],put:[21,2,1,""],put_nowait:[21,2,1,""],qsize:[21,2,1,""],resume:[21,2,1,""],run:[21,2,1,""],stop:[21,2,1,""]},"QUANTAXIS.QAFetch":{Fetcher:[22,0,0,"-"],QACrawler:[22,0,0,"-"],QAEastMoney:[22,0,0,"-"],QAQuery:[22,0,0,"-"],QAQuery_Advance:[22,0,0,"-"],QATdx:[22,0,0,"-"],QATdx_adv:[22,0,0,"-"],QAThs:[22,0,0,"-"],QATushare:[22,0,0,"-"],QAWind:[22,0,0,"-"],QA_fetch_get_future_day:[22,4,1,""],QA_fetch_get_future_list:[22,4,1,""],QA_fetch_get_future_min:[22,4,1,""],QA_fetch_get_index_day:[22,4,1,""],QA_fetch_get_index_min:[22,4,1,""],QA_fetch_get_security_bars:[22,4,1,""],QA_fetch_get_stock_block:[22,4,1,""],QA_fetch_get_stock_day:[22,4,1,""],QA_fetch_get_stock_indicator:[22,4,1,""],QA_fetch_get_stock_info:[22,4,1,""],QA_fetch_get_stock_list:[22,4,1,""],QA_fetch_get_stock_min:[22,4,1,""],QA_fetch_get_stock_realtime:[22,4,1,""],QA_fetch_get_stock_transaction:[22,4,1,""],QA_fetch_get_stock_transaction_realtime:[22,4,1,""],QA_fetch_get_stock_xdxr:[22,4,1,""],QA_fetch_get_trade_date:[22,4,1,""],QAfinancial:[22,0,0,"-"],base:[22,0,0,"-"],data_list:[22,0,0,"-"],realtime:[22,0,0,"-"],use:[22,4,1,""]},"QUANTAXIS.QAFetch.Fetcher":{QA_Fetcher:[22,1,1,""],QA_quotation:[22,4,1,""]},"QUANTAXIS.QAFetch.Fetcher.QA_Fetcher":{change_ip:[22,2,1,""],get_info:[22,2,1,""],get_quotation:[22,2,1,""]},"QUANTAXIS.QAFetch.QACrawler":{QA_fetch_get_sh_margin:[22,4,1,""],QA_fetch_get_sz_margin:[22,4,1,""]},"QUANTAXIS.QAFetch.QAEastMoney":{QA_fetch_get_stock_analysis:[22,4,1,""]},"QUANTAXIS.QAFetch.QAQuery":{QA_fetch_account:[22,4,1,""],QA_fetch_backtest_history:[22,4,1,""],QA_fetch_backtest_info:[22,4,1,""],QA_fetch_future_day:[22,4,1,""],QA_fetch_future_min:[22,4,1,""],QA_fetch_future_tick:[22,4,1,""],QA_fetch_index_day:[22,4,1,""],QA_fetch_index_min:[22,4,1,""],QA_fetch_indexlist_day:[22,4,1,""],QA_fetch_quotation:[22,4,1,""],QA_fetch_quotations:[22,4,1,""],QA_fetch_stock_block:[22,4,1,""],QA_fetch_stock_day:[22,4,1,""],QA_fetch_stock_full:[22,4,1,""],QA_fetch_stock_info:[22,4,1,""],QA_fetch_stock_list:[22,4,1,""],QA_fetch_stock_min:[22,4,1,""],QA_fetch_stock_name:[22,4,1,""],QA_fetch_stock_xdxr:[22,4,1,""],QA_fetch_trade_date:[22,4,1,""]},"QUANTAXIS.QAFetch.QAQuery_Advance":{QA_fetch_index_day_adv:[22,4,1,""],QA_fetch_index_min_adv:[22,4,1,""],QA_fetch_security_list_adv:[22,4,1,""],QA_fetch_stock_block_adv:[22,4,1,""],QA_fetch_stock_day_adv:[22,4,1,""],QA_fetch_stock_day_full_adv:[22,4,1,""],QA_fetch_stock_list_adv:[22,4,1,""],QA_fetch_stock_min_adv:[22,4,1,""],QA_fetch_stock_realtime_adv:[22,4,1,""],QA_fetch_stock_transaction_adv:[22,4,1,""]},"QUANTAXIS.QAFetch.QATdx":{QA_fetch_depth_market_data:[22,4,1,""],QA_fetch_get_future_day:[22,4,1,""],QA_fetch_get_future_list:[22,4,1,""],QA_fetch_get_future_min:[22,4,1,""],QA_fetch_get_future_realtime:[22,4,1,""],QA_fetch_get_future_transaction:[22,4,1,""],QA_fetch_get_future_transaction_realtime:[22,4,1,""],QA_fetch_get_index_day:[22,4,1,""],QA_fetch_get_index_min:[22,4,1,""],QA_fetch_get_security_bars:[22,4,1,""],QA_fetch_get_stock_block:[22,4,1,""],QA_fetch_get_stock_day:[22,4,1,""],QA_fetch_get_stock_info:[22,4,1,""],QA_fetch_get_stock_latest:[22,4,1,""],QA_fetch_get_stock_list:[22,4,1,""],QA_fetch_get_stock_min:[22,4,1,""],QA_fetch_get_stock_realtime:[22,4,1,""],QA_fetch_get_stock_transaction:[22,4,1,""],QA_fetch_get_stock_transaction_realtime:[22,4,1,""],QA_fetch_get_stock_xdxr:[22,4,1,""],QA_fetch_get_wholemarket_list:[22,4,1,""],for_sh:[22,4,1,""],for_sz:[22,4,1,""],ping:[22,4,1,""],select_best_ip:[22,4,1,""]},"QUANTAXIS.QAFetch.QATdx_adv":{QA_Tdx_Executor:[22,1,1,""],bat:[22,4,1,""],get_bar:[22,4,1,""],get_day_once:[22,4,1,""]},"QUANTAXIS.QAFetch.QATdx_adv.QA_Tdx_Executor":{api:[22,3,1,""],api_worker:[22,2,1,""],get_available:[22,2,1,""],get_frequence:[22,2,1,""],get_market:[22,2,1,""],get_realtime:[22,2,1,""],get_realtime_concurrent:[22,2,1,""],get_security_bar:[22,2,1,""],get_security_bar_concurrent:[22,2,1,""],ipsize:[22,3,1,""],save_mongo:[22,2,1,""]},"QUANTAXIS.QAFetch.QAThs":{QA_fetch_get_stock_block:[22,4,1,""],QA_fetch_get_stock_day:[22,4,1,""],QA_fetch_get_stock_day_in_year:[22,4,1,""]},"QUANTAXIS.QAFetch.QATushare":{QA_fetch_get_stock_day:[22,4,1,""],QA_fetch_get_stock_info:[22,4,1,""],QA_fetch_get_stock_list:[22,4,1,""],QA_fetch_get_stock_realtime:[22,4,1,""],QA_fetch_get_stock_tick:[22,4,1,""],QA_fetch_get_stock_time_to_market:[22,4,1,""],QA_fetch_get_trade_date:[22,4,1,""]},"QUANTAXIS.QAFetch.QAWind":{QA_fetch_get_stock_day:[22,4,1,""],QA_fetch_get_stock_day_simple:[22,4,1,""],QA_fetch_get_stock_financial:[22,4,1,""],QA_fetch_get_stock_indicator:[22,4,1,""],QA_fetch_get_stock_info:[22,4,1,""],QA_fetch_get_stock_list:[22,4,1,""],QA_fetch_get_stock_list_special:[22,4,1,""],QA_fetch_get_stock_risk:[22,4,1,""],QA_fetch_get_stock_shape:[22,4,1,""],QA_fetch_get_stock_xueqiu:[22,4,1,""],QA_fetch_get_trade_date:[22,4,1,""]},"QUANTAXIS.QAFetch.QAfinancial":{download:[22,4,1,""],get_and_parse:[22,4,1,""],get_filename:[22,4,1,""],prase_all:[22,4,1,""]},"QUANTAXIS.QAFetch.realtime":{get_today_all:[22,4,1,""]},"QUANTAXIS.QAIndicator":{base:[23,0,0,"-"],indicators:[23,0,0,"-"]},"QUANTAXIS.QAIndicator.base":{ABS:[23,4,1,""],AVEDEV:[23,4,1,""],BBI:[23,4,1,""],BBIBOLL:[23,4,1,""],COUNT:[23,4,1,""],CROSS:[23,4,1,""],DIFF:[23,4,1,""],EMA:[23,4,1,""],HHV:[23,4,1,""],IF:[23,4,1,""],LAST:[23,4,1,""],LLV:[23,4,1,""],MA:[23,4,1,""],MACD:[23,4,1,""],MAX:[23,4,1,""],MIN:[23,4,1,""],REF:[23,4,1,""],SMA:[23,4,1,""],STD:[23,4,1,""],SUM:[23,4,1,""]},"QUANTAXIS.QAIndicator.indicators":{QA_indicator_ADTM:[23,4,1,""],QA_indicator_ARBR:[23,4,1,""],QA_indicator_ASI:[23,4,1,""],QA_indicator_ATR:[23,4,1,""],QA_indicator_BBI:[23,4,1,""],QA_indicator_BIAS:[23,4,1,""],QA_indicator_BOLL:[23,4,1,""],QA_indicator_CCI:[23,4,1,""],QA_indicator_CHO:[23,4,1,""],QA_indicator_CR:[23,4,1,""],QA_indicator_DDI:[23,4,1,""],QA_indicator_DMA:[23,4,1,""],QA_indicator_DMI:[23,4,1,""],QA_indicator_EMA:[23,4,1,""],QA_indicator_EXPMA:[23,4,1,""],QA_indicator_KDJ:[23,4,1,""],QA_indicator_MA:[23,4,1,""],QA_indicator_MACD:[23,4,1,""],QA_indicator_MFI:[23,4,1,""],QA_indicator_MIKE:[23,4,1,""],QA_indicator_MTM:[23,4,1,""],QA_indicator_OBV:[23,4,1,""],QA_indicator_OSC:[23,4,1,""],QA_indicator_PBX:[23,4,1,""],QA_indicator_PVT:[23,4,1,""],QA_indicator_ROC:[23,4,1,""],QA_indicator_RSI:[23,4,1,""],QA_indicator_SKDJ:[23,4,1,""],QA_indicator_SMA:[23,4,1,""],QA_indicator_VPT:[23,4,1,""],QA_indicator_VR:[23,4,1,""],QA_indicator_VRSI:[23,4,1,""],QA_indicator_VSTD:[23,4,1,""],QA_indicator_WR:[23,4,1,""],QA_indicator_shadow:[23,4,1,""],amplitude:[23,4,1,""],body:[23,4,1,""],body_abs:[23,4,1,""],lower_shadow:[23,4,1,""],price_pcg:[23,4,1,""],upper_shadow:[23,4,1,""]},"QUANTAXIS.QAMarket":{QABacktestBroker:[24,0,0,"-"],QABroker:[24,0,0,"-"],QADealer:[24,0,0,"-"],QAMarket:[24,0,0,"-"],QAOrder:[24,0,0,"-"],QAOrderHandler:[24,0,0,"-"],QARandomBroker:[24,0,0,"-"],QARealBroker:[24,0,0,"-"],QASimulatedBroker:[24,0,0,"-"],QATrade:[24,0,0,"-"],shipaneBroker:[24,0,0,"-"],shipaneclient:[24,0,0,"-"],tdxRealBroker:[24,0,0,"-"]},"QUANTAXIS.QAMarket.QABacktestBroker":{QA_BacktestBroker:[24,1,1,""]},"QUANTAXIS.QAMarket.QABacktestBroker.QA_BacktestBroker":{get_market:[24,2,1,""],query_data:[24,2,1,""],receive_order:[24,2,1,""],run:[24,2,1,""],warp:[24,2,1,""]},"QUANTAXIS.QAMarket.QABroker":{QA_BROKER_EVENT:[24,1,1,""],QA_Broker:[24,1,1,""]},"QUANTAXIS.QAMarket.QABroker.QA_Broker":{get_market:[24,2,1,""],receive_order:[24,2,1,""],warp:[24,2,1,""]},"QUANTAXIS.QAMarket.QADealer":{QA_Dealer:[24,1,1,""],Stock_Dealer:[24,1,1,""],commission:[24,1,1,""],dealer_preset:[24,1,1,""]},"QUANTAXIS.QAMarket.QADealer.QA_Dealer":{backtest_stock_dealer:[24,2,1,""],cal_fee:[24,2,1,""],callback_message:[24,2,1,""],deal:[24,2,1,""]},"QUANTAXIS.QAMarket.QADealer.commission":{if_buyside_commission:[24,3,1,""],if_commission:[24,3,1,""],if_sellside_commission:[24,3,1,""]},"QUANTAXIS.QAMarket.QADealer.dealer_preset":{load_preset:[24,2,1,""]},"QUANTAXIS.QAMarket.QAMarket":{QA_Market:[24,1,1,""]},"QUANTAXIS.QAMarket.QAMarket.QA_Market":{clear:[24,2,1,""],connect:[24,2,1,""],get_account:[24,2,1,""],get_account_id:[24,2,1,""],get_trading_day:[24,2,1,""],insert_order:[24,2,1,""],login:[24,2,1,""],logout:[24,2,1,""],on_insert_order:[24,2,1,""],on_query_data:[24,2,1,""],on_trade_event:[24,2,1,""],query_assets:[24,2,1,""],query_cash:[24,2,1,""],query_currentbar:[24,2,1,""],query_data:[24,2,1,""],query_data_no_wait:[24,2,1,""],query_order:[24,2,1,""],query_position:[24,2,1,""],register:[24,2,1,""],start:[24,2,1,""],upcoming_data:[24,2,1,""]},"QUANTAXIS.QAMarket.QAOrder":{QA_Order:[24,1,1,""],QA_OrderQueue:[24,1,1,""]},"QUANTAXIS.QAMarket.QAOrder.QA_Order":{from_dict:[24,2,1,""],info:[24,2,1,""],to_df:[24,2,1,""],to_dict:[24,2,1,""]},"QUANTAXIS.QAMarket.QAOrder.QA_OrderQueue":{insert_order:[24,2,1,""],order_ids:[24,3,1,""],pending:[24,3,1,""],query_order:[24,2,1,""],set_status:[24,2,1,""],settle:[24,2,1,""],trade_list:[24,3,1,""]},"QUANTAXIS.QAMarket.QAOrderHandler":{QA_OrderHandler:[24,1,1,""]},"QUANTAXIS.QAMarket.QAOrderHandler.QA_OrderHandler":{query_order:[24,2,1,""],run:[24,2,1,""]},"QUANTAXIS.QAMarket.QARandomBroker":{QA_RandomBroker:[24,1,1,""]},"QUANTAXIS.QAMarket.QARandomBroker.QA_RandomBroker":{get_data:[24,2,1,""],receive_order:[24,2,1,""],warp:[24,2,1,""]},"QUANTAXIS.QAMarket.QARealBroker":{QA_RealBroker:[24,1,1,""]},"QUANTAXIS.QAMarket.QARealBroker.QA_RealBroker":{get_data:[24,2,1,""],receive_order:[24,2,1,""],warp:[24,2,1,""]},"QUANTAXIS.QAMarket.QASimulatedBroker":{QA_SimulatedBroker:[24,1,1,""]},"QUANTAXIS.QAMarket.QASimulatedBroker.QA_SimulatedBroker":{get_market:[24,2,1,""],query_data:[24,2,1,""],receive_order:[24,2,1,""]},"QUANTAXIS.QAMarket.QATrade":{QA_Trade:[24,1,1,""]},"QUANTAXIS.QAMarket.QATrade.QA_Trade":{cancel_order:[24,2,1,""],connect:[24,2,1,""],get_account_id:[24,2,1,""],get_api_last_error:[24,2,1,""],get_api_version:[24,2,1,""],get_client_id:[24,2,1,""],get_trading_day:[24,2,1,""],insert_order:[24,2,1,""],login:[24,2,1,""],logout:[24,2,1,""],on_cancel_order:[24,2,1,""],on_cancel_order_event:[24,2,1,""],on_connect:[24,2,1,""],on_error:[24,2,1,""],on_insert_order:[24,2,1,""],on_order_event:[24,2,1,""],on_query_assets:[24,2,1,""],on_query_data:[24,2,1,""],on_query_order:[24,2,1,""],on_query_position:[24,2,1,""],on_query_trade:[24,2,1,""],on_trade_event:[24,2,1,""],query_assets:[24,2,1,""],query_data:[24,2,1,""],query_order:[24,2,1,""],query_position:[24,2,1,""],query_trade:[24,2,1,""],register_spi:[24,2,1,""],release:[24,2,1,""],subscribe_public_topic:[24,2,1,""]},"QUANTAXIS.QAMarket.shipaneBroker":{SPETradeApi:[24,1,1,""]},"QUANTAXIS.QAMarket.shipaneBroker.SPETradeApi":{call:[24,2,1,""],cancel_order:[24,2,1,""],data_to_df:[24,2,1,""],get_quote:[24,2,1,""],logoff:[24,2,1,""],logon:[24,2,1,""],ping:[24,2,1,""],query_data:[24,2,1,""],receive_order:[24,2,1,""],repay:[24,2,1,""],run:[24,2,1,""],send_order:[24,2,1,""]},"QUANTAXIS.QAMarket.shipaneclient":{Client:[24,1,1,""],ConnectionMethod:[24,1,1,""],MediaType:[24,1,1,""]},"QUANTAXIS.QAMarket.shipaneclient.Client":{KEY_REGEX:[24,3,1,""],buy:[24,2,1,""],cancel:[24,2,1,""],cancel_all:[24,2,1,""],create_adjustment:[24,2,1,""],execute:[24,2,1,""],get_account:[24,2,1,""],get_orders:[24,2,1,""],get_positions:[24,2,1,""],get_statuses:[24,2,1,""],host:[24,3,1,""],ipo:[24,2,1,""],key:[24,3,1,""],port:[24,3,1,""],purchase_convertible_bonds:[24,2,1,""],purchase_new_stocks:[24,2,1,""],query:[24,2,1,""],query_convertible_bonds:[24,2,1,""],query_new_stocks:[24,2,1,""],sell:[24,2,1,""],shutdown_clients:[24,2,1,""],start_clients:[24,2,1,""],timeout:[24,3,1,""]},"QUANTAXIS.QAMarket.shipaneclient.ConnectionMethod":{DIRECT:[24,3,1,""],PROXY:[24,3,1,""]},"QUANTAXIS.QAMarket.shipaneclient.MediaType":{DEFAULT:[24,3,1,""],JOIN_QUANT:[24,3,1,""]},"QUANTAXIS.QAMarket.tdxRealBroker":{TDXBroker:[24,1,1,""],TdxTradeApiParams:[24,1,1,""]},"QUANTAXIS.QAMarket.tdxRealBroker.TDXBroker":{call:[24,2,1,""],cancel_order:[24,2,1,""],data_to_df:[24,2,1,""],decrypt:[24,2,1,""],encrypt:[24,2,1,""],get_quote:[24,2,1,""],logoff:[24,2,1,""],logon:[24,2,1,""],ping:[24,2,1,""],query_data:[24,2,1,""],receive_order:[24,2,1,""],repay:[24,2,1,""],run:[24,2,1,""],send_order:[24,2,1,""]},"QUANTAXIS.QAMarket.tdxRealBroker.TdxTradeApiParams":{QUERY_CATEGORY_BALANCE_OF_MARGIN_LOAN:[24,3,1,""],QUERY_CATEGORY_BALANCE_OF_STOCK_LOAN:[24,3,1,""],QUERY_CATEGORY_CANCELABLE_ORDER:[24,3,1,""],QUERY_CATEGORY_CASH:[24,3,1,""],QUERY_CATEGORY_DEAL_OF_TODAY:[24,3,1,""],QUERY_CATEGORY_NEW_STOCKS:[24,3,1,""],QUERY_CATEGORY_NEW_STOCKS_QUOTA:[24,3,1,""],QUERY_CATEGORY_NEW_STOCK_HIT:[24,3,1,""],QUERY_CATEGORY_NEW_STOCK_NUMBER:[24,3,1,""],QUERY_CATEGORY_OPERABLE_MARGIN_SOTCK:[24,3,1,""],QUERY_CATEGORY_ORDER_OF_TODAY:[24,3,1,""],QUERY_CATEGORY_SHAREHOLDERS_CODE:[24,3,1,""],QUERY_CATEGORY_STOCKS:[24,3,1,""]},"QUANTAXIS.QASU":{main:[25,0,0,"-"],save_account:[25,0,0,"-"],save_backtest:[25,0,0,"-"],save_local:[25,0,0,"-"],save_tdx:[25,0,0,"-"],save_tdx_file:[25,0,0,"-"],save_tushare:[25,0,0,"-"],user:[25,0,0,"-"]},"QUANTAXIS.QASU.main":{QA_SU_save_etf_day:[25,4,1,""],QA_SU_save_etf_min:[25,4,1,""],QA_SU_save_index_day:[25,4,1,""],QA_SU_save_index_min:[25,4,1,""],QA_SU_save_stock_block:[25,4,1,""],QA_SU_save_stock_day:[25,4,1,""],QA_SU_save_stock_info:[25,4,1,""],QA_SU_save_stock_list:[25,4,1,""],QA_SU_save_stock_min:[25,4,1,""],QA_SU_save_stock_min_5:[25,4,1,""],QA_SU_save_stock_xdxr:[25,4,1,""],select_save_engine:[25,4,1,""]},"QUANTAXIS.QASU.save_account":{save_account:[25,4,1,""],save_riskanalysis:[25,4,1,""],update_account:[25,4,1,""]},"QUANTAXIS.QASU.save_backtest":{QA_SU_save_account_message:[25,4,1,""],QA_SU_save_account_to_csv:[25,4,1,""],QA_SU_save_backtest_message:[25,4,1,""],QA_SU_save_pnl_to_csv:[25,4,1,""]},"QUANTAXIS.QASU.save_local":{make_cache:[25,4,1,""],make_dir:[25,4,1,""]},"QUANTAXIS.QASU.save_tdx":{QA_SU_save_etf_day:[25,4,1,""],QA_SU_save_etf_min:[25,4,1,""],QA_SU_save_index_day:[25,4,1,""],QA_SU_save_index_min:[25,4,1,""],QA_SU_save_stock_block:[25,4,1,""],QA_SU_save_stock_day:[25,4,1,""],QA_SU_save_stock_info:[25,4,1,""],QA_SU_save_stock_list:[25,4,1,""],QA_SU_save_stock_min:[25,4,1,""],QA_SU_save_stock_transaction:[25,4,1,""],QA_SU_save_stock_xdxr:[25,4,1,""],now_time:[25,4,1,""]},"QUANTAXIS.QASU.save_tdx_file":{QA_save_tdx_to_mongo:[25,4,1,""]},"QUANTAXIS.QASU.save_tushare":{QA_SU_save_stock_info:[25,4,1,""],QA_SU_save_stock_list:[25,4,1,""],QA_SU_save_trade_date_all:[25,4,1,""],QA_save_stock_day_all:[25,4,1,""],QA_save_stock_day_all_bfq:[25,4,1,""],QA_save_stock_day_with_fqfactor:[25,4,1,""]},"QUANTAXIS.QASU.user":{QA_user_sign_in:[25,4,1,""],QA_user_sign_up:[25,4,1,""]},"QUANTAXIS.QAUtil":{QAAuth:[26,0,0,"-"],QABar:[26,0,0,"-"],QACfg:[26,0,0,"-"],QACode:[26,0,0,"-"],QACsv:[26,0,0,"-"],QADate:[26,0,0,"-"],QADate_trade:[26,0,0,"-"],QADict:[26,0,0,"-"],QAList:[26,0,0,"-"],QALocalize:[26,0,0,"-"],QALogs:[26,0,0,"-"],QAMail:[26,0,0,"-"],QAMongo:[26,0,0,"-"],QAParameter:[26,0,0,"-"],QAPlot:[26,0,0,"-"],QARandom:[26,0,0,"-"],QASetting:[26,0,0,"-"],QASql:[26,0,0,"-"],QAText:[26,0,0,"-"],QATransform:[26,0,0,"-"],QAWeb:[26,0,0,"-"],host:[26,0,0,"-"]},"QUANTAXIS.QAUtil.QABar":{QA_util_make_hour_index:[26,4,1,""],QA_util_make_min_index:[26,4,1,""],QA_util_time_gap:[26,4,1,""]},"QUANTAXIS.QAUtil.QACfg":{QA_util_cfg_initial:[26,4,1,""],QA_util_get_cfg:[26,4,1,""]},"QUANTAXIS.QAUtil.QACode":{QA_util_code_tolist:[26,4,1,""],QA_util_code_tostr:[26,4,1,""]},"QUANTAXIS.QAUtil.QACsv":{QA_util_save_csv:[26,4,1,""]},"QUANTAXIS.QAUtil.QADate":{QA_util_calc_time:[26,4,1,""],QA_util_date_int2str:[26,4,1,""],QA_util_date_stamp:[26,4,1,""],QA_util_date_str2int:[26,4,1,""],QA_util_date_today:[26,4,1,""],QA_util_date_valid:[26,4,1,""],QA_util_get_date_index:[26,4,1,""],QA_util_get_index_date:[26,4,1,""],QA_util_id2date:[26,4,1,""],QA_util_is_trade:[26,4,1,""],QA_util_ms_stamp:[26,4,1,""],QA_util_realtime:[26,4,1,""],QA_util_select_hours:[26,4,1,""],QA_util_select_min:[26,4,1,""],QA_util_stamp2datetime:[26,4,1,""],QA_util_time_delay:[26,4,1,""],QA_util_time_now:[26,4,1,""],QA_util_time_stamp:[26,4,1,""],QA_util_to_datetime:[26,4,1,""]},"QUANTAXIS.QAUtil.QADate_trade":{QA_util_date_gap:[26,4,1,""],QA_util_get_last_day:[26,4,1,""],QA_util_get_next_day:[26,4,1,""],QA_util_get_real_date:[26,4,1,""],QA_util_get_real_datelist:[26,4,1,""],QA_util_get_trade_gap:[26,4,1,""],QA_util_get_trade_range:[26,4,1,""],QA_util_if_trade:[26,4,1,""],QA_util_if_tradetime:[26,4,1,""]},"QUANTAXIS.QAUtil.QADict":{QA_util_dict_remove_key:[26,4,1,""]},"QUANTAXIS.QAUtil.QAList":{QA_util_diff_list:[26,4,1,""],QA_util_multi_demension_list:[26,4,1,""]},"QUANTAXIS.QAUtil.QALogs":{QA_util_log_debug:[26,4,1,""],QA_util_log_expection:[26,4,1,""],QA_util_log_info:[26,4,1,""]},"QUANTAXIS.QAUtil.QAMail":{QA_util_send_mail:[26,4,1,""]},"QUANTAXIS.QAUtil.QAMongo":{QA_util_mongo_infos:[26,4,1,""],QA_util_mongo_initial:[26,4,1,""],QA_util_mongo_status:[26,4,1,""]},"QUANTAXIS.QAUtil.QAParameter":{ACCOUNT_EVENT:[26,1,1,""],AMOUNT_MODEL:[26,1,1,""],BROKER_EVENT:[26,1,1,""],BROKER_TYPE:[26,1,1,""],CURRENCY_TYPE:[26,1,1,""],DATASOURCE:[26,1,1,""],ENGINE_EVENT:[26,1,1,""],EVENT_TYPE:[26,1,1,""],FREQUENCE:[26,1,1,""],MARKET_ERROR:[26,1,1,""],MARKET_EVENT:[26,1,1,""],MARKET_TYPE:[26,1,1,""],ORDER_DIRECTION:[26,1,1,""],ORDER_EVENT:[26,1,1,""],ORDER_MODEL:[26,1,1,""],ORDER_STATUS:[26,1,1,""],OUTPUT_FORMAT:[26,1,1,""],RUNNING_ENVIRONMENT:[26,1,1,""],TRADE_STATUS:[26,1,1,""]},"QUANTAXIS.QAUtil.QAParameter.ACCOUNT_EVENT":{MAKE_ORDER:[26,3,1,""],SETTLE:[26,3,1,""],UPDATE:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.AMOUNT_MODEL":{BY_AMOUNT:[26,3,1,""],BY_PRICE:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.BROKER_EVENT":{DAILY_SETTLE:[26,3,1,""],LOAD_DATA:[26,3,1,""],RECEIVE_ORDER:[26,3,1,""],SETTLE:[26,3,1,""],TRADE:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.BROKER_TYPE":{BACKETEST:[26,3,1,""],RANODM:[26,3,1,""],REAL:[26,3,1,""],SIMULATION:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.CURRENCY_TYPE":{AUD:[26,3,1,""],BTC:[26,3,1,""],CAD:[26,3,1,""],EUR:[26,3,1,""],GBP:[26,3,1,""],HKD:[26,3,1,""],JPY:[26,3,1,""],RMB:[26,3,1,""],USD:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.DATASOURCE":{CCXT:[26,3,1,""],CHOICE:[26,3,1,""],EASTMONEY:[26,3,1,""],LOCALFILE:[26,3,1,""],MONGO:[26,3,1,""],TDB:[26,3,1,""],TDX:[26,3,1,""],THS:[26,3,1,""],TUSHARE:[26,3,1,""],WIND:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.ENGINE_EVENT":{BAR_SETTLE:[26,3,1,""],DAILY_SETTLE:[26,3,1,""],MARKET_INIT:[26,3,1,""],UPCOMING_DATA:[26,3,1,""],UPDATE:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.EVENT_TYPE":{ACCOUNT_EVENT:[26,3,1,""],BROKER_EVENT:[26,3,1,""],ENGINE_EVENT:[26,3,1,""],MARKET_EVENT:[26,3,1,""],ORDER_EVENT:[26,3,1,""],TRADE_EVENT:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.FREQUENCE":{CURRENT:[26,3,1,""],DAY:[26,3,1,""],FIFTEEN_MIN:[26,3,1,""],FIVE_MIN:[26,3,1,""],HOUR:[26,3,1,""],MONTH:[26,3,1,""],ONE_MIN:[26,3,1,""],QUARTER:[26,3,1,""],SIXTY_MIN:[26,3,1,""],THIRTY_MIN:[26,3,1,""],TICK:[26,3,1,""],WEEK:[26,3,1,""],YEAR:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.MARKET_ERROR":{ACCOUNT_EXIST:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.MARKET_EVENT":{QUERY_ACCOUNT:[26,3,1,""],QUERY_ASSETS:[26,3,1,""],QUERY_CASH:[26,3,1,""],QUERY_DATA:[26,3,1,""],QUERY_ORDER:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.MARKET_TYPE":{BOND_CN:[26,3,1,""],CRYPTOCURRENCY:[26,3,1,""],FUND_CN:[26,3,1,""],FUTURE_CN:[26,3,1,""],INDEX_CN:[26,3,1,""],OPTION_CN:[26,3,1,""],STOCKOPTION_CN:[26,3,1,""],STOCK_CN:[26,3,1,""],STOCK_HK:[26,3,1,""],STOCK_US:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.ORDER_DIRECTION":{BUY:[26,3,1,""],BUY_CLOSE:[26,3,1,""],BUY_OPEN:[26,3,1,""],SELL:[26,3,1,""],SELL_CLOSE:[26,3,1,""],SELL_OPEN:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.ORDER_EVENT":{CANCEL:[26,3,1,""],CREATE:[26,3,1,""],TRADE:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.ORDER_MODEL":{CLOSE:[26,3,1,""],LIMIT:[26,3,1,""],MARKET:[26,3,1,""],NEXT_OPEN:[26,3,1,""],STRICT:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.ORDER_STATUS":{CANCEL_ALL:[26,3,1,""],NEW:[26,3,1,""],QUEUED:[26,3,1,""],SETTLED:[26,3,1,""],SUCCESS_ALL:[26,3,1,""],SUCCESS_PART:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.OUTPUT_FORMAT":{DATAFRAME:[26,3,1,""],DATASTRUCT:[26,3,1,""],JSON:[26,3,1,""],LIST:[26,3,1,""],NDARRAY:[26,3,1,""],SERIES:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.RUNNING_ENVIRONMENT":{BACKETEST:[26,3,1,""],RANODM:[26,3,1,""],REAL:[26,3,1,""],SIMULATION:[26,3,1,""]},"QUANTAXIS.QAUtil.QAParameter.TRADE_STATUS":{FAILED:[26,3,1,""],NO_MARKET_DATA:[26,3,1,""],PRICE_LIMIT:[26,3,1,""],SUCCESS:[26,3,1,""]},"QUANTAXIS.QAUtil.QAPlot":{QA_plot_save_html:[26,4,1,""],plot_datastruct:[26,4,1,""]},"QUANTAXIS.QAUtil.QARandom":{QA_util_random_with_topic:[26,4,1,""]},"QUANTAXIS.QAUtil.QASetting":{QA_Setting:[26,1,1,""],future_ip_list:[26,5,1,""]},"QUANTAXIS.QAUtil.QASetting.QA_Setting":{change:[26,2,1,""],client:[26,3,1,""],login:[26,2,1,""]},"QUANTAXIS.QAUtil.QASql":{QA_util_sql_async_mongo_setting:[26,4,1,""],QA_util_sql_mongo_setting:[26,4,1,""]},"QUANTAXIS.QAUtil.QAText":{split_word:[26,4,1,""]},"QUANTAXIS.QAUtil.QATransform":{QA_util_to_json_from_list:[26,4,1,""],QA_util_to_json_from_numpy:[26,4,1,""],QA_util_to_json_from_pandas:[26,4,1,""],QA_util_to_list_from_numpy:[26,4,1,""],QA_util_to_list_from_pandas:[26,4,1,""],QA_util_to_pandas_from_json:[26,4,1,""],QA_util_to_pandas_from_list:[26,4,1,""]},"QUANTAXIS.QAUtil.QAWeb":{QA_Util_web_pool:[26,1,1,""],QA_util_web_ping:[26,4,1,""]},"QUANTAXIS.QAUtil.QAWeb.QA_Util_web_pool":{dynamic_optimics:[26,2,1,""],hot_update:[26,2,1,""],task_queue:[26,2,1,""]},"QUANTAXIS.QAWeb":{QA_Web:[27,0,0,"-"],chain:[27,0,0,"-"]},"QUANTAXIS.QAWeb.QA_Web":{hello:[27,4,1,""],main:[27,4,1,""],query_backtest:[27,4,1,""],query_backtest_by_:[27,4,1,""],query_backtest_history:[27,4,1,""],query_day_bfq:[27,4,1,""],query_day_hfq:[27,4,1,""],query_day_qfq:[27,4,1,""],query_k:[27,4,1,""],query_min_bfq:[27,4,1,""],query_min_qfq:[27,4,1,""],realtime:[27,4,1,""],run_backtest:[27,4,1,""],signin:[27,4,1,""],signup:[27,4,1,""],status:[27,4,1,""],test_message:[27,4,1,""]},"QUANTAXIS.QAWeb.chain":{Blockchain:[27,1,1,""],consensus:[27,4,1,""],full_chain:[27,4,1,""],mine:[27,4,1,""],new_transaction:[27,4,1,""],register_nodes:[27,4,1,""]},"QUANTAXIS.QAWeb.chain.Blockchain":{hash:[27,6,1,""],last_block:[27,3,1,""],new_block:[27,2,1,""],new_transaction:[27,2,1,""],proof_of_work:[27,2,1,""],register_node:[27,2,1,""],resolve_conflicts:[27,2,1,""],valid_chain:[27,2,1,""],valid_proof:[27,6,1,""]},QUANTAXIS:{QAARP:[15,0,0,"-"],QAAnalysis:[16,0,0,"-"],QABacktest:[17,0,0,"-"],QACmd:[18,0,0,"-"],QAData:[19,0,0,"-"],QAEngine:[21,0,0,"-"],QAFetch:[22,0,0,"-"],QAIndicator:[23,0,0,"-"],QAMarket:[24,0,0,"-"],QASU:[25,0,0,"-"],QAUtil:[26,0,0,"-"],QAWeb:[27,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","function","Python function"],"5":["py","data","Python data"],"6":["py","staticmethod","Python static method"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:function","5":"py:data","6":"py:staticmethod"},terms:{"000001\u7684\u80a1\u7968\u4f1a\u53d8\u6210office\u5f3a\u5236\u8f6c\u5316\u6210\u6570\u5b571":26,"0201e20000000000":22,"0\u5e02\u573a\u662f":24,"10\u4f4d\u957f\u5ea6\u7684\u65e5\u671f":22,"10x":22,"15min":26,"1\u65e5\u524d\u7684typ":23,"1\u7684\u5e02\u573a\u662f":24,"1min":[19,22,26],"30min":26,"4\u4f4d\u5927\u5c0f\u5199\u968f\u673a":26,"4\u6570\u5b57id":26,"4cekgzn":[0,12],"5em":11,"5min":26,"60min":26,"6\u4f4d\u957f\u5ea6\u7684str":22,"\u4e00\u4e2a\u5f85\u6210\u4ea4\u961f\u5217":24,"\u4e00\u4e2a\u7edf\u4e00\u7684fetch":22,"\u4e00\u4e2a\u901a\u7528\u7684\u53ef\u4ee5\u63a5\u5165\u4e0d\u540c\u6a21\u578b\u7684\u7c7b":16,"\u4e00\u5207\u90fd\u662f\u57fa\u4e8e\u5185\u90e8\u7684account\u7684\u4fe1\u606f\u7684\u53d8\u66f4\u800c\u53d8\u66f4\u7684":15,"\u4e00\u822c\u53d614":23,"\u4e00\u822c\u662f\u7ec4\u5408":15,"\u4e0a\u4e0b\u5f71\u7ebf\u6307\u6807":23,"\u4e0a\u5f71\u7ebf":16,"\u4e0a\u6d77\u4e94\u6863\u5373\u6210\u5269\u64a4":24,"\u4e0a\u6d77\u4e94\u6863\u5373\u6210\u8f6c\u9650\u4ef7":24,"\u4e0a\u6d77\u9650\u4ef7\u59d4\u6258":24,"\u4e0b\u4e00\u4e2abar\u7684\u5f00\u76d8\u4ef7\u6210\u4ea4":26,"\u4e0b\u5f71\u7ebf":16,"\u4e0d\u518d\u52a8\u6001\u8ba1\u7b97\u8d26\u6237\u80a1\u7968":15,"\u4e0d\u518d\u8ba1\u7b97\u4ea4\u6613\u5bf9\u7167\u660e\u7ec6\u8868":15,"\u4e0d\u518d\u8ba1\u7b97\u5f53\u524d\u6301\u4ed3":15,"\u4e0d\u518d\u8ba1\u7b97\u603b\u8d44\u4ea7":15,"\u4e0d\u590d\u6743":22,"\u4e0d\u63a8\u8350":26,"\u4e0d\u66f4\u65b0\u53ef\u5356\u6570\u91cf":24,"\u4e0e\u5e02\u573a\u57fa\u51c6\u6536\u76ca\u65e0\u5173\u7684\u8d85\u989d\u6536\u76ca\u7387":15,"\u4e25\u683c\u8ba2\u5355":26,"\u4e2d\u7b7e\u67e5\u8be2":24,"\u4e2d\u7ea7":23,"\u4e2d\u95f4\u8981\u6709\u7a7a\u683c":26,"\u4e34\u65f6\u6263\u9664\u8d44\u4ea7":26,"\u4e3a\u4e86\u662f\u4e0d\u963b\u585e\u8fdb\u7a0b":26,"\u4e3a\u771f\u5b9e\u6ce2\u5e45":23,"\u4e3b\u52a8\u64a4\u5355":26,"\u4e3b\u8425\u5229\u6da6":22,"\u4e3b\u8425\u6210\u672c":22,"\u4e3b\u8425\u6536\u5165":22,"\u4e3b\u8425\u6784\u6210":22,"\u4e3b\u8425\u6784\u6210\u5206\u6790":22,"\u4e3b\u8425\u8303\u56f4":22,"\u4e56\u79bb\u7387":23,"\u4e5f\u53eb\u53d8\u52a8\u901f\u7387\u7ebf":23,"\u4e5f\u53ef\u4ee5\u662f\u7b80\u5199":22,"\u4e70\u5165":26,"\u4e70\u5165\u4fe1\u53f7\u53c2\u8003":23,"\u4e70\u5356\u5224\u65ad\u901a\u8fc7\u4ea4\u6613\u524d\u7f6e\u53d1\u9001\u7ed9\u5bf9\u5e94\u7684broker":17,"\u4e70\u5356\u539f\u5219":23,"\u4ea4\u6613":26,"\u4ea4\u6613\u524d\u7f6e":24,"\u4ea4\u6613\u524d\u7f6e\u4e8b\u4ef6":26,"\u4ea4\u6613\u5386\u53f2":15,"\u4ea4\u6613\u5386\u53f2\u7684tabl":15,"\u4ea4\u6613\u5bf9\u7167\u8868":15,"\u4ea4\u6613\u65e5":26,"\u4ea4\u6613\u72b6\u6001\u8fd4\u56de\u503c":26,"\u4ea4\u6613\u91cf\u8fc7\u5927\u7b49\u7b49":26,"\u4ea7\u54c1":22,"\u4ea7\u751f\u65b0\u7684\u4e70\u5356\u5224\u65ad":17,"\u4ec5\u7528\u4e8e\u8bad\u7ec3\u6d4b\u8bd5":26,"\u4ec5\u8d1f\u8d23\u4e00\u4e2a\u65e0\u72b6\u6001\u7684\u6267\u884c\u5c42":24,"\u4ec5\u9002\u7528\u4e8eseri":23,"\u4ec5\u9650\u56de\u6d4b":26,"\u4eca\u65e5\u632f\u5e45":23,"\u4eca\u65e5\u6700\u4f4e\u4e0e\u6628\u6536\u5dee\u4ef7\u4e2d\u7684\u6700\u5927\u503c":23,"\u4eca\u65e5\u6700\u9ad8\u4e0e\u6628\u6536\u5dee\u4ef7":23,"\u4ece\u800c\u6d4b\u51fa\u80a1\u4ef7\u7684\u9707\u8361\u5e45\u5ea6":23,"\u4ee3\u7801":16,"\u4ee54\u4e2a0\u5f00\u5934":27,"\u4ee5\u514d\u76f4\u63a5\u88ab\u53d8\u6210\u4e86\u65f6\u95f4\u6233":26,"\u4ee5\u53ca\u7ec4\u5408\u7ba1\u7406":15,"\u4f1a\u4ea7\u751f\u591a\u5c11\u7684\u8d85\u989d\u62a5\u916c":17,"\u4f1a\u51fa\u73b0socket":22,"\u4f1a\u521b\u5efa\u4e00\u4e2adownload":22,"\u4f1a\u81ea\u52a8\u53bb\u91cd":19,"\u4f1a\u901a\u77e5market\u4ea4\u6613\u524d\u7f6e":17,"\u4f5c\u4e3a\u4e00\u4e2aview\u5b58\u5728":15,"\u4f73\u5e86\u6307\u6807":23,"\u4f7f\u5f97":27,"\u4f7f\u7528\u6570\u636e\u5e93\u6570\u636e\u8fdb\u884c\u590d\u6743":19,"\u4f7f\u7528\u7f51\u7edc\u4e2d\u6700\u957f\u7684\u94fe":27,"\u4f7f\u7528\u7f51\u7edc\u6570\u636e\u8fdb\u884c\u590d\u6743":19,"\u4f7f\u7528jieba\u5206\u8bcd":26,"\u4f7f\u7528threading\u91cc\u9762\u7684\u5ef6\u65f6":26,"\u4fe1\u606f\u5c06\u52a0\u5165\u5230\u4e0b\u4e00\u4e2a\u5f85\u6316\u7684\u533a\u5757\u4e2d":27,"\u4fe1\u606f\u6bd4\u7387":17,"\u4fe1\u606f\u7c7b":15,"\u503a\u5238":24,"\u504f\u5ea6":15,"\u5141\u8bb8\u65e0\u4ed3\u4f4d\u7684\u65f6\u5019\u5356\u51fa\u8bc1\u5238":24,"\u5143":22,"\u5171\u8bc6\u7b97\u6cd5\u89e3\u51b3\u51b2\u7a81":27,"\u5176\u4e2d":26,"\u5176\u4ed6\u65f6\u5019":26,"\u5176\u4f5c\u7528\u4e0d\u5927":23,"\u5177\u4f53\u8ba1\u7b97\u65b9\u5f0f\u4e3a":17,"\u5177\u4f53\u8ba1\u7b97\u65b9\u6cd5\u4e3a":17,"\u518d\u6839\u636e\u8fd4\u56de\u7684\u4fe1\u606f":24,"\u51c0\u5229\u6da6":15,"\u51fd\u6570\u91cd\u65b0\u83b7\u53d6":22,"\u5206\u5e03\u968f\u673a\u751f\u6210\u884c\u60c5":26,"\u5206\u6790ddi\u67f1\u72b6\u7ebf":23,"\u5206\u949f\u7ebf":[22,26],"\u5206\u949f\u7ebf\u56de\u6d4b\u7684\u65f6\u5019\u7684gap":26,"\u5219\u4f7f\u7528\u7b2c\u4e00\u4e2aportfolio\u6765\u521b\u5efa\u4e00\u4e2aaccount":15,"\u5219\u521b\u5efa\u4e00\u4e2aportfolio":15,"\u521a\u521b\u5efa\u8ba2\u5355\u7684\u65f6\u5019":26,"\u521b\u5efa\u80a1\u7968\u5206\u949f\u7ebf\u7684index":26,"\u521b\u5efa\u80a1\u7968\u7684\u5c0f\u65f6\u7ebf\u7684index":26,"\u521b\u5efa\u8ba2\u5355":26,"\u521d\u59cb\u5316\u8ba2\u5355":26,"\u5224\u65ad\u662f\u5426\u662f\u4ea4\u6613\u65e5":26,"\u5229\u6da6":15,"\u5229\u6da6\u6bd4\u4f8b":22,"\u524d\u590d\u6743":22,"\u5269\u4e0b\u7684\u5168\u90e8\u60f0\u6027\u8ba1\u7b97":15,"\u52a0\u5bc6\u8d27\u5e01\u5e02\u573a":[24,26],"\u52a0\u5bc6\u8d27\u5e01\u5e02\u573a\u4e0d\u5141\u8bb8\u5356\u7a7a":24,"\u52a8\u6001\u4e70\u5356\u6c14\u6307\u6807":23,"\u52a8\u6001\u8ba1\u7b97\u6210\u4ea4\u91cf":26,"\u52a8\u91cf\u7ebf":23,"\u5305\u542b\u96c6\u5408\u7ade\u4ef7":22,"\u533a\u57df":22,"\u5355\u65e5\u6700\u5927\u6301\u4ed3":17,"\u5355\u6b21\u4ea4\u6613\u6536\u76ca":17,"\u5355\u7ebf\u7a0b\u7684\u5b9e\u65f6\u83b7\u53d6":22,"\u5356\u51fa":26,"\u5356\u51fa\u4fe1\u53f7\u53c2\u8003":23,"\u5356\u7a7a\u7684\u89c4\u5219\u662f":24,"\u5361\u739b\u6bd4\u7387":15,"\u5373\u65f6\u66f4\u65b0":24,"\u5373\u65f6\u66f4\u65b0\u6301\u4ed3\u548c\u53ef\u5356":24,"\u5386\u53f2\u9010\u7b14\u6210\u4ea4":22,"\u53bb\u91cd":15,"\u53c2\u6570":23,"\u53c2\u8003\u6807\u51c6\u5e74\u5316\u6536\u76ca":17,"\u53c2\u8003\u6807\u51c6\u6bcf\u65e5\u6536\u76ca":17,"\u53c2\u8003\u6807\u51c6\u6bcf\u65e5\u6536\u76ca\u7684\u65b9\u5dee":17,"\u53ca\u5728bar\u7684\u6536\u76d8\u65f6\u7684\u4ef7\u683c":26,"\u53ca\u65f6\u66f4\u65b0\u53ef\u7528\u8d44\u91d1":24,"\u53cat":16,"\u53cd\u5f39\u673a\u7387\u5927":23,"\u53d1\u9001\u7ed9\u76f8\u5e94\u7684marker_brok":24,"\u53d6\u6570\u636e\u7684\u771f\u5b9e\u533a\u95f4":26,"\u53d8\u52a8\u7387\u6307\u6807":23,"\u53d8\u52a8\u901f\u7387\u7ebf":23,"\u53ea\u7ef4\u62a4":15,"\u53ef\u4ee5\u53bb\u8861\u91cf\u98ce\u9669":15,"\u53ef\u4ee5\u88ab\u4e8b\u4ef6\u9a71\u52a8":15,"\u53ef\u4ee5\u8c03\u6574":15,"\u53ef\u5356":17,"\u53ef\u5356\u80a1\u4efd":26,"\u53ef\u5356\u80a1\u7968":15,"\u53ef\u64a4\u5355":24,"\u53ef\u7528\u73b0\u91d1":[15,26],"\u53ef\u7528\u73b0\u91d1\u7b49":17,"\u53ef\u7528\u7684market_brok":24,"\u53ef\u7533\u8d2d\u65b0\u80a1\u67e5\u8be2":24,"\u53ef\u878d\u8bc1\u5238":24,"\u53ef\u8fde\u63a5\u5230\u591a\u4e2abroker\u4e2d":24,"\u53ef\u9009":26,"\u540c\u65f6\u53d1\u8fdb\u53bb\u4e24\u4e2a\u51fd\u6570":26,"\u540c\u6b65\u53ef\u7528\u8d44\u91d1":15,"\u540e\u590d\u6743":22,"\u5411\u540e\u63a8":26,"\u5426\u5219\u4e3afals":27,"\u5426\u5219\u8fd4\u56de0\u7684n\u65e5\u7d2f\u548c":23,"\u548c\u6628\u6536":23,"\u548cdate":26,"\u56de\u6863\u673a\u7387\u5927":23,"\u56de\u6d4b":[15,24,26],"\u56de\u6d4b\u4ea4\u6613\u65e5\u6570\u91cf":17,"\u56de\u6d4b\u53bb\u8ba1\u7b97\u8fd9\u6bb5\u65f6\u95f4\u7684\u5404\u4e2a\u8d26\u6237\u6536\u76ca":17,"\u56de\u6d4b\u76d8":24,"\u56de\u6d4b\u8d77\u59cb\u4ea4\u6613\u65e5\u7684\u65e0\u98ce\u9669\u5229\u7387":17,"\u56e0\u4e3a\u6709\u65f6\u5019\u5728csv\u7b49\u8f6c\u6362\u7684\u65f6\u5019":26,"\u5728\u5b9e\u76d8\u4e2d":24,"\u5728\u62ff\u5230\u5e02\u573a\u6570\u636e\u540e\u5bf9\u4e8e\u8ba2\u5355\u7684\u64ae\u5408\u5224\u65ad":24,"\u5728portfolio\u4e2d":15,"\u5730\u57df":19,"\u57fa\u51c6\u7ec4\u5408\u7684\u5e74\u5316\u6536\u76ca":15,"\u57fa\u51c6\u7ec4\u5408\u7684\u6536\u76ca\u767e\u5206\u6bd4\u8ba1\u7b97":15,"\u57fa\u51c6\u7ec4\u5408\u7684\u884c\u60c5\u6570\u636e":15,"\u57fa\u51c6\u7ec4\u5408\u7684\u8d26\u6237\u8d44\u4ea7\u961f\u5217":15,"\u57fa\u91d1":[24,26],"\u590f\u666e\u6bd4\u4f8b":15,"\u590f\u666e\u6bd4\u7387":[15,17],"\u591a\u5934\u5e73\u65e7\u4ed3":26,"\u591a\u5e73":26,"\u591a\u5f00":26,"\u591a\u7a7a\u6307\u6807":23,"\u591a\u7ebf\u7a0b":24,"\u591a\u8d26\u6237":15,"\u5927\u76d8\u84dd\u7b79":22,"\u5927\u90e8\u5206\u65f6\u95f4\u90fd\u4f9d\u8d56\u5b50\u7ebf\u7a0b\u4e3b\u52a8\u67e5\u8be2":24,"\u5929\u6570":23,"\u5982\u679c\u51fa\u73b0\u7f51\u7edc\u95ee\u9898":22,"\u5982\u679c\u51fa\u9519\u6bd4\u5982\u53ea\u83b7\u53d6\u4e86\u4e00\u5929":22,"\u5982\u679c\u5df2\u6709\u4e00\u4e2a\u6216\u591a\u4e2aportfolio":15,"\u5982\u679c\u5f53\u524duser\u4e2d\u6ca1\u6709\u521b\u5efaportfolio":15,"\u5982\u679c\u8fdc\u79bb\u5e73\u5747\u7ebf":23,"\u5982\u679c\u94fe\u88ab\u53d6\u4ee3\u8fd4\u56de":27,"\u5982\u679c\u9700\u8981\u521b\u5efa\u4e00\u4e2a":26,"\u5982\u679ctyp":23,"\u59d4\u6258\u6210\u529f":26,"\u5a01\u5ec9\u6307\u6807":23,"\u5a01\u5ec9sma\u7b97\u6cd5":23,"\u5b83\u53cd\u5e94\u5f53\u65e5\u6536\u76d8\u4ef7\u4e0e\u4e00\u6bb5\u65f6\u95f4\u5185\u5e73\u5747\u6536\u76d8\u4ef7\u7684\u5dee\u79bb\u503c":23,"\u5b8c\u5168\u4ea4\u6613":26,"\u5b8c\u5168\u6210\u4ea4":26,"\u5b9a\u4e49\u4e00\u4e9b\u53ef\u4ee5\u6269\u5c55\u7684\u6570\u636e\u7ed3\u6784":19,"\u5b9a\u70b9\u524d\u590d\u6743":22,"\u5b9a\u70b9\u540e\u590d\u6743":22,"\u5b9e\u4f53\u90e8\u5206":16,"\u5b9e\u65f6\u6a21\u62df\u76d8":24,"\u5b9e\u65f6\u9010\u7b14\u6210\u4ea4":22,"\u5b9e\u76d8":[15,24,26],"\u5b9e\u76d8\u91cc\u9762\u662f\u4e94\u6863\u5269\u4f59\u6700\u4f18\u6210\u4ea4\u4ef7":26,"\u5bf9\u4e8e\u4e0d\u540c\u7684\u5e02\u573a\u89c4\u5219":24,"\u5bf9\u4e8eaccount\u7684\u6307\u6807":15,"\u5bf9\u4e8edataframe\u7684\u5e94\u7528\u8bf7\u4f7f\u7528qa_indicator_macd":23,"\u5bf9\u4e8eportfolio\u800c\u8a00":15,"\u5bf9order":24,"\u5c06\u6240\u6709\u6caa\u6df1\u80a1\u7968\u4ece\u6570\u5b57\u8f6c\u5316\u52306\u4f4d\u7684\u4ee3\u7801":26,"\u5c06\u8f93\u5165\u7684\u8bed\u53e5\u5206\u8bcd":26,"\u5c06list\u4fdd\u5b58\u6210csv":26,"\u5c0f\u76d8\u80a1":22,"\u5c1d\u8bd5\u518d\u6b21\u83b7\u53d6":22,"\u5c31\u5f88\u53ef\u80fd\u5411\u5e73\u5747\u7ebf\u56de\u5f52":23,"\u5c3e\u657001":26,"\u5c3e\u657002":26,"\u5c3e\u657003":26,"\u5c55\u793adatastruct":19,"\u5c5e\u4e8e\u8d85\u4e70\u8d85\u5356\u7c7b\u6307\u6807":23,"\u5cf0\u5ea6\u7b49":15,"\u5df2\u64a4\u5355":26,"\u5e02\u4ef7\u5355":26,"\u5e02\u4ef7\u59d4\u6258":24,"\u5e02\u573a":[22,26],"\u5e02\u573a\u4e0d\u4f1a\u8fd4\u56de\u4e00\u4e2a\u66f4\u65b0\u7684\u8ba2\u5355\u7c7b\u56de\u6765":24,"\u5e02\u573a\u79cd\u7c7b":26,"\u5e03\u6797\u7ebf":23,"\u5e73\u5747\u76c8\u4e8f\u6bd4":15,"\u5e73\u5747\u7ebf\u5dee":23,"\u5e73\u5747\u7edd\u5bf9\u504f\u5dee":23,"\u5e74\u5316\u6536\u76ca":15,"\u5e74\u5316\u6807\u51c6\u5dee":17,"\u5e76\u4e14\u7acb\u523b\u7ed3\u8f6c":16,"\u5e76\u5c06\u5176\u63d2\u5165\u4ed6\u5df2\u6709\u7684\u6570\u636e\u4e2d":17,"\u5e76\u7528\u6b64portfolio\u521b\u5efa\u4e00\u4e2aaccount":15,"\u5e76\u7ed9\u51fa\u7efc\u5408\u7684\u6700\u7ec8\u7ed3\u679c":17,"\u5e95\u4e0b\u6ce8\u518c\u7684\u7b56\u7565strategy\u6839\u636e\u65b0\u7684\u5e02\u573a\u51fd\u6570":17,"\u5f00\u59cb\u65e5\u671f":22,"\u5f15\u5165\u65f6\u95f4\u8f74\u73af\u5883":17,"\u5f15\u64ce\u4e8b\u4ef6":26,"\u5f3a\u529b\u538b\u529b":23,"\u5f3a\u529b\u652f\u6491":23,"\u5f52\u5c5e\u4e8emarket\u524d\u7f6e":24,"\u5f53\u4e00\u4e2a\u8ba2\u5355\u53d1\u9001\u51fa\u53bb\u7684\u65f6\u5019":24,"\u5f53\u524dbar\u7684\u6700\u4f4e\u4ef7\u5356\u51fa":26,"\u5f53\u5929\u65e0\u4ea4\u6613\u6570\u636e":26,"\u5f53\u6211\u4eec\u53ea\u6709\u4e00\u4e2a\u6210\u4ea4\u8bb0\u5f55\u7684\u65f6\u5019":16,"\u5f53\u65e5\u4e4b\u524d\u865a\u62df\u8d26\u6237\u6700\u9ad8\u4ef7\u503c":17,"\u5f53\u65e5\u4e70\u5165":24,"\u5f53\u65e5\u5356\u51fa":24,"\u5f53\u65e5\u59d4\u6258":24,"\u5f53\u65e5\u6210\u4ea4":24,"\u5f53\u65e5\u7684\u4e70\u5165":24,"\u5f53\u65e5\u7684\u5356\u51fa":24,"\u5f53start":26,"\u5f97\u5230\u4e0a\u4e00\u4e2a":26,"\u5f97\u5230\u4e0b\u4e00\u4e2a":26,"\u603b\u4e8f\u635f":15,"\u603b\u76c8\u5229":15,"\u6062\u590d\u4e34\u65f6\u8d44\u4ea7":26,"\u60f0\u6027\u8ba1\u7b97":15,"\u6210\u4ea4\u91cf":23,"\u6210\u529f\u4ea4\u6613":26,"\u6210\u672c\u6bd4\u4f8b":22,"\u6211\u4eec\u4f1a\u521b\u5efa\u4e00\u4e2a\u8d26\u6237\u5355\u5143":16,"\u6211\u4eec\u5e0c\u671b\u901a\u8fc7cookie\u6765\u63a7\u5236account_unit":15,"\u6216\u8005\u662f\u4e00\u4e2a\u5e02\u573a\u4fe1\u606f\u6765\u8fdb\u884c\u5224\u65ad":24,"\u6240\u6709\u6210\u4ea4\u8bb0\u5f55\u5206\u6790":16,"\u624b":23,"\u6253\u5370\u51faaccount\u7684\u5185\u5bb9":15,"\u6267\u884c\u73af\u5883":26,"\u6279\u91cf\u4ea4\u6613":24,"\u6295\u8d44\u7ec4\u5408\u6536\u76ca\u548c\u4e0b\u884c\u98ce\u9669\u6bd4\u503c":15,"\u62ff\u5230\u6574\u4e2aportfolio\u7684\u53ef\u7528\u8d44\u91d1":15,"\u6301\u4ed3":15,"\u6301\u4ed3\u5206\u6790":15,"\u6301\u4ed3\u65f6\u95f4\u5360\u6bd4":15,"\u6301\u4ed3\u9762\u677f":15,"\u6307\u6570":[15,19,24,26],"\u6307\u6570\u5206\u949f\u7ebf":22,"\u6307\u6570\u5e73\u5747\u7ebf":23,"\u6307\u6570\u65e5\u7ebf":22,"\u6307\u6807":23,"\u6307\u6807\u8bf4\u660e":23,"\u6309\u56fa\u5b9a\u6210\u5bb6\u91cf\u4e0b\u5355":26,"\u6309\u5e02\u503c\u548c\u4fdd\u8bc1\u91d1\u6bd4\u4f8b\u9650\u5236\u7b97":24,"\u6309\u7167\u79fb\u52a8\u5e73\u5747\u7ebf\u539f\u7406":23,"\u6309\u7b97\u6cd5":26,"\u6309bar\u957f\u5ea6\u63a8\u7b97\u6570\u636e":22,"\u63a5\u53d7\u4ea4\u6613\u7ed3\u679c\u6570\u636e":15,"\u63a5\u6536\u65b0\u7684\u6570\u636e":15,"\u63cf\u8ff0\u7b56\u7565\u53ef\u80fd\u51fa\u73b0\u7684\u6700\u7cdf\u7cd5\u7684\u60c5\u51b5":17,"\u64a4\u5355":26,"\u64ae\u5408\u6210\u4ea4\u7684\u4efb\u52a1":26,"\u6536\u5165\u6bd4\u4f8bcbbl":22,"\u6536\u76ca":17,"\u6536\u76ca\u6027\u7684\u5305\u62ec\u5e74\u5316\u6536\u76ca\u7387":15,"\u6536\u76d8\u4ef7":23,"\u6536\u76d8\u5355":26,"\u6570\u636e\u5e93":22,"\u6570\u636e\u6765\u6e90":26,"\u6570\u636e\u683c\u5f0f\u6700\u597d\u662f":26,"\u6587\u4ef6\u5939":22,"\u6587\u4ef6\u7684\u5730\u5740":25,"\u6587\u672c\u5206\u8bcd":26,"\u65b0\u80a1\u7533\u8d2d\u989d\u5ea6\u67e5\u8be2":24,"\u65b9\u4fbf\u5e8f\u5217\u5316":19,"\u65b9\u5411\u6807\u51c6\u79bb\u5dee\u6307\u6570":23,"\u65b9\u6cd5":15,"\u65e0\u98ce\u9669\u6536\u76ca":17,"\u65e5\u671f\u5411\u524d\u8fed\u4ee3":26,"\u65e5\u671f\u5411\u540e\u8fed\u4ee3":26,"\u65e5\u671f\u662f\u5426\u4ea4\u6613":26,"\u65e5\u7ebf":[22,26],"\u65f6":23,"\u65f6\u95f4":16,"\u65f6\u95f4\u662f\u5426\u4ea4\u6613":26,"\u660e\u65e5\u6da8\u505c\u4ef7":19,"\u660e\u65e5\u8dcc\u505c\u4ef7":19,"\u662f\u4e00\u4e2a\u5355\u72ec\u7684code":22,"\u662f\u4e00\u4e2a\u98ce\u9669\u63d2\u4ef6":15,"\u662f\u4e0a\u4e00\u4e2a\u5757\u7684\u8bc1\u660e":27,"\u662f\u4ece\u79fb\u52a8\u5e73\u5747\u7ebf\u539f\u7406\u6d3e\u751f\u51fa\u6765\u7684\u4e00\u79cd\u5206\u6790\u6307\u6807":23,"\u662f\u5426\u5141\u8bb8\u5356\u7a7a":15,"\u662f\u5426\u5141\u8bb8t0\u7ed3\u7b97":15,"\u662f\u5426hash":27,"\u662f\u5728\u5f53\u524dbar\u7684\u6700\u9ad8\u4ef7\u4e70\u5165":26,"\u662f\u5f53\u524d\u7684\u8bc1\u660e":27,"\u662fquantaxis\u7684\u6700\u5c0f\u4e0d\u53ef\u5206\u5272\u5355\u5143\u4e4b\u4e00":15,"\u6682\u65f6\u8fd8\u662f\u91c7\u7528\u591a\u7ebf\u7a0bengine\u6a21\u5f0f":24,"\u66f4\u6362ip\u5373\u53ef":22,"\u66f4\u65b0\u6301\u4ed3":[17,24],"\u6700\u4f4e\u4ef7":23,"\u6700\u4f4e\u4ef7\u7684\u7edd\u5bf9\u503c\u7684\u8f83\u5927\u503c":23,"\u6700\u5927\u56de\u64a4":[15,17],"\u6700\u5927\u56de\u64a4\u6bd4\u4f8b":15,"\u6700\u5927\u8fde\u7eed\u4e8f\u635f\u6b21\u6570":15,"\u6700\u5927\u8fde\u7eed\u76c8\u5229\u6b21\u6570":15,"\u6700\u65b0\u603b\u8d44\u4ea7":15,"\u6700\u65b0\u6301\u4ed3":15,"\u6700\u65b0\u73b0\u91d1":15,"\u6700\u9ad8\u4ef7":23,"\u6700\u9ad8\u4ef7\u7684\u7edd\u5bf9\u503c\u7684\u8f83\u5927\u503c\u548c\u6628\u6536":23,"\u6709\u4e09\u7c7b\u8f93\u5165":15,"\u6709\u52a0\u8f7d\u6570\u636e\u7684\u4efb\u52a1":26,"\u6709\u6548\u5e74\u5316\u6536\u76ca\u7387":15,"\u6709\u65b0\u7684\u5e02\u573a\u6570\u636e":17,"\u6709\u65f6\u5019":26,"\u670d\u52a1\u5668\u62d2\u7edd":22,"\u670d\u52a1\u5668\u64a4\u5355":26,"\u671f\u6743":24,"\u671f\u6743\u5e02\u573a\u5141\u8bb8\u5356\u7a7a":24,"\u671f\u8d27":[15,24,26],"\u671f\u8d27\u4ee3\u7801list":22,"\u671f\u8d27\u5386\u53f2\u6210\u4ea4\u5206\u7b14":22,"\u671f\u8d27\u5b9e\u65f6\u4ef7\u683c":22,"\u671f\u8d27\u5e02\u503c":15,"\u671f\u8d27\u6570\u636e":22,"\u672a\u5b8c\u5168\u4ea4\u6613":26,"\u672a\u5b8c\u5168\u6210\u529f":26,"\u672a\u6210\u4ea4":26,"\u672c\u51fd\u6570\u4e0d\u505a\u5904\u7406":22,"\u672c\u6b21\u4fee\u6b63\u4e3b\u8981\u662f\u5bf9\u4e8e\u8fd4\u56de\u503c\u7684\u4f18\u5316":23,"\u6765\u6e90":22,"\u677f\u5757\u6570\u636e":22,"\u67e5\u627e\u4e00\u4e2a":27,"\u67e5\u8be2\u7684\u7ea7\u522b":26,"\u6807\u51c6\u683c\u5f0f\u662fnumpi":24,"\u6839\u636eosc\u7684\u503c\u53ef\u63a8\u65ad\u4ef7\u683c\u7684\u8d8b\u52bf":23,"\u6982\u5ff5":19,"\u6a21\u62df":26,"\u6a21\u7cca\u67e5\u8be2":26,"\u6b21\u6570\u7684\u9891\u6b21\u76f4\u65b9\u56fe":17,"\u6b21\u65b0\u80a1":22,"\u6b63\u5219\u5339\u914d":26,"\u6b63\u53d8\u8d1f":23,"\u6b7b\u4ea1":26,"\u6bcf\u65e5\u4ea4\u6613\u7ed3\u7b97\u65f6\u7684\u6301\u4ed3\u8868":15,"\u6bcf\u65e5\u4ea4\u6613\u7ed3\u7b97\u65f6\u7684\u73b0\u91d1\u8868":15,"\u6bcf\u65e5\u7ed3\u7b97":26,"\u6bcf\u6b21\u4ea4\u6613\u7684pivot\u8868":15,"\u6bd4\u5982":22,"\u6bd4\u598230\u5206\u523059\u5206":26,"\u6bd4\u5982\u4e70\u5356\u4ef7\u683c\u8d85\u8fc7\u6da8\u8dcc\u505c\u4ef7\u683c\u8303\u56f4":26,"\u6bd4\u5982\u65e9\u4e0a9\u70b9\u523011\u70b9":26,"\u6bd4\u5982\u8bf4":26,"\u6bd4\u7279\u5e01":26,"\u6bdb\u5229\u7387":22,"\u6c42\u771f\u5b9e\u6ce2\u5e45\u7684n\u65e5\u79fb\u52a8\u5e73\u5747":23,"\u6ce2\u52a8\u7387":15,"\u6da8\u505c\u4ef7":19,"\u6da8\u8dcc\u505c\u9650\u5236":26,"\u6df1\u5733\u4e94\u6863\u5373\u6210\u5269\u64a4":24,"\u6df1\u5733\u5168\u989d\u6210\u4ea4\u6216\u64a4\u9500":24,"\u6df1\u5733\u5373\u65f6\u6210\u4ea4\u5269\u4f59\u64a4\u9500":24,"\u6df1\u5733\u5bf9\u65b9\u6700\u4f18\u4ef7\u683c":24,"\u6df1\u5733\u672c\u65b9\u6700\u4f18\u4ef7\u683c":24,"\u6df1\u5733\u9650\u4ef7\u59d4\u6258":24,"\u6e05\u7a7a\u8ba2\u5355\u7c3f":24,"\u6e2f\u80a1":26,"\u7011\u5e03\u7ebf":23,"\u7136\u540e\u6309\u751f\u6210\u5668\u5c06\u6570\u636e\u8fed\u4ee3\u63d2\u5165\u56de\u6d4b\u7684broker":17,"\u73b0\u5728\u7684\u8fd4\u56de\u503c\u4f1a\u5e26\u4e0a\u539f\u5148\u8f93\u5165\u7684\u7d22\u5f15index":23,"\u73b0\u91d1":15,"\u73b0\u91d1\u7684tabl":15,"\u751f\u6210\u5757\u7684":27,"\u751f\u6210\u6210\u4ea4\u4fe1\u606f":24,"\u751f\u6210\u65b0\u4ea4\u6613\u4fe1\u606f":27,"\u751f\u6210\u65b0\u5757":27,"\u751f\u6210\u8ba2\u5355":15,"\u751f\u6210account\u968f\u673a\u503c":26,"\u7528\u4e8e\u5408\u5e76\u4e00\u4e2alist\u91cc\u9762\u7684\u591a\u4e2adatastruct":19,"\u7528\u4e8e\u63a5\u53d7\u8ba2\u5355":24,"\u7528\u4e8e\u66f4\u65b0\u8d26\u6237":15,"\u7528\u6765\u6d4b\u91cf\u8d44\u4ea7\u7684\u98ce\u9669\u6027":17,"\u7528account\u7684cookie\u6765\u7ba1\u7406\u63a7\u5236account":15,"\u7528set":15,"\u7528sleep\u5c31\u4f1a\u963b\u585e\u6389\u7b2c\u4e8c\u4e2a\u8fdb\u7a0b":26,"\u7531\u7ea2\u53d8\u7eff":23,"\u7531\u7eff\u53d8\u7ea2":23,"\u7684\u4ea4\u6613\u5165\u53e3":16,"\u7684\u5e74\u5316\u5747\u503c":17,"\u76d8\u524d":22,"\u76ee\u524d\u5e02\u4ef7\u5355\u5728\u56de\u6d4b\u4e2d\u662fbar\u7684\u5f00\u76d8\u4ef7":26,"\u76f8\u4e92\u8f6c\u6362":19,"\u76f8\u5bf9\u5f3a\u5f31\u6307\u6807rsi1":23,"\u7a7a\u5934\u5e73\u65e7\u4ed3":26,"\u7a7a\u5e73":26,"\u7a7a\u5f00":26,"\u7b2c\u4e00\u4e2a\u51fd\u6570\u9700\u8981\u5ef6\u65f6":26,"\u7b2c\u4e00\u4e2a\u53c2\u6570\u662flist":26,"\u7b2c\u4e09\u4e2a\u53c2\u6570\u662f\u884c\u7684\u540d\u79f0":26,"\u7b2c\u4e09\u4e2a\u53c2\u6570towards\u662f\u8868\u793a\u5411\u524d":26,"\u7b2c\u4e8c\u4e2a\u4e0d\u9700\u8981\u7684\u8bdd":26,"\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u8981\u4fdd\u5b58\u7684\u540d\u5b57":26,"\u7b2c\u56db\u4e2a\u662f\u4fdd\u5b58\u4f4d\u7f6e":26,"\u7b49\u5f85\u4ea4\u6613":26,"\u7b56\u7565\u521d\u59cb\u4ef7\u503c":17,"\u7b56\u7565\u5e74\u5316\u6536\u76ca":17,"\u7b56\u7565\u5e74\u5316\u6536\u76ca\u7387":17,"\u7b56\u7565\u5f53\u65e5\u4ef7\u503c":17,"\u7b56\u7565\u6536\u76ca\u6ce2\u52a8\u7387":17,"\u7b56\u7565\u6700\u7ec8\u4ef7\u503c":17,"\u7b56\u7565\u6bcf\u65e5\u6536\u76ca":17,"\u7b56\u7565\u6bcf\u65e5\u6536\u76ca\u4e0e\u53c2\u8003\u6807\u51c6\u6bcf\u65e5\u6536\u76ca\u7684\u534f\u65b9\u5dee":17,"\u7b56\u7565\u6bcf\u65e5\u6536\u76ca\u7684\u5e74\u5316\u6807\u51c6\u5dee":17,"\u7b80\u5355\u7684\u5de5\u4f5c\u91cf\u8bc1\u660e":27,"\u7b97\u6cd5":23,"\u7b97\u9996\u5c3e":26,"\u7c7b\u4f3c\u4e8epd":19,"\u7d22\u63d0\u8bfa\u6bd4\u7387":15,"\u7ea6\u5b9a\u65f6\u95f4\u7684\u8303\u56f4":26,"\u7ec4\u5408\u6210\u6700\u4f18\u7684\u6295\u8d44\u7ec4\u5408\u7684\u91cf":15,"\u7ec4\u5408\u7684\u7cfb\u7edf\u6027\u98ce\u9669":15,"\u7ecf\u8425\u8bc4\u8ff0":22,"\u7ed3\u675f\u65e5\u671f":22,"\u7ed3\u675f\u8fd9\u4e00\u4e2abar\u7684\u6240\u6709\u4ea4\u6613":17,"\u7ed3\u7b97":24,"\u7ed9\u51fa\u4ea4\u6613\u5177\u4f53\u65f6\u95f4":26,"\u7edf\u8ba1\u6bcf\u4e00\u4e2a\u65f6\u95f4\u70b9\u7684\u65f6\u5019\u7684cash\u603b\u548c":15,"\u7efc\u5408\u6027\u6307\u6807\u4e3b\u8981\u5305\u62ec\u98ce\u9669\u6536\u76ca\u6bd4":15,"\u7efc\u5408\u751f\u6210\u4fe1\u53f7":17,"\u7f13\u5b58\u65b0\u6570\u636e\u7684market_data":15,"\u7f8e\u80a1":26,"\u800c\u5f53\u5929\u505c\u724c":22,"\u8017\u65f6\u957f\u5ea6\u7684\u88c5\u9970\u5668":26,"\u80a1\u4e1c\u4ee3\u7801":24,"\u80a1\u4efd":24,"\u80a1\u7968":[24,26],"\u80a1\u7968\u4ee3\u7801":19,"\u80a1\u7968\u57fa\u672c\u4fe1\u606f":22,"\u80a1\u7968\u5e02\u573a":24,"\u80a1\u7968\u7684\u4ee3\u7801":22,"\u80fd\u91cf\u6f6e":23,"\u81ea\u5b9a\u4e49\u7684\u5206\u949f\u7ebf\u6570\u636e\u7ed3\u6784":19,"\u81ea\u5b9a\u4e49\u7684\u65e5\u7ebf\u6570\u636e\u7ed3\u6784":19,"\u83b7\u53d6\u4e86\u65b0\u7684\u5e02\u573a\u51fd\u6570":17,"\u83b7\u53d6\u4ea4\u6613\u65e5\u671f":22,"\u83b7\u53d6\u5168\u5e02\u573a\u7684\u67d0\u4e00\u65e5\u7684\u6570\u636e":22,"\u83b7\u53d6\u5168\u90e8\u5b9e\u65f65\u6863\u884c\u60c5\u7684\u5b58\u50a8\u7ed3\u679c":22,"\u83b7\u53d6\u5168\u90e8\u7684\u6570\u636e":17,"\u83b7\u53d6\u591a\u4e2a\u80a1\u7968\u7684\u65e5\u7ebf":22,"\u83b7\u53d6\u6307\u6570\u65e5\u7ebf":22,"\u83b7\u53d6\u65e5\u7ebf\u53ca\u4ee5\u4e0a\u7ea7\u522b\u7684\u6570\u636e":22,"\u83b7\u53d6\u677f\u5757":19,"\u83b7\u53d6\u67d0\u4e00\u53ea\u5b9e\u65f65\u6863\u884c\u60c5\u7684\u5b58\u50a8\u7ed3\u679c":22,"\u83b7\u53d6\u67d0\u4e00\u53ea\u80a1\u7968\u7684\u677f\u5757":19,"\u83b7\u53d6\u771f\u5b9e\u7684\u4ea4\u6613\u65e5\u671f":26,"\u83b7\u53d6\u80a1\u7968\u5206\u949f\u7ebf":22,"\u83b7\u53d6\u80a1\u7968\u5217\u8868":22,"\u83b7\u53d6\u80a1\u7968\u65e5\u7ebf":22,"\u83b7\u53d6\u80a1\u7968\u9664\u6743\u4fe1\u606f":22,"\u878d\u5238\u4f59\u989d":24,"\u878d\u8d44\u4f59\u989d":24,"\u878d\u8d44\u878d\u5238\u6807\u7684":22,"\u884c\u4e1a":22,"\u884c\u60c5\u5206\u6790\u5668":16,"\u8861\u91cf\u8d85\u989d\u98ce\u9669\u5e26\u6765\u7684\u8d85\u989d\u6536\u76ca":17,"\u8868\u793a\u6295\u8d44\u671f\u9650\u4e3a\u4e00\u5e74\u7684\u9884\u671f\u6536\u76ca\u7387":17,"\u8868\u793a\u6bcf\u627f\u53d7\u4e00\u5355\u4f4d\u603b\u98ce\u9669":17,"\u8868\u8fbe\u6301\u7eed\u6027":23,"\u88c5\u9970\u5668\u7684\u5ef6\u65f6\u51fd\u6570":26,"\u8981":26,"\u8981\u8fdb\u884c\u98ce\u9669\u63a7\u5236":15,"\u89c2\u5bdf\u4e1a\u7ee9\u7b49\u7b49":15,"\u89c4\u5219\u7c7b":15,"\u89c6\u4e3a\u4e70\u8fdb\u4fe1\u53f7\u53c2\u8003":23,"\u89c6\u4e3a\u5356\u51fa\u4fe1\u53f7\u53c2\u8003":23,"\u89e3\u6790\u76ee\u5f55\u4e0b\u7684\u6240\u6709\u6587\u4ef6":22,"\u8ba1\u7b97\u4e0a\u4e0b\u5f71\u7ebf":16,"\u8ba1\u7b97\u4ea4\u6613\u65e5\u671f":17,"\u8ba1\u7b97\u590f\u666e\u6bd4\u7387":[15,17],"\u8ba1\u7b97\u6240\u6709\u7684\u6307\u6807":16,"\u8ba2\u5355\u4e8b\u4ef6":26,"\u8ba2\u5355\u5931\u8d25":26,"\u8ba2\u5355\u5b58\u6d3b":26,"\u8ba2\u5355\u5b8c\u5168\u4ea4\u6613":26,"\u8ba2\u5355\u5f85\u751f\u6210":26,"\u8ba2\u5355\u6b7b\u4ea1":26,"\u8ba2\u5355\u72b6\u6001":26,"\u8ba2\u5355\u751f\u6210":26,"\u8ba2\u5355\u7684\u4e70\u5356\u65b9\u5411":26,"\u8ba2\u5355\u7684\u6210\u4ea4\u6a21\u5f0f":26,"\u8ba2\u5355\u7684\u6210\u4ea4\u91cf":26,"\u8bc1\u5238":22,"\u8be5\u6587\u4ef6\u4e3b\u8981\u662f\u8d1f\u8d23\u4e00\u4e9b\u5bf9\u4e8ecode\u540d\u79f0\u7684\u5904\u7406":26,"\u8be5\u8d26\u6237\u66fe\u4ea4\u6613\u4ee3\u7801":15,"\u8bf8\u5982":26,"\u8d1d\u5854":[15,17],"\u8d26\u6237\u4e5f\u8fdb\u884c\u6e05\u7b97":17,"\u8d26\u6237\u4e8b\u4ef6":26,"\u8d26\u6237\u7684\u6210\u4ea4\u53d1\u751f\u5f02\u5e38\u6210\u4ea4\u8bb0\u5f55\u7684\u5206\u6790":15,"\u8d26\u6237\u7684\u7528\u6237\u540d":15,"\u8d26\u6237\u7684broker":15,"\u8d26\u6237\u7c7b\u522b":15,"\u8d26\u6237\u7ed1\u5b9a\u7684\u7b56\u7565\u540d":15,"\u8d26\u6237\u8bc6\u522b\u7801":15,"\u8d27\u5e01\u79cd\u7c7b":26,"\u8d44\u4ea7\u7c7b":15,"\u8d44\u91d1":24,"\u8d44\u91d1\u4f7f\u7528\u7387":15,"\u8d44\u91d1\u51bb\u7ed3":24,"\u8d44\u91d1\u6307\u6807":23,"\u8d44\u91d1\u7684\u5206\u914d":15,"\u8d4b\u503c":23,"\u8d8b\u5411\u6307\u6807":23,"\u8dcc\u505c\u4ef7":19,"\u8f6c\u878d\u5238\u6807\u7684":22,"\u8f93\u5165\u4e00\u4e2adict":26,"\u8f93\u5165\u7684\u662f\u4e00\u4e2a\u884c\u60c5\u5207\u7247":16,"\u8f93\u51fa\u683c\u5f0f":26,"\u8f93\u51fa\u771f\u5b9e\u6ce2\u5e45":23,"\u8f93\u51fa\u7c7b\u578b":22,"\u8f93\u51fa\u8d44\u91d1\u6d41\u91cf\u6307\u6807":23,"\u8f93\u51fatr":23,"\u8fd4\u56de\u5168\u5e02\u573a\u67d0\u4e00\u5929\u7684\u6570\u636e":22,"\u8fd4\u56de\u5220\u9664\u540e\u7684":26,"\u8fd4\u56de\u552f\u4e00\u7684\u8bc1\u5238\u4ee3\u7801":19,"\u8fd4\u56de\u5728trade_list\u4e2d\u7684index\u4f4d\u7f6e":26,"\u8fd4\u56de\u5f53\u65e5\u7684\u4e0a\u4e0b\u4e94\u6863":22,"\u8fd4\u56de\u6240\u6709\u7684\u677f\u5757\u540d":19,"\u8fd4\u56de\u677f\u5757":22,"\u8fd4\u56de\u7684\u65f6\u5019\u7528":26,"\u8fd4\u56de\u7684\u662fdatafram":22,"\u8fd4\u56de\u7684\u90fd\u662f":26,"\u8fd4\u56dedatastruct\u7684\u957f\u5ea6":19,"\u8fd4\u56denone":[22,26],"\u8fd4\u56destart_day\u5230end_day\u4e2d\u95f4\u6709\u591a\u5c11\u4e2a\u4ea4\u6613\u5929":26,"\u8fd4\u56detyp":23,"\u8fd9\u4e00\u4e2a\u8fc7\u7a0b\u662f\u6a21\u62df\u5728\u771f\u5b9e\u60c5\u51b5\u4e2d\u5e02\u573a\u7684\u65f6\u95f4\u53d8\u5316\u548c\u4ef7\u683c\u53d8\u5316":17,"\u8fd9\u4e2a\u662f\u4ece\u6570\u636e\u5e93\u6062\u590d\u8d26\u6237\u65f6\u9700\u8981\u7684":15,"\u8fd9\u4e2a\u89c6\u56fe\u4f5c\u4e3a\u4e00\u4e2a\u9759\u6001\u7684\u89c2\u5bdf\u70b9":15,"\u8fd9\u662f\u4e00\u4e2a\u4e00\u5b9a\u4f1a\u6210\u4ea4":16,"\u8fd9\u662f\u4e00\u4e2a\u7528\u4e8e\u590d\u7528":26,"\u8fd9\u662f\u4e00\u4e2a\u968f\u610f\u65b0\u5efa\u7ebf\u7a0b\u7684\u751f\u4ea7\u8005\u6d88\u8d39\u8005\u6a21\u578b":21,"\u8fd9\u91cc\u4e3b\u8981\u662f\u4e00\u4e9b\u5173\u4e8e\u6587\u672c\u7684\u4ee3\u7801":26,"\u8fd9\u91cc\u5b9a\u4e49\u7684\u662f\u4e00\u4e9b\u5e38\u7528\u5e38\u91cf":26,"\u8fd9\u91cc\u7684\u65e0\u98ce\u9669\u6536\u76ca\u6307\u7684\u662f\u4e2d\u56fd\u56fa\u5b9a\u5229\u7387\u56fd\u503a\u6536\u76ca\u7387\u66f2\u7ebf\u4e0a10\u5e74\u671f\u56fd\u503a\u7684\u5e74\u5316\u5230\u671f\u6536\u76ca\u7387":17,"\u8fd9\u91cc\u9762\u90fd\u662f\u5bf9\u4e8e\u65b9\u6cd5\u7684\u5c01\u88c5":24,"\u8fdb\u5165\u5f85\u6210\u4ea4\u961f\u5217":26,"\u8fdb\u884c\u4ea4\u6613":17,"\u8fdb\u884c\u66f4\u65b0":24,"\u8fdb\u884c\u6e05\u7b97":17,"\u8fdb\u884c\u8f6c\u6362":26,"\u8fed\u4ee3\u5faa\u73af\u76f4\u81f3\u7ed3\u675f\u56de\u6d4b":17,"\u9002\u7528":15,"\u9009\u62e9\u5f85\u6210\u4ea4\u5217\u8868":24,"\u90a3\u5c31\u7528":26,"\u90ae\u4ef6\u53d1\u9001":26,"\u90e8\u5206":24,"\u90e8\u5206\u6210\u4ea4":26,"\u90fd\u4f1a\u88ab\u52a0\u8f7d\u5230\u8be5\u5355\u5143\u4e2d\u8fdb\u884c\u5206\u6790":16,"\u914d\u53f7\u67e5\u8be2":24,"\u963f\u5c14\u6cd5":17,"\u9650\u4ef7\u59d4\u6258":24,"\u9650\u4ef7\u6a21\u5f0f":26,"\u9664\u6743\u9664\u606f":22,"\u968f\u673a":26,"\u9700\u8981\u4e00\u4e2a\u53ef\u4ee5\u88ab\u4fee\u6539\u548c\u7ee7\u627f\u7684\u57fa\u7c7b":24,"\u9700\u8981\u517c\u5bb9\u80a1\u7968":15,"\u9700\u8981\u52a0\u8f7d\u4e00\u4e2aaccount":15,"\u9700\u8981\u5b8c\u5584run\u65b9\u6cd5":21,"\u9700\u8981\u5bf9\u4e8edatetim":26,"\u9700\u8981\u63a5\u53d7qa_ev":21,"\u9700\u8981\u6709":15,"\u9700\u8981\u8054\u7f51":19,"\u9707\u8361\u91cf\u6307\u6807osc":23,"\u9884\u8b66":22,"\u9891\u7387":22,"\u98ce\u683c":19,"\u98ce\u683c\u5206\u6790":15,"\u98ce\u9669\u6027\u4e3b\u8981\u5305\u62ec\u80dc\u7387":15,"\u9a8c\u8bc1\u8bc1\u660e":27,"abstract":24,"alpha\u6bd4\u7387":15,"backtest\u7684\u4e3b\u8981\u76ee\u7684":17,"beta\u6bd4\u7387":15,"boolean":9,"break":[2,6,8],"broker\u4e8b\u4ef6":26,"broker\u53d1\u9001settle\u6307\u4ee4":17,"broker\u6709\u4e86\u65b0\u6570\u636e\u4ee5\u540e":17,"by_price\u662f\u6309\u56fa\u5b9a\u6210\u4ea4\u603b\u989d\u4e0b\u5355":26,"case":[1,2,6,8,9],"class":[1,4,6,9,11,15,16,17,18,19,21,22,24,26,27],"code\u53ef\u4ee5\u662f\u80a1\u7968\u53ef\u4ee5\u662flist":22,"datastruct\u7684\u65b9\u6cd5":19,"datestamp\u8f6cdatetim":26,"default":[1,2,5,6,9,11,19,22,24,25],"end\u4e2d\u95f4\u6ca1\u6709\u4ea4\u6613\u65e5":26,"enum":[22,24],"export":[1,6],"final":[5,6],"float":[16,21],"function":[0,1,3,5,6,9,12,17],"generator\u6a21\u5f0f":24,"goto":3,"hash\u503c":27,"history\u4e24\u4e2a\u5b57\u6bb5":15,"import":[0,6,11,12],"int":[22,27],"ip\u53ef\u4ee5\u901a\u8fc7select_best_ip":22,"job\u662fwork":21,"k\u572820\u5de6\u53f3\u5411\u4e0a\u4ea4\u53c9d\u65f6":23,"k\u572880\u5de6\u53f3\u5411\u4e0b\u4ea4\u53c9d\u65f6":23,"long":23,"macd\u6307\u6807":23,"market\u544a\u77e5\u5df2\u7ecf\u6ce8\u518c\u7684\u6240\u6709\u7684account":17,"market\u7684\u5c01\u88c5":24,"mike\u6307\u6807":23,"mike\u662f\u53e6\u5916\u4e00\u79cd\u5f62\u5f0f\u7684\u8def\u5f84\u6307\u6807":23,"new":[1,4,5,8,9,11,19,26,27],"null":[3,6],"num\u662f\u6bcf\u4e2a\u80a1\u7968\u83b7\u53d6\u7684\u6570\u91cf":22,"on_tick\u65b9\u6cd5":15,"order\u6267\u884c\u5668":24,"order\u6267\u884c\u5668\u7684\u4f5c\u7528\u662f\u56e0\u4e3a":24,"order_handler\u7684\u4f5c\u7528\u5c31\u662f\u6839\u636e\u4fe1\u606f\u66f4\u65b0ord":24,"pandas\u8f6c\u51fa\u6765\u7684timestamp\u662f13\u4f4d\u6574\u6570":26,"portfolio\u4e0d\u5e94\u8be5\u6709\u8fc7\u591a\u53ef\u4ee5\u4fee\u6539\u7684\u90e8\u5206":15,"portfolio\u5e94\u5f53\u4f5c\u4e3a\u4e00\u4e2a\u89c6\u56fe\u6765\u5904\u7406":15,"portfolio\u662f\u4e00\u4e2a\u6807\u51c6\u5355\u5143":16,"portfolio\u7c7b\u8fdb\u6765":15,"portfolio\u91cc\u9762\u7684\u8d44\u4ea7\u4e3b\u8981\u8003\u8651\u7684\u662f":15,"qa_account\u53ef\u4ee5\u76f4\u63a5\u88abqa_strategy\u7ee7\u627f":15,"qa_account\u662f\u8d26\u6237\u7c7b":15,"qa_account\u7ee7\u627f\u81eaqa_work":15,"qa_performance\u662f\u4e00\u4e2a\u7ee9\u6548\u5206\u6790\u63d2\u4ef6":15,"quantaxis\u7684\u65f6\u95f4\u9009\u62e9\u51fd\u6570":26,"r\u4e09\u6761\u7ebf\u4ee3\u8868\u521d\u7ea7":23,"return":[1,5,9,15,16,17,19,21,22,24,25,26,27],"s\u4e09\u6761\u7ebf\u4ee3\u8868\u521d\u7ea7":23,"short":[2,5,23],"skdj\u6ce2\u52a8\u4e8e50\u5de6\u53f3\u7684\u4efb\u4f55\u8baf\u53f7":23,"st\u80a1":22,"static":27,"throw":1,"tick\u91c7\u6837\u6210\u4efb\u610f\u7ea7\u522b\u5206\u949f\u7ebf":19,"tr\u7684n\u65e5\u7b80\u5355\u79fb\u52a8\u5e73\u5747":23,"trade\u662f\u4e00\u4e2a\u53ef\u8fed\u4ee3\u7684list":16,"true":[1,3,6,9,15,22,24,25,26,27],"try":11,"v1\u8d4b\u503c":23,"var":[3,15],"while":[6,9,15],ABS:23,AND:23,And:[0,8,9,12],But:8,DNS:3,DOS:3,DTS:3,For:[0,6,9,12],Not:8,One:[8,11],Such:6,THS:26,The:[1,2,5,6,8,9,10,11,21,27],Then:8,There:[7,11],These:[6,11],Use:[6,11],Used:[1,9],__data:19,__file_nam:26,__file_path:26,_block_nam:19,_quotation_bas:[19,26],_realtime_bas:19,_time:26,_type:[16,22],_wv:[0,12],a001050100000000:22,a001050200000000:22,a001050d00000000:22,a001050e00000000:22,ab_board:19,abl:1,abnf:3,abnormal_act:15,about:[0,12],abov:2,absent:[1,9],absolut:23,absoult_path:17,acc:26,accept:[1,5,7],access:[3,5],accesslog:3,accord:[0,9,12],account:[0,6,12,15,16,17,22,24,25,26],account_cooki:[15,22,24],account_dai:17,account_ev:26,account_exist:26,account_handl:15,account_id:24,account_list:15,account_make_ord:26,account_settl:26,account_upd:26,accumul:15,accumulate_return:15,achiev:[0,9,12],actionscript:3,activ:21,actual:[0,2,6,8,12],ada:3,add:[1,11,15,27],add_account:15,add_func:16,added:[1,3,7],adding:7,addit:[2,3,9],address:27,adoc:3,adratio:19,affect:11,after:[1,2,9,21],after_backtest:[0,12],after_success:17,agnost:11,algol:3,algorithm:27,alia:[1,2],alias:1,aliv:21,all:[1,2,5,6,8,9,11,15,17,22],allow:[6,9],allow_sellopen:15,allow_t0:15,almost:11,along:9,alpha:[15,17],alreadi:26,also:[0,1,2,3,5,6,7,8,9,11,12,15,21],altogeth:9,alwai:[8,11,21],among:9,amount:[0,12,15,16,19,24,27],amount_model:[15,16,24,26],amplitud:[16,23],analysi:[0,12,15,17],ani:[0,3,5,6,7,8,9,12,21,27],annot:3,annual:17,annualize_return:15,annualized_return:[15,17],anoth:[3,6,7,9,10],answer:7,anyon:8,anyth:[3,6,9,10,11],apach:3,apacheconf:3,apart:2,api:[4,10,19,22,24],api_work:22,appear:7,append:1,applescript:3,appli:1,applic:24,approach:2,arbitrari:11,aren:[1,5,6],arg:[16,17,18,21,22,24,26],argument:[3,15,16,19,21,22,23,24,25,26],arm:3,armasm:3,around:8,arrai:[1,6,9],art:2,arturndai:19,arturnov:19,asciidoc:3,asi:23,asit:23,ask1:19,ask2:19,ask3:19,ask:8,ask_bid:19,ask_vol1:19,ask_vol2:19,ask_vol3:19,aspectj:3,assembl:3,assest_histori:17,assest_profit:[15,17],assest_profit_matrix:17,asset:[0,12,15,17],assets_d:17,atom:3,attach:1,attempt:[6,21],attent:[0,12],attr:[3,11],attribut:[1,3,10,11],aud:26,augment:9,author:[11,22],auto:[1,2,9,11],autohotkei:3,autoit:3,automat:[2,6],avail:[1,2,9,11,18],avedev:23,avoid:9,avr:3,avrasm:3,awk:3,axapta:3,back:[0,9,12,15],backetest:26,background:[8,11],backslash:6,backslash_escap:9,backtest:[0,12,14,15,17,26,28],backtest_framework:17,backtest_histori:22,backtest_info:22,backtest_init:[0,12],backtest_nam:17,backtest_result_analyz:17,backtest_set:[14,28],backtest_stock_deal:24,backward:1,bar:5,bar_settl:26,base:[0,2,12,14,15,16,17,18,19,21,24,26,27,28],base_datastruct:[14,28],bash:3,basic:3,bat:[3,22],bbi:23,bbibol:23,becom:[6,9],been:21,befor:[0,1,2,6,9,12,21],before_backtest:[0,12],begin:6,being:[1,7],below:[0,12],benchmark:15,benchmark_annualize_return:15,benchmark_annualized_return:[15,17],benchmark_asset:15,benchmark_cod:[0,12,15],benchmark_data:[15,17],benchmark_profit:[15,17],benchmark_profitpct:15,benchmark_typ:15,besid:9,best:[1,6,7,9],best_ip:22,beta:[0,12,15,17],better:[8,9],bfq:[19,22],bfq_data:19,bid1:19,bid2:19,bid3:19,bid_vol1:19,bid_vol2:19,bid_vol3:19,big:19,bigamount:19,binari:2,bind:3,bip:19,bit:6,black:[2,11],bloat:8,blob:[0,12],block:[3,8,9,11,16,21,27],block_nam:[16,19],block_pcg:16,block_pric:16,block_turnov:16,blockchain:27,blocknam:22,blog:8,bnf:3,board:19,bodi:23,body_ab:23,bold:11,bond_cn:26,bool:27,border:11,both:5,bother:8,brainfuck:3,bring:6,brinson:15,broker:[15,17,24,26],broker_calend:[14,28],broker_dailysettl:26,broker_ev:26,broker_nam:24,broker_settl:26,broker_trad:26,broker_typ:26,brought:8,browser:2,btc:26,buffer:[3,9],bug:[4,8],bui:[0,12,19,22,24,26],build:[0,4,5,12],built:[3,6],built_in:3,builtin:3,bullet:3,business_incom:19,button:8,buy_clos:26,buy_open:26,buyorsel:[19,22],bvp:19,by_amount:[16,24,26],by_pric:26,c_line_com:6,cach:3,cad:26,cal:3,cal_fe:24,calc:23,calc_alpha:15,calc_annualize_return:15,calc_beta:15,calc_every_pnl:17,calc_profit:15,calc_profitpctchang:15,calc_sharp:15,calc_trade_tim:17,call:[5,6,9,17,21,24],callabl:21,callback:[21,24],callback_messag:24,calmar:15,can:[0,1,2,6,9,10,12,15,21],cancel:[24,26],cancel_al:[24,26],cancel_ord:24,cannot:[6,7,9],canon:9,cap:3,capnp:3,capnproto:3,captur:[0,12],case_insensit:6,cash:[0,12,15],cash_tabl:15,cashflowratio:19,cashratio:19,categori:24,caus:[9,21],caution:9,caveat:11,cci:23,ccxt:26,center:17,cf_liabil:19,cf_nm:19,cf_sale:19,chain:[14,28],chanc:6,chang:[1,3,10,11,15,19,26],change_cash:15,change_ip:22,charact:[1,3,11],chart:[0,12],check:24,checklist:[4,6],cho:23,choic:[24,26],choos:11,chunk:6,circul:19,cixin:22,classic:6,classnam:6,classprefix:1,clean:[0,12],clear:[9,21,24],clearli:6,cli:18,client:[0,12,15,17,22,24,25,26],client_id:24,clj:3,clojur:3,close:[6,9,16,23,26],cls:3,cmake:3,cmd:[3,18],code:[0,1,2,3,4,6,8,10,12,15,16,17,19,22,24,26,27],code_list:17,coffe:3,coffeescript:3,col:26,col_:26,collabor:[0,12],collect:[15,22,25],color:[8,9,11],column:26,com:[0,4,5,11,12],combin:11,come:9,comma:9,commad:18,command:[2,18],comment:[3,5,8,9,11],commiss:24,commission_fe:17,commission_fee_coeff:24,commit:10,committ:10,common:[1,2,5,6,11],commonli:6,comparison:[0,12],compat:1,complex:[8,9],complic:2,compress:2,concat:19,concern:[0,12],cond:23,condit:6,conf:[3,10],config:3,config_fil:26,conjunct:9,connect:[15,22,24,25,26],connect_databas:15,connectionmethod:24,consensu:27,consid:[8,9],consist:[1,2,6],consol:3,constant:[0,3,12],constrain:9,construct:[2,3],constructor:21,contact:[0,12],contain:[1,5,6,11],content:[4,9,28],contribut:5,contributor:[4,6,7,11],control:9,conveni:[0,12],convent:6,cooki:[15,22,25],cookie_id:17,cookie_mang:15,cool:5,coq:3,core:[1,6,8,10],correct:27,correctli:9,cos:3,could:9,count:23,cpp:3,craftcm:3,crawler:[0,12],creat:[2,9,15,26],create_adjust:24,create_kern:21,crm:3,crmsh:3,cross:23,cross_valid:16,cryptocurr:26,crystal:3,csharp:3,cson:3,csp:3,css:[4,5,9,11],cur_vol:19,currency_typ:26,current:[1,8,9,15,19,21,26,27],current_tim:15,currentasset_dai:19,currentasset_turnov:19,currentratio:19,custom:[0,6,12],cutal:26,dai:[15,16,17,19,22,26],daily_cash:15,daily_hold:15,daily_settl:26,dart:3,data:[0,11,12,15,16,17,22,24,26],data_co:16,data_fq:[14,28],data_list:[14,28],data_resampl:[14,28],data_to_df:24,databas:[15,22,25,26],database_uri:17,datafram:[15,19,22,23,24,26],datasourc:[22,26],datastruct1:19,datastruct2:19,datastruct:[16,19,26],datastructn:19,date:[16,19,22,24,26],date_rang:22,datetim:[16,19,22,24],day_pct_chang:16,ddhfq:22,ddqfq:22,deadlock:21,deal:[19,24],dealer_preset:24,debian:2,debug:2,decid:21,decis:8,declar:[3,19],decor:19,decoupl:[0,12],decrypt:24,def:[0,9,12],defend:8,defin:[1,3,5,8,9],definit:[1,2,4,7,9],delet:[3,11],deliber:11,delphi:3,demo:5,demonstr:9,depend:2,des:18,describ:[5,6,8],descriopt:22,descript:[5,8,15,19,22,23,24,25,26],design:8,detail:[0,5,9,12,17,18,25],detect:[1,2,5,6,9],determin:27,develop:[2,7],deviat:23,devic:3,dfm:3,dict:[0,12,15,22,25,26,27],didn:10,diff:[3,23],differ:[0,2,5,6,9,12,15],digit:9,dir:17,direct:[3,24,25],directli:6,directori:2,discuss:[0,2,4,7,8,12],displai:11,distract:8,distrib:19,distribut:[0,12],divis:2,django:3,dma:23,dmi:23,dns:3,do_clean:18,do_drop_databas:18,do_exampl:18,do_exit:18,do_fn:18,do_help:18,do_quit:18,do_sav:18,do_shel:18,do_vers:18,doc:[6,10],docker:3,dockerfil:3,doctag:3,document:3,document_class:[15,22,25,26],doesn:[6,7,8,9],doing:[2,7],dom:1,domain:[5,11],domest:[0,12],don:[1,6,8,9],done:[2,5,6],dos:3,doubl:[6,9],doubt:[2,8],down:2,down_shdow:16,download:22,dpr:3,drawdown:17,driven:17,drop:[2,6,9],dsconfig:3,dsmethod:[14,28],dst:3,dts:3,dtype:19,dure:5,dust:3,dynam:1,dynamic_optim:26,each:[5,6,8,9],earli:6,easier:15,easili:9,eastmonei:26,ebnf:3,echo:9,effect:[6,9],effective_d:19,either:[5,6,8,11,21],element:[2,6,9],elixir:[3,9],elm:3,els:[0,6,9,12],ema:23,email:[5,11],embed:[3,9],emphasi:3,empti:9,emul:11,enabl:6,enc_iv:24,enc_kei:24,encod:24,encrypt:24,end:[0,6,12,16,17,19,22,24,26],end_backtest:[0,12],end_dat:[15,22],enddat:22,endpoint:24,eng:17,engin:[0,11,12,21,24,25],engine_ev:26,enging:24,english:[5,11],ensur:9,entir:9,entiti:16,enumer:24,environ:[2,3,15],epcf:19,eps:19,eps_yoi:19,epsg:19,erl:3,erlang:3,error:[2,21],escap:6,essenti:6,etc:[2,3,6,10,11],etf:24,etf_dai:25,etf_min:25,eur:26,evalu:1,even:[1,2,6],event:[1,15,21,24],event_typ:[21,26],ever:8,everi:[2,8,9,11],everydai:19,everyth:10,everywher:10,evil:8,exact:19,exactli:11,exampl:[0,2,6,9,11,12],excel:[0,3,12],except:[1,6,21,22],excess:6,exchang:22,exchange_id:24,exclud:[9,11],execut:24,exist:26,exot:6,expand:9,expans:3,expect:2,experi:[0,12],explan:[8,9],explicit:[6,9],explicitli:2,expma:23,express:[1,3,9],ext:19,extend:[5,9],extra:6,extract:9,f90:3,f95:3,face:11,fact:8,fail:26,fals:[3,6,9,15,21,22,24,25,26,27],fanci:[8,11],far:8,fast:23,featur:[8,9],feel:5,fetch:22,fetcher:[14,28],few:[1,2,6,11],fifteen_min:26,file:[2,3,11,25],file_dir:25,filenam:[9,22],financi:14,find:[6,9],fininsh:17,finish:1,first:[2,3,6,9,11],five_min:26,fix:[2,3,8],fixabl:10,flag:[1,3,9],flow:17,follow:[1,3,6,8],font:11,foo:[5,9],for_sh:22,for_sz:22,forbid:7,forc:[1,9],forget:11,fork:8,form:[6,9],format:[5,11,15,22],formula:3,fortran:3,forward:9,found:[1,2,6,9],fraction:21,fragment:6,frame:[0,12],framework:[1,14],free:[5,11],freepasc:3,frequenc:[15,17,22,24,26],from:[0,1,2,3,5,6,7,8,9,11,12,15,19,21],from_dict:24,from_messag:15,from_password:26,from_tushar:19,from_us:26,fsharp:3,full:[2,19],full_chain:27,func:[21,24,26],fund_cn:26,fundament:[7,14,28],further:8,futur:[0,12,19],future_cn:26,future_dai:19,future_ip_list:26,future_min:19,gam:3,gap:[0,12,16,17,26],gauss:3,gawk:3,gbp:26,gcode:3,gddm:24,gemspec:3,gener:[1,2,3,7,9,11,16,17],generate_simpleaccount:15,get:[0,2,7,12,15,21,22,24],get_account:[15,24],get_account_id:24,get_and_pars:22,get_api_last_error:24,get_api_vers:24,get_avail:22,get_bar:22,get_big_ord:19,get_block:19,get_cash:15,get_client_id:24,get_cod:19,get_data:[16,24],get_day_onc:22,get_etf:19,get_filenam:22,get_frequ:22,get_gap_trad:16,get_index:19,get_info:22,get_loss_trad:17,get_market:[22,24],get_medium_ord:19,get_nowait:21,get_ord:24,get_portfolio:15,get_posit:24,get_pric:19,get_profit_trad:17,get_quot:[22,24],get_realtim:22,get_realtime_concurr:22,get_security_bar:22,get_security_bar_concurr:22,get_small_ord:19,get_status:24,get_stock:19,get_stock_info:16,get_stock_tradedetail:17,get_stock_tradehistori:17,get_tim:19,get_today_al:22,get_trade_before_and_after_pnl:17,get_trade_marketdata:17,get_trading_dai:24,getblock:19,getcod:19,getdtyp:19,getlanguag:9,gherkin:3,git:10,github:[0,4,5,11,12],give:[2,5,15,17],given:[6,9,27],global:[0,1,12],glsl:3,gms:3,goe:9,going:2,golang:3,golo:3,gololang:3,good:[5,6,11],googl:4,gradl:3,graph:3,groovi:3,gross_profit_r:19,group:[0,2,4,6,7,11,12],gss:3,gte:26,gui:8,guid:[4,7,9],guidelin:11,gyp:3,haml:3,hand:[6,11],handl:[0,9,12],handlebar:3,happen:[6,7,21],has:[0,2,6,9,11,12,21,26],hash:27,haskel:3,have:[0,2,6,7,8,9,11,12],hax:3,hbs:3,head:3,header:[5,10],hei:8,height:11,hello:[9,27],help:[2,6,18],help_clean:18,help_drop_databas:18,help_exampl:18,help_exit:18,help_quit:18,help_sav:18,help_vers:18,helper:6,henc:11,here:[6,7,9],heurist:[1,2,6],hfq:22,hhv:23,high:[6,16,23],high_limit:19,higher:[6,19],highest:[0,12],highli:[0,12],highlight:[2,3,7,8,9,11],highlightj:[4,5,10],hint:6,histori:[0,12,15,17],history_t:15,hkd:26,hlj:[1,5,6,9,11],hold:[0,12,15,27],host:[14,15,22,24,25,28],hot_upd:26,hour:26,how:[2,7,8],howev:[9,11],hpp:3,hs300:[0,12],hth:24,html:[1,2,3,5,8,9],http:[0,3,4,5,10,12,24,27],human:5,hylang:3,hyperlink:3,iced:3,icratio:19,idea:2,ident_r:9,identifi:[3,5,9],idx:26,if_buyside_commiss:24,if_commiss:24,if_drop_index:22,if_fq:[19,22],if_nondatabas:24,if_open_web:26,if_sellside_commiss:24,iif:9,illeg:1,illustr:6,imag:11,immedi:[5,9],implement:[0,7,8,9,12],implic:11,implicitli:9,import_trad:16,improv:[2,6,8],includ:[2,3,7,9,11],inclus:8,increment:10,indent:1,index:[4,13,16,19,27],index_cn:[15,26],index_dai:[19,22,25],index_min:[19,22,25],indic:[6,14,28],individu:9,infinit:9,influenc:6,info:[0,12,24,25],inform7:3,inform:[0,12,17],ini:3,init:[0,12],init_assest:[0,12],init_asset:[15,16,17],initi:1,input:[0,12],input_text:26,ins:6,insensit:[6,9],insert_ord:24,insid:[2,3,6,9,15],inspir:5,instal:2,instanc:3,instead:[1,6,7,9,11],institut:22,instruct:[3,5],integ:1,intend:10,interact:[0,12],interest:[6,7,9,10],interfac:[0,3,12],intern:[1,3,9],internet:8,introduct:[0,12],invent:11,inventory_dai:19,inventory_turnov:19,invok:21,ip_a:15,ip_b:15,ipo:24,ipsiz:22,irb:3,irpf90:3,irrelev:6,isagalaev:4,isal:21,isol:2,issu:[0,4,7,12],ital:11,item:[0,3,12],its:[5,6,8,9],itself:[2,6,8,9],java:[3,5],javascript:[1,2,3,6,9],jinja:3,job:6,john:[5,11],johnson:5,join:21,join_quant:24,joinquant:24,jpy:26,json:[3,10,22,24,26],jsp:3,jsx:3,just:[5,6,8,9,22],jy_passwrod:24,jyp:22,kdb:3,kei:[0,3,5,9,12,24,26],kernal:21,kernel_num:21,key_regex:24,keyword:[3,5,19,21,22,25],kind:[6,9],know:9,kurtosi:16,kwarg:[16,17,19,21,22,24,26],label:3,lack:8,lan:[0,12],languag:[0,2,4,9,11,12],larger:8,lasso:3,lassoscript:3,last:[9,10,22,23],last_block:27,last_proof:27,lastest:15,latest:10,latest_cash:15,lazaru:3,ldif:3,leaf:3,left:11,len:[16,19,22,26],less:3,lessen:6,letter:6,level:[3,9,19,22],lex:6,lexem:[6,8],lfm:3,librari:[3,4,5,7],like:[0,2,3,6,9,10,12],limit:[0,11,12,26],line:[1,2,3,4,5,6,9,11],link:[0,2,3,4,12],lisp:3,list:[1,3,5,6,9,11,18,19,22,24,26,27],liter:[2,3,6,9],live:5,livecod:3,livecodeserv:3,livescript:3,llv:23,load:[1,26],load_data:[16,26],load_modul:16,load_preset:24,load_strategi:[0,12],local:1,localfil:26,locat:[2,26],log:[3,26],logger:24,login:[15,24,26],logoff:24,logon:24,logout:24,look:[1,2,6,8,10,11],loop:9,low:[16,23],low_limit:19,lower:19,lower_shadow:23,lowest:[0,12],lpr:3,lru_cach:19,lte:26,lua:3,macd:23,machin:2,mad:16,made:21,mai:[1,6,9,11,21],main:[9,14,27,28],maintain:8,mainten:8,major:6,mak:3,make:[2,5,6,7,8,10,11,15],make_cach:25,make_d:16,make_dir:25,make_ord:26,make_portfolio:15,makefil:3,manag:[0,12],mani:[0,6,8,11,12,21],margin:[11,22],margin_level:15,mark:1,markdown:3,market:[0,12,15,16,17,22,24,26],market_data:[16,19,24],market_error:26,market_ev:26,market_init:26,market_typ:[15,17,22,24,26],markup:[1,3,9],master:10,match:9,mathemat:3,mathematica:3,matlab:3,matt:5,matter:7,mawk:3,max:[16,17,23],max_dropback:15,maxima:3,maya:3,mbrg:19,mean:[5,7,8,16,23],mean_harmon:16,meaning:5,media_typ:24,mediatyp:24,medium:[0,12,19,23],mel:3,menu:2,mercuri:3,mes:25,messag:[0,2,12,15,17,21,22,25,27],meta:[3,11],method:[1,3,15,19,21,26],mfi:23,mid:23,might:[2,6,8],mike:5,min:[16,23],mine:27,minimalist:11,minut:[10,19],miscellan:4,mismatch:10,mizar:3,mkd:3,mkdown:3,mma:3,mocha:2,mode:[1,4,5,16],model:[0,12,15],modif:9,modifi:[3,22],modul:[3,4,13,28],modular:[0,12],mojolici:3,moment:[7,8],monei:15,mongo:[25,26],mongocli:[15,22,25,26],mongodb:[15,25],monitor:10,monkei:3,month:[22,26],month_data:16,monthli:16,moon:3,moonscript:3,more:[0,5,8,9,12],most:[6,9],mostli:[1,9],msg:26,multi:[0,12],multipl:9,must:21,myclass:6,myself:8,n1ql:3,name:[2,5,6,9,11,19,21,22,25,26],nav:19,navig:24,nawk:3,ndarrai:26,necessari:[2,11],need:[0,2,6,9,12],needless:9,nest:6,net:3,net_profit:19,net_profit_ratio:19,never:[8,9],new_account:15,new_block:27,new_portfolio:15,new_statu:24,new_transact:27,newlin:6,next_day_high_limit:19,next_day_low_limit:19,next_open:26,nginx:3,nginxconf:3,nice:6,nim:3,nimrod:3,nix:3,no_market_data:26,node:[1,2,27],nodej:2,nois:6,non:[1,11],none:[15,16,19,21,22,24,26,27],nonetyp:27,normal:21,notabl:[6,8],notat:10,note:[2,9,10],now_tim:25,npm:2,nprg:19,nsi:3,num:[17,19,22],number:[3,4,6,9,10,21],number_mod:5,numpi:22,obj:3,objc:3,object:[1,3,5,6,9,15,16,17,19,21,22,24,26,27],objectivec:3,obscur:7,obviou:5,obvious:11,ocaml:3,occupi:5,occur:21,often:9,okai:11,omit:[6,9],on_bar:15,on_cancel_ord:24,on_cancel_order_ev:24,on_connect:24,on_error:24,on_insert_ord:24,on_order_ev:24,on_query_asset:24,on_query_data:24,on_query_ord:24,on_query_posit:24,on_query_trad:24,on_tick:15,on_trade_ev:24,one:[1,6,8,9],one_min:26,ones:[5,8],onli:[1,2,5,6,8,9],open:[0,12,16,23],opengl:3,openscad:3,oper:21,opinion:8,optim:[0,12],option:[2,6,9,21],option_cn:26,oracl:3,ordehandld:24,order:[0,12,19,24],order_direct:26,order_ev:26,order_id:24,order_model:[0,12,15,16,24,26],order_pb2:[14,19],order_statu:26,org:[5,10],orient:[0,12],osascript:3,other:[1,5,6,11],otherwis:1,our:7,out:[9,21,22],output:[1,22],output_format:[22,26],outsid:6,over:9,overal:2,overdo:8,overflow:11,overrid:[1,6,21],overridden:9,oversight:8,own:[0,5,6,8,9,12],oxygen:3,p21:3,packag:[2,5,10,28],pad:11,page:[1,4,5,8,13],pai:[0,12],pair:[5,9],panda:22,param:[3,24,27],paramet:[1,3,5,6,9],parent:9,pars:[1,3,6,9,11],parser3:3,parser:[6,9],part:[3,6,8,9,10],parti:1,particular:7,pas:3,pascal:3,pass:[0,1,12,21],password:[15,22,25,26],patch:[3,10],path:[25,26],paus:21,pcmk:3,pct_chang:16,pend:24,peopl:8,perfectli:11,perform:[15,17],period:15,perl:3,person:8,php3:3,php4:3,php5:3,php6:3,php:[3,9],pic_handl:26,ping:[22,24],pipe:[6,9],place:[2,3,10],plai:9,plain:[6,10],plan:7,platform:[0,12],pleas:2,plist:3,plot_datastruct:26,podspec:3,point:[6,7,9,21],polici:[0,8,12],poni:3,port:[15,22,24,26],portfolio:[0,12,15],portfolio_cooki:15,posit:[8,11],possibl:[2,5,6,9,11],post:[1,8],powershel:3,practic:[2,11],prase_al:22,pre:1,preclos:19,prefer:15,prefix:[1,6],preprocessor:3,presenc:6,present:[1,21],pretti:5,previou:27,previous_hash:27,price:[0,12,15,16,19,24],price_chg:19,price_diff:16,price_limit:26,price_pcg:23,price_typ:24,principl:8,print:[0,12],probabl:8,process:[0,1,3,4,5,6,9,12],profil:3,profit:15,profit_dai:17,profit_pct:15,profits_yoi:19,program:[0,6,12],progress:[0,12],project:[7,8],prolog:3,proof:27,proof_of_work:27,properti:[1,3,6],proto:[3,14,19],protobuf:3,protocol:[0,3,12,22,26],provid:[2,7],proxi:24,pseudo:3,pstdev:16,pull:[11,15],puppet:3,purchase_convertible_bond:24,purchase_new_stock:24,purpos:3,push:[0,10,12,15],put:[6,9,21],put_nowait:21,pvarianc:16,python:[2,3,6],qa_account:15,qa_backtest:17,qa_backtest_analysis_backtest:17,qa_backtest_calc_alpha:17,qa_backtest_calc_asset:17,qa_backtest_calc_benchmark:17,qa_backtest_calc_beta:17,qa_backtest_calc_dropback_max:17,qa_backtest_calc_profit:17,qa_backtest_calc_profit_matrix:17,qa_backtest_calc_profit_per_year:17,qa_backtest_calc_sharp:17,qa_backtest_calc_trade_d:17,qa_backtest_calc_volatil:17,qa_backtest_calc_win_r:17,qa_backtest_get_market_data:[0,12],qa_backtest_hold_amount:[0,12],qa_backtest_send_ord:[0,12],qa_backtest_stock_dai:[0,12],qa_backtestbrok:24,qa_brok:24,qa_broker_ev:24,qa_cmd:18,qa_data_get_hfq:19,qa_data_get_qfq:19,qa_data_make_hfq:19,qa_data_make_qfq:19,qa_data_stock_to_fq:19,qa_data_tick_resampl:19,qa_datastruct_future_dai:19,qa_datastruct_future_min:19,qa_datastruct_index_dai:19,qa_datastruct_index_min:19,qa_datastruct_security_list:19,qa_datastruct_stock_block:19,qa_datastruct_stock_dai:19,qa_datastruct_stock_min:19,qa_datastruct_stock_realtim:19,qa_datastruct_stock_realtime_seri:19,qa_datastruct_stock_transact:19,qa_deal:24,qa_engin:21,qa_ev:[21,24],qa_fetch:22,qa_fetch_account:22,qa_fetch_backtest_histori:22,qa_fetch_backtest_info:22,qa_fetch_depth_market_data:22,qa_fetch_future_dai:22,qa_fetch_future_min:22,qa_fetch_future_tick:22,qa_fetch_get_future_dai:22,qa_fetch_get_future_list:22,qa_fetch_get_future_min:22,qa_fetch_get_future_realtim:22,qa_fetch_get_future_transact:22,qa_fetch_get_future_transaction_realtim:22,qa_fetch_get_index_dai:22,qa_fetch_get_index_min:22,qa_fetch_get_security_bar:22,qa_fetch_get_sh_margin:22,qa_fetch_get_stock_analysi:22,qa_fetch_get_stock_block:22,qa_fetch_get_stock_dai:22,qa_fetch_get_stock_day_in_year:22,qa_fetch_get_stock_day_simpl:22,qa_fetch_get_stock_financi:22,qa_fetch_get_stock_ind:22,qa_fetch_get_stock_info:22,qa_fetch_get_stock_latest:22,qa_fetch_get_stock_list:22,qa_fetch_get_stock_list_speci:22,qa_fetch_get_stock_min:22,qa_fetch_get_stock_realtim:22,qa_fetch_get_stock_risk:22,qa_fetch_get_stock_shap:22,qa_fetch_get_stock_tick:22,qa_fetch_get_stock_time_to_market:22,qa_fetch_get_stock_transact:22,qa_fetch_get_stock_transaction_realtim:22,qa_fetch_get_stock_xdxr:22,qa_fetch_get_stock_xueqiu:22,qa_fetch_get_sz_margin:22,qa_fetch_get_trade_d:22,qa_fetch_get_wholemarket_list:22,qa_fetch_index_dai:22,qa_fetch_index_day_adv:22,qa_fetch_index_min:22,qa_fetch_index_min_adv:22,qa_fetch_indexlist_dai:22,qa_fetch_quot:22,qa_fetch_security_list_adv:22,qa_fetch_stock_block:22,qa_fetch_stock_block_adv:22,qa_fetch_stock_dai:[0,12,22],qa_fetch_stock_day_adv:22,qa_fetch_stock_day_full_adv:22,qa_fetch_stock_ful:22,qa_fetch_stock_info:22,qa_fetch_stock_list:22,qa_fetch_stock_list_adv:22,qa_fetch_stock_min:22,qa_fetch_stock_min_adv:22,qa_fetch_stock_nam:22,qa_fetch_stock_realtime_adv:22,qa_fetch_stock_transaction_adv:22,qa_fetch_stock_xdxr:22,qa_fetch_trade_d:22,qa_indicator_adtm:23,qa_indicator_arbr:23,qa_indicator_asi:23,qa_indicator_atr:23,qa_indicator_bbi:23,qa_indicator_bia:23,qa_indicator_bol:23,qa_indicator_cci:23,qa_indicator_cho:23,qa_indicator_cr:23,qa_indicator_ddi:23,qa_indicator_dma:23,qa_indicator_dmi:23,qa_indicator_ema:23,qa_indicator_expma:23,qa_indicator_kdj:23,qa_indicator_ma:23,qa_indicator_macd:23,qa_indicator_mfi:23,qa_indicator_mik:23,qa_indicator_mtm:23,qa_indicator_obv:23,qa_indicator_osc:23,qa_indicator_pbx:23,qa_indicator_pvt:23,qa_indicator_roc:23,qa_indicator_rsi:23,qa_indicator_shadow:23,qa_indicator_skdj:23,qa_indicator_sma:23,qa_indicator_vpt:23,qa_indicator_vr:23,qa_indicator_vrsi:23,qa_indicator_vstd:23,qa_indicator_wr:23,qa_market:24,qa_ord:24,qa_orderhandl:24,qa_orderqueu:24,qa_perform:15,qa_plot_save_html:26,qa_portfolio:15,qa_portfolioview:15,qa_quot:22,qa_randombrok:24,qa_realbrok:24,qa_risk:15,qa_save_stock_day_al:25,qa_save_stock_day_all_bfq:25,qa_save_stock_day_with_fqfactor:25,qa_save_tdx_to_mongo:25,qa_set:26,qa_simulatedbrok:24,qa_strategi:15,qa_su_save_account_messag:25,qa_su_save_account_to_csv:25,qa_su_save_backtest_messag:25,qa_su_save_etf_dai:25,qa_su_save_etf_min:25,qa_su_save_index_dai:25,qa_su_save_index_min:25,qa_su_save_pnl_to_csv:25,qa_su_save_stock_block:25,qa_su_save_stock_dai:25,qa_su_save_stock_info:25,qa_su_save_stock_list:25,qa_su_save_stock_min:25,qa_su_save_stock_min_5:25,qa_su_save_stock_transact:25,qa_su_save_stock_xdxr:25,qa_su_save_trade_date_al:25,qa_task:21,qa_tdx_executor:22,qa_test_makeportfolio:15,qa_thread:21,qa_trad:24,qa_us:15,qa_user_sign_in:25,qa_user_sign_up:25,qa_util_calc_tim:26,qa_util_cfg_initi:26,qa_util_code_tolist:26,qa_util_code_tostr:26,qa_util_date_gap:26,qa_util_date_int2str:26,qa_util_date_stamp:26,qa_util_date_str2int:26,qa_util_date_todai:26,qa_util_date_valid:26,qa_util_dict_remove_kei:26,qa_util_diff_list:26,qa_util_get_cfg:26,qa_util_get_date_index:26,qa_util_get_index_d:26,qa_util_get_last_dai:26,qa_util_get_next_dai:26,qa_util_get_real_d:26,qa_util_get_real_datelist:26,qa_util_get_trade_gap:26,qa_util_get_trade_rang:26,qa_util_id2d:26,qa_util_if_trad:26,qa_util_if_tradetim:26,qa_util_is_trad:26,qa_util_log_debug:26,qa_util_log_expect:26,qa_util_log_info:[0,12,26],qa_util_log_x:26,qa_util_make_hour_index:26,qa_util_make_min_index:26,qa_util_mongo_info:26,qa_util_mongo_initi:26,qa_util_mongo_statu:26,qa_util_ms_stamp:26,qa_util_multi_demension_list:26,qa_util_random_with_top:26,qa_util_realtim:26,qa_util_save_csv:26,qa_util_select_hour:26,qa_util_select_min:26,qa_util_send_mail:26,qa_util_sql_async_mongo_set:26,qa_util_sql_mongo_ip:[0,12],qa_util_sql_mongo_set:26,qa_util_stamp2datetim:26,qa_util_time_delai:26,qa_util_time_gap:26,qa_util_time_now:26,qa_util_time_stamp:26,qa_util_to_datetim:26,qa_util_to_json_from_list:26,qa_util_to_json_from_numpi:26,qa_util_to_json_from_panda:26,qa_util_to_list_from_numpi:26,qa_util_to_list_from_panda:26,qa_util_to_pandas_from_json:26,qa_util_to_pandas_from_list:26,qa_util_web_p:26,qa_util_web_pool:26,qa_web:[14,28],qa_work:[15,21,24],qaaccount:[14,28],qaanalysi:[14,28],qaanalysis_block:[14,28],qaanalysis_codewithblock:16,qaanalysis_datafram:[14,28],qaanalysis_machine_learn:16,qaanalysis_machinelearn:[14,28],qaanalysis_seri:[14,28],qaanalysis_series_slop:16,qaanalysis_stock:16,qaanalysis_tick:[14,28],qaanalysis_trad:[14,28],qaanalysis_transact:16,qaarp:[14,28],qaauth:[14,28],qabacktest:[14,28],qabacktestbrok:[14,28],qabar:[14,28],qabrok:[14,28],qacfg:[14,28],qacmd:[14,28],qacod:[14,28],qacrawl:[14,28],qacsv:[14,28],qadat:[14,28],qadata:[14,28],qadatastruct:[14,28],qadate_trad:[14,28],qadeal:[14,28],qadict:[14,28],qaeastmonei:[14,28],qaengin:[14,15,24,28],qaevent:[14,15,24,28],qafetch:[14,28],qafinanci:[14,28],qaindic:[14,28],qalist:[14,28],qaloc:[14,28],qalog:[14,28],qamail:[14,28],qamarket:[14,28],qamongo:[14,28],qaorder:[14,28],qaorderhandl:[14,28],qaparamet:[14,28],qaplot:[14,28],qaportfolio:[14,28],qaqueri:[14,28],qaquery_adv:[14,28],qarandom:[14,28],qarandombrok:[14,28],qarealbrok:[14,28],qaresult:[14,28],qarisk:[14,28],qaset:[14,28],qasimulatedbrok:[14,28],qasql:[14,28],qastandard:[22,26],qastrategi:[14,28],qasu:[14,28],qatask:[14,28],qatdx:[14,28],qatdx_adv:[14,28],qatext:[14,28],qath:[14,28],qathreadengin:[14,28],qatrad:[14,28],qatransform:[14,28],qatushar:[14,28],qauser:[14,28],qautil:[14,28],qaweb:[14,28],qawind:[14,28],qfq:22,qml:3,qsize:21,quantit:14,quantiti:24,quarter:[19,22,26],queri:[0,12,24],query_account:26,query_asset:[24,26],query_backtest:27,query_backtest_by_:27,query_backtest_histori:27,query_cash:[24,26],query_category_balance_of_margin_loan:24,query_category_balance_of_stock_loan:24,query_category_cancelable_ord:24,query_category_cash:24,query_category_deal_of_todai:24,query_category_new_stock:24,query_category_new_stock_hit:24,query_category_new_stock_numb:24,query_category_new_stocks_quota:24,query_category_operable_margin_sotck:24,query_category_order_of_todai:24,query_category_shareholders_cod:24,query_category_stock:24,query_convertible_bond:24,query_currentbar:24,query_data:[24,26],query_data_no_wait:24,query_day_bfq:27,query_day_hfq:27,query_day_qfq:27,query_k:27,query_m:22,query_min_bfq:27,query_min_qfq:27,query_new_stock:24,query_ord:[24,26],query_posit:24,query_trad:24,question:[0,12],queu:26,queue:21,quickli:[0,12],quickratio:19,quit:[6,8,9],quot:[3,6,9],quotat:3,quote_string_mod:6,rais:21,random:26,ranodm:26,rapid:[0,12],rateofreturn:19,ratio:17,read:5,readabl:[2,5],reader:8,real:[8,15,26],realiz:[0,12],realtim:[14,27,28],realtime_2018:22,realtimedata:[14,28],reason:2,receive_d:15,receive_ord:[24,26],recipi:27,recommend:[6,9],red:9,ref:23,refer:[1,2,4,6,11],referenc:8,regex:[2,6,9],regexp:[3,5,6,9],regist:[1,17,24],register_account:15,register_kern:21,register_nod:27,register_spi:24,regular:[1,3,9],reinterpret_cast:6,rel:6,releas:[4,24],relev:[1,2,9],remain:9,render:2,renderman:3,repai:24,repeat:9,repetit:9,replac:[1,2],report_d:19,repres:[1,9,21],request:[4,11],request_json:24,requir:[2,5,6,9,11],res:[16,22],resampl:19,research:8,reset:11,reset_asset:15,reset_histori:15,resid:8,resolve_conflict:27,respect:21,respons:[0,12],rest:[0,8,12],restart:1,restrict:1,result:[2,3,15,21,24],resum:[15,21],retri:22,revis:10,rib:3,rich:11,right:9,risk:[0,12,25],risk_posit:[0,12],rmb:26,roboconf:3,roe:19,root:11,row_:26,rsl:3,rss:3,rubi:[2,3],rule:[3,6,7,9,11],ruleslanguag:3,run:[2,15,17,18,21,24],run_backtest:27,run_job:21,running_environ:26,runtimeerror:21,russian:[5,11],rust:3,rzrq:22,sai:8,same:[1,6,9,21],satisfi:2,save:[15,25],save_account:[14,28],save_backtest:[14,28],save_engin:25,save_loc:[14,28],save_mongo:22,save_riskanalysi:25,save_tdx:[14,28],save_tdx_fil:[14,28],save_tushar:[14,28],scad:3,scala:3,scene:[0,12],schema:[14,28],scheme:3,sci:3,scilab:3,script:[2,3,9],scss:3,search:[4,13],second:[1,21],second_best:1,section:[3,11],see:[0,1,2,7,8,9,12],seem:11,seg:19,select:[2,25],select_best_ip:22,select_save_engin:25,selector:[3,9,11],self:[6,24],sell:[0,12,19,22,24,26],sell_avail:15,sell_clos:26,sell_open:26,semant:3,semicolon:9,send:[0,5,11,12],send_ord:[15,24],sender:27,sending_tim:24,sens:[2,6,11],separ:[6,8,9,11],sequenc:6,sequenti:21,seri:[19,23,26],serial:[14,28],server:[2,3],set:[0,1,3,6,8,9,11,12],set_benchmark:15,set_statu:24,settl:[15,24,26],sever:[6,9],sha:27,shade:3,shadow:16,shadow_calc:16,shadow_panel:16,shanghai:22,share:[6,19],sharp:[15,17],shell:[3,18],shenzhen:22,sheqratio:19,shipanebrok:[14,28],shipanecli:[14,28],shortli:5,should:[0,2,5,6,9,11,12,21],shouldn:2,show:[6,8,9,19],shown:11,shutdown_cli:24,sid:19,signific:3,signin:27,signup:27,similar:9,simpl:[6,9,15],simpli:[2,5,8,10],simplic:8,simul:26,sinc:[9,10],singl:[6,8,9,11],site:10,situat:[0,12],sixty_min:26,size:[0,11,12],skewnewss:16,skip:2,slash:9,slice:16,slow:23,sma:23,smali:3,small:[0,8,12,19],smallamount:19,smaller:8,smalltalk:3,smith:[5,11],smtp:26,snippet:[2,8],solut:[0,8,12],solv:8,some:[2,5,6,8,11,17],someth:10,sometim:[6,9],somewher:6,sort:6,sortino:15,sourc:[15,16,17,18,19,21,22,23,24,25,26,27],source_obj:24,sourcecpi:18,space:[1,6,9],span:[6,9],spec:6,speci:[0,12],special:[3,5,6,9],specif:[2,6,11],specifi:[1,9,21],spetradeapi:24,split_word:26,sql:[3,5],sql_set:17,sqlalchemi:19,sr_seri:19,src:18,sst:22,st_option:19,stack:1,stan:3,standard:[0,3,11,12,15,21],start:[0,6,8,12,16,17,19,21,22,24,26],start_client:24,start_dat:[15,22],start_kern:21,start_market:17,startdat:22,stata:3,state:1,statist:6,statu:[24,27],status1xx:26,status2xx:26,status3xx:26,status4xx:26,status500:26,std:23,stdev:16,step1:24,step2:24,step3:24,step:3,still:[2,21],stock:[0,12,22,24,25],stock_block:[22,25],stock_cn:[15,26],stock_dai:[0,12,19,22,25],stock_day_pb2:[14,19],stock_deal:24,stock_hk:26,stock_info:[16,22,25],stock_list:[22,25],stock_min5:25,stock_min:[19,22,25],stock_min_pb2:[14,19],stock_transact:[22,25],stock_turnov:16,stock_u:26,stock_xdxr:[22,25],stockoption_cn:26,stop:[8,17,21],stop_al:21,stop_kern:21,stp:3,str:[16,19,22,25,27],straightforward:8,strategi:[14,15,22,24],strategy_end_d:[0,12],strategy_nam:15,strategy_start_d:[0,12],strategy_stock_list:[0,12],stratetgi:15,strict:[0,12,26],string:[1,2,3,6,9,11],stripe:8,strong:[3,23],strtime:26,struct:19,structur:[1,3],stuff:[6,8],styl:3,style:[3,4,6,9,15],stylesheet:1,stylu:3,sub:[3,9],subclass:21,subject:8,submodul:[14,28],subpackag:28,subscribe_public_top:24,subset:1,subst:3,subthread:17,subunit:3,success:26,success_al:26,success_part:26,suit:2,suitabl:9,sum:23,summari:[15,24,25,26],superlanguag:5,support:[6,8],sure:[2,5],swift:3,symbol:[2,3,9],syntact:[2,3],syntax:[1,9],system:[2,5,24],szse:22,tab:1,tabl:15,tabreplac:1,tag:[1,3,6,9,10],take:5,taken:21,tao:3,tap:3,targ:19,target:[5,21],task:21,task_queu:26,tax_coeff:24,tcl:3,tdb:26,tdx:26,tdxbroker:24,tdxrealbrok:[14,28],tdxtradeapiparam:24,team:[0,12],tell:[2,9],templat:[3,11],tend:11,termin:[9,21],test:[0,3,4,5,12],test_messag:27,test_nam:2,tex:3,text:[3,6,8,9],thei:[5,6,8],them:[6,9,11],thereof:21,thi:[0,1,2,5,6,7,8,9,10,12,16,19,21,27],thing:[6,8,9],third:[1,10],thirty_min:26,thor:3,those:1,thread:[17,21],thread_num:22,three:[0,10,12],thrift:3,through:[0,12,21],ths:26,tick:[15,19,26],till:19,time:[7,15,19,21,22,24,26],time_:26,timeout:[21,24],timestamp:26,titl:[3,6,9,26],to_addr:26,to_df:24,to_dict:24,to_hfq:19,to_protobuf:19,to_qfq:19,todai:[0,12,22],togeth:8,tool:[2,26],top:[1,5,9,11],topic:[17,26],total_d:17,toward:[0,12,15,16,19,24,26],track:4,tracker:7,trade:[15,16,17,19,24,26],trade_account:24,trade_d:19,trade_ev:26,trade_histori:17,trade_id:24,trade_list:[24,26],trade_statu:26,train:16,trait:3,transact:[19,27],transact_tim:24,transef:15,tree:[3,6],tri:6,trigger:10,truli:8,turn:6,tushar:[19,26],twice:9,twig:3,two:[2,9,10,11],tx_password:24,txt:[2,11],typ:23,type:[3,8,15,19,22,23,24,25,26],type_:[19,22,26],typescript:3,tz_awar:[15,22,25,26],ubuntu:2,undefin:1,under:[1,6,22,26],underlin:11,understand:8,unfinish:1,unhandl:21,union:27,uniqu:[6,11],unit:3,unlik:[2,9],unstyl:11,until:21,up_shadow:16,upcoming_data:[24,26],updat:[1,5,10,11,15,17,25,26],update_account:25,update_log:[0,12],upon:6,upper_shadow:23,url:26,usabl:[5,8],usag:8,usd:26,use:[1,2,5,6,8,9,11,22],usebr:1,used:[1,2,5,6,9,11],useful:[1,2,5,6,9],user:[0,3,6,12,14,15,22,24,28],user_cooki:15,user_nam:[15,26],usernam:22,uses:1,using:[1,2,6,9,10],usual:[2,6,11],utf:24,util:26,vala:3,valid:27,valid_chain:27,valid_proof:27,valu:[3,5,6,9],variabl:[3,6,9,11],varianc:16,variou:[2,6],vbnet:3,vbs:3,vbscript:3,verbatim:11,veri:6,verilog:3,version:[5,10,11,17,22,24],vhdl:3,view:[6,15],vim:3,visual:[0,2,9,12],vnd:24,vol:[16,19,23],volatil:[15,17],volatility_year:[15,17],volum:[16,19],wai:[5,6,7,8,9,15],wait:21,wan:[0,12],want:[0,7,8,11,12],warp:24,weak:23,websit:[0,12],week:[22,26],week_data:16,weekli:16,weird:7,weird_voodoo:9,welcom:[0,12],what:[9,11],when:[1,2,6,9,10,17,21],where:[2,10],whether:21,which:[0,1,2,6,9,10,12,15,24],whole:[0,2,9,12],whose:[9,21],why:8,width:9,wilson:5,win:6,wind:[22,26],winner:16,within:[1,3,8,9,11],without:[2,7,9],won:[6,9],word:[3,6],work:[2,5,6,7,8,9,10,11,27],worker:21,world:9,wors:8,worth:[6,8],would:[8,9,21],wrap:[6,9],written:[0,2,12],x86:3,x86asm:3,xdxr_data:19,xhtml:3,xjb:3,xls:3,xlsx:3,xml:[3,6],xpath:3,xqueri:3,xsd:3,xsl:3,xxxx:[0,12],year:[22,26],yes:8,yield:6,you:[0,1,2,5,7,9,11,12,21],your:[2,5,8,11],yourself:11,yutiansut:[0,12,14,22,23,24,26],yyb_id:24,yyyi:22,zep:3,zephir:3,zero:6,zone:3,zqdm:24,zsh:3,zyfw:22,zygcfx:22},titles:["QUANTAXIS quantitative financial strategy framework","Library API","Building and testing","CSS classes reference","highlight.js developer documentation","Language contributor checklist","Language definition guide","On requesting new languages","Line numbers","Mode reference","Release process","Style guide","QUANTAXIS quantitative financial strategy framework","Welcome to QUANTAXIS's documentation!","QUANTAXIS package","QUANTAXIS.QAARP package","QUANTAXIS.QAAnalysis package","QUANTAXIS.QABacktest package","QUANTAXIS.QACmd package","QUANTAXIS.QAData package","QUANTAXIS.QAData.proto package","QUANTAXIS.QAEngine package","QUANTAXIS.QAFetch package","QUANTAXIS.QAIndicator package","QUANTAXIS.QAMarket package","QUANTAXIS.QASU package","QUANTAXIS.QAUtil package","QUANTAXIS.QAWeb package","QUANTAXIS"],titleterms:{"class":[3,5],"new":7,add:5,alias:[3,9],api:1,attribut:[6,9],author:5,backtest:18,backtest_set:17,base:[22,23],base_datastruct:19,basic:2,begin:9,beginkeyword:9,block:1,broker_calend:24,build:2,case_insensit:9,chain:27,chang:5,checklist:5,classnam:9,code:5,comment:6,configur:1,contain:9,content:[14,15,16,17,18,19,20,21,22,23,24,25,26,27],continu:1,contribut:[6,11],contributor:5,creat:5,css:3,data:5,data_fq:19,data_list:22,data_resampl:19,defin:[6,11],definit:[5,6],develop:4,document:[4,13],don:11,dos:11,dsmethod:19,end:9,endspar:9,endswithpar:9,exampl:5,excludebegin:9,excludeend:9,express:6,fetcher:22,file:5,financi:[0,12],fixmarkup:1,framework:[0,12],fundament:19,gener:6,getlanguag:1,guid:[6,11],highlight:[1,4,6],highlightauto:1,highlightblock:1,host:26,ignore_illeg:1,illeg:[6,9],indic:[4,13,23],inithighlight:1,inithighlightingonload:1,kei:11,keyword:[6,9],languag:[1,3,5,6,7],languagesubset:1,layout:11,lexem:9,librari:1,line:8,listlanguag:1,main:25,markup:[2,6],meta:5,mode:[6,9],modul:[14,15,16,17,18,19,20,21,22,23,24,25,26,27],name:[1,3],note:[0,12],number:8,option:1,order_pb2:20,overview:6,packag:[14,15,16,17,18,19,20,21,22,23,24,25,26,27],pre:6,principl:11,process:10,proto:20,provid:5,pull:5,put:5,qa_web:27,qaaccount:15,qaanalysi:[16,17],qaanalysis_block:16,qaanalysis_datafram:16,qaanalysis_machinelearn:16,qaanalysis_seri:16,qaanalysis_tick:16,qaanalysis_trad:16,qaarp:15,qaauth:26,qabacktest:17,qabacktestbrok:24,qabar:26,qabrok:24,qacfg:26,qacmd:18,qacod:26,qacrawl:22,qacsv:26,qadat:26,qadata:[19,20],qadatastruct:19,qadate_trad:26,qadeal:24,qadict:26,qaeastmonei:22,qaengin:21,qaevent:21,qafetch:22,qafinanci:22,qaindic:23,qalist:26,qaloc:26,qalog:26,qamail:26,qamarket:24,qamongo:26,qaorder:24,qaorderhandl:24,qaparamet:26,qaplot:26,qaportfolio:15,qaqueri:22,qaquery_adv:22,qarandom:26,qarandombrok:24,qarealbrok:24,qaresult:17,qarisk:15,qaset:26,qasimulatedbrok:24,qasql:26,qastrategi:15,qasu:25,qatask:21,qatdx:22,qatdx_adv:22,qatext:26,qath:22,qathreadengin:21,qatrad:24,qatransform:26,qatushar:22,qauser:15,qautil:26,qaweb:[26,27],qawind:22,quantaxi:[0,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28],quantit:[0,12],realtim:22,realtimedata:19,refer:[3,5,9],registerlanguag:1,regular:6,releas:[0,10,12],relev:6,request:[5,7],returnbegin:9,returnend:9,save_account:25,save_backtest:25,save_loc:25,save_tdx:25,save_tdx_fil:25,save_tushar:25,schema:19,serial:19,shipanebrok:24,shipanecli:24,skip:9,start:9,stock_day_pb2:20,stock_min_pb2:20,strategi:[0,12],stylabl:3,style:11,sub:6,sublanguag:9,submodul:[15,16,17,18,19,20,21,22,23,24,25,26,27],subpackag:[14,19],subst:11,symbol:6,syntax:6,tabl:[4,13],tdxrealbrok:24,test:2,theme:11,txt:5,type:9,typographi:11,user:25,valu:1,variant:9,welcom:13,write:5,yourself:5}}) \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QAARP.html b/_build/html/source/QUANTAXIS.QAARP.html new file mode 100644 index 000000000..5b5b25882 --- /dev/null +++ b/_build/html/source/QUANTAXIS.QAARP.html @@ -0,0 +1,709 @@ + + + + + + + + QUANTAXIS.QAARP package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QAARP package

+
+

Submodules

+
+
+

QUANTAXIS.QAARP.QAAccount module

+
+
+class QUANTAXIS.QAARP.QAAccount.Account_handler[source]
+

Bases: object

+
+
+get_account(message)[source]
+
+ +
+ +
+
+class QUANTAXIS.QAARP.QAAccount.QA_Account(strategy_name=None, user_cookie=None, market_type='stock_cn', frequence='day', broker='backtest', portfolio_cookie=None, account_cookie=None, sell_available={}, init_assets=None, cash=None, history=None, margin_level=False, allow_t0=False, allow_sellopen=False)[source]
+

Bases: QUANTAXIS.QAEngine.QAEvent.QA_Worker

+

[QA_Account]

+
    +
  • 不再计算总资产/不再计算当前持仓/不再计算交易对照明细表
  • +
  • 不再动态计算账户股票/期货市值
  • +
  • 只维护 cash/history两个字段 剩下的全部惰性计算
  • +
+

QA_Account 是QUANTAXIS的最小不可分割单元之一

+

QA_Account是账户类 需要兼容股票/期货/指数 +QA_Account继承自QA_Worker 可以被事件驱动 +QA_Account可以直接被QA_Strategy继承

+

有三类输入: +信息类: 账户绑定的策略名/账户的用户名/账户类别/账户识别码/账户的broker +资产类: 现金/可用现金/交易历史/交易对照表 +规则类: 是否允许卖空/是否允许t0结算

+

方法: +惰性计算:最新持仓/最新总资产/最新现金/持仓面板 +生成订单/接受交易结果数据 +接收新的数据/on_bar/on_tick方法/缓存新数据的market_data

+
+
+cash_table
+

现金的table

+
+ +
+
+change_cash(money)[source]
+
+ +
+
+code
+

该账户曾交易代码 用set 去重

+
+ +
+
+current_time
+

return current time (in backtest/real environment)

+
+ +
+
+daily_cash
+

每日交易结算时的现金表

+
+ +
+
+daily_hold
+

每日交易结算时的持仓表

+
+ +
+
+end_date
+
+ +
+
+from_message(message)[source]
+

resume the account from standard message +这个是从数据库恢复账户时需要的

+
+ +
+
+history_table
+

交易历史的table

+
+ +
+
+hold
+

持仓

+
+ +
+
+latest_cash
+

return the lastest cash

+
+ +
+
+message
+

the standard message which can be transef

+
+ +
+
+on_bar(event)[source]
+

while updating the market data

+
+ +
+
+on_tick(event)[source]
+

on tick event

+
+ +
+
+receive_deal(message)[source]
+

[用于更新账户]

+

[description]

+

update history and cash

+
+ +
+
+reset_assets(init_assets=None)[source]
+

reset_history/cash/

+
+ +
+
+run(event)[source]
+

QA_WORKER method

+
+ +
+
+save()[source]
+
+ +
+
+send_order(code, amount, time, towards, price, order_model, amount_model)[source]
+

[summary]

+
+
Arguments:
+
code {[type]} -- [description] +amount {[type]} -- [description] +time {[type]} -- [description] +towards {[type]} -- [description] +price {[type]} -- [description] +order_model {[type]} -- [description] +amount_model {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+settle()[source]
+

同步可用资金/可卖股票

+
+ +
+
+start_date
+
+ +
+
+table
+

打印出account的内容

+
+ +
+
+trade
+

每次交易的pivot表

+
+ +
+ +
+
+

QUANTAXIS.QAARP.QAPortfolio module

+
+
+class QUANTAXIS.QAARP.QAPortfolio.QA_Portfolio(user_cookie=None, strategy_name=None, init_assets=1000000, cash=None, sell_available=None, history=None)[source]
+

Bases: object

+

QUANTAXIS 多账户 +以及组合管理

+

# 适用 回测/实盘

+

# PORTFOLIO应当作为一个视图来处理,这个视图作为一个静态的观察点 可以去衡量风险 观察业绩等等 +@2018/02/26

+

:: ::STRATEGY 1 -- ACCOUNT 1 --{P1,P3} :: +:: USER ::STRATEGY 2 -- ACCOUNT 2 --{P1,P2} :: +:: ::STRATEGY 3 -- ACCOUNT 3 --{P2,P3} :: +:::::::::::::::::::::::::::::::::::::::::::::::

+

PORTFOLIO

+

在portfolio中,我们希望通过cookie来控制account_unit

+

对于account的指标,要进行风险控制,组合成最优的投资组合的量

+

用account的cookie来管理控制account

+

portfolio里面的资产主要考虑的是 资金的分配

+
+
+add_account(account)[source]
+

portfolio add a account/stratetgy

+
+ +
+
+cookie_mangement()[source]
+
+ +
+
+get_account(cookie)[source]
+

give the account_cookie and return the account/strategy back

+
+ +
+
+get_cash()[source]
+

拿到整个portfolio的可用资金

+

统计每一个时间点的时候的cash总和

+
+ +
+
+get_portfolio()[source]
+

return the accounts dict

+
+ +
+
+new_account(account_cookie=None)[source]
+

portfolio create a account/strategy

+
+ +
+
+pull(account_cookie=None, collection=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'account'))[source]
+

pull from the databases

+
+ +
+
+push(account_cookie=None, collection=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'account'))[source]
+

push to databases

+
+ +
+
+table
+
+ +
+ +
+
+class QUANTAXIS.QAARP.QAPortfolio.QA_PortfolioView(account_list)[source]
+

Bases: object

+

对于Portfolio而言,一切都是基于内部的account的信息的变更而变更的

+

Portfolio不应该有过多可以修改的部分(作为一个view存在)

+
+ +
+ +
+
+accounts
+

return all accounts inside the portfolio view

+
+ +
+
+code
+
+ +
+
+daily_cash
+
+ +
+
+daily_hold
+
+ +
+
+end_date
+
+ +
+
+init_assets
+
+ +
+
+start_date
+
+ +
+ +
+
+class QUANTAXIS.QAARP.QAPortfolio.QA_TEST_MAKEPortfolio[source]
+

Bases: object

+
+
+make_portfolio(account_list)[source]
+
+ +
+ +
+
+

QUANTAXIS.QAARP.QARisk module

+

收益性的包括年化收益率、净利润、总盈利、总亏损、有效年化收益率、资金使用率。

+

风险性主要包括胜率、平均盈亏比、最大回撤比例、最大连续亏损次数、最大连续盈利次数、持仓时间占比、贝塔。

+

综合性指标主要包括风险收益比,夏普比例,波动率,VAR,偏度,峰度等

+
+
+class QUANTAXIS.QAARP.QARisk.QA_Performance(account)[source]
+

Bases: object

+

QA_Performance是一个绩效分析插件

+

需要加载一个account/portfolio类进来: +需要有 +code,start_date,end_date,daily_cash,daily_hold

+
+
+abnormal_active()[source]
+

账户的成交发生异常成交记录的分析

+
+ +
+
+accumulate_return
+

returns a pd-Dataframe format accumulate return for different periods

+
+ +
+
+brinson()[source]
+

Brinson Model analysis

+
+ +
+
+hold()[source]
+

持仓分析

+
+ +
+
+prefer
+
+ +
+
+save()[source]
+

save the performance analysis result to database

+
+ +
+
+style
+

风格分析

+
+ +
+ +
+
+class QUANTAXIS.QAARP.QARisk.QA_Risk(account, benchmark_code='000300', benchmark_type='index_cn')[source]
+

Bases: object

+

QARISK 是一个风险插件

+

需要加载一个account/portfolio类进来: +需要有 +code,start_date,end_date,daily_cash,daily_hold

+
+
+alpha
+

alpha比率 与市场基准收益无关的超额收益率

+
+ +
+
+annualize_return
+

年化收益

+
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+benchmark_annualize_return
+

基准组合的年化收益

+
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+benchmark_assets
+

基准组合的账户资产队列

+
+ +
+
+benchmark_data
+

基准组合的行情数据(一般是组合,可以调整)

+
+ +
+
+benchmark_profitpct
+

benchmark 基准组合的收益百分比计算

+
+ +
+
+beta
+

beta比率 组合的系统性风险

+
+ +
+
+calc_alpha(annualized_returns, benchmark_annualized_returns, beta, r=0.05)[source]
+
+ +
+
+calc_annualize_return(assets, days)[source]
+
+ +
+
+calc_beta(assest_profit, benchmark_profit)[source]
+
+ +
+
+calc_profit(assets)[source]
+
+ +
+
+calc_profitpctchange(assets)[source]
+
+ +
+
+calc_sharpe(annualized_returns, volatility_year, r=0.05)[source]
+

计算夏普比率

+
+ +
+
+calmar
+

卡玛比率

+
+ +
+
+max_dropback
+

最大回撤

+
+ +
+
+message
+
+ +
+
+profit
+
+ +
+
+profit_pct
+

利润

+
+ +
+
+save()[source]
+

save to mongodb

+
+ +
+
+set_benchmark(code, market_type)[source]
+
+ +
+
+sharpe
+

夏普比率

+
+ +
+
+sortino
+

索提诺比率 投资组合收益和下行风险比值

+
+ +
+
+volatility
+

波动率

+
+
Returns:
+
[type] -- [description]
+
+
+ +
+ +
+
+

QUANTAXIS.QAARP.QAStrategy module

+
+
+class QUANTAXIS.QAARP.QAStrategy.QA_Strategy[source]
+

Bases: QUANTAXIS.QAARP.QAAccount.QA_Account

+

account

+

[description]

+
+ +
+
+

QUANTAXIS.QAARP.QAUser module

+
+
+class QUANTAXIS.QAARP.QAUser.QA_User[source]
+

Bases: object

+

User--Portfolio--Account/Strategy

+
+
+client()[source]
+

user.client to connect database

+
+ +
+
+connect_database(ip='127.0.0.1', port=27017)[source]
+

connect is also a way to change database from IP_A to IP_B

+
+ +
+
+generate_simpleaccount()[source]
+

make a simple account with a easier way +如果当前user中没有创建portfolio, 则创建一个portfolio,并用此portfolio创建一个account +如果已有一个或多个portfolio,则使用第一个portfolio来创建一个account

+
+ +
+
+get_portfolio(portfolio)[source]
+

get a portfolio

+
+ +
+
+login(user_name, password)[source]
+

login to a database

+
+ +
+
+new_portfolio()[source]
+

create a portfolio

+
+ +
+
+register_account(account)[source]
+
+ +
+
+table
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QAAnalysis.html b/_build/html/source/QUANTAXIS.QAAnalysis.html new file mode 100644 index 000000000..2f351760d --- /dev/null +++ b/_build/html/source/QUANTAXIS.QAAnalysis.html @@ -0,0 +1,439 @@ + + + + + + + + QUANTAXIS.QAAnalysis package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QAAnalysis package

+
+

Submodules

+
+
+

QUANTAXIS.QAAnalysis.QAAnalysis_block module

+
+
+class QUANTAXIS.QAAnalysis.QAAnalysis_block.QAAnalysis_block(block=None, block_name=None, lens=90, *args, **kwargs)[source]
+

Bases: object

+
+
+block_pcg(market_data=None)[source]
+
+ +
+
+block_price(market_data=None)[source]
+
+ +
+
+block_turnover(market_data=None)[source]
+
+ +
+
+market_data(start, end, _type='day')[source]
+
+ +
+
+month_data
+

this monthly data

+
+ +
+
+res()[source]
+
+ +
+
+stock_info()[source]
+
+ +
+
+stock_turnover(market_data=None)[source]
+
+ +
+
+week_data
+

this weekly data

+
+ +
+ +
+
+class QUANTAXIS.QAAnalysis.QAAnalysis_block.QAAnalysis_codewithblock(block)[source]
+

Bases: object

+
+ +
+
+QUANTAXIS.QAAnalysis.QAAnalysis_block.get_gap_trade(gap)[source]
+
+ +
+
+

QUANTAXIS.QAAnalysis.QAAnalysis_dataframe module

+
+
+class QUANTAXIS.QAAnalysis.QAAnalysis_dataframe.QAAnalysis_stock(dataStruct, *args, **kwargs)[source]
+

Bases: object

+

行情分析器

+

计算所有的指标

+
+
+add_func[source]
+
+ +
+
+amplitude
+
+ +
+
+close
+
+ +
+
+date
+
+ +
+
+datetime
+
+ +
+
+day_pct_change
+
+ +
+
+high
+
+ +
+
+index
+
+ +
+
+kurtosis
+
+ +
+
+low
+
+ +
+
+mad
+
+ +
+
+max
+
+ +
+
+mean
+
+ +
+
+mean_harmonic
+
+ +
+
+min
+
+ +
+
+mode
+
+ +
+
+open
+
+ +
+
+pct_change
+
+ +
+
+price
+
+ +
+
+price_diff
+
+ +
+
+pstdev
+
+ +
+
+pvariance
+
+ +
+
+skewnewss
+
+ +
+
+stdev
+
+ +
+
+variance
+
+ +
+
+vol
+
+ +
+
+volume
+
+ +
+ +
+
+class QUANTAXIS.QAAnalysis.QAAnalysis_dataframe.shadow(data)[source]
+

Bases: object

+
+
+shadow_panel()[source]
+
+ +
+ +
+
+QUANTAXIS.QAAnalysis.QAAnalysis_dataframe.shadow_calc(data)[source]
+

计算上下影线

+
+
Arguments:
+
data {DataStruct.slice} -- 输入的是一个行情切片
+
Returns:
+
up_shadow {float} -- 上影线 +down_shdow {float} -- 下影线 +entity {float} -- 实体部分 +date {str} -- 时间 +code {str} -- 代码
+
+
+ +
+
+

QUANTAXIS.QAAnalysis.QAAnalysis_machinelearning module

+

一个通用的可以接入不同模型的类

+
+
+class QUANTAXIS.QAAnalysis.QAAnalysis_machinelearning.QAAnalysis_Machine_Learning(*args, **kwargs)[source]
+

Bases: object

+
+
+cross_valid()[source]
+
+ +
+
+data_co()[source]
+
+ +
+
+load_data()[source]
+
+ +
+
+load_modules()[source]
+
+ +
+
+training()[source]
+
+ +
+ +
+
+

QUANTAXIS.QAAnalysis.QAAnalysis_series module

+
+
+QUANTAXIS.QAAnalysis.QAAnalysis_series.QAAnalysis_Series_slope(data)[source]
+
+ +
+
+

QUANTAXIS.QAAnalysis.QAAnalysis_tick module

+
+
+class QUANTAXIS.QAAnalysis.QAAnalysis_tick.QAAnalysis_Transaction[source]
+

Bases: object

+
+
+get_data(code, start, end)[source]
+
+ +
+
+get_stock_info(code)[source]
+
+ +
+
+winner()[source]
+
+ +
+ +
+
+

QUANTAXIS.QAAnalysis.QAAnalysis_trade module

+
+
+class QUANTAXIS.QAAnalysis.QAAnalysis_trade.QAAnalysis_trade(init_assets, *args, **kwargs)[source]
+

Bases: object

+

Account/Portfolio是一个标准单元,所有成交记录分析 都会被加载到该单元中进行分析 +当我们只有一个成交记录的时候,我们会创建一个账户单元

+
+
+import_trade(trade)[source]
+

trade是一个可迭代的list/generator

+
+ +
+
+make_deal(code, datetime, amount=100, towards=1, price=0, order_model='market', amount_model='by_amount')[source]
+

这是一个一定会成交,并且立刻结转(及t+0)的交易入口

+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QABacktest.html b/_build/html/source/QUANTAXIS.QABacktest.html new file mode 100644 index 000000000..47abd7b39 --- /dev/null +++ b/_build/html/source/QUANTAXIS.QABacktest.html @@ -0,0 +1,340 @@ + + + + + + + + QUANTAXIS.QABacktest package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QABacktest package

+
+

Submodules

+
+
+

QUANTAXIS.QABacktest.QAAnalysis module

+

Analysis Center for Backtest +we will give some function

+
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_analysis_backtest(client, code_list, assets_d, account_days, message, total_date, benchmark_data)[source]
+

Annualized Returns: 策略年化收益率。表示投资期限为一年的预期收益率。 +具体计算方式为 (策略最终价值 / 策略初始价值)^(250 / 回测交易日数量) - 1

+

Alpha:阿尔法 +具体计算方式为 (策略年化收益 - 无风险收益) - beta × (参考标准年化收益 - 无风险收益),这里的无风险收益指的是中国固定利率国债收益率曲线上10年期国债的年化到期收益率。

+

Beta:贝塔 +具体计算方法为 策略每日收益与参考标准每日收益的协方差 / 参考标准每日收益的方差 。

+

Sharpe Ratio:夏普比率。表示每承受一单位总风险,会产生多少的超额报酬。 +具体计算方法为 (策略年化收益率 - 回测起始交易日的无风险利率) / 策略收益波动率 。

+

Volatility:策略收益波动率。用来测量资产的风险性。 +具体计算方法为 策略每日收益的年化标准差 。

+

Information Ratio:信息比率。衡量超额风险带来的超额收益。 +具体计算方法为 (策略每日收益 - 参考标准每日收益)的年化均值 / 年化标准差 。

+

Max Drawdown:最大回撤。描述策略可能出现的最糟糕的情况。 +具体计算方法为 max(1 - 策略当日价值 / 当日之前虚拟账户最高价值)

+

单次交易收益 +收益/次数的频次直方图 +单日最大持仓

+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_alpha(annualized_returns, benchmark_annualized_returns, beta, r)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_assets(trade_history, assets)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_benchmark(benchmark_data, init_assets)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_beta(assest_profit, benchmark_profit)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_dropback_max(history)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_profit(assest_history)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_profit_matrix(assest_history)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_profit_per_year(assest_history, days)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_sharpe(annualized_returns, r, volatility_year)[source]
+

计算夏普比率

+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_trade_date(history)[source]
+

计算交易日期

+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_volatility(assest_profit_matrix)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.QA_backtest_calc_win_rate(profit_day)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.calc_every_pnl(detail)[source]
+
+ +
+
+QUANTAXIS.QABacktest.QAAnalysis.calc_trade_time(history)[source]
+
+ +
+
+

QUANTAXIS.QABacktest.QABacktest module

+
+
+class QUANTAXIS.QABacktest.QABacktest.BACKTEST_FRAMEWORK[source]
+

Bases: object

+
+ +
+
+class QUANTAXIS.QABacktest.QABacktest.QA_Backtest(market_type, frequence, start, end, code_list, commission_fee)[source]
+

Bases: object

+

BACKTEST

+

BACKTEST的主要目的:

+
    +
  • +
    引入时间轴环境,获取全部的数据,然后按生成器将数据迭代插入回测的BROKER
    +
    (这一个过程是模拟在真实情况中市场的时间变化和价格变化)
    +
    +
  • +
  • BROKER有了新数据以后 会通知MARKET交易前置,MARKET告知已经注册的所有的ACCOUNT 有新的市场数据
  • +
  • ACCOUNT 获取了新的市场函数,并将其插入他已有的数据中(update)
  • +
  • ACCOUNT 底下注册的策略STRATEGY根据新的市场函数,产生新的买卖判断,综合生成信号
  • +
  • 买卖判断通过交易前置发送给对应的BROKER,进行交易
  • +
  • BROKER发送SETTLE指令 结束这一个bar的所有交易,进行清算
  • +
  • 账户也进行清算,更新持仓,可卖,可用现金等
  • +
  • 迭代循环直至结束回测
  • +
  • 回测去计算这段时间的各个账户收益,并给出综合的最终结果
  • +
+
+
+after_success()[source]
+

called when all trading fininshed, for performance analysis

+
+ +
+
+run()[source]
+

generator driven data flow

+
+ +
+
+start_market()[source]
+

start the market thread and register backtest broker thread

+
+ +
+
+stop()[source]
+

stop all the market trade enging threads and all subthreads

+
+ +
+ +
+
+

QUANTAXIS.QABacktest.QAResult module

+
+
+class QUANTAXIS.QABacktest.QAResult.backtest_result_analyzer(cookie_id, *args, **kwargs)[source]
+

Bases: object

+
+
+codes
+
+ +
+
+detail
+
+ +
+
+get_loss_trade(num=5)[source]
+
+ +
+
+get_profit_trade(num=5)[source]
+
+ +
+
+get_stock_tradedetail(code)[source]
+
+ +
+
+get_stock_tradehistory(code)[source]
+
+ +
+
+get_trade_before_and_after_pnl(rx, N=3, M=10)[source]
+
+ +
+
+get_trade_marketdata(rx, gap=3)[source]
+
+ +
+
+history
+
+ +
+ +
+
+

QUANTAXIS.QABacktest.backtest_setting module

+
+
+class QUANTAXIS.QABacktest.backtest_setting.backtest_setting(topic, version, backtest_name, sql_setting)[source]
+

Bases: object

+
+
+absoult_path
+
+ +
+
+database_uri
+
+ +
+
+dirs
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QACmd.html b/_build/html/source/QUANTAXIS.QACmd.html new file mode 100644 index 000000000..03b8e0346 --- /dev/null +++ b/_build/html/source/QUANTAXIS.QACmd.html @@ -0,0 +1,215 @@ + + + + + + + + QUANTAXIS.QACmd package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QACmd package

+
+

Submodules

+
+
+

QUANTAXIS.QACmd.backtest module

+
+
+

Module contents

+
+
+class QUANTAXIS.QACmd.CLI[source]
+

Bases: cmd.Cmd

+
+
+do_clean(arg)[source]
+
+ +
+
+do_drop_database(arg)[source]
+
+ +
+
+do_examples(arg)[source]
+
+ +
+
+do_exit(arg)[source]
+
+ +
+
+do_fn(arg)[source]
+
+ +
+
+do_help(arg)[source]
+

List available commands with "help" or detailed help with "help cmd".

+
+ +
+
+do_quit(arg)[source]
+
+ +
+
+do_save(arg)[source]
+
+ +
+
+do_shell(arg)[source]
+

run a shell commad

+
+ +
+
+do_version(arg)[source]
+
+ +
+
+help()[source]
+
+ +
+
+help_clean()[source]
+
+ +
+
+help_drop_database()[source]
+
+ +
+
+help_examples()[source]
+
+ +
+
+help_exit()[source]
+
+ +
+
+help_quit()[source]
+
+ +
+
+help_save()[source]
+
+ +
+
+help_version()[source]
+
+ +
+ +
+
+QUANTAXIS.QACmd.QA_cmd()[source]
+
+ +
+
+QUANTAXIS.QACmd.sourcecpy(src, des)[source]
+
+ +
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QAData.html b/_build/html/source/QUANTAXIS.QAData.html new file mode 100644 index 000000000..3116483d0 --- /dev/null +++ b/_build/html/source/QUANTAXIS.QAData.html @@ -0,0 +1,1096 @@ + + + + + + + + QUANTAXIS.QAData package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QAData package

+ +
+

Submodules

+
+
+

QUANTAXIS.QAData.QADataStruct module

+

定义一些可以扩展的数据结构

+

方便序列化/相互转换

+
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Future_day(DataFrame, dtype='future_day', if_fq='')[source]
+

Bases: QUANTAXIS.QAData.base_datastruct._quotation_base

+
+ +
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Future_min(DataFrame, dtype='future_min', if_fq='')[source]
+

Bases: QUANTAXIS.QAData.base_datastruct._quotation_base

+

struct for future

+
+ +
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Index_day(DataFrame, dtype='index_day', if_fq='')[source]
+

Bases: QUANTAXIS.QAData.base_datastruct._quotation_base

+

自定义的日线数据结构

+
+ +
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Index_min(DataFrame, dtype='index_min', if_fq='')[source]
+

Bases: QUANTAXIS.QAData.base_datastruct._quotation_base

+

自定义的分钟线数据结构

+
+ +
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Security_list(DataFrame)[source]
+

Bases: object

+
+
+code
+
+ +
+
+get_etf()[source]
+
+ +
+
+get_index()[source]
+
+ +
+
+get_stock(ST_option)[source]
+
+ +
+
+name
+
+ +
+ +
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_block(DataFrame)[source]
+

Bases: object

+
+
+block_name
+

返回所有的板块名

+
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+code
+

返回唯一的证券代码

+
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+get_block(_block_name)[source]
+

getblock 获取板块

+
+
Arguments:
+
_block_name {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+get_code(code)[source]
+

getcode 获取某一只股票的板块

+
+
Arguments:
+
code {str} -- 股票代码
+
Returns:
+
DataStruct -- [description]
+
+
+ +
+
+get_price(_block_name=None)[source]
+
+
Keyword Arguments:
+
_block_name {[type]} -- [description] (default: {None})
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+getdtype(dtype)[source]
+
+
Arguments:
+
dtype {str} -- gn-概念/dy-地域/fg-风格/zs-指数
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+len
+

返回DataStruct的长度

+
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+show()[source]
+

展示DataStruct

+
+
Returns:
+
dataframe -- [description]
+
+
+ +
+ +
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_day(DataFrame, dtype='stock_day', if_fq='bfq')[source]
+

Bases: QUANTAXIS.QAData.base_datastruct._quotation_base

+

this is a datastruct for stock_day

+
+
+high_limit
+

涨停价

+
+ +
+
+low_limit
+

跌停价

+
+ +
+
+next_day_high_limit
+

明日涨停价

+
+ +
+
+next_day_low_limit
+

明日跌停价

+
+ +
+
+preclose
+
+ +
+
+price_chg
+
+ +
+
+to_hfq()[source]
+
+ +
+
+to_qfq()[source]
+
+ +
+ +
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_min(DataFrame, dtype='stock_min', if_fq='bfq')[source]
+

Bases: QUANTAXIS.QAData.base_datastruct._quotation_base

+
+
+high_limit
+

涨停价

+
+ +
+
+low_limit
+

跌停价

+
+ +
+
+to_hfq()[source]
+
+ +
+
+to_qfq()[source]
+
+ +
+ +
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_realtime(market_data)[source]
+

Bases: QUANTAXIS.QAData.QADataStruct._realtime_base

+
+
+ab_board
+

ask_bid board +bid3 bid_vol3 +bid2 bid_vol2 +bid1 bid_vol1 +=============== +price /cur_vol +=============== +ask1 ask_vol1 +ask2 ask_vol2 +ask3 ask_vol3

+
+ +
+
+serialize()[source]
+

to_protobuf

+
+ +
+ +
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_realtime_series(sr_series)[source]
+

Bases: object

+
+ +
+
+class QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_transaction(DataFrame)[source]
+

Bases: object

+
+
+amount
+

return current tick trading amount

+
+
Decorators:
+
lru_cache
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+buyorsell
+

return the buy or sell towards 0--buy 1--sell 2--none

+
+
Decorators:
+
lru_cache
+
Returns:
+
[pd.Series] -- [description]
+
+
+ +
+
+date
+

return the date of transaction

+
+
Decorators:
+
lru_cache
+
Returns:
+
pd.Series -- date of transaction
+
+
+ +
+
+datetime
+

return the datetime of transaction

+
+
Decorators:
+
lru_cache
+
Returns:
+
pd.Series -- [description]
+
+
+ +
+
+get_big_orders(bigamount=1000000)[source]
+

return big order

+
+
Keyword Arguments:
+
bigamount {[type]} -- [description] (default: {1000000})
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+get_medium_order(lower=200000, higher=1000000)[source]
+

return medium

+
+
Keyword Arguments:
+
lower {[type]} -- [description] (default: {200000}) +higher {[type]} -- [description] (default: {1000000})
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+get_small_order(smallamount=200000)[source]
+

return small level order

+
+
Keyword Arguments:
+
smallamount {[type]} -- [description] (default: {200000})
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+get_time(start, end=None)[source]
+
+ +
+
+index
+

return the transaction index

+
+
Decorators:
+
lru_cache
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+order
+

return the order num of transaction/ for everyday change

+
+
Decorators:
+
lru_cache
+
Returns:
+
pd.series -- [description]
+
+
+ +
+
+price
+

return the deal price of tick transaction

+
+
Decorators:
+
lru_cache
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+resample(type_='1min')[source]
+

resample methods

+
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+time
+

return the exact time of transaction(to minute level)

+
+
Decorators:
+
lru_cache
+
Returns:
+
pd.Series -- till minute level
+
+
+ +
+
+vol
+

return the deal volume of tick

+
+
Decorators:
+
lru_cache
+
Returns:
+
pd.Series -- volume of transaction
+
+
+ +
+
+volume
+

return the deal volume of tick

+
+
Decorators:
+
lru_cache
+
Returns:
+
pd.Series -- volume of transaction
+
+
+ +
+ +
+
+

QUANTAXIS.QAData.base_datastruct module

+
+
+

QUANTAXIS.QAData.data_fq module

+
+
+QUANTAXIS.QAData.data_fq.QA_data_get_hfq(code, start, end)[source]
+

使用网络数据进行复权/需要联网

+
+ +
+
+QUANTAXIS.QAData.data_fq.QA_data_get_qfq(code, start, end)[source]
+

使用网络数据进行复权/需要联网

+
+ +
+
+QUANTAXIS.QAData.data_fq.QA_data_make_hfq(bfq_data, xdxr_data)[source]
+

使用数据库数据进行复权

+
+ +
+
+QUANTAXIS.QAData.data_fq.QA_data_make_qfq(bfq_data, xdxr_data)[source]
+

使用数据库数据进行复权

+
+ +
+
+QUANTAXIS.QAData.data_fq.QA_data_stock_to_fq(__data, type_='01')[source]
+
+ +
+
+

QUANTAXIS.QAData.data_resample module

+
+
+QUANTAXIS.QAData.data_resample.QA_data_tick_resample(tick, type_='1min')[source]
+

tick采样成任意级别分钟线

+
+
Arguments:
+
tick {[type]} -- transaction
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+

QUANTAXIS.QAData.dsmethods module

+

DataStruct的方法

+
+
+QUANTAXIS.QAData.dsmethods.concat(lists)[source]
+

类似于pd.concat 用于合并一个list里面的多个DataStruct,会自动去重

+
+
Arguments:
+
lists {[type]} -- [DataStruct1,DataStruct2,....,DataStructN]
+
Returns:
+
[type] -- new DataStruct
+
+
+ +
+
+QUANTAXIS.QAData.dsmethods.from_tushare(dataframe, dtype='day')[source]
+

dataframe from tushare

+
+
Arguments:
+
dataframe {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+

QUANTAXIS.QAData.fundamental module

+
+
+

QUANTAXIS.QAData.realtimedata module

+
+
+

QUANTAXIS.QAData.schema module

+
+
+class QUANTAXIS.QAData.schema.Shares(**kwargs)[source]
+

Bases: sqlalchemy.ext.declarative.api.Base

+
+
+circulation
+
+ +
+
+effective_date
+
+ +
+
+shares
+
+ +
+
+sid
+
+ +
+ +
+
+class QUANTAXIS.QAData.schema.full(**kwargs)[source]
+

Bases: sqlalchemy.ext.declarative.api.Base

+
+
+adratio
+
+ +
+
+arturndays
+
+ +
+
+arturnover
+
+ +
+
+bips
+
+ +
+
+business_income
+
+ +
+
+bvps
+
+ +
+
+cashflowratio
+
+ +
+
+cashratio
+
+ +
+
+cf_liabilities
+
+ +
+
+cf_nm
+
+ +
+
+cf_sales
+
+ +
+
+code
+
+ +
+
+currentasset_days
+
+ +
+
+currentasset_turnover
+
+ +
+
+currentratio
+
+ +
+
+distrib
+
+ +
+
+epcf
+
+ +
+
+eps
+
+ +
+
+eps_yoy
+
+ +
+
+epsg
+
+ +
+
+gross_profit_rate
+
+ +
+
+icratio
+
+ +
+
+inventory_days
+
+ +
+
+inventory_turnover
+
+ +
+
+mbrg
+
+ +
+
+name
+
+ +
+
+nav
+
+ +
+
+net_profit_ratio
+
+ +
+
+net_profits
+
+ +
+
+nprg
+
+ +
+
+profits_yoy
+
+ +
+
+quarter
+
+ +
+
+quickratio
+
+ +
+
+rateofreturn
+
+ +
+
+report_date
+
+ +
+
+roe
+
+ +
+
+seg
+
+ +
+
+sheqratio
+
+ +
+
+targ
+
+ +
+
+trade_date
+
+ +
+ +
+
+class QUANTAXIS.QAData.schema.fundamental(**kwargs)[source]
+

Bases: sqlalchemy.ext.declarative.api.Base

+
+
+adratio
+
+ +
+
+arturndays
+
+ +
+
+arturnover
+
+ +
+
+bips
+
+ +
+
+business_income
+
+ +
+
+bvps
+
+ +
+
+cashflowratio
+
+ +
+
+cashratio
+
+ +
+
+cf_liabilities
+
+ +
+
+cf_nm
+
+ +
+
+cf_sales
+
+ +
+
+code
+
+ +
+
+currentasset_days
+
+ +
+
+currentasset_turnover
+
+ +
+
+currentratio
+
+ +
+
+distrib
+
+ +
+
+epcf
+
+ +
+
+eps
+
+ +
+
+eps_yoy
+
+ +
+
+epsg
+
+ +
+
+gross_profit_rate
+
+ +
+
+icratio
+
+ +
+
+inventory_days
+
+ +
+
+inventory_turnover
+
+ +
+
+mbrg
+
+ +
+
+name
+
+ +
+
+nav
+
+ +
+
+net_profit_ratio
+
+ +
+
+net_profits
+
+ +
+
+nprg
+
+ +
+
+profits_yoy
+
+ +
+
+quarter
+
+ +
+
+quickratio
+
+ +
+
+rateofreturn
+
+ +
+
+report_date
+
+ +
+
+roe
+
+ +
+
+seg
+
+ +
+
+sheqratio
+
+ +
+
+targ
+
+ +
+ +
+
+

QUANTAXIS.QAData.serialize module

+
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QAData.proto.html b/_build/html/source/QUANTAXIS.QAData.proto.html new file mode 100644 index 000000000..c319d283d --- /dev/null +++ b/_build/html/source/QUANTAXIS.QAData.proto.html @@ -0,0 +1,115 @@ + + + + + + + + QUANTAXIS.QAData.proto package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QAData.proto package

+
+

Submodules

+
+
+

QUANTAXIS.QAData.proto.order_pb2 module

+
+
+

QUANTAXIS.QAData.proto.stock_day_pb2 module

+
+
+

QUANTAXIS.QAData.proto.stock_min_pb2 module

+
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QAEngine.html b/_build/html/source/QUANTAXIS.QAEngine.html new file mode 100644 index 000000000..5beca4548 --- /dev/null +++ b/_build/html/source/QUANTAXIS.QAEngine.html @@ -0,0 +1,298 @@ + + + + + + + + QUANTAXIS.QAEngine package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QAEngine package

+
+

Submodules

+
+
+

QUANTAXIS.QAEngine.QAEvent module

+
+
+class QUANTAXIS.QAEngine.QAEvent.QA_Event(event_type=None, func=None, message=None, callback=False, *args, **kwargs)[source]
+

Bases: object

+
+ +
+
+class QUANTAXIS.QAEngine.QAEvent.QA_Worker[source]
+

Bases: object

+

JOB是worker 需要接受QA_EVENT 需要完善RUN方法

+
+
+run(event)[source]
+
+ +
+ +
+
+

QUANTAXIS.QAEngine.QATask module

+
+
+class QUANTAXIS.QAEngine.QATask.QA_Task(worker, event, engine=None, callback=False)[source]
+

Bases: object

+
+
+do()[source]
+
+ +
+
+result
+
+ +
+ +
+
+

QUANTAXIS.QAEngine.QAThreadEngine module

+
+
+class QUANTAXIS.QAEngine.QAThreadEngine.QA_Engine(queue=None, *args, **kwargs)[source]
+

Bases: QUANTAXIS.QAEngine.QAThreadEngine.QA_Thread

+
+
+clear()[source]
+
+ +
+
+create_kernal(name)[source]
+
+ +
+
+join()[source]
+

Wait until the thread terminates.

+

This blocks the calling thread until the thread whose join() method is +called terminates -- either normally or through an unhandled exception +or until the optional timeout occurs.

+

When the timeout argument is present and not None, it should be a +floating point number specifying a timeout for the operation in seconds +(or fractions thereof). As join() always returns None, you must call +isAlive() after join() to decide whether a timeout happened -- if the +thread is still alive, the join() call timed out.

+

When the timeout argument is not present or None, the operation will +block until the thread terminates.

+

A thread can be join()ed many times.

+

join() raises a RuntimeError if an attempt is made to join the current +thread as that would cause a deadlock. It is also an error to join() a +thread before it has been started and attempts to do so raises the same +exception.

+
+ +
+
+kernel_num
+
+ +
+
+pause()[source]
+
+ +
+
+register_kernal(name, kernal)[source]
+
+ +
+
+resume()[source]
+
+ +
+
+run()[source]
+

Method representing the thread's activity.

+

You may override this method in a subclass. The standard run() method +invokes the callable object passed to the object's constructor as the +target argument, if any, with sequential and keyword arguments taken +from the args and kwargs arguments, respectively.

+
+ +
+
+run_job(task)[source]
+
+ +
+
+start_kernal(name)[source]
+
+ +
+
+stop()[source]
+
+ +
+
+stop_all()[source]
+
+ +
+
+stop_kernal(name)[source]
+
+ +
+ +
+
+class QUANTAXIS.QAEngine.QAThreadEngine.QA_Thread(queue=None, name=None)[source]
+

Bases: threading.Thread

+

这是一个随意新建线程的生产者消费者模型

+
+
+get(task)[source]
+
+ +
+
+get_nowait(task)[source]
+
+ +
+
+pause()[source]
+
+ +
+
+put(task)[source]
+
+ +
+
+put_nowait(task)[source]
+
+ +
+
+qsize()[source]
+
+ +
+
+resume()[source]
+
+ +
+
+run()[source]
+

Method representing the thread's activity.

+

You may override this method in a subclass. The standard run() method +invokes the callable object passed to the object's constructor as the +target argument, if any, with sequential and keyword arguments taken +from the args and kwargs arguments, respectively.

+
+ +
+
+stop()[source]
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QAFetch.html b/_build/html/source/QUANTAXIS.QAFetch.html new file mode 100644 index 000000000..3ff3bebef --- /dev/null +++ b/_build/html/source/QUANTAXIS.QAFetch.html @@ -0,0 +1,909 @@ + + + + + + + + QUANTAXIS.QAFetch package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QAFetch package

+
+

Submodules

+
+
+

QUANTAXIS.QAFetch.Fetcher module

+

QA fetch module

+

@yutiansut

+

QAFetch is Under [QAStandard#0.0.2@10x] Protocol

+
+
+class QUANTAXIS.QAFetch.Fetcher.QA_Fetcher(ip='127.0.0.1', port=27017, username='', password='')[source]
+

Bases: object

+
+
+change_ip(ip, port)[source]
+
+ +
+
+get_info(code, frequence, market, source, output)[source]
+
+ +
+
+get_quotation(code=None, start=None, end=None, frequence=None, market=None, source=None, output=None)[source]
+
+
Arguments:
+
code {str/list} -- 证券/股票的代码 +start {str} -- 开始日期 +end {str} -- 结束日期 +frequence {enum} -- 频率 QA.FREQUENCE +market {enum} -- 市场 QA.MARKET_TYPE +source {enum} -- 来源 QA.DATASOURCE +output {enum} -- 输出类型 QA.OUTPUT_FORMAT
+
+
+ +
+ +
+
+QUANTAXIS.QAFetch.Fetcher.QA_quotation(code, start, end, frequence, market, source, output)[source]
+

一个统一的fetch

+
+
Arguments:
+
code {str/list} -- 证券/股票的代码 +start {str} -- 开始日期 +end {str} -- 结束日期 +frequence {enum} -- 频率 QA.FREQUENCE +market {enum} -- 市场 QA.MARKET_TYPE +source {enum} -- 来源 QA.DATASOURCE +output {enum} -- 输出类型 QA.OUTPUT_FORMAT
+
+
+ +
+
+

QUANTAXIS.QAFetch.QACrawler module

+
+
+QUANTAXIS.QAFetch.QACrawler.QA_fetch_get_sh_margin(date)[source]
+

return shanghai margin data

+
+
Arguments:
+
date {str YYYY-MM-DD} -- date format
+
Returns:
+
pandas.DataFrame -- res for margin data
+
+
+ +
+
+QUANTAXIS.QAFetch.QACrawler.QA_fetch_get_sz_margin(date)[source]
+

return shenzhen margin data

+
+
Arguments:
+
date {str YYYY-MM-DD} -- date format
+
Returns:
+
pandas.DataFrame -- res for margin data
+
+
+ +
+
+

QUANTAXIS.QAFetch.QAEastMoney module

+
+
+QUANTAXIS.QAFetch.QAEastMoney.QA_fetch_get_stock_analysis(code)[source]
+

'zyfw', 主营范围 'jyps'#经营评述 'zygcfx' 主营构成分析

+

date 主营构成 主营收入(元) 收入比例cbbl 主营成本(元) 成本比例 主营利润(元) 利润比例 毛利率(%) +行业 /产品/ 区域 hq cp qy

+
+ +
+
+

QUANTAXIS.QAFetch.QAQuery module

+
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_account(message={}, db=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

get the account

+
+
Arguments:
+
query_mes {[type]} -- [description]
+
Keyword Arguments:
+
collection {[type]} -- [description] (default: {DATABASE})
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_backtest_history(cookie=None, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'backtest_history'))[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_backtest_info(user=None, account_cookie=None, strategy=None, stock_list=None, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'backtest_info'))[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_future_day()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_future_min()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_future_tick()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_index_day(code, start, end, format='numpy', collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'index_day'))[source]
+

获取指数日线

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_index_min(code, start, end, format='numpy', frequence='1min', collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'index_min'))[source]
+

获取股票分钟线

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_indexlist_day(stock_list, date_range, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'index_day'))[source]
+

获取多个股票的日线

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_quotation(code, date=datetime.date(2018, 5, 7), db=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

获取某一只实时5档行情的存储结果

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_quotations(date=datetime.date(2018, 5, 7), db=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

获取全部实时5档行情的存储结果

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_stock_block(code=None, format='pd', collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_block'))[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_stock_day(code, start, end, format='numpy', frequence='day', collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_day'))[source]
+

获取股票日线

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_stock_full(date, format='numpy', collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_day'))[source]
+

获取全市场的某一日的数据

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_stock_info(code, format='pd', collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_info'))[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_stock_list(collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_list'))[source]
+

获取股票列表

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_stock_min(code, start, end, format='numpy', frequence='1min', collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_min'))[source]
+

获取股票分钟线

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_stock_name(code, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_list'))[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_stock_xdxr(code, format='pd', collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_xdxr'))[source]
+

获取股票除权信息/数据库

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery.QA_fetch_trade_date()[source]
+

获取交易日期

+
+ +
+
+

QUANTAXIS.QAFetch.QAQuery_Advance module

+
+
+QUANTAXIS.QAFetch.QAQuery_Advance.QA_fetch_index_day_adv(code, start, end=None, if_drop_index=False, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'index_day'))[source]
+

获取指数日线

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery_Advance.QA_fetch_index_min_adv(code, start, end=None, frequence='1min', if_drop_index=False, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'index_min'))[source]
+

获取股票分钟线

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery_Advance.QA_fetch_security_list_adv(collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_list'))[source]
+

获取股票列表

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery_Advance.QA_fetch_stock_block_adv(code=None, blockname=None, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_block'))[source]
+

返回板块

+
+
Keyword Arguments:
+
code {[type]} -- [description] (default: {None}) +blockname {[type]} -- [descrioption] (default : {None}) +collections {[type]} -- [description] (default: {DATABASE})
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAFetch.QAQuery_Advance.QA_fetch_stock_day_adv(code, start='all', end=None, if_drop_index=False, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_day'))[source]
+

获取股票日线

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery_Advance.QA_fetch_stock_day_full_adv(date)[source]
+

返回全市场某一天的数据

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery_Advance.QA_fetch_stock_list_adv(collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_list'))[source]
+

获取股票列表

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery_Advance.QA_fetch_stock_min_adv(code, start, end=None, frequence='1min', if_drop_index=False, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_min'))[source]
+

获取股票分钟线

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery_Advance.QA_fetch_stock_realtime_adv(code=None, num=1, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'realtime_2018-05-07'))[source]
+

返回当日的上下五档, code可以是股票可以是list, num是每个股票获取的数量

+
+ +
+
+QUANTAXIS.QAFetch.QAQuery_Advance.QA_fetch_stock_transaction_adv(code, start, end=None, if_drop_index=False, collections=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'stock_transaction'))[source]
+
+ +
+
+

QUANTAXIS.QAFetch.QATdx module

+
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_depth_market_data(code=['000001', '000002'], ip='60.191.117.167', port=7709)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_future_day(code, start_date, end_date, frequence='day', ip='58.246.109.27', port=7721)[source]
+

期货数据 日线

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_future_list(ip='58.246.109.27', port=7721)[source]
+

期货代码list

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_future_min(code, start, end, frequence='1min', ip='58.246.109.27', port=7721)[source]
+

期货数据 分钟线

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_future_realtime(code, ip='58.246.109.27', port=7721)[source]
+

期货实时价格

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_future_transaction(ip='58.246.109.27', port=7721)[source]
+

期货历史成交分笔

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_future_transaction_realtime(ip='58.246.109.27', port=7721)[source]
+

期货历史成交分笔

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_index_day(code, start_date, end_date, frequence='day', ip='60.191.117.167', port=7709)[source]
+

指数日线

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_index_min(code, start, end, frequence='1min', ip='60.191.117.167', port=7709)[source]
+

指数分钟线

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_security_bars(code, _type, lens, ip='60.191.117.167', port=7709)[source]
+

按bar长度推算数据

+
+
Arguments:
+
code {[type]} -- [description] +_type {[type]} -- [description] +lens {[type]} -- [description]
+
Keyword Arguments:
+
ip {[type]} -- [description] (default: {best_ip}) +port {[type]} -- [description] (default: {7709})
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_stock_block(ip='60.191.117.167', port=7709)[source]
+

板块数据

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_stock_day(code, start_date, end_date, if_fq='00', frequence='day', ip='60.191.117.167', port=7709)[source]
+

获取日线及以上级别的数据

+
+
Arguments:
+
code {str:6} -- code 是一个单独的code 6位长度的str +start_date {str:10} -- 10位长度的日期 比如'2017-01-01' +end_date {str:10} -- 10位长度的日期 比如'2018-01-01'
+
Keyword Arguments:
+
if_fq {str} -- '00'/'bfq' -- 不复权 '01'/'qfq' -- 前复权 '02'/'hfq' -- 后复权 '03'/'ddqfq' -- 定点前复权 '04'/'ddhfq' --定点后复权 +frequency {str} -- day/week/month/quarter/year 也可以是简写 D/W/M/Q/Y +ip {str} -- [description] (default: best_ip['stock']['ip']) ip可以通过select_best_ip()函数重新获取 +port {int} -- [description] (default: {7709})
+
Returns:
+
pd.DataFrame/None -- 返回的是dataframe,如果出错比如只获取了一天,而当天停牌,返回None
+
Exception:
+
如果出现网络问题/服务器拒绝, 会出现socket:time out 尝试再次获取/更换ip即可, 本函数不做处理
+
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_stock_info(code, ip='60.191.117.167', port=7709)[source]
+

股票基本信息

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_stock_latest(code, ip='60.191.117.167', port=7709)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_stock_list(type_='stock', ip='60.191.117.167', port=7709)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_stock_min(code, start, end, frequence='1min', ip='60.191.117.167', port=7709)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_stock_realtime(code=['000001', '000002'], ip='60.191.117.167', port=7709)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_stock_transaction(code, start, end, retry=2, ip='60.191.117.167', port=7709)[source]
+

历史逐笔成交 buyorsell 1--sell 0--buy 2--盘前

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_stock_transaction_realtime(code, ip='60.191.117.167', port=7709)[source]
+

实时逐笔成交 包含集合竞价 buyorsell 1--sell 0--buy 2--盘前

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_stock_xdxr(code, ip='60.191.117.167', port=7709)[source]
+

除权除息

+
+ +
+
+QUANTAXIS.QAFetch.QATdx.QA_fetch_get_wholemarket_list()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.for_sh(code)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.for_sz(code)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.ping(ip, port=7709, type_='stock')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx.select_best_ip()[source]
+
+ +
+
+

QUANTAXIS.QAFetch.QATdx_adv module

+
+
+class QUANTAXIS.QAFetch.QATdx_adv.QA_Tdx_Executor(thread_num=2, *args, **kwargs)[source]
+

Bases: object

+
+
+api
+
+ +
+
+api_worker()[source]
+
+ +
+
+get_available()[source]
+
+ +
+
+get_frequence(frequence)[source]
+
+ +
+
+get_market(code)[source]
+
+ +
+
+get_realtime(code)[source]
+
+ +
+
+get_realtime_concurrent(code)[source]
+
+ +
+
+get_security_bar(code, _type, lens)[source]
+
+ +
+
+get_security_bar_concurrent(code, _type, lens)[source]
+
+ +
+
+ipsize
+
+ +
+
+save_mongo(data, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+
+ +
+ +
+
+QUANTAXIS.QAFetch.QATdx_adv.bat()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx_adv.get_bar()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATdx_adv.get_day_once()[source]
+
+ +
+
+

QUANTAXIS.QAFetch.QAThs module

+
+
+QUANTAXIS.QAFetch.QAThs.QA_fetch_get_stock_block()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAThs.QA_fetch_get_stock_day(code, start, end, if_fq='00')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAThs.QA_fetch_get_stock_day_in_year(code, year, if_fq='00')[source]
+
+ +
+
+

QUANTAXIS.QAFetch.QATushare module

+
+
+QUANTAXIS.QAFetch.QATushare.QA_fetch_get_stock_day(name, start='', end='', if_fq='01', type_='json')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATushare.QA_fetch_get_stock_info(name)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATushare.QA_fetch_get_stock_list()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATushare.QA_fetch_get_stock_realtime()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATushare.QA_fetch_get_stock_tick(name, date)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATushare.QA_fetch_get_stock_time_to_market()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QATushare.QA_fetch_get_trade_date(end, exchange)[source]
+
+ +
+
+

QUANTAXIS.QAFetch.QAWind module

+

QAWind

+

QAWind is a data fetch module just for WIND Institution Version

+

QAWind is under the [QAStandard#0.0.2 @101-1],[QAStandard#0.0.2 @501-0] protocol

+

@author: yutiansut

+

@last modified:2017/4/5

+
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_stock_day(name, startDate, endDate, if_fq='01')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_stock_day_simple(name, startDate, endDate)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_stock_financial(name, startDate, endDate)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_stock_indicator(name, startDate, endDate)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_stock_info(name, startDate, endDate)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_stock_list(date)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_stock_list_special(date, id)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_stock_risk(name, startDate, endDate)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_stock_shape(name, startDate, endDate)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_stock_xueqiu(name, startDate, endDate)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAWind.QA_fetch_get_trade_date(endDate, exchange)[source]
+
+ +
+
+

QUANTAXIS.QAFetch.QAfinancial module

+
+
+QUANTAXIS.QAFetch.QAfinancial.download()[source]
+

会创建一个download/文件夹

+
+ +
+
+QUANTAXIS.QAFetch.QAfinancial.get_and_parse(filename)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAfinancial.get_filename()[source]
+
+ +
+
+QUANTAXIS.QAFetch.QAfinancial.prase_all()[source]
+

解析目录下的所有文件

+
+ +
+
+

QUANTAXIS.QAFetch.base module

+
+
+

QUANTAXIS.QAFetch.data_list module

+

0201e20000000000 RZRQ (融资融券标的) 1000009226000000 RQ (转融券标的) a001050100000000 ST(ST股)

+

a001050200000000 SST (*ST) 1000023325000000 YJ(预警 SZSE) a001050d00000000 小盘股

+

a001050e00000000 大盘蓝筹 0201240000000000 cixin(次新股)

+
+
+

QUANTAXIS.QAFetch.realtime module

+

单线程的实时获取

+
+
+QUANTAXIS.QAFetch.realtime.get_today_all(output='pd')[source]
+

today all

+
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+

Module contents

+

QA fetch module

+

@yutiansut

+

QAFetch is Under [QAStandard#0.0.2@10x] Protocol

+
+
+QUANTAXIS.QAFetch.QA_fetch_get_future_day(package, code, start, end, frequence='day')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_future_list(package)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_future_min(package, code, start, end, frequence='1min')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_index_day(package, code, start, end, level='day')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_index_min(package, code, start, end, level='1min')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_security_bars(code, _type, lens)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_stock_block(package)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_stock_day(package, code, start, end, if_fq='01', level='day', type_='json')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_stock_indicator(package, code, start, end)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_stock_info(package, code)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_stock_list(package, type_='stock')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_stock_min(package, code, start, end, level='1min')[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_stock_realtime(package, code)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_stock_transaction(package, code, start, end, retry=2)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_stock_transaction_realtime(package, code)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_stock_xdxr(package, code)[source]
+
+ +
+
+QUANTAXIS.QAFetch.QA_fetch_get_trade_date(package, end, exchange)[source]
+
+ +
+
+QUANTAXIS.QAFetch.use(package)[source]
+
+ +
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QAIndicator.html b/_build/html/source/QUANTAXIS.QAIndicator.html new file mode 100644 index 000000000..b74e42251 --- /dev/null +++ b/_build/html/source/QUANTAXIS.QAIndicator.html @@ -0,0 +1,486 @@ + + + + + + + + QUANTAXIS.QAIndicator package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QAIndicator package

+
+

Submodules

+
+
+

QUANTAXIS.QAIndicator.base module

+
+
+QUANTAXIS.QAIndicator.base.ABS(Series)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.AVEDEV(Series, N)[source]
+

平均绝对偏差 mean absolute deviation

+
+ +
+
+QUANTAXIS.QAIndicator.base.BBI(Series, N1, N2, N3, N4)[source]
+

多空指标

+
+ +
+
+QUANTAXIS.QAIndicator.base.BBIBOLL(Series, N1, N2, N3, N4, N, M)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.COUNT(COND, N)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.CROSS(A, B)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.DIFF(Series, N=1)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.EMA(Series, N)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.HHV(Series, N)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.IF(COND, V1, V2)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.LAST(COND, N1, N2)[source]
+

表达持续性

+
+
Arguments:
+
COND {[type]} -- [description] +N1 {[type]} -- [description] +N2 {[type]} -- [description]
+
+
+ +
+
+QUANTAXIS.QAIndicator.base.LLV(Series, N)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.MA(Series, N)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.MACD(Series, FAST, SLOW, MID)[source]
+

macd指标 仅适用于Series +对于DATAFRAME的应用请使用QA_indicator_macd

+
+ +
+
+QUANTAXIS.QAIndicator.base.MAX(A, B)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.MIN(A, B)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.REF(Series, N)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.SMA(Series, N, M=1)[source]
+

威廉SMA算法

+

本次修正主要是对于返回值的优化,现在的返回值会带上原先输入的索引index +2018/5/3 +@yutiansut

+
+ +
+
+QUANTAXIS.QAIndicator.base.STD(Series, N)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.base.SUM(Series, N)[source]
+
+ +
+
+

QUANTAXIS.QAIndicator.indicators module

+
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_ADTM(DataFrame, N=23, M=8)[source]
+

动态买卖气指标

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_ARBR(DataFrame, M1=26, M2=70, M3=150)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_ASI(DataFrame, M1=26, M2=10)[source]
+

LC=REF(CLOSE,1); +AA=ABS(HIGH-LC); +BB=ABS(LOW-LC); +CC=ABS(HIGH-REF(LOW,1)); +DD=ABS(LC-REF(OPEN,1)); +R=IF(AA>BB AND AA>CC,AA+BB/2+DD/4,IF(BB>CC AND BB>AA,BB+AA/2+DD/4,CC+DD/4)); +X=(CLOSE-LC+(CLOSE-OPEN)/2+LC-REF(OPEN,1)); +SI=16*X/R*MAX(AA,BB); +ASI:SUM(SI,M1); +ASIT:MA(ASI,M2);

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_ATR(DataFrame, N=14)[source]
+

输出TR:(最高价-最低价)和昨收-最高价的绝对值的较大值和昨收-最低价的绝对值的较大值 +输出真实波幅:TR的N日简单移动平均 +算法:今日振幅、今日最高与昨收差价、今日最低与昨收差价中的最大值,为真实波幅,求真实波幅的N日移动平均

+

参数:N 天数,一般取14

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_BBI(DataFrame, N1=3, N2=6, N3=12, N4=24)[source]
+

多空指标

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_BIAS(DataFrame, N1, N2, N3)[source]
+

乖离率

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_BOLL(DataFrame, N=20, P=2)[source]
+

布林线

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_CCI(DataFrame, N=14)[source]
+

TYP:=(HIGH+LOW+CLOSE)/3; +CCI:(TYP-MA(TYP,N))/(0.015*AVEDEV(TYP,N));

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_CHO(DataFrame, N1=10, N2=20, M=6)[source]
+

佳庆指标 CHO

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_CR(DataFrame, N=26, M1=5, M2=10, M3=20)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_DDI(DataFrame, N=13, N1=26, M=1, M1=5)[source]
+

'方向标准离差指数' +分析DDI柱状线,由红变绿(正变负),卖出信号参考;由绿变红,买入信号参考。

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_DMA(DataFrame, M1=10, M2=50, M3=10)[source]
+

平均线差 DMA

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_DMI(DataFrame, M1=14, M2=6)[source]
+

趋向指标 DMI

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_EMA(DataFrame, N)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_EXPMA(DataFrame, P1=5, P2=10, P3=20, P4=60)[source]
+

指数平均线 EXPMA

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_KDJ(DataFrame, N=9, M1=3, M2=3)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_MA(DataFrame, N)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_MACD(DataFrame, short=12, long=26, mid=9)[source]
+

MACD CALC

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_MFI(DataFrame, N=14)[source]
+

资金指标 +TYP := (HIGH + LOW + CLOSE)/3; +V1:=SUM(IF(TYP>REF(TYP,1),TYP*VOL,0),N)/SUM(IF(TYP<REF(TYP,1),TYP*VOL,0),N); +MFI:100-(100/(1+V1)); +赋值: (最高价 + 最低价 + 收盘价)/3 +V1赋值:如果TYP>1日前的TYP,返回TYP*成交量(手),否则返回0的N日累和/如果TYP<1日前的TYP,返回TYP*成交量(手),否则返回0的N日累和 +输出资金流量指标:100-(100/(1+V1))

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_MIKE(DataFrame, N=12)[source]
+

MIKE指标 +指标说明 +MIKE是另外一种形式的路径指标。 +买卖原则 +1 WEAK-S,MEDIUM-S,STRONG-S三条线代表初级、中级、强力支撑。 +2 WEAK-R,MEDIUM-R,STRONG-R三条线代表初级、中级、强力压力。

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_MTM(DataFrame, N=12, M=6)[source]
+

动量线

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_OBV(DataFrame)[source]
+

能量潮

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_OSC(DataFrame, N=20, M=6)[source]
+

变动速率线

+

震荡量指标OSC,也叫变动速率线。属于超买超卖类指标,是从移动平均线原理派生出来的一种分析指标。

+

它反应当日收盘价与一段时间内平均收盘价的差离值,从而测出股价的震荡幅度。

+

按照移动平均线原理,根据OSC的值可推断价格的趋势,如果远离平均线,就很可能向平均线回归。

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_PBX(DataFrame, N1=3, N2=5, N3=8, N4=13, N5=18, N6=24)[source]
+

瀑布线

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_PVT(DataFrame)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_ROC(DataFrame, N=12, M=6)[source]
+

变动率指标

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_RSI(DataFrame, N1=12, N2=26, N3=9)[source]
+

相对强弱指标RSI1:SMA(MAX(CLOSE-LC,0),N1,1)/SMA(ABS(CLOSE-LC),N1,1)*100;

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_SKDJ(DataFrame, N=9, M=3)[source]
+

1.指标>80 时,回档机率大;指标<20 时,反弹机率大; +2.K在20左右向上交叉D时,视为买进信号参考; +3.K在80左右向下交叉D时,视为卖出信号参考; +4.SKDJ波动于50左右的任何讯号,其作用不大。

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_SMA(DataFrame, N)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_VPT(DataFrame, N=51, M=6)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_VR(DataFrame, M1=26, M2=100, M3=200)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_VRSI(DataFrame, N=6)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_VSTD(DataFrame, N=10)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_WR(DataFrame, N, N1)[source]
+

威廉指标

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.QA_indicator_shadow(DataFrame)[source]
+

上下影线指标

+
+ +
+
+QUANTAXIS.QAIndicator.indicators.amplitude(DataFrame)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.body(DataFrame)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.body_abs(DataFrame)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.lower_shadow(DataFrame)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.price_pcg(DataFrame)[source]
+
+ +
+
+QUANTAXIS.QAIndicator.indicators.upper_shadow(DataFrame)[source]
+
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QAMarket.html b/_build/html/source/QUANTAXIS.QAMarket.html new file mode 100644 index 000000000..dc84a8ec4 --- /dev/null +++ b/_build/html/source/QUANTAXIS.QAMarket.html @@ -0,0 +1,1208 @@ + + + + + + + + QUANTAXIS.QAMarket package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QAMarket package

+
+

Submodules

+
+
+

QUANTAXIS.QAMarket.Broker_Calender module

+
+
+

QUANTAXIS.QAMarket.QABacktestBroker module

+
+
+class QUANTAXIS.QAMarket.QABacktestBroker.QA_BacktestBroker(commission_fee_coeff=0.0015, if_nondatabase=False)[source]
+

Bases: QUANTAXIS.QAMarket.QABroker.QA_Broker

+

QUANTAXIS Broker 部分

+

回测 +股票/指数/期货/债券/ETF/基金 +@yutiansut

+

对于不同的市场规则: +股票市场 t+1 +期货/期权/加密货币市场 t+0

+

股票/加密货币市场不允许卖空 +期货/期权市场允许卖空

+

t+1的市场是 +当日的买入 更新持仓- 不更新可卖数量- 资金冻结 +当日的卖出 及时更新可用资金

+

t+0市场是: +当日买入 即时更新持仓和可卖 +当日卖出 即时更新

+

卖空的规则是 +允许无仓位的时候卖出证券(按市值和保证金比例限制算)

+
+
+get_market(order)[source]
+

get_market func

+

[description]

+
+
Arguments:
+
order {orders} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+query_data(code, start, end, frequence, market_type=None)[source]
+

标准格式是numpy

+
+ +
+
+receive_order(event)[source]
+

get the order and choice which market to trade

+
+ +
+
+run(event)[source]
+
+ +
+
+warp(order)[source]
+

对order/market的封装

+

[description]

+
+
Arguments:
+
order {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.QABroker module

+

需要一个可以被修改和继承的基类

+

2017/8/12

+
+
+class QUANTAXIS.QAMarket.QABroker.QA_BROKER_EVENT(*args, **kwargs)[source]
+

Bases: QUANTAXIS.QAEngine.QAEvent.QA_Event

+
+ +
+
+class QUANTAXIS.QAMarket.QABroker.QA_Broker(*args, **kwargs)[source]
+

Bases: QUANTAXIS.QAEngine.QAEvent.QA_Worker

+

MARKET ENGINGE ABSTRACT

+

receive_order => warp => get_data => engine

+
+
+get_market(order)[source]
+
+ +
+
+receive_order(event)[source]
+
+ +
+
+warp(order)[source]
+

对order/market的封装

+

[description]

+
+
Arguments:
+
order {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.QADealer module

+
+
+class QUANTAXIS.QAMarket.QADealer.QA_Dealer(commission_fee_coeff=0.00025, tax_coeff=0.001, *args, **kwargs)[source]
+

Bases: object

+

[summary]

+

对于不同的市场规则: +股票市场 t+1 +期货/期权/加密货币市场 t+0

+

股票/加密货币市场不允许卖空 +期货/期权市场允许卖空

+

t+1的市场是 +当日的买入 更新持仓- 不更新可卖数量- 资金冻结 +当日的卖出 及时更新可用资金

+

t+0市场是: +当日买入 即时更新持仓和可卖 +当日卖出 即时更新

+

卖空的规则是 +允许无仓位的时候卖出证券(按市值和保证金比例限制算)

+
+
+backtest_stock_dealer()[source]
+

MARKET ENGINE STOCK

+

在拿到市场数据后对于订单的撮合判断 生成成交信息

+

trading system +step1: check self.market_data +step2: deal +step3: return callback

+
+ +
+
+cal_fee()[source]
+
+ +
+
+callback_message()[source]
+
+ +
+
+deal(order, market_data)[source]
+
+ +
+ +
+
+class QUANTAXIS.QAMarket.QADealer.Stock_Dealer(*args, **kwargs)[source]
+

Bases: QUANTAXIS.QAMarket.QADealer.QA_Dealer

+
+ +
+
+class QUANTAXIS.QAMarket.QADealer.commission[source]
+

Bases: object

+
+
+if_buyside_commission = False
+
+ +
+
+if_commission = False
+
+ +
+
+if_sellside_commission = True
+
+ +
+ +
+
+class QUANTAXIS.QAMarket.QADealer.dealer_preset(market_type, *args, **kwargs)[source]
+

Bases: object

+
+
+load_preset()[source]
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.QAMarket module

+
+
+class QUANTAXIS.QAMarket.QAMarket.QA_Market(*args, **kwargs)[source]
+

Bases: QUANTAXIS.QAMarket.QATrade.QA_Trade

+

QUANTAXIS MARKET 部分

+

交易前置/可连接到多个broker中

+

暂时还是采用多线程engine模式

+
+
+clear()[source]
+
+ +
+
+connect(broker)[source]
+
+ +
+
+get_account(account_cookie)[source]
+
+ +
+
+get_account_id()[source]
+
+ +
+
+get_trading_day()[source]
+
+ +
+
+insert_order(account_id, amount, amount_model, time, code, price, order_model, towards, market_type, frequence, broker_name)[source]
+
+ +
+
+login(broker_name, account_cookie, account=None)[source]
+
+ +
+
+logout(account_cookie, broker_name)[source]
+
+ +
+
+on_insert_order(order)[source]
+
+ +
+
+on_query_data(data)[source]
+
+ +
+
+on_trade_event(event)[source]
+
+ +
+
+query_assets(account_cookie)[source]
+
+ +
+
+query_cash(account_cookie)[source]
+
+ +
+
+query_currentbar(broker_name, market_type, code)[source]
+
+ +
+
+query_data(broker_name, frequence, market_type, code, start, end=None)[source]
+
+ +
+
+query_data_no_wait(broker_name, frequence, market_type, code, start, end=None)[source]
+
+ +
+
+query_order(broker_name, order_id)[source]
+
+ +
+
+query_position(account_cookie)[source]
+
+ +
+
+register(broker_name, broker)[source]
+
+ +
+
+start()[source]
+
+ +
+
+upcoming_data(broker, data)[source]
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.QAOrder module

+
+
+class QUANTAXIS.QAMarket.QAOrder.QA_Order(price=None, date=None, datetime=None, sending_time=None, transact_time=None, amount=None, market_type=None, frequence=None, towards=None, code=None, user=None, account_cookie=None, strategy=None, order_model=None, amount_model='by_amount', order_id=None, trade_id=None, status='100', callback=False, *args, **kwargs)[source]
+

Bases: object

+
+
+from_dict(order)[source]
+
+ +
+
+info()[source]
+
+ +
+
+to_df()[source]
+
+ +
+
+to_dict()[source]
+
+ +
+ +
+
+class QUANTAXIS.QAMarket.QAOrder.QA_OrderQueue[source]
+

Bases: object

+

一个待成交队列 +这里面都是对于方法的封装

+
+
+insert_order(order)[source]
+
+ +
+
+order_ids
+
+ +
+
+pending
+

选择待成交列表

+

[description]

+
+
Returns:
+
dataframe
+
+
+ +
+
+query_order(order_id)[source]
+
+ +
+
+set_status(order_id, new_status)[source]
+
+ +
+
+settle()[source]
+

结算

+

清空订单簿

+
+ +
+
+trade_list
+

批量交易

+

[description]

+
+
Returns:
+
list of orders
+
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.QAOrderHandler module

+
+
+class QUANTAXIS.QAMarket.QAOrderHandler.QA_OrderHandler(*args, **kwargs)[source]
+

Bases: QUANTAXIS.QAEngine.QAEvent.QA_Worker

+

ORDER执行器

+

ORDEHANDLDER 归属于MARKET前置

+

仅负责一个无状态的执行层

+

ORDER执行器的作用是因为 +在实盘中 当一个订单发送出去的时候,市场不会返回一个更新的订单类回来 +大部分时间都依赖子线程主动查询 或者是一个市场信息来进行判断

+

ORDER_Handler的作用就是根据信息更新Order

+

用于接受订单 发送给相应的marker_broker 再根据返回的信息 进行更新

+

可用的market_broker: +1.回测盘 +2.实时模拟盘 +3.实盘

+
+
+query_order(order_id)[source]
+
+ +
+
+run(event)[source]
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.QARandomBroker module

+
+
+class QUANTAXIS.QAMarket.QARandomBroker.QA_RandomBroker(*args, **kwargs)[source]
+

Bases: QUANTAXIS.QAMarket.QABroker.QA_Broker

+
+
+get_data(order)[source]
+
+ +
+
+receive_order(order)[source]
+
+ +
+
+warp(order)[source]
+

对order/market的封装

+

[description]

+
+
Arguments:
+
order {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.QARealBroker module

+
+
+class QUANTAXIS.QAMarket.QARealBroker.QA_RealBroker(*args, **kwargs)[source]
+

Bases: QUANTAXIS.QAMarket.QABroker.QA_Broker

+
+
+get_data(order)[source]
+
+ +
+
+receive_order(order)[source]
+
+ +
+
+warp(order)[source]
+

对order/market的封装

+

[description]

+
+
Arguments:
+
order {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.QASimulatedBroker module

+
+
+class QUANTAXIS.QAMarket.QASimulatedBroker.QA_SimulatedBroker(*args, **kwargs)[source]
+

Bases: QUANTAXIS.QAMarket.QABroker.QA_Broker

+
+
+get_market(order)[source]
+
+ +
+
+query_data(code, start, end, frequence, market_type=None)[source]
+

标准格式是numpy

+
+ +
+
+receive_order(event)[source]
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.QATrade module

+
+
+class QUANTAXIS.QAMarket.QATrade.QA_Trade(*args, **kwargs)[source]
+

Bases: object

+

多线程+generator模式

+
+
+cancel_order(*args, **kwargs)[source]
+
+ +
+
+connect(*args, **kwargs)[source]
+
+ +
+
+get_account_id(*args, **kwargs)[source]
+
+ +
+
+get_api_last_error(*args, **kwargs)[source]
+
+ +
+
+get_api_version(*args, **kwargs)[source]
+
+ +
+
+get_client_id(*args, **kwargs)[source]
+
+ +
+
+get_trading_day(*args, **kwargs)[source]
+
+ +
+
+insert_order(*args, **kwargs)[source]
+
+ +
+
+login(*args, **kwargs)[source]
+
+ +
+
+logout(*args, **kwargs)[source]
+
+ +
+
+on_cancel_order(*args, **kwargs)[source]
+
+ +
+
+on_cancel_order_event(*args, **kwargs)[source]
+
+ +
+
+on_connect(*args, **kwargs)[source]
+
+ +
+
+on_error(*args, **kwargs)[source]
+
+ +
+
+on_insert_order(*args, **kwargs)[source]
+
+ +
+
+on_order_event(*args, **kwargs)[source]
+
+ +
+
+on_query_assets(*args, **kwargs)[source]
+
+ +
+
+on_query_data(*args, **kwargs)[source]
+
+ +
+
+on_query_order(*args, **kwargs)[source]
+
+ +
+
+on_query_position(*args, **kwargs)[source]
+
+ +
+
+on_query_trade(*args, **kwargs)[source]
+
+ +
+
+on_trade_event(*args, **kwargs)[source]
+
+ +
+
+query_assets(*args, **kwargs)[source]
+
+ +
+
+query_data(*args, **kwargs)[source]
+
+ +
+
+query_order(*args, **kwargs)[source]
+
+ +
+
+query_position(*args, **kwargs)[source]
+
+ +
+
+query_trade(*args, **kwargs)[source]
+
+ +
+
+register_spi(*args, **kwargs)[source]
+
+ +
+
+release(*args, **kwargs)[source]
+
+ +
+
+subscribe_public_topic(*args, **kwargs)[source]
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.shipaneBroker module

+
+
+class QUANTAXIS.QAMarket.shipaneBroker.SPETradeApi(endpoint='http://127.0.0.1:8888')[source]
+

Bases: QUANTAXIS.QAMarket.QABroker.QA_Broker

+
+
+call(func, params=None)[source]
+
+ +
+
+cancel_order(client_id, exchange_id, hth)[source]
+
+ +
+
+data_to_df(result)[source]
+
+ +
+
+get_quote(client_id, code)[source]
+
+ +
+
+logoff(client_id)[source]
+
+ +
+
+logon(ip, port, version, yyb_id, account_id, trade_account, jy_passwrod, tx_password)[source]
+
+ +
+
+ping()[source]
+
+ +
+
+query_data(client_id, category)[source]
+
+ +
+
+receive_order(event)[source]
+

0 限价委托; 上海限价委托 / 深圳限价委托 +1 市价委托(深圳对方最优价格) +2 市价委托(深圳本方最优价格) +3 市价委托(深圳即时成交剩余撤销) +4 市价委托(上海五档即成剩撤 / 深圳五档即成剩撤) +5 市价委托(深圳全额成交或撤销) +6 市价委托(上海五档即成转限价)

+
+ +
+
+repay(client_id, amount)[source]
+
+ +
+
+run(event)[source]
+
+ +
+
+send_order(client_id, category, price_type, gddm, zqdm, price, quantity)[source]
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.shipaneclient module

+
+
+class QUANTAXIS.QAMarket.shipaneclient.Client(logger=None, **kwargs)[source]
+

Bases: object

+
+
+KEY_REGEX = 'key=([^&]*)'
+
+ +
+
+buy(client=None, timeout=None, **kwargs)[source]
+
+ +
+
+cancel(client=None, order_id=None, timeout=None)[source]
+
+ +
+
+cancel_all(client=None, timeout=None)[source]
+
+ +
+
+create_adjustment(client=None, request_json=None, timeout=None)[source]
+
+ +
+
+execute(client=None, timeout=None, **kwargs)[source]
+
+ +
+
+get_account(client=None, timeout=None)[source]
+
+ +
+
+get_orders(client=None, status='', timeout=None)[source]
+
+ +
+
+get_positions(client=None, media_type=<MediaType.DEFAULT: 'application/json'>, timeout=None)[source]
+
+ +
+
+get_statuses(timeout=None)[source]
+
+ +
+
+host
+
+ +
+
+ipo(client=None, timeout=None, **kwargs)[source]
+
+ +
+
+key
+
+ +
+
+port
+
+ +
+
+purchase_convertible_bonds(client=None, timeout=None)[source]
+
+ +
+
+purchase_new_stocks(client=None, timeout=None)[source]
+
+ +
+
+query(client=None, navigation=None, timeout=None)[source]
+
+ +
+
+query_convertible_bonds()[source]
+
+ +
+
+query_new_stocks()[source]
+
+ +
+
+sell(client=None, timeout=None, **kwargs)[source]
+
+ +
+
+shutdown_clients(timeout=None)[source]
+
+ +
+
+start_clients(timeout=None)[source]
+
+ +
+
+timeout
+
+ +
+ +
+
+class QUANTAXIS.QAMarket.shipaneclient.ConnectionMethod[source]
+

Bases: enum.Enum

+

An enumeration.

+
+
+DIRECT = 'DIRECT'
+
+ +
+
+PROXY = 'PROXY'
+
+ +
+ +
+
+class QUANTAXIS.QAMarket.shipaneclient.MediaType[source]
+

Bases: enum.Enum

+

An enumeration.

+
+
+DEFAULT = 'application/json'
+
+ +
+
+JOIN_QUANT = 'application/vnd.joinquant+json'
+
+ +
+ +
+
+

QUANTAXIS.QAMarket.tdxRealBroker module

+
+
+class QUANTAXIS.QAMarket.tdxRealBroker.TDXBroker(endpoint='http://127.0.0.1:10092/api', encoding='utf-8', enc_key=None, enc_iv=None)[source]
+

Bases: QUANTAXIS.QAMarket.QABroker.QA_Broker

+
+
+call(func, params=None)[source]
+
+ +
+
+cancel_order(client_id, exchange_id, hth)[source]
+
+ +
+
+data_to_df(result)[source]
+
+ +
+
+decrypt(source)[source]
+
+ +
+
+encrypt(source_obj)[source]
+
+ +
+
+get_quote(client_id, code)[source]
+
+ +
+
+logoff(client_id)[source]
+
+ +
+
+logon(ip, port, version, yyb_id, account_id, trade_account, jy_passwrod, tx_password)[source]
+
+ +
+
+ping()[source]
+
+ +
+
+query_data(client_id, category)[source]
+
+ +
+
+receive_order(event)[source]
+

0 限价委托; 上海限价委托 / 深圳限价委托 +1 市价委托(深圳对方最优价格) +2 市价委托(深圳本方最优价格) +3 市价委托(深圳即时成交剩余撤销) +4 市价委托(上海五档即成剩撤 / 深圳五档即成剩撤) +5 市价委托(深圳全额成交或撤销) +6 市价委托(上海五档即成转限价)

+
+ +
+
+repay(client_id, amount)[source]
+
+ +
+
+run(event)[source]
+
+ +
+
+send_order(client_id, category, price_type, gddm, zqdm, price, quantity)[source]
+
+ +
+ +
+
+class QUANTAXIS.QAMarket.tdxRealBroker.TdxTradeApiParams[source]
+

Bases: object

+

0 资金 +1 股份 +2 当日委托 +3 当日成交 +4 可撤单 +5 股东代码 +6 融资余额 +7 融券余额 +8 可融证券 +9 +10 +11 +12 可申购新股查询 +13 新股申购额度查询 +14 配号查询 +15 中签查询

+
+
+QUERY_CATEGORY_BALANCE_OF_MARGIN_LOAN = 6
+
+ +
+
+QUERY_CATEGORY_BALANCE_OF_STOCK_LOAN = 7
+
+ +
+
+QUERY_CATEGORY_CANCELABLE_ORDER = 4
+
+ +
+
+QUERY_CATEGORY_CASH = 0
+
+ +
+
+QUERY_CATEGORY_DEAL_OF_TODAY = 3
+
+ +
+
+QUERY_CATEGORY_NEW_STOCKS = 12
+
+ +
+
+QUERY_CATEGORY_NEW_STOCKS_QUOTA = 13
+
+ +
+
+QUERY_CATEGORY_NEW_STOCK_HIT = 15
+
+ +
+
+QUERY_CATEGORY_NEW_STOCK_NUMBER = 14
+
+ +
+
+QUERY_CATEGORY_OPERABLE_MARGIN_SOTCK = 8
+
+ +
+
+QUERY_CATEGORY_ORDER_OF_TODAY = 2
+
+ +
+
+QUERY_CATEGORY_SHAREHOLDERS_CODE = 5
+
+ +
+
+QUERY_CATEGORY_STOCKS = 1
+
+ +
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QASU.html b/_build/html/source/QUANTAXIS.QASU.html new file mode 100644 index 000000000..e152b01f0 --- /dev/null +++ b/_build/html/source/QUANTAXIS.QASU.html @@ -0,0 +1,507 @@ + + + + + + + + QUANTAXIS.QASU package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QASU package

+
+

Submodules

+
+
+

QUANTAXIS.QASU.main module

+
+
+QUANTAXIS.QASU.main.QA_SU_save_etf_day(engine, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save etf_day

+
+
Arguments:
+
engine {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.main.QA_SU_save_etf_min(engine, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save etf_min

+
+
Arguments:
+
engine {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.main.QA_SU_save_index_day(engine, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save index_day

+
+
Arguments:
+
engine {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.main.QA_SU_save_index_min(engine, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save index_min

+
+
Arguments:
+
engine {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.main.QA_SU_save_stock_block(engine, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_block

+
+
Arguments:
+
engine {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.main.QA_SU_save_stock_day(engine, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_day

+
+
Arguments:
+
engine {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.main.QA_SU_save_stock_info(engine, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock info

+
+
Arguments:
+
engine {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.main.QA_SU_save_stock_list(engine, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_list

+
+
Arguments:
+
engine {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.main.QA_SU_save_stock_min(engine, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_min

+
+
Arguments:
+
engine {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.main.QA_SU_save_stock_min_5(file_dir, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_min5

+
+
Arguments:
+
file_dir {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QASU.main.QA_SU_save_stock_xdxr(engine, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_xdxr

+
+
Arguments:
+
engine {[type]} -- [description]
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.main.select_save_engine(engine)[source]
+

select save_engine

+
+
Arguments:
+
engine {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+

QUANTAXIS.QASU.save_account module

+
+
+QUANTAXIS.QASU.save_account.save_account(message, collection=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'account'))[source]
+

save account

+
+
Arguments:
+
message {[type]} -- [description]
+
Keyword Arguments:
+
collection {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_account.save_riskanalysis(message, collection=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'risk'))[source]
+
+ +
+
+QUANTAXIS.QASU.save_account.update_account(mes, collection=Collection(Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'), 'account'))[source]
+

update the account with account message

+
+
Arguments:
+
mes {[type]} -- [description]
+
Keyword Arguments:
+
collection {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+

QUANTAXIS.QASU.save_backtest module

+
+
+QUANTAXIS.QASU.save_backtest.QA_SU_save_account_message(message, client)[source]
+
+ +
+
+QUANTAXIS.QASU.save_backtest.QA_SU_save_account_to_csv(message, path='E:\\quantaxis')[source]
+
+ +
+
+QUANTAXIS.QASU.save_backtest.QA_SU_save_backtest_message(message, client)[source]
+
+ +
+
+QUANTAXIS.QASU.save_backtest.QA_SU_save_pnl_to_csv(detail, cookie)[source]
+
+ +
+
+

QUANTAXIS.QASU.save_local module

+
+
+QUANTAXIS.QASU.save_local.make_cache()[source]
+
+ +
+
+QUANTAXIS.QASU.save_local.make_dir()[source]
+
+ +
+
+

QUANTAXIS.QASU.save_tdx module

+
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_etf_day(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save etf_day

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_etf_min(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save etf_min

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_index_day(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save index_day

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_index_min(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save index_min

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_stock_block(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_block

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_stock_day(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_day

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_stock_info(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_info

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_stock_list(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_list

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_stock_min(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_min

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_stock_transaction(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save stock_transaction

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.QA_SU_save_stock_xdxr(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

[summary]

+
+
Keyword Arguments:
+
client {[type]} -- [description] (default: {DATABASE})
+
+
+ +
+
+QUANTAXIS.QASU.save_tdx.now_time()[source]
+
+ +
+
+

QUANTAXIS.QASU.save_tdx_file module

+
+
+QUANTAXIS.QASU.save_tdx_file.QA_save_tdx_to_mongo(file_dir, client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+

save file

+
+
Arguments:
+
file_dir {str:direction} -- 文件的地址
+
Keyword Arguments:
+
client {Mongodb:Connection} -- Mongo Connection (default: {DATABASE})
+
+
+ +
+
+

QUANTAXIS.QASU.save_tushare module

+
+
+QUANTAXIS.QASU.save_tushare.QA_SU_save_stock_info(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+
+ +
+
+QUANTAXIS.QASU.save_tushare.QA_SU_save_stock_list(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+
+ +
+
+QUANTAXIS.QASU.save_tushare.QA_SU_save_trade_date_all(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+
+ +
+
+QUANTAXIS.QASU.save_tushare.QA_save_stock_day_all(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+
+ +
+
+QUANTAXIS.QASU.save_tushare.QA_save_stock_day_all_bfq(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+
+ +
+
+QUANTAXIS.QASU.save_tushare.QA_save_stock_day_with_fqfactor(client=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+
+ +
+
+

QUANTAXIS.QASU.user module

+
+
+QUANTAXIS.QASU.user.QA_user_sign_in(name, password, client)[source]
+
+ +
+
+QUANTAXIS.QASU.user.QA_user_sign_up(name, password, client)[source]
+
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QAUtil.html b/_build/html/source/QUANTAXIS.QAUtil.html new file mode 100644 index 000000000..6b6bf7283 --- /dev/null +++ b/_build/html/source/QUANTAXIS.QAUtil.html @@ -0,0 +1,1454 @@ + + + + + + + + QUANTAXIS.QAUtil package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QAUtil package

+
+

Submodules

+
+
+

QUANTAXIS.QAUtil.QAAuth module

+
+
+

QUANTAXIS.QAUtil.QABar module

+
+
+QUANTAXIS.QAUtil.QABar.QA_util_make_hour_index(day, type_='1h')[source]
+

创建股票的小时线的index

+
+
Arguments:
+
day {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QABar.QA_util_make_min_index(day, type_='1min')[source]
+

创建股票分钟线的index

+
+
Arguments:
+
day {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QABar.QA_util_time_gap(time, gap, methods, type_)[source]
+

分钟线回测的时候的gap

+
+ +
+
+

QUANTAXIS.QAUtil.QACfg module

+
+
+QUANTAXIS.QAUtil.QACfg.QA_util_cfg_initial(CONFIG_FILE)[source]
+

[summary]

+
+
Arguments:
+
CONFIG_FILE {[type]} -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QACfg.QA_util_get_cfg(__file_path, __file_name)[source]
+

[summary]

+
+
Arguments:
+
__file_path {[type]} -- [description] +__file_name {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+

QUANTAXIS.QAUtil.QACode module

+

该文件主要是负责一些对于code名称的处理

+
+
+QUANTAXIS.QAUtil.QACode.QA_util_code_tolist(code)[source]
+
+ +
+
+QUANTAXIS.QAUtil.QACode.QA_util_code_tostr(code)[source]
+

将所有沪深股票从数字转化到6位的代码

+

因为有时候在csv等转换的时候,诸如 000001的股票会变成office强制转化成数字1

+
+ +
+
+

QUANTAXIS.QAUtil.QACsv module

+
+
+QUANTAXIS.QAUtil.QACsv.QA_util_save_csv(data, name, column, location)[source]
+

将list保存成csv +第一个参数是list +第二个参数是要保存的名字 +第三个参数是行的名称(可选) +第四个是保存位置(可选)

+

@yutiansut

+
+ +
+
+

QUANTAXIS.QAUtil.QADate module

+
+
+QUANTAXIS.QAUtil.QADate.QA_util_calc_time(func, *args, **kwargs)[source]
+

耗时长度的装饰器

+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_date_int2str(date)[source]
+

[summary]

+
+
Arguments:
+
date {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_date_stamp(date)[source]
+

[summary]

+
+
Arguments:
+
date {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_date_str2int(date)[source]
+

[summary]

+
+
Arguments:
+
date {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_date_today()[source]
+

[summary]

+
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_date_valid(date)[source]
+

[summary]

+
+
Arguments:
+
date {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_get_date_index(date, trade_list)[source]
+

返回在trade_list中的index位置

+
+
Arguments:
+
date {[type]} -- [description] +trade_list {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_get_index_date(id, trade_list)[source]
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_id2date(idx, client)[source]
+

[summary]

+
+
Arguments:
+
idx {[type]} -- [description] +client {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_is_trade(date, code, client)[source]
+

判断是否是交易日

+
+
Arguments:
+
date {[type]} -- [description] +code {[type]} -- [description] +client {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_ms_stamp(ms)[source]
+

[summary]

+
+
Arguments:
+
ms {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_realtime(strtime, client)[source]
+

[summary]

+
+
Arguments:
+
strtime {[type]} -- [description] +client {[type]} -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_select_hours(time=None, gt=None, lt=None, gte=None, lte=None)[source]
+

quantaxis的时间选择函数,约定时间的范围,比如早上9点到11点

+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_select_min(time=None, gt=None, lt=None, gte=None, lte=None)[source]
+

quantaxis的时间选择函数,约定时间的范围,比如30分到59分

+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_stamp2datetime(timestamp)[source]
+

datestamp转datetime

+

pandas转出来的timestamp是13位整数 要/1000

+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_time_delay(time_=0)[source]
+

这是一个用于复用/比如说@装饰器的延时函数 使用threading里面的延时,为了是不阻塞进程 有时候,同时发进去两个函数,第一个函数需要延时 第二个不需要的话,用sleep就会阻塞掉第二个进程

+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_time_now()[source]
+

[summary]

+
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_time_stamp(time_)[source]
+

数据格式最好是%Y-%m-%d %H:%M:%S 中间要有空格

+
+ +
+
+QUANTAXIS.QAUtil.QADate.QA_util_to_datetime(time)[source]
+

[summary]

+
+
Arguments:
+
time {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+

QUANTAXIS.QAUtil.QADate_trade module

+
+
+QUANTAXIS.QAUtil.QADate_trade.QA_util_date_gap(date, gap, methods)[source]
+

[summary]

+
+
Arguments:
+
date {[type]} -- [description] +gap {[type]} -- [description] +methods {[type]} -- [description]
+
Returns:
+
[type] -- [description]
+
+
+ +
+
+QUANTAXIS.QAUtil.QADate_trade.QA_util_get_last_day(date, n=1)[source]
+

得到上一个(n)交易日

+
+ +
+
+QUANTAXIS.QAUtil.QADate_trade.QA_util_get_next_day(date, n=1)[source]
+

得到下一个(n)交易日

+
+ +
+
+QUANTAXIS.QAUtil.QADate_trade.QA_util_get_real_date(date, trade_list=['1990-12-19', '1990-12-20', '1990-12-21', '1990-12-24', '1990-12-25', '1990-12-26', '1990-12-27', '1990-12-28', '1990-12-31', '1991-01-02', '1991-01-03', '1991-01-04', '1991-01-07', '1991-01-08', '1991-01-09', '1991-01-10', '1991-01-11', '1991-01-14', '1991-01-15', '1991-01-16', '1991-01-17', '1991-01-18', '1991-01-21', '1991-01-22', '1991-01-23', '1991-01-24', '1991-01-25', '1991-01-28', '1991-01-29', '1991-01-30', '1991-01-31', '1991-02-01', '1991-02-04', '1991-02-05', '1991-02-06', '1991-02-07', '1991-02-08', '1991-02-11', '1991-02-12', '1991-02-13', '1991-02-14', '1991-02-19', '1991-02-20', '1991-02-21', '1991-02-22', '1991-02-25', '1991-02-26', '1991-02-27', '1991-02-28', '1991-03-01', '1991-03-04', '1991-03-05', '1991-03-06', '1991-03-07', '1991-03-08', '1991-03-11', '1991-03-12', '1991-03-13', '1991-03-14', '1991-03-15', '1991-03-18', '1991-03-19', '1991-03-20', '1991-03-21', '1991-03-22', '1991-03-25', '1991-03-26', '1991-03-27', '1991-03-28', '1991-03-29', '1991-04-01', '1991-04-02', '1991-04-03', '1991-04-04', '1991-04-05', '1991-04-08', '1991-04-09', '1991-04-10', '1991-04-11', '1991-04-12', '1991-04-15', '1991-04-16', '1991-04-17', '1991-04-18', '1991-04-19', '1991-04-22', '1991-04-23', '1991-04-24', '1991-04-25', '1991-04-26', '1991-04-29', '1991-04-30', '1991-05-02', '1991-05-03', '1991-05-06', '1991-05-07', '1991-05-08', '1991-05-09', '1991-05-10', '1991-05-13', '1991-05-14', '1991-05-15', '1991-05-16', '1991-05-17', '1991-05-20', '1991-05-21', '1991-05-22', '1991-05-23', '1991-05-24', '1991-05-27', '1991-05-28', '1991-05-29', '1991-05-30', '1991-05-31', '1991-06-03', '1991-06-04', '1991-06-05', '1991-06-06', '1991-06-07', '1991-06-10', '1991-06-11', '1991-06-12', '1991-06-13', '1991-06-14', '1991-06-17', '1991-06-18', '1991-06-19', '1991-06-20', '1991-06-21', '1991-06-24', '1991-06-25', '1991-06-26', '1991-06-27', '1991-06-28', '1991-07-01', '1991-07-02', '1991-07-03', '1991-07-04', '1991-07-05', '1991-07-08', '1991-07-09', '1991-07-10', '1991-07-11', '1991-07-12', '1991-07-15', '1991-07-16', '1991-07-17', '1991-07-18', '1991-07-19', '1991-07-22', '1991-07-23', '1991-07-24', '1991-07-25', '1991-07-26', '1991-07-29', '1991-07-30', '1991-07-31', '1991-08-01', '1991-08-02', '1991-08-05', '1991-08-06', '1991-08-07', '1991-08-08', '1991-08-09', '1991-08-12', '1991-08-13', '1991-08-14', '1991-08-15', '1991-08-16', '1991-08-19', '1991-08-20', '1991-08-21', '1991-08-22', '1991-08-23', '1991-08-26', '1991-08-27', '1991-08-28', '1991-08-29', '1991-08-30', '1991-09-02', '1991-09-03', '1991-09-04', '1991-09-05', '1991-09-06', '1991-09-09', '1991-09-10', '1991-09-11', '1991-09-12', '1991-09-13', '1991-09-16', '1991-09-17', '1991-09-18', '1991-09-19', '1991-09-20', '1991-09-23', '1991-09-24', '1991-09-25', '1991-09-26', '1991-09-27', '1991-09-30', '1991-10-03', '1991-10-04', '1991-10-07', '1991-10-08', '1991-10-09', '1991-10-10', '1991-10-11', '1991-10-14', '1991-10-15', '1991-10-16', '1991-10-17', '1991-10-18', '1991-10-21', '1991-10-22', '1991-10-23', '1991-10-24', '1991-10-25', '1991-10-28', '1991-10-29', '1991-10-30', '1991-10-31', '1991-11-01', '1991-11-04', '1991-11-05', '1991-11-06', '1991-11-07', '1991-11-08', '1991-11-11', '1991-11-12', '1991-11-13', '1991-11-14', '1991-11-15', '1991-11-18', '1991-11-19', '1991-11-20', '1991-11-21', '1991-11-22', '1991-11-25', '1991-11-26', '1991-11-27', '1991-11-28', '1991-11-29', '1991-12-02', '1991-12-03', '1991-12-04', '1991-12-05', '1991-12-06', '1991-12-09', '1991-12-10', '1991-12-11', '1991-12-12', '1991-12-13', '1991-12-16', '1991-12-17', '1991-12-18', '1991-12-19', '1991-12-20', '1991-12-23', '1991-12-24', '1991-12-25', '1991-12-26', '1991-12-27', '1991-12-30', '1991-12-31', '1992-01-02', '1992-01-03', '1992-01-06', '1992-01-07', '1992-01-08', '1992-01-09', '1992-01-10', '1992-01-13', '1992-01-14', '1992-01-15', '1992-01-16', '1992-01-17', '1992-01-20', '1992-01-21', '1992-01-22', '1992-01-23', '1992-01-24', '1992-01-27', '1992-01-28', '1992-01-29', '1992-01-30', '1992-01-31', '1992-02-03', '1992-02-07', '1992-02-10', '1992-02-11', '1992-02-12', '1992-02-13', '1992-02-14', '1992-02-17', '1992-02-18', '1992-02-19', '1992-02-20', '1992-02-21', '1992-02-24', '1992-02-25', '1992-02-26', '1992-02-27', '1992-02-28', '1992-03-02', '1992-03-03', '1992-03-04', '1992-03-05', '1992-03-06', '1992-03-09', '1992-03-10', '1992-03-11', '1992-03-12', '1992-03-13', '1992-03-16', '1992-03-17', '1992-03-18', '1992-03-19', '1992-03-20', '1992-03-23', '1992-03-24', '1992-03-25', '1992-03-26', '1992-03-27', '1992-03-30', '1992-03-31', '1992-04-01', '1992-04-02', '1992-04-03', '1992-04-06', '1992-04-07', '1992-04-08', '1992-04-09', '1992-04-10', '1992-04-13', '1992-04-14', '1992-04-15', '1992-04-16', '1992-04-17', '1992-04-20', '1992-04-21', '1992-04-22', '1992-04-23', '1992-04-24', '1992-04-27', '1992-04-28', '1992-04-29', '1992-04-30', '1992-05-04', '1992-05-05', '1992-05-06', '1992-05-07', '1992-05-08', '1992-05-11', '1992-05-12', '1992-05-13', '1992-05-14', '1992-05-15', '1992-05-18', '1992-05-19', '1992-05-20', '1992-05-21', '1992-05-22', '1992-05-25', '1992-05-26', '1992-05-27', '1992-05-28', '1992-05-29', '1992-06-01', '1992-06-02', '1992-06-03', '1992-06-04', '1992-06-05', '1992-06-08', '1992-06-09', '1992-06-10', '1992-06-11', '1992-06-12', '1992-06-15', '1992-06-16', '1992-06-17', '1992-06-18', '1992-06-19', '1992-06-22', '1992-06-23', '1992-06-24', '1992-06-25', '1992-06-26', '1992-06-29', '1992-06-30', '1992-07-01', '1992-07-02', '1992-07-03', '1992-07-06', '1992-07-07', '1992-07-08', '1992-07-09', '1992-07-10', '1992-07-13', '1992-07-14', '1992-07-15', '1992-07-16', '1992-07-17', '1992-07-20', '1992-07-21', '1992-07-22', '1992-07-23', '1992-07-24', '1992-07-27', '1992-07-28', '1992-07-29', '1992-07-30', '1992-07-31', '1992-08-03', '1992-08-04', '1992-08-05', '1992-08-06', '1992-08-07', '1992-08-10', '1992-08-11', '1992-08-12', '1992-08-13', '1992-08-14', '1992-08-17', '1992-08-18', '1992-08-19', '1992-08-20', '1992-08-21', '1992-08-24', '1992-08-25', '1992-08-26', '1992-08-27', '1992-08-28', '1992-08-31', '1992-09-01', '1992-09-02', '1992-09-03', '1992-09-04', '1992-09-07', '1992-09-08', '1992-09-09', '1992-09-10', '1992-09-11', '1992-09-14', '1992-09-15', '1992-09-16', '1992-09-17', '1992-09-18', '1992-09-21', '1992-09-22', '1992-09-23', '1992-09-24', '1992-09-25', '1992-09-28', '1992-09-29', '1992-09-30', '1992-10-05', '1992-10-06', '1992-10-07', '1992-10-08', '1992-10-09', '1992-10-12', '1992-10-13', '1992-10-14', '1992-10-15', '1992-10-16', '1992-10-19', '1992-10-20', '1992-10-21', '1992-10-22', '1992-10-23', '1992-10-26', '1992-10-27', '1992-10-28', '1992-10-29', '1992-10-30', '1992-11-02', '1992-11-03', '1992-11-04', '1992-11-05', '1992-11-06', '1992-11-09', '1992-11-10', '1992-11-11', '1992-11-12', '1992-11-13', '1992-11-16', '1992-11-17', '1992-11-18', '1992-11-19', '1992-11-20', '1992-11-23', '1992-11-24', '1992-11-25', '1992-11-26', '1992-11-27', '1992-11-30', '1992-12-01', '1992-12-02', '1992-12-03', '1992-12-04', '1992-12-07', '1992-12-08', '1992-12-09', '1992-12-10', '1992-12-11', '1992-12-14', '1992-12-15', '1992-12-16', '1992-12-17', '1992-12-18', '1992-12-21', '1992-12-22', '1992-12-23', '1992-12-24', '1992-12-25', '1992-12-28', '1992-12-29', '1992-12-30', '1992-12-31', '1993-01-04', '1993-01-05', '1993-01-06', '1993-01-07', '1993-01-08', '1993-01-11', '1993-01-12', '1993-01-13', '1993-01-14', '1993-01-15', '1993-01-18', '1993-01-19', '1993-01-20', '1993-01-21', '1993-01-22', '1993-01-27', '1993-01-28', '1993-01-29', '1993-02-01', '1993-02-02', '1993-02-03', '1993-02-04', '1993-02-05', '1993-02-08', '1993-02-09', '1993-02-10', '1993-02-11', '1993-02-12', '1993-02-15', '1993-02-16', '1993-02-17', '1993-02-18', '1993-02-19', '1993-02-22', '1993-02-23', '1993-02-24', '1993-02-25', '1993-02-26', '1993-03-01', '1993-03-02', '1993-03-03', '1993-03-04', '1993-03-05', '1993-03-08', '1993-03-09', '1993-03-10', '1993-03-11', '1993-03-12', '1993-03-15', '1993-03-16', '1993-03-17', '1993-03-18', '1993-03-19', '1993-03-22', '1993-03-23', '1993-03-24', '1993-03-25', '1993-03-26', '1993-03-29', '1993-03-30', '1993-03-31', '1993-04-01', '1993-04-02', '1993-04-05', '1993-04-06', '1993-04-07', '1993-04-08', '1993-04-09', '1993-04-12', '1993-04-13', '1993-04-14', '1993-04-15', '1993-04-16', '1993-04-19', '1993-04-20', '1993-04-21', '1993-04-22', '1993-04-23', '1993-04-26', '1993-04-27', '1993-04-28', '1993-04-29', '1993-04-30', '1993-05-03', '1993-05-04', '1993-05-05', '1993-05-06', '1993-05-07', '1993-05-10', '1993-05-11', '1993-05-12', '1993-05-13', '1993-05-14', '1993-05-17', '1993-05-18', '1993-05-19', '1993-05-20', '1993-05-21', '1993-05-24', '1993-05-25', '1993-05-26', '1993-05-27', '1993-05-28', '1993-05-31', '1993-06-01', '1993-06-02', '1993-06-03', '1993-06-04', '1993-06-07', '1993-06-08', '1993-06-09', '1993-06-10', '1993-06-11', '1993-06-14', '1993-06-15', '1993-06-16', '1993-06-17', '1993-06-18', '1993-06-21', '1993-06-22', '1993-06-23', '1993-06-24', '1993-06-25', '1993-06-28', '1993-06-29', '1993-06-30', '1993-07-01', '1993-07-02', '1993-07-05', '1993-07-06', '1993-07-07', '1993-07-08', '1993-07-09', '1993-07-12', '1993-07-13', '1993-07-14', '1993-07-15', '1993-07-16', '1993-07-19', '1993-07-20', '1993-07-21', '1993-07-22', '1993-07-23', '1993-07-26', '1993-07-27', '1993-07-28', '1993-07-29', '1993-07-30', '1993-08-02', '1993-08-03', '1993-08-04', '1993-08-05', '1993-08-06', '1993-08-09', '1993-08-10', '1993-08-11', '1993-08-12', '1993-08-13', '1993-08-16', '1993-08-17', '1993-08-18', '1993-08-19', '1993-08-20', '1993-08-23', '1993-08-24', '1993-08-25', '1993-08-26', '1993-08-27', '1993-08-30', '1993-08-31', '1993-09-01', '1993-09-02', '1993-09-03', '1993-09-06', '1993-09-07', '1993-09-08', '1993-09-09', '1993-09-10', '1993-09-13', '1993-09-14', '1993-09-15', '1993-09-16', '1993-09-17', '1993-09-20', '1993-09-21', '1993-09-22', '1993-09-23', '1993-09-24', '1993-09-27', '1993-09-28', '1993-09-29', '1993-09-30', '1993-10-04', '1993-10-05', '1993-10-06', '1993-10-07', '1993-10-08', '1993-10-11', '1993-10-12', '1993-10-13', '1993-10-14', '1993-10-15', '1993-10-18', '1993-10-19', '1993-10-20', '1993-10-21', '1993-10-22', '1993-10-25', '1993-10-26', '1993-10-27', '1993-10-28', '1993-10-29', '1993-11-01', '1993-11-02', '1993-11-03', '1993-11-04', '1993-11-05', '1993-11-08', '1993-11-09', '1993-11-10', '1993-11-11', '1993-11-12', '1993-11-15', '1993-11-16', '1993-11-17', '1993-11-18', '1993-11-19', '1993-11-22', '1993-11-23', '1993-11-24', '1993-11-25', '1993-11-26', '1993-11-29', '1993-11-30', '1993-12-01', '1993-12-02', '1993-12-03', '1993-12-06', '1993-12-07', '1993-12-08', '1993-12-09', '1993-12-10', '1993-12-13', '1993-12-14', '1993-12-15', '1993-12-16', '1993-12-17', '1993-12-20', '1993-12-21', '1993-12-22', '1993-12-23', '1993-12-24', '1993-12-27', '1993-12-28', '1993-12-29', '1993-12-30', '1993-12-31', '1994-01-03', '1994-01-04', '1994-01-05', '1994-01-06', '1994-01-07', '1994-01-10', '1994-01-11', '1994-01-12', '1994-01-13', '1994-01-14', '1994-01-17', '1994-01-18', '1994-01-19', '1994-01-20', '1994-01-21', '1994-01-24', '1994-01-25', '1994-01-26', '1994-01-27', '1994-01-28', '1994-01-31', '1994-02-01', '1994-02-02', '1994-02-03', '1994-02-04', '1994-02-14', '1994-02-15', '1994-02-16', '1994-02-17', '1994-02-18', '1994-02-21', '1994-02-22', '1994-02-23', '1994-02-24', '1994-02-25', '1994-02-28', '1994-03-01', '1994-03-02', '1994-03-03', '1994-03-04', '1994-03-07', '1994-03-08', '1994-03-09', '1994-03-10', '1994-03-11', '1994-03-14', '1994-03-15', '1994-03-16', '1994-03-17', '1994-03-18', '1994-03-21', '1994-03-22', '1994-03-23', '1994-03-24', '1994-03-25', '1994-03-28', '1994-03-29', '1994-03-30', '1994-03-31', '1994-04-01', '1994-04-04', '1994-04-05', '1994-04-06', '1994-04-07', '1994-04-08', '1994-04-11', '1994-04-12', '1994-04-13', '1994-04-14', '1994-04-15', '1994-04-18', '1994-04-19', '1994-04-20', '1994-04-21', '1994-04-22', '1994-04-25', '1994-04-26', '1994-04-27', '1994-04-28', '1994-04-29', '1994-05-03', '1994-05-04', '1994-05-05', '1994-05-06', '1994-05-09', '1994-05-10', '1994-05-11', '1994-05-12', '1994-05-13', '1994-05-16', '1994-05-17', '1994-05-18', '1994-05-19', '1994-05-20', '1994-05-23', '1994-05-24', '1994-05-25', '1994-05-26', '1994-05-27', '1994-05-30', '1994-05-31', '1994-06-01', '1994-06-02', '1994-06-03', '1994-06-06', '1994-06-07', '1994-06-08', '1994-06-09', '1994-06-10', '1994-06-13', '1994-06-14', '1994-06-15', '1994-06-16', '1994-06-17', '1994-06-20', '1994-06-21', '1994-06-22', '1994-06-23', '1994-06-24', '1994-06-27', '1994-06-28', '1994-06-29', '1994-06-30', '1994-07-01', '1994-07-04', '1994-07-05', '1994-07-06', '1994-07-07', '1994-07-08', '1994-07-11', '1994-07-12', '1994-07-13', '1994-07-14', '1994-07-15', '1994-07-18', '1994-07-19', '1994-07-20', '1994-07-21', '1994-07-22', '1994-07-25', '1994-07-26', '1994-07-27', '1994-07-28', '1994-07-29', '1994-08-01', '1994-08-02', '1994-08-03', '1994-08-04', '1994-08-05', '1994-08-08', '1994-08-09', '1994-08-10', '1994-08-11', '1994-08-12', '1994-08-15', '1994-08-16', '1994-08-17', '1994-08-18', '1994-08-19', '1994-08-22', '1994-08-23', '1994-08-24', '1994-08-25', '1994-08-26', '1994-08-29', '1994-08-30', '1994-08-31', '1994-09-01', '1994-09-02', '1994-09-05', '1994-09-06', '1994-09-07', '1994-09-08', '1994-09-09', '1994-09-12', '1994-09-13', '1994-09-14', '1994-09-15', '1994-09-16', '1994-09-19', '1994-09-20', '1994-09-21', '1994-09-22', '1994-09-23', '1994-09-26', '1994-09-27', '1994-09-28', '1994-09-29', '1994-09-30', '1994-10-05', '1994-10-06', '1994-10-07', '1994-10-10', '1994-10-11', '1994-10-12', '1994-10-13', '1994-10-14', '1994-10-17', '1994-10-18', '1994-10-19', '1994-10-20', '1994-10-21', '1994-10-24', '1994-10-25', '1994-10-26', '1994-10-27', '1994-10-28', '1994-10-31', '1994-11-01', '1994-11-02', '1994-11-03', '1994-11-04', '1994-11-07', '1994-11-08', '1994-11-09', '1994-11-10', '1994-11-11', '1994-11-14', '1994-11-15', '1994-11-16', '1994-11-17', '1994-11-18', '1994-11-21', '1994-11-22', '1994-11-23', '1994-11-24', '1994-11-25', '1994-11-28', '1994-11-29', '1994-11-30', '1994-12-01', '1994-12-02', '1994-12-05', '1994-12-06', '1994-12-07', '1994-12-08', '1994-12-09', '1994-12-12', '1994-12-13', '1994-12-14', '1994-12-15', '1994-12-16', '1994-12-19', '1994-12-20', '1994-12-21', '1994-12-22', '1994-12-23', '1994-12-26', '1994-12-27', '1994-12-28', '1994-12-29', '1994-12-30', '1995-01-03', '1995-01-04', '1995-01-05', '1995-01-06', '1995-01-09', '1995-01-10', '1995-01-11', '1995-01-12', '1995-01-13', '1995-01-16', '1995-01-17', '1995-01-18', '1995-01-19', '1995-01-20', '1995-01-23', '1995-01-24', '1995-01-25', '1995-01-26', '1995-01-27', '1995-02-06', '1995-02-07', '1995-02-08', '1995-02-09', '1995-02-10', '1995-02-13', '1995-02-14', '1995-02-15', '1995-02-16', '1995-02-17', '1995-02-20', '1995-02-21', '1995-02-22', '1995-02-23', '1995-02-24', '1995-02-27', '1995-02-28', '1995-03-01', '1995-03-02', '1995-03-03', '1995-03-06', '1995-03-07', '1995-03-08', '1995-03-09', '1995-03-10', '1995-03-13', '1995-03-14', '1995-03-15', '1995-03-16', '1995-03-17', '1995-03-20', '1995-03-21', '1995-03-22', '1995-03-23', '1995-03-24', '1995-03-27', '1995-03-28', '1995-03-29', '1995-03-30', '1995-03-31', '1995-04-03', '1995-04-04', '1995-04-05', '1995-04-06', '1995-04-07', '1995-04-10', '1995-04-11', '1995-04-12', '1995-04-13', '1995-04-14', '1995-04-17', '1995-04-18', '1995-04-19', '1995-04-20', '1995-04-21', '1995-04-24', '1995-04-25', '1995-04-26', '1995-04-27', '1995-04-28', '1995-05-02', '1995-05-03', '1995-05-04', '1995-05-05', '1995-05-08', '1995-05-09', '1995-05-10', '1995-05-11', '1995-05-12', '1995-05-15', '1995-05-16', '1995-05-17', '1995-05-18', '1995-05-19', '1995-05-22', '1995-05-23', '1995-05-24', '1995-05-25', '1995-05-26', '1995-05-29', '1995-05-30', '1995-05-31', '1995-06-01', '1995-06-02', '1995-06-05', '1995-06-06', '1995-06-07', '1995-06-08', '1995-06-09', '1995-06-12', '1995-06-13', '1995-06-14', '1995-06-15', '1995-06-16', '1995-06-19', '1995-06-20', '1995-06-21', '1995-06-22', '1995-06-23', '1995-06-26', '1995-06-27', '1995-06-28', '1995-06-29', '1995-06-30', '1995-07-03', '1995-07-04', '1995-07-05', '1995-07-06', '1995-07-07', '1995-07-10', '1995-07-11', '1995-07-12', '1995-07-13', '1995-07-14', '1995-07-17', '1995-07-18', '1995-07-19', '1995-07-20', '1995-07-21', '1995-07-24', '1995-07-25', '1995-07-26', '1995-07-27', '1995-07-28', '1995-07-31', '1995-08-01', '1995-08-02', '1995-08-03', '1995-08-04', '1995-08-07', '1995-08-08', '1995-08-09', '1995-08-10', '1995-08-11', '1995-08-14', '1995-08-15', '1995-08-16', '1995-08-17', '1995-08-18', '1995-08-21', '1995-08-22', '1995-08-23', '1995-08-24', '1995-08-25', '1995-08-28', '1995-08-29', '1995-08-30', '1995-08-31', '1995-09-01', '1995-09-04', '1995-09-05', '1995-09-06', '1995-09-07', '1995-09-08', '1995-09-11', '1995-09-12', '1995-09-13', '1995-09-14', '1995-09-15', '1995-09-18', '1995-09-19', '1995-09-20', '1995-09-21', '1995-09-22', '1995-09-25', '1995-09-26', '1995-09-27', '1995-09-28', '1995-09-29', '1995-10-04', '1995-10-05', '1995-10-06', '1995-10-09', '1995-10-10', '1995-10-11', '1995-10-12', '1995-10-13', '1995-10-16', '1995-10-17', '1995-10-18', '1995-10-19', '1995-10-20', '1995-10-23', '1995-10-24', '1995-10-25', '1995-10-26', '1995-10-27', '1995-10-30', '1995-10-31', '1995-11-01', '1995-11-02', '1995-11-03', '1995-11-06', '1995-11-07', '1995-11-08', '1995-11-09', '1995-11-10', '1995-11-13', '1995-11-14', '1995-11-15', '1995-11-16', '1995-11-17', '1995-11-20', '1995-11-21', '1995-11-22', '1995-11-23', '1995-11-24', '1995-11-27', '1995-11-28', '1995-11-29', '1995-11-30', '1995-12-01', '1995-12-04', '1995-12-05', '1995-12-06', '1995-12-07', '1995-12-08', '1995-12-11', '1995-12-12', '1995-12-13', '1995-12-14', '1995-12-15', '1995-12-18', '1995-12-19', '1995-12-20', '1995-12-21', '1995-12-22', '1995-12-25', '1995-12-26', '1995-12-27', '1995-12-28', '1995-12-29', '1996-01-02', '1996-01-03', '1996-01-04', '1996-01-05', '1996-01-08', '1996-01-09', '1996-01-10', '1996-01-11', '1996-01-12', '1996-01-15', '1996-01-16', '1996-01-17', '1996-01-18', '1996-01-19', '1996-01-22', '1996-01-23', '1996-01-24', '1996-01-25', '1996-01-26', '1996-01-29', '1996-01-30', '1996-01-31', '1996-02-01', '1996-02-02', '1996-02-05', '1996-02-06', '1996-02-07', '1996-02-08', '1996-02-09', '1996-02-12', '1996-02-13', '1996-02-14', '1996-02-15', '1996-02-16', '1996-03-04', '1996-03-05', '1996-03-06', '1996-03-07', '1996-03-08', '1996-03-11', '1996-03-12', '1996-03-13', '1996-03-14', '1996-03-15', '1996-03-18', '1996-03-19', '1996-03-20', '1996-03-21', '1996-03-22', '1996-03-25', '1996-03-26', '1996-03-27', '1996-03-28', '1996-03-29', '1996-04-01', '1996-04-02', '1996-04-03', '1996-04-04', '1996-04-05', '1996-04-08', '1996-04-09', '1996-04-10', '1996-04-11', '1996-04-12', '1996-04-15', '1996-04-16', '1996-04-17', '1996-04-18', '1996-04-19', '1996-04-22', '1996-04-23', '1996-04-24', '1996-04-25', '1996-04-26', '1996-04-29', '1996-04-30', '1996-05-02', '1996-05-03', '1996-05-06', '1996-05-07', '1996-05-08', '1996-05-09', '1996-05-10', '1996-05-13', '1996-05-14', '1996-05-15', '1996-05-16', '1996-05-17', '1996-05-20', '1996-05-21', '1996-05-22', '1996-05-23', '1996-05-24', '1996-05-27', '1996-05-28', '1996-05-29', '1996-05-30', '1996-05-31', '1996-06-03', '1996-06-04', '1996-06-05', '1996-06-06', '1996-06-07', '1996-06-10', '1996-06-11', '1996-06-12', '1996-06-13', '1996-06-14', '1996-06-17', '1996-06-18', '1996-06-19', '1996-06-20', '1996-06-21', '1996-06-24', '1996-06-25', '1996-06-26', '1996-06-27', '1996-06-28', '1996-07-01', '1996-07-02', '1996-07-03', '1996-07-04', '1996-07-05', '1996-07-08', '1996-07-09', '1996-07-10', '1996-07-11', '1996-07-12', '1996-07-15', '1996-07-16', '1996-07-17', '1996-07-18', '1996-07-19', '1996-07-22', '1996-07-23', '1996-07-24', '1996-07-25', '1996-07-26', '1996-07-29', '1996-07-30', '1996-07-31', '1996-08-01', '1996-08-02', '1996-08-05', '1996-08-06', '1996-08-07', '1996-08-08', '1996-08-09', '1996-08-12', '1996-08-13', '1996-08-14', '1996-08-15', '1996-08-16', '1996-08-19', '1996-08-20', '1996-08-21', '1996-08-22', '1996-08-23', '1996-08-26', '1996-08-27', '1996-08-28', '1996-08-29', '1996-08-30', '1996-09-02', '1996-09-03', '1996-09-04', '1996-09-05', '1996-09-06', '1996-09-09', '1996-09-10', '1996-09-11', '1996-09-12', '1996-09-13', '1996-09-16', '1996-09-17', '1996-09-18', '1996-09-19', '1996-09-20', '1996-09-23', '1996-09-24', '1996-09-25', '1996-09-26', '1996-09-27', '1996-10-03', '1996-10-04', '1996-10-07', '1996-10-08', '1996-10-09', '1996-10-10', '1996-10-11', '1996-10-14', '1996-10-15', '1996-10-16', '1996-10-17', '1996-10-18', '1996-10-21', '1996-10-22', '1996-10-23', '1996-10-24', '1996-10-25', '1996-10-28', '1996-10-29', '1996-10-30', '1996-10-31', '1996-11-01', '1996-11-04', '1996-11-05', '1996-11-06', '1996-11-07', '1996-11-08', '1996-11-11', '1996-11-12', '1996-11-13', '1996-11-14', '1996-11-15', '1996-11-18', '1996-11-19', '1996-11-20', '1996-11-21', '1996-11-22', '1996-11-25', '1996-11-26', '1996-11-27', '1996-11-28', '1996-11-29', '1996-12-02', '1996-12-03', '1996-12-04', '1996-12-05', '1996-12-06', '1996-12-09', '1996-12-10', '1996-12-11', '1996-12-12', '1996-12-13', '1996-12-16', '1996-12-17', '1996-12-18', '1996-12-19', '1996-12-20', '1996-12-23', '1996-12-24', '1996-12-25', '1996-12-26', '1996-12-27', '1996-12-30', '1996-12-31', '1997-01-02', '1997-01-03', '1997-01-06', '1997-01-07', '1997-01-08', '1997-01-09', '1997-01-10', '1997-01-13', '1997-01-14', '1997-01-15', '1997-01-16', '1997-01-17', '1997-01-20', '1997-01-21', '1997-01-22', '1997-01-23', '1997-01-24', '1997-01-27', '1997-01-28', '1997-01-29', '1997-01-30', '1997-01-31', '1997-02-17', '1997-02-18', '1997-02-19', '1997-02-20', '1997-02-21', '1997-02-24', '1997-02-25', '1997-02-26', '1997-02-27', '1997-02-28', '1997-03-03', '1997-03-04', '1997-03-05', '1997-03-06', '1997-03-07', '1997-03-10', '1997-03-11', '1997-03-12', '1997-03-13', '1997-03-14', '1997-03-17', '1997-03-18', '1997-03-19', '1997-03-20', '1997-03-21', '1997-03-24', '1997-03-25', '1997-03-26', '1997-03-27', '1997-03-28', '1997-03-31', '1997-04-01', '1997-04-02', '1997-04-03', '1997-04-04', '1997-04-07', '1997-04-08', '1997-04-09', '1997-04-10', '1997-04-11', '1997-04-14', '1997-04-15', '1997-04-16', '1997-04-17', '1997-04-18', '1997-04-21', '1997-04-22', '1997-04-23', '1997-04-24', '1997-04-25', '1997-04-28', '1997-04-29', '1997-04-30', '1997-05-05', '1997-05-06', '1997-05-07', '1997-05-08', '1997-05-09', '1997-05-12', '1997-05-13', '1997-05-14', '1997-05-15', '1997-05-16', '1997-05-19', '1997-05-20', '1997-05-21', '1997-05-22', '1997-05-23', '1997-05-26', '1997-05-27', '1997-05-28', '1997-05-29', '1997-05-30', '1997-06-02', '1997-06-03', '1997-06-04', '1997-06-05', '1997-06-06', '1997-06-09', '1997-06-10', '1997-06-11', '1997-06-12', '1997-06-13', '1997-06-16', '1997-06-17', '1997-06-18', '1997-06-19', '1997-06-20', '1997-06-23', '1997-06-24', '1997-06-25', '1997-06-26', '1997-06-27', '1997-07-02', '1997-07-03', '1997-07-04', '1997-07-07', '1997-07-08', '1997-07-09', '1997-07-10', '1997-07-11', '1997-07-14', '1997-07-15', '1997-07-16', '1997-07-17', '1997-07-18', '1997-07-21', '1997-07-22', '1997-07-23', '1997-07-24', '1997-07-25', '1997-07-28', '1997-07-29', '1997-07-30', '1997-07-31', '1997-08-01', '1997-08-04', '1997-08-05', '1997-08-06', '1997-08-07', '1997-08-08', '1997-08-11', '1997-08-12', '1997-08-13', '1997-08-14', '1997-08-15', '1997-08-18', '1997-08-19', '1997-08-20', '1997-08-21', '1997-08-22', '1997-08-25', '1997-08-26', '1997-08-27', '1997-08-28', '1997-08-29', '1997-09-01', '1997-09-02', '1997-09-03', '1997-09-04', '1997-09-05', '1997-09-08', '1997-09-09', '1997-09-10', '1997-09-11', '1997-09-12', '1997-09-15', '1997-09-16', '1997-09-17', '1997-09-18', '1997-09-19', '1997-09-22', '1997-09-23', '1997-09-24', '1997-09-25', '1997-09-26', '1997-09-29', '1997-09-30', '1997-10-06', '1997-10-07', '1997-10-08', '1997-10-09', '1997-10-10', '1997-10-13', '1997-10-14', '1997-10-15', '1997-10-16', '1997-10-17', '1997-10-20', '1997-10-21', '1997-10-22', '1997-10-23', '1997-10-24', '1997-10-27', '1997-10-28', '1997-10-29', '1997-10-30', '1997-10-31', '1997-11-03', '1997-11-04', '1997-11-05', '1997-11-06', '1997-11-07', '1997-11-10', '1997-11-11', '1997-11-12', '1997-11-13', '1997-11-14', '1997-11-17', '1997-11-18', '1997-11-19', '1997-11-20', '1997-11-21', '1997-11-24', '1997-11-25', '1997-11-26', '1997-11-27', '1997-11-28', '1997-12-01', '1997-12-02', '1997-12-03', '1997-12-04', '1997-12-05', '1997-12-08', '1997-12-09', '1997-12-10', '1997-12-11', '1997-12-12', '1997-12-15', '1997-12-16', '1997-12-17', '1997-12-18', '1997-12-19', '1997-12-22', '1997-12-23', '1997-12-24', '1997-12-25', '1997-12-26', '1997-12-29', '1997-12-30', '1997-12-31', '1998-01-05', '1998-01-06', '1998-01-07', '1998-01-08', '1998-01-09', '1998-01-12', '1998-01-13', '1998-01-14', '1998-01-15', '1998-01-16', '1998-01-19', '1998-01-20', '1998-01-21', '1998-01-22', '1998-01-23', '1998-02-09', '1998-02-10', '1998-02-11', '1998-02-12', '1998-02-13', '1998-02-16', '1998-02-17', '1998-02-18', '1998-02-19', '1998-02-20', '1998-02-23', '1998-02-24', '1998-02-25', '1998-02-26', '1998-02-27', '1998-03-02', '1998-03-03', '1998-03-04', '1998-03-05', '1998-03-06', '1998-03-09', '1998-03-10', '1998-03-11', '1998-03-12', '1998-03-13', '1998-03-16', '1998-03-17', '1998-03-18', '1998-03-19', '1998-03-20', '1998-03-23', '1998-03-24', '1998-03-25', '1998-03-26', '1998-03-27', '1998-03-30', '1998-03-31', '1998-04-01', '1998-04-02', '1998-04-03', '1998-04-06', '1998-04-07', '1998-04-08', '1998-04-09', '1998-04-10', '1998-04-13', '1998-04-14', '1998-04-15', '1998-04-16', '1998-04-17', '1998-04-20', '1998-04-21', '1998-04-22', '1998-04-23', '1998-04-24', '1998-04-27', '1998-04-28', '1998-04-29', '1998-04-30', '1998-05-04', '1998-05-05', '1998-05-06', '1998-05-07', '1998-05-08', '1998-05-11', '1998-05-12', '1998-05-13', '1998-05-14', '1998-05-15', '1998-05-18', '1998-05-19', '1998-05-20', '1998-05-21', '1998-05-22', '1998-05-25', '1998-05-26', '1998-05-27', '1998-05-28', '1998-05-29', '1998-06-01', '1998-06-02', '1998-06-03', '1998-06-04', '1998-06-05', '1998-06-08', '1998-06-09', '1998-06-10', '1998-06-11', '1998-06-12', '1998-06-15', '1998-06-16', '1998-06-17', '1998-06-18', '1998-06-19', '1998-06-22', '1998-06-23', '1998-06-24', '1998-06-25', '1998-06-26', '1998-06-29', '1998-06-30', '1998-07-01', '1998-07-02', '1998-07-03', '1998-07-06', '1998-07-07', '1998-07-08', '1998-07-09', '1998-07-10', '1998-07-13', '1998-07-14', '1998-07-15', '1998-07-16', '1998-07-17', '1998-07-20', '1998-07-21', '1998-07-22', '1998-07-23', '1998-07-24', '1998-07-27', '1998-07-28', '1998-07-29', '1998-07-30', '1998-07-31', '1998-08-03', '1998-08-04', '1998-08-05', '1998-08-06', '1998-08-07', '1998-08-10', '1998-08-11', '1998-08-12', '1998-08-13', '1998-08-14', '1998-08-17', '1998-08-18', '1998-08-19', '1998-08-20', '1998-08-21', '1998-08-24', '1998-08-25', '1998-08-26', '1998-08-27', '1998-08-28', '1998-08-31', '1998-09-01', '1998-09-02', '1998-09-03', '1998-09-04', '1998-09-07', '1998-09-08', '1998-09-09', '1998-09-10', '1998-09-11', '1998-09-14', '1998-09-15', '1998-09-16', '1998-09-17', '1998-09-18', '1998-09-21', '1998-09-22', '1998-09-23', '1998-09-24', '1998-09-25', '1998-09-28', '1998-09-29', '1998-09-30', '1998-10-05', '1998-10-06', '1998-10-07', '1998-10-08', '1998-10-09', '1998-10-12', '1998-10-13', '1998-10-14', '1998-10-15', '1998-10-16', '1998-10-19', '1998-10-20', '1998-10-21', '1998-10-22', '1998-10-23', '1998-10-26', '1998-10-27', '1998-10-28', '1998-10-29', '1998-10-30', '1998-11-02', '1998-11-03', '1998-11-04', '1998-11-05', '1998-11-06', '1998-11-09', '1998-11-10', '1998-11-11', '1998-11-12', '1998-11-13', '1998-11-16', '1998-11-17', '1998-11-18', '1998-11-19', '1998-11-20', '1998-11-23', '1998-11-24', '1998-11-25', '1998-11-26', '1998-11-27', '1998-11-30', '1998-12-01', '1998-12-02', '1998-12-03', '1998-12-04', '1998-12-07', '1998-12-08', '1998-12-09', '1998-12-10', '1998-12-11', '1998-12-14', '1998-12-15', '1998-12-16', '1998-12-17', '1998-12-18', '1998-12-21', '1998-12-22', '1998-12-23', '1998-12-24', '1998-12-25', '1998-12-28', '1998-12-29', '1998-12-30', '1998-12-31', '1999-01-04', '1999-01-05', '1999-01-06', '1999-01-07', '1999-01-08', '1999-01-11', '1999-01-12', '1999-01-13', '1999-01-14', '1999-01-15', '1999-01-18', '1999-01-19', '1999-01-20', '1999-01-21', '1999-01-22', '1999-01-25', '1999-01-26', '1999-01-27', '1999-01-28', '1999-01-29', '1999-02-01', '1999-02-02', '1999-02-03', '1999-02-04', '1999-02-05', '1999-02-08', '1999-02-09', '1999-03-01', '1999-03-02', '1999-03-03', '1999-03-04', '1999-03-05', '1999-03-08', '1999-03-09', '1999-03-10', '1999-03-11', '1999-03-12', '1999-03-15', '1999-03-16', '1999-03-17', '1999-03-18', '1999-03-19', '1999-03-22', '1999-03-23', '1999-03-24', '1999-03-25', '1999-03-26', '1999-03-29', '1999-03-30', '1999-03-31', '1999-04-01', '1999-04-02', '1999-04-05', '1999-04-06', '1999-04-07', '1999-04-08', '1999-04-09', '1999-04-12', '1999-04-13', '1999-04-14', '1999-04-15', '1999-04-16', '1999-04-19', '1999-04-20', '1999-04-21', '1999-04-22', '1999-04-23', '1999-04-26', '1999-04-27', '1999-04-28', '1999-04-29', '1999-04-30', '1999-05-04', '1999-05-05', '1999-05-06', '1999-05-07', '1999-05-10', '1999-05-11', '1999-05-12', '1999-05-13', '1999-05-14', '1999-05-17', '1999-05-18', '1999-05-19', '1999-05-20', '1999-05-21', '1999-05-24', '1999-05-25', '1999-05-26', '1999-05-27', '1999-05-28', '1999-05-31', '1999-06-01', '1999-06-02', '1999-06-03', '1999-06-04', '1999-06-07', '1999-06-08', '1999-06-09', '1999-06-10', '1999-06-11', '1999-06-14', '1999-06-15', '1999-06-16', '1999-06-17', '1999-06-18', '1999-06-21', '1999-06-22', '1999-06-23', '1999-06-24', '1999-06-25', '1999-06-28', '1999-06-29', '1999-06-30', '1999-07-01', '1999-07-02', '1999-07-05', '1999-07-06', '1999-07-07', '1999-07-08', '1999-07-09', '1999-07-12', '1999-07-13', '1999-07-14', '1999-07-15', '1999-07-16', '1999-07-19', '1999-07-20', '1999-07-21', '1999-07-22', '1999-07-23', '1999-07-26', '1999-07-27', '1999-07-28', '1999-07-29', '1999-07-30', '1999-08-02', '1999-08-03', '1999-08-04', '1999-08-05', '1999-08-06', '1999-08-09', '1999-08-10', '1999-08-11', '1999-08-12', '1999-08-13', '1999-08-16', '1999-08-17', '1999-08-18', '1999-08-19', '1999-08-20', '1999-08-23', '1999-08-24', '1999-08-25', '1999-08-26', '1999-08-27', '1999-08-30', '1999-08-31', '1999-09-01', '1999-09-02', '1999-09-03', '1999-09-06', '1999-09-07', '1999-09-08', '1999-09-09', '1999-09-10', '1999-09-13', '1999-09-14', '1999-09-15', '1999-09-16', '1999-09-17', '1999-09-20', '1999-09-21', '1999-09-22', '1999-09-23', '1999-09-24', '1999-09-27', '1999-09-28', '1999-09-29', '1999-09-30', '1999-10-08', '1999-10-11', '1999-10-12', '1999-10-13', '1999-10-14', '1999-10-15', '1999-10-18', '1999-10-19', '1999-10-20', '1999-10-21', '1999-10-22', '1999-10-25', '1999-10-26', '1999-10-27', '1999-10-28', '1999-10-29', '1999-11-01', '1999-11-02', '1999-11-03', '1999-11-04', '1999-11-05', '1999-11-08', '1999-11-09', '1999-11-10', '1999-11-11', '1999-11-12', '1999-11-15', '1999-11-16', '1999-11-17', '1999-11-18', '1999-11-19', '1999-11-22', '1999-11-23', '1999-11-24', '1999-11-25', '1999-11-26', '1999-11-29', '1999-11-30', '1999-12-01', '1999-12-02', '1999-12-03', '1999-12-06', '1999-12-07', '1999-12-08', '1999-12-09', '1999-12-10', '1999-12-13', '1999-12-14', '1999-12-15', '1999-12-16', '1999-12-17', '1999-12-21', '1999-12-22', '1999-12-23', '1999-12-24', '1999-12-27', '1999-12-28', '1999-12-29', '1999-12-30', '2000-01-04', '2000-01-05', '2000-01-06', '2000-01-07', '2000-01-10', '2000-01-11', '2000-01-12', '2000-01-13', '2000-01-14', '2000-01-17', '2000-01-18', '2000-01-19', '2000-01-20', '2000-01-21', '2000-01-24', '2000-01-25', '2000-01-26', '2000-01-27', '2000-01-28', '2000-02-14', '2000-02-15', '2000-02-16', '2000-02-17', '2000-02-18', '2000-02-21', '2000-02-22', '2000-02-23', '2000-02-24', '2000-02-25', '2000-02-28', '2000-02-29', '2000-03-01', '2000-03-02', '2000-03-03', '2000-03-06', '2000-03-07', '2000-03-08', '2000-03-09', '2000-03-10', '2000-03-13', '2000-03-14', '2000-03-15', '2000-03-16', '2000-03-17', '2000-03-20', '2000-03-21', '2000-03-22', '2000-03-23', '2000-03-24', '2000-03-27', '2000-03-28', '2000-03-29', '2000-03-30', '2000-03-31', '2000-04-03', '2000-04-04', '2000-04-05', '2000-04-06', '2000-04-07', '2000-04-10', '2000-04-11', '2000-04-12', '2000-04-13', '2000-04-14', '2000-04-17', '2000-04-18', '2000-04-19', '2000-04-20', '2000-04-21', '2000-04-24', '2000-04-25', '2000-04-26', '2000-04-27', '2000-04-28', '2000-05-08', '2000-05-09', '2000-05-10', '2000-05-11', '2000-05-12', '2000-05-15', '2000-05-16', '2000-05-17', '2000-05-18', '2000-05-19', '2000-05-22', '2000-05-23', '2000-05-24', '2000-05-25', '2000-05-26', '2000-05-29', '2000-05-30', '2000-05-31', '2000-06-01', '2000-06-02', '2000-06-05', '2000-06-06', '2000-06-07', '2000-06-08', '2000-06-09', '2000-06-12', '2000-06-13', '2000-06-14', '2000-06-15', '2000-06-16', '2000-06-19', '2000-06-20', '2000-06-21', '2000-06-22', '2000-06-23', '2000-06-26', '2000-06-27', '2000-06-28', '2000-06-29', '2000-06-30', '2000-07-03', '2000-07-04', '2000-07-05', '2000-07-06', '2000-07-07', '2000-07-10', '2000-07-11', '2000-07-12', '2000-07-13', '2000-07-14', '2000-07-17', '2000-07-18', '2000-07-19', '2000-07-20', '2000-07-21', '2000-07-24', '2000-07-25', '2000-07-26', '2000-07-27', '2000-07-28', '2000-07-31', '2000-08-01', '2000-08-02', '2000-08-03', '2000-08-04', '2000-08-07', '2000-08-08', '2000-08-09', '2000-08-10', '2000-08-11', '2000-08-14', '2000-08-15', '2000-08-16', '2000-08-17', '2000-08-18', '2000-08-21', '2000-08-22', '2000-08-23', '2000-08-24', '2000-08-25', '2000-08-28', '2000-08-29', '2000-08-30', '2000-08-31', '2000-09-01', '2000-09-04', '2000-09-05', '2000-09-06', '2000-09-07', '2000-09-08', '2000-09-11', '2000-09-12', '2000-09-13', '2000-09-14', '2000-09-15', '2000-09-18', '2000-09-19', '2000-09-20', '2000-09-21', '2000-09-22', '2000-09-25', '2000-09-26', '2000-09-27', '2000-09-28', '2000-09-29', '2000-10-09', '2000-10-10', '2000-10-11', '2000-10-12', '2000-10-13', '2000-10-16', '2000-10-17', '2000-10-18', '2000-10-19', '2000-10-20', '2000-10-23', '2000-10-24', '2000-10-25', '2000-10-26', '2000-10-27', '2000-10-30', '2000-10-31', '2000-11-01', '2000-11-02', '2000-11-03', '2000-11-06', '2000-11-07', '2000-11-08', '2000-11-09', '2000-11-10', '2000-11-13', '2000-11-14', '2000-11-15', '2000-11-16', '2000-11-17', '2000-11-20', '2000-11-21', '2000-11-22', '2000-11-23', '2000-11-24', '2000-11-27', '2000-11-28', '2000-11-29', '2000-11-30', '2000-12-01', '2000-12-04', '2000-12-05', '2000-12-06', '2000-12-07', '2000-12-08', '2000-12-11', '2000-12-12', '2000-12-13', '2000-12-14', '2000-12-15', '2000-12-18', '2000-12-19', '2000-12-20', '2000-12-21', '2000-12-22', '2000-12-25', '2000-12-26', '2000-12-27', '2000-12-28', '2000-12-29', '2001-01-02', '2001-01-03', '2001-01-04', '2001-01-05', '2001-01-08', '2001-01-09', '2001-01-10', '2001-01-11', '2001-01-12', '2001-01-15', '2001-01-16', '2001-01-17', '2001-01-18', '2001-01-19', '2001-02-05', '2001-02-06', '2001-02-07', '2001-02-08', '2001-02-09', '2001-02-12', '2001-02-13', '2001-02-14', '2001-02-15', '2001-02-16', '2001-02-19', '2001-02-20', '2001-02-21', '2001-02-22', '2001-02-23', '2001-02-26', '2001-02-27', '2001-02-28', '2001-03-01', '2001-03-02', '2001-03-05', '2001-03-06', '2001-03-07', '2001-03-08', '2001-03-09', '2001-03-12', '2001-03-13', '2001-03-14', '2001-03-15', '2001-03-16', '2001-03-19', '2001-03-20', '2001-03-21', '2001-03-22', '2001-03-23', '2001-03-26', '2001-03-27', '2001-03-28', '2001-03-29', '2001-03-30', '2001-04-02', '2001-04-03', '2001-04-04', '2001-04-05', '2001-04-06', '2001-04-09', '2001-04-10', '2001-04-11', '2001-04-12', '2001-04-13', '2001-04-16', '2001-04-17', '2001-04-18', '2001-04-19', '2001-04-20', '2001-04-23', '2001-04-24', '2001-04-25', '2001-04-26', '2001-04-27', '2001-04-30', '2001-05-08', '2001-05-09', '2001-05-10', '2001-05-11', '2001-05-14', '2001-05-15', '2001-05-16', '2001-05-17', '2001-05-18', '2001-05-21', '2001-05-22', '2001-05-23', '2001-05-24', '2001-05-25', '2001-05-28', '2001-05-29', '2001-05-30', '2001-05-31', '2001-06-01', '2001-06-04', '2001-06-05', '2001-06-06', '2001-06-07', '2001-06-08', '2001-06-11', '2001-06-12', '2001-06-13', '2001-06-14', '2001-06-15', '2001-06-18', '2001-06-19', '2001-06-20', '2001-06-21', '2001-06-22', '2001-06-25', '2001-06-26', '2001-06-27', '2001-06-28', '2001-06-29', '2001-07-02', '2001-07-03', '2001-07-04', '2001-07-05', '2001-07-06', '2001-07-09', '2001-07-10', '2001-07-11', '2001-07-12', '2001-07-13', '2001-07-16', '2001-07-17', '2001-07-18', '2001-07-19', '2001-07-20', '2001-07-23', '2001-07-24', '2001-07-25', '2001-07-26', '2001-07-27', '2001-07-30', '2001-07-31', '2001-08-01', '2001-08-02', '2001-08-03', '2001-08-06', '2001-08-07', '2001-08-08', '2001-08-09', '2001-08-10', '2001-08-13', '2001-08-14', '2001-08-15', '2001-08-16', '2001-08-17', '2001-08-20', '2001-08-21', '2001-08-22', '2001-08-23', '2001-08-24', '2001-08-27', '2001-08-28', '2001-08-29', '2001-08-30', '2001-08-31', '2001-09-03', '2001-09-04', '2001-09-05', '2001-09-06', '2001-09-07', '2001-09-10', '2001-09-11', '2001-09-12', '2001-09-13', '2001-09-14', '2001-09-17', '2001-09-18', '2001-09-19', '2001-09-20', '2001-09-21', '2001-09-24', '2001-09-25', '2001-09-26', '2001-09-27', '2001-09-28', '2001-10-08', '2001-10-09', '2001-10-10', '2001-10-11', '2001-10-12', '2001-10-15', '2001-10-16', '2001-10-17', '2001-10-18', '2001-10-19', '2001-10-22', '2001-10-23', '2001-10-24', '2001-10-25', '2001-10-26', '2001-10-29', '2001-10-30', '2001-10-31', '2001-11-01', '2001-11-02', '2001-11-05', '2001-11-06', '2001-11-07', '2001-11-08', '2001-11-09', '2001-11-12', '2001-11-13', '2001-11-14', '2001-11-15', '2001-11-16', '2001-11-19', '2001-11-20', '2001-11-21', '2001-11-22', '2001-11-23', '2001-11-26', '2001-11-27', '2001-11-28', '2001-11-29', '2001-11-30', '2001-12-03', '2001-12-04', '2001-12-05', '2001-12-06', '2001-12-07', '2001-12-10', '2001-12-11', '2001-12-12', '2001-12-13', '2001-12-14', '2001-12-17', '2001-12-18', '2001-12-19', '2001-12-20', '2001-12-21', '2001-12-24', '2001-12-25', '2001-12-26', '2001-12-27', '2001-12-28', '2001-12-31', '2002-01-04', '2002-01-07', '2002-01-08', '2002-01-09', '2002-01-10', '2002-01-11', '2002-01-14', '2002-01-15', '2002-01-16', '2002-01-17', '2002-01-18', '2002-01-21', '2002-01-22', '2002-01-23', '2002-01-24', '2002-01-25', '2002-01-28', '2002-01-29', '2002-01-30', '2002-01-31', '2002-02-01', '2002-02-04', '2002-02-05', '2002-02-06', '2002-02-07', '2002-02-08', '2002-02-25', '2002-02-26', '2002-02-27', '2002-02-28', '2002-03-01', '2002-03-04', '2002-03-05', '2002-03-06', '2002-03-07', '2002-03-08', '2002-03-11', '2002-03-12', '2002-03-13', '2002-03-14', '2002-03-15', '2002-03-18', '2002-03-19', '2002-03-20', '2002-03-21', '2002-03-22', '2002-03-25', '2002-03-26', '2002-03-27', '2002-03-28', '2002-03-29', '2002-04-01', '2002-04-02', '2002-04-03', '2002-04-04', '2002-04-05', '2002-04-08', '2002-04-09', '2002-04-10', '2002-04-11', '2002-04-12', '2002-04-15', '2002-04-16', '2002-04-17', '2002-04-18', '2002-04-19', '2002-04-22', '2002-04-23', '2002-04-24', '2002-04-25', '2002-04-26', '2002-04-29', '2002-04-30', '2002-05-08', '2002-05-09', '2002-05-10', '2002-05-13', '2002-05-14', '2002-05-15', '2002-05-16', '2002-05-17', '2002-05-20', '2002-05-21', '2002-05-22', '2002-05-23', '2002-05-24', '2002-05-27', '2002-05-28', '2002-05-29', '2002-05-30', '2002-05-31', '2002-06-03', '2002-06-04', '2002-06-05', '2002-06-06', '2002-06-07', '2002-06-10', '2002-06-11', '2002-06-12', '2002-06-13', '2002-06-14', '2002-06-17', '2002-06-18', '2002-06-19', '2002-06-20', '2002-06-21', '2002-06-24', '2002-06-25', '2002-06-26', '2002-06-27', '2002-06-28', '2002-07-01', '2002-07-02', '2002-07-03', '2002-07-04', '2002-07-05', '2002-07-08', '2002-07-09', '2002-07-10', '2002-07-11', '2002-07-12', '2002-07-15', '2002-07-16', '2002-07-17', '2002-07-18', '2002-07-19', '2002-07-22', '2002-07-23', '2002-07-24', '2002-07-25', '2002-07-26', '2002-07-29', '2002-07-30', '2002-07-31', '2002-08-01', '2002-08-02', '2002-08-05', '2002-08-06', '2002-08-07', '2002-08-08', '2002-08-09', '2002-08-12', '2002-08-13', '2002-08-14', '2002-08-15', '2002-08-16', '2002-08-19', '2002-08-20', '2002-08-21', '2002-08-22', '2002-08-23', '2002-08-26', '2002-08-27', '2002-08-28', '2002-08-29', '2002-08-30', '2002-09-02', '2002-09-03', '2002-09-04', '2002-09-05', '2002-09-06', '2002-09-09', '2002-09-10', '2002-09-11', '2002-09-12', '2002-09-13', '2002-09-16', '2002-09-17', '2002-09-18', '2002-09-19', '2002-09-20', '2002-09-23', '2002-09-24', '2002-09-25', '2002-09-26', '2002-09-27', '2002-10-08', '2002-10-09', '2002-10-10', '2002-10-11', '2002-10-14', '2002-10-15', '2002-10-16', '2002-10-17', '2002-10-18', '2002-10-21', '2002-10-22', '2002-10-23', '2002-10-24', '2002-10-25', '2002-10-28', '2002-10-29', '2002-10-30', '2002-10-31', '2002-11-01', '2002-11-04', '2002-11-05', '2002-11-06', '2002-11-07', '2002-11-08', '2002-11-11', '2002-11-12', '2002-11-13', '2002-11-14', '2002-11-15', '2002-11-18', '2002-11-19', '2002-11-20', '2002-11-21', '2002-11-22', '2002-11-25', '2002-11-26', '2002-11-27', '2002-11-28', '2002-11-29', '2002-12-02', '2002-12-03', '2002-12-04', '2002-12-05', '2002-12-06', '2002-12-09', '2002-12-10', '2002-12-11', '2002-12-12', '2002-12-13', '2002-12-16', '2002-12-17', '2002-12-18', '2002-12-19', '2002-12-20', '2002-12-23', '2002-12-24', '2002-12-25', '2002-12-26', '2002-12-27', '2002-12-30', '2002-12-31', '2003-01-02', '2003-01-03', '2003-01-06', '2003-01-07', '2003-01-08', '2003-01-09', '2003-01-10', '2003-01-13', '2003-01-14', '2003-01-15', '2003-01-16', '2003-01-17', '2003-01-20', '2003-01-21', '2003-01-22', '2003-01-23', '2003-01-24', '2003-01-27', '2003-01-28', '2003-01-29', '2003-02-10', '2003-02-11', '2003-02-12', '2003-02-13', '2003-02-14', '2003-02-17', '2003-02-18', '2003-02-19', '2003-02-20', '2003-02-21', '2003-02-24', '2003-02-25', '2003-02-26', '2003-02-27', '2003-02-28', '2003-03-03', '2003-03-04', '2003-03-05', '2003-03-06', '2003-03-07', '2003-03-10', '2003-03-11', '2003-03-12', '2003-03-13', '2003-03-14', '2003-03-17', '2003-03-18', '2003-03-19', '2003-03-20', '2003-03-21', '2003-03-24', '2003-03-25', '2003-03-26', '2003-03-27', '2003-03-28', '2003-03-31', '2003-04-01', '2003-04-02', '2003-04-03', '2003-04-04', '2003-04-07', '2003-04-08', '2003-04-09', '2003-04-10', '2003-04-11', '2003-04-14', '2003-04-15', '2003-04-16', '2003-04-17', '2003-04-18', '2003-04-21', '2003-04-22', '2003-04-23', '2003-04-24', '2003-04-25', '2003-04-28', '2003-04-29', '2003-04-30', '2003-05-12', '2003-05-13', '2003-05-14', '2003-05-15', '2003-05-16', '2003-05-19', '2003-05-20', '2003-05-21', '2003-05-22', '2003-05-23', '2003-05-26', '2003-05-27', '2003-05-28', '2003-05-29', '2003-05-30', '2003-06-02', '2003-06-03', '2003-06-04', '2003-06-05', '2003-06-06', '2003-06-09', '2003-06-10', '2003-06-11', '2003-06-12', '2003-06-13', '2003-06-16', '2003-06-17', '2003-06-18', '2003-06-19', '2003-06-20', '2003-06-23', '2003-06-24', '2003-06-25', '2003-06-26', '2003-06-27', '2003-06-30', '2003-07-01', '2003-07-02', '2003-07-03', '2003-07-04', '2003-07-07', '2003-07-08', '2003-07-09', '2003-07-10', '2003-07-11', '2003-07-14', '2003-07-15', '2003-07-16', '2003-07-17', '2003-07-18', '2003-07-21', '2003-07-22', '2003-07-23', '2003-07-24', '2003-07-25', '2003-07-28', '2003-07-29', '2003-07-30', '2003-07-31', '2003-08-01', '2003-08-04', '2003-08-05', '2003-08-06', '2003-08-07', '2003-08-08', '2003-08-11', '2003-08-12', '2003-08-13', '2003-08-14', '2003-08-15', '2003-08-18', '2003-08-19', '2003-08-20', '2003-08-21', '2003-08-22', '2003-08-25', '2003-08-26', '2003-08-27', '2003-08-28', '2003-08-29', '2003-09-01', '2003-09-02', '2003-09-03', '2003-09-04', '2003-09-05', '2003-09-08', '2003-09-09', '2003-09-10', '2003-09-11', '2003-09-12', '2003-09-15', '2003-09-16', '2003-09-17', '2003-09-18', '2003-09-19', '2003-09-22', '2003-09-23', '2003-09-24', '2003-09-25', '2003-09-26', '2003-09-29', '2003-09-30', '2003-10-08', '2003-10-09', '2003-10-10', '2003-10-13', '2003-10-14', '2003-10-15', '2003-10-16', '2003-10-17', '2003-10-20', '2003-10-21', '2003-10-22', '2003-10-23', '2003-10-24', '2003-10-27', '2003-10-28', '2003-10-29', '2003-10-30', '2003-10-31', '2003-11-03', '2003-11-04', '2003-11-05', '2003-11-06', '2003-11-07', '2003-11-10', '2003-11-11', '2003-11-12', '2003-11-13', '2003-11-14', '2003-11-17', '2003-11-18', '2003-11-19', '2003-11-20', '2003-11-21', '2003-11-24', '2003-11-25', '2003-11-26', '2003-11-27', '2003-11-28', '2003-12-01', '2003-12-02', '2003-12-03', '2003-12-04', '2003-12-05', '2003-12-08', '2003-12-09', '2003-12-10', '2003-12-11', '2003-12-12', '2003-12-15', '2003-12-16', '2003-12-17', '2003-12-18', '2003-12-19', '2003-12-22', '2003-12-23', '2003-12-24', '2003-12-25', '2003-12-26', '2003-12-29', '2003-12-30', '2003-12-31', '2004-01-02', '2004-01-05', '2004-01-06', '2004-01-07', '2004-01-08', '2004-01-09', '2004-01-12', '2004-01-13', '2004-01-14', '2004-01-15', '2004-01-16', '2004-01-29', '2004-01-30', '2004-02-02', '2004-02-03', '2004-02-04', '2004-02-05', '2004-02-06', '2004-02-09', '2004-02-10', '2004-02-11', '2004-02-12', '2004-02-13', '2004-02-16', '2004-02-17', '2004-02-18', '2004-02-19', '2004-02-20', '2004-02-23', '2004-02-24', '2004-02-25', '2004-02-26', '2004-02-27', '2004-03-01', '2004-03-02', '2004-03-03', '2004-03-04', '2004-03-05', '2004-03-08', '2004-03-09', '2004-03-10', '2004-03-11', '2004-03-12', '2004-03-15', '2004-03-16', '2004-03-17', '2004-03-18', '2004-03-19', '2004-03-22', '2004-03-23', '2004-03-24', '2004-03-25', '2004-03-26', '2004-03-29', '2004-03-30', '2004-03-31', '2004-04-01', '2004-04-02', '2004-04-05', '2004-04-06', '2004-04-07', '2004-04-08', '2004-04-09', '2004-04-12', '2004-04-13', '2004-04-14', '2004-04-15', '2004-04-16', '2004-04-19', '2004-04-20', '2004-04-21', '2004-04-22', '2004-04-23', '2004-04-26', '2004-04-27', '2004-04-28', '2004-04-29', '2004-04-30', '2004-05-10', '2004-05-11', '2004-05-12', '2004-05-13', '2004-05-14', '2004-05-17', '2004-05-18', '2004-05-19', '2004-05-20', '2004-05-21', '2004-05-24', '2004-05-25', '2004-05-26', '2004-05-27', '2004-05-28', '2004-05-31', '2004-06-01', '2004-06-02', '2004-06-03', '2004-06-04', '2004-06-07', '2004-06-08', '2004-06-09', '2004-06-10', '2004-06-11', '2004-06-14', '2004-06-15', '2004-06-16', '2004-06-17', '2004-06-18', '2004-06-21', '2004-06-22', '2004-06-23', '2004-06-24', '2004-06-25', '2004-06-28', '2004-06-29', '2004-06-30', '2004-07-01', '2004-07-02', '2004-07-05', '2004-07-06', '2004-07-07', '2004-07-08', '2004-07-09', '2004-07-12', '2004-07-13', '2004-07-14', '2004-07-15', '2004-07-16', '2004-07-19', '2004-07-20', '2004-07-21', '2004-07-22', '2004-07-23', '2004-07-26', '2004-07-27', '2004-07-28', '2004-07-29', '2004-07-30', '2004-08-02', '2004-08-03', '2004-08-04', '2004-08-05', '2004-08-06', '2004-08-09', '2004-08-10', '2004-08-11', '2004-08-12', '2004-08-13', '2004-08-16', '2004-08-17', '2004-08-18', '2004-08-19', '2004-08-20', '2004-08-23', '2004-08-24', '2004-08-25', '2004-08-26', '2004-08-27', '2004-08-30', '2004-08-31', '2004-09-01', '2004-09-02', '2004-09-03', '2004-09-06', '2004-09-07', '2004-09-08', '2004-09-09', '2004-09-10', '2004-09-13', '2004-09-14', '2004-09-15', '2004-09-16', '2004-09-17', '2004-09-20', '2004-09-21', '2004-09-22', '2004-09-23', '2004-09-24', '2004-09-27', '2004-09-28', '2004-09-29', '2004-09-30', '2004-10-08', '2004-10-11', '2004-10-12', '2004-10-13', '2004-10-14', '2004-10-15', '2004-10-18', '2004-10-19', '2004-10-20', '2004-10-21', '2004-10-22', '2004-10-25', '2004-10-26', '2004-10-27', '2004-10-28', '2004-10-29', '2004-11-01', '2004-11-02', '2004-11-03', '2004-11-04', '2004-11-05', '2004-11-08', '2004-11-09', '2004-11-10', '2004-11-11', '2004-11-12', '2004-11-15', '2004-11-16', '2004-11-17', '2004-11-18', '2004-11-19', '2004-11-22', '2004-11-23', '2004-11-24', '2004-11-25', '2004-11-26', '2004-11-29', '2004-11-30', '2004-12-01', '2004-12-02', '2004-12-03', '2004-12-06', '2004-12-07', '2004-12-08', '2004-12-09', '2004-12-10', '2004-12-13', '2004-12-14', '2004-12-15', '2004-12-16', '2004-12-17', '2004-12-20', '2004-12-21', '2004-12-22', '2004-12-23', '2004-12-24', '2004-12-27', '2004-12-28', '2004-12-29', '2004-12-30', '2004-12-31', '2005-01-04', '2005-01-05', '2005-01-06', '2005-01-07', '2005-01-10', '2005-01-11', '2005-01-12', '2005-01-13', '2005-01-14', '2005-01-17', '2005-01-18', '2005-01-19', '2005-01-20', '2005-01-21', '2005-01-24', '2005-01-25', '2005-01-26', '2005-01-27', '2005-01-28', '2005-01-31', '2005-02-01', '2005-02-02', '2005-02-03', '2005-02-04', '2005-02-16', '2005-02-17', '2005-02-18', '2005-02-21', '2005-02-22', '2005-02-23', '2005-02-24', '2005-02-25', '2005-02-28', '2005-03-01', '2005-03-02', '2005-03-03', '2005-03-04', '2005-03-07', '2005-03-08', '2005-03-09', '2005-03-10', '2005-03-11', '2005-03-14', '2005-03-15', '2005-03-16', '2005-03-17', '2005-03-18', '2005-03-21', '2005-03-22', '2005-03-23', '2005-03-24', '2005-03-25', '2005-03-28', '2005-03-29', '2005-03-30', '2005-03-31', '2005-04-01', '2005-04-04', '2005-04-05', '2005-04-06', '2005-04-07', '2005-04-08', '2005-04-11', '2005-04-12', '2005-04-13', '2005-04-14', '2005-04-15', '2005-04-18', '2005-04-19', '2005-04-20', '2005-04-21', '2005-04-22', '2005-04-25', '2005-04-26', '2005-04-27', '2005-04-28', '2005-04-29', '2005-05-09', '2005-05-10', '2005-05-11', '2005-05-12', '2005-05-13', '2005-05-16', '2005-05-17', '2005-05-18', '2005-05-19', '2005-05-20', '2005-05-23', '2005-05-24', '2005-05-25', '2005-05-26', '2005-05-27', '2005-05-30', '2005-05-31', '2005-06-01', '2005-06-02', '2005-06-03', '2005-06-06', '2005-06-07', '2005-06-08', '2005-06-09', '2005-06-10', '2005-06-13', '2005-06-14', '2005-06-15', '2005-06-16', '2005-06-17', '2005-06-20', '2005-06-21', '2005-06-22', '2005-06-23', '2005-06-24', '2005-06-27', '2005-06-28', '2005-06-29', '2005-06-30', '2005-07-01', '2005-07-04', '2005-07-05', '2005-07-06', '2005-07-07', '2005-07-08', '2005-07-11', '2005-07-12', '2005-07-13', '2005-07-14', '2005-07-15', '2005-07-18', '2005-07-19', '2005-07-20', '2005-07-21', '2005-07-22', '2005-07-25', '2005-07-26', '2005-07-27', '2005-07-28', '2005-07-29', '2005-08-01', '2005-08-02', '2005-08-03', '2005-08-04', '2005-08-05', '2005-08-08', '2005-08-09', '2005-08-10', '2005-08-11', '2005-08-12', '2005-08-15', '2005-08-16', '2005-08-17', '2005-08-18', '2005-08-19', '2005-08-22', '2005-08-23', '2005-08-24', '2005-08-25', '2005-08-26', '2005-08-29', '2005-08-30', '2005-08-31', '2005-09-01', '2005-09-02', '2005-09-05', '2005-09-06', '2005-09-07', '2005-09-08', '2005-09-09', '2005-09-12', '2005-09-13', '2005-09-14', '2005-09-15', '2005-09-16', '2005-09-19', '2005-09-20', '2005-09-21', '2005-09-22', '2005-09-23', '2005-09-26', '2005-09-27', '2005-09-28', '2005-09-29', '2005-09-30', '2005-10-10', '2005-10-11', '2005-10-12', '2005-10-13', '2005-10-14', '2005-10-17', '2005-10-18', '2005-10-19', '2005-10-20', '2005-10-21', '2005-10-24', '2005-10-25', '2005-10-26', '2005-10-27', '2005-10-28', '2005-10-31', '2005-11-01', '2005-11-02', '2005-11-03', '2005-11-04', '2005-11-07', '2005-11-08', '2005-11-09', '2005-11-10', '2005-11-11', '2005-11-14', '2005-11-15', '2005-11-16', '2005-11-17', '2005-11-18', '2005-11-21', '2005-11-22', '2005-11-23', '2005-11-24', '2005-11-25', '2005-11-28', '2005-11-29', '2005-11-30', '2005-12-01', '2005-12-02', '2005-12-05', '2005-12-06', '2005-12-07', '2005-12-08', '2005-12-09', '2005-12-12', '2005-12-13', '2005-12-14', '2005-12-15', '2005-12-16', '2005-12-19', '2005-12-20', '2005-12-21', '2005-12-22', '2005-12-23', '2005-12-26', '2005-12-27', '2005-12-28', '2005-12-29', '2005-12-30', '2006-01-04', '2006-01-05', '2006-01-06', '2006-01-09', '2006-01-10', '2006-01-11', '2006-01-12', '2006-01-13', '2006-01-16', '2006-01-17', '2006-01-18', '2006-01-19', '2006-01-20', '2006-01-23', '2006-01-24', '2006-01-25', '2006-02-06', '2006-02-07', '2006-02-08', '2006-02-09', '2006-02-10', '2006-02-13', '2006-02-14', '2006-02-15', '2006-02-16', '2006-02-17', '2006-02-20', '2006-02-21', '2006-02-22', '2006-02-23', '2006-02-24', '2006-02-27', '2006-02-28', '2006-03-01', '2006-03-02', '2006-03-03', '2006-03-06', '2006-03-07', '2006-03-08', '2006-03-09', '2006-03-10', '2006-03-13', '2006-03-14', '2006-03-15', '2006-03-16', '2006-03-17', '2006-03-20', '2006-03-21', '2006-03-22', '2006-03-23', '2006-03-24', '2006-03-27', '2006-03-28', '2006-03-29', '2006-03-30', '2006-03-31', '2006-04-03', '2006-04-04', '2006-04-05', '2006-04-06', '2006-04-07', '2006-04-10', '2006-04-11', '2006-04-12', '2006-04-13', '2006-04-14', '2006-04-17', '2006-04-18', '2006-04-19', '2006-04-20', '2006-04-21', '2006-04-24', '2006-04-25', '2006-04-26', '2006-04-27', '2006-04-28', '2006-05-08', '2006-05-09', '2006-05-10', '2006-05-11', '2006-05-12', '2006-05-15', '2006-05-16', '2006-05-17', '2006-05-18', '2006-05-19', '2006-05-22', '2006-05-23', '2006-05-24', '2006-05-25', '2006-05-26', '2006-05-29', '2006-05-30', '2006-05-31', '2006-06-01', '2006-06-02', '2006-06-05', '2006-06-06', '2006-06-07', '2006-06-08', '2006-06-09', '2006-06-12', '2006-06-13', '2006-06-14', '2006-06-15', '2006-06-16', '2006-06-19', '2006-06-20', '2006-06-21', '2006-06-22', '2006-06-23', '2006-06-26', '2006-06-27', '2006-06-28', '2006-06-29', '2006-06-30', '2006-07-03', '2006-07-04', '2006-07-05', '2006-07-06', '2006-07-07', '2006-07-10', '2006-07-11', '2006-07-12', '2006-07-13', '2006-07-14', '2006-07-17', '2006-07-18', '2006-07-19', '2006-07-20', '2006-07-21', '2006-07-24', '2006-07-25', '2006-07-26', '2006-07-27', '2006-07-28', '2006-07-31', '2006-08-01', '2006-08-02', '2006-08-03', '2006-08-04', '2006-08-07', '2006-08-08', '2006-08-09', '2006-08-10', '2006-08-11', '2006-08-14', '2006-08-15', '2006-08-16', '2006-08-17', '2006-08-18', '2006-08-21', '2006-08-22', '2006-08-23', '2006-08-24', '2006-08-25', '2006-08-28', '2006-08-29', '2006-08-30', '2006-08-31', '2006-09-01', '2006-09-04', '2006-09-05', '2006-09-06', '2006-09-07', '2006-09-08', '2006-09-11', '2006-09-12', '2006-09-13', '2006-09-14', '2006-09-15', '2006-09-18', '2006-09-19', '2006-09-20', '2006-09-21', '2006-09-22', '2006-09-25', '2006-09-26', '2006-09-27', '2006-09-28', '2006-09-29', '2006-10-09', '2006-10-10', '2006-10-11', '2006-10-12', '2006-10-13', '2006-10-16', '2006-10-17', '2006-10-18', '2006-10-19', '2006-10-20', '2006-10-23', '2006-10-24', '2006-10-25', '2006-10-26', '2006-10-27', '2006-10-30', '2006-10-31', '2006-11-01', '2006-11-02', '2006-11-03', '2006-11-06', '2006-11-07', '2006-11-08', '2006-11-09', '2006-11-10', '2006-11-13', '2006-11-14', '2006-11-15', '2006-11-16', '2006-11-17', '2006-11-20', '2006-11-21', '2006-11-22', '2006-11-23', '2006-11-24', '2006-11-27', '2006-11-28', '2006-11-29', '2006-11-30', '2006-12-01', '2006-12-04', '2006-12-05', '2006-12-06', '2006-12-07', '2006-12-08', '2006-12-11', '2006-12-12', '2006-12-13', '2006-12-14', '2006-12-15', '2006-12-18', '2006-12-19', '2006-12-20', '2006-12-21', '2006-12-22', '2006-12-25', '2006-12-26', '2006-12-27', '2006-12-28', '2006-12-29', '2007-01-04', '2007-01-05', '2007-01-08', '2007-01-09', '2007-01-10', '2007-01-11', '2007-01-12', '2007-01-15', '2007-01-16', '2007-01-17', '2007-01-18', '2007-01-19', '2007-01-22', '2007-01-23', '2007-01-24', '2007-01-25', '2007-01-26', '2007-01-29', '2007-01-30', '2007-01-31', '2007-02-01', '2007-02-02', '2007-02-05', '2007-02-06', '2007-02-07', '2007-02-08', '2007-02-09', '2007-02-12', '2007-02-13', '2007-02-14', '2007-02-15', '2007-02-16', '2007-02-26', '2007-02-27', '2007-02-28', '2007-03-01', '2007-03-02', '2007-03-05', '2007-03-06', '2007-03-07', '2007-03-08', '2007-03-09', '2007-03-12', '2007-03-13', '2007-03-14', '2007-03-15', '2007-03-16', '2007-03-19', '2007-03-20', '2007-03-21', '2007-03-22', '2007-03-23', '2007-03-26', '2007-03-27', '2007-03-28', '2007-03-29', '2007-03-30', '2007-04-02', '2007-04-03', '2007-04-04', '2007-04-05', '2007-04-06', '2007-04-09', '2007-04-10', '2007-04-11', '2007-04-12', '2007-04-13', '2007-04-16', '2007-04-17', '2007-04-18', '2007-04-19', '2007-04-20', '2007-04-23', '2007-04-24', '2007-04-25', '2007-04-26', '2007-04-27', '2007-04-30', '2007-05-08', '2007-05-09', '2007-05-10', '2007-05-11', '2007-05-14', '2007-05-15', '2007-05-16', '2007-05-17', '2007-05-18', '2007-05-21', '2007-05-22', '2007-05-23', '2007-05-24', '2007-05-25', '2007-05-28', '2007-05-29', '2007-05-30', '2007-05-31', '2007-06-01', '2007-06-04', '2007-06-05', '2007-06-06', '2007-06-07', '2007-06-08', '2007-06-11', '2007-06-12', '2007-06-13', '2007-06-14', '2007-06-15', '2007-06-18', '2007-06-19', '2007-06-20', '2007-06-21', '2007-06-22', '2007-06-25', '2007-06-26', '2007-06-27', '2007-06-28', '2007-06-29', '2007-07-02', '2007-07-03', '2007-07-04', '2007-07-05', '2007-07-06', '2007-07-09', '2007-07-10', '2007-07-11', '2007-07-12', '2007-07-13', '2007-07-16', '2007-07-17', '2007-07-18', '2007-07-19', '2007-07-20', '2007-07-23', '2007-07-24', '2007-07-25', '2007-07-26', '2007-07-27', '2007-07-30', '2007-07-31', '2007-08-01', '2007-08-02', '2007-08-03', '2007-08-06', '2007-08-07', '2007-08-08', '2007-08-09', '2007-08-10', '2007-08-13', '2007-08-14', '2007-08-15', '2007-08-16', '2007-08-17', '2007-08-20', '2007-08-21', '2007-08-22', '2007-08-23', '2007-08-24', '2007-08-27', '2007-08-28', '2007-08-29', '2007-08-30', '2007-08-31', '2007-09-03', '2007-09-04', '2007-09-05', '2007-09-06', '2007-09-07', '2007-09-10', '2007-09-11', '2007-09-12', '2007-09-13', '2007-09-14', '2007-09-17', '2007-09-18', '2007-09-19', '2007-09-20', '2007-09-21', '2007-09-24', '2007-09-25', '2007-09-26', '2007-09-27', '2007-09-28', '2007-10-08', '2007-10-09', '2007-10-10', '2007-10-11', '2007-10-12', '2007-10-15', '2007-10-16', '2007-10-17', '2007-10-18', '2007-10-19', '2007-10-22', '2007-10-23', '2007-10-24', '2007-10-25', '2007-10-26', '2007-10-29', '2007-10-30', '2007-10-31', '2007-11-01', '2007-11-02', '2007-11-05', '2007-11-06', '2007-11-07', '2007-11-08', '2007-11-09', '2007-11-12', '2007-11-13', '2007-11-14', '2007-11-15', '2007-11-16', '2007-11-19', '2007-11-20', '2007-11-21', '2007-11-22', '2007-11-23', '2007-11-26', '2007-11-27', '2007-11-28', '2007-11-29', '2007-11-30', '2007-12-03', '2007-12-04', '2007-12-05', '2007-12-06', '2007-12-07', '2007-12-10', '2007-12-11', '2007-12-12', '2007-12-13', '2007-12-14', '2007-12-17', '2007-12-18', '2007-12-19', '2007-12-20', '2007-12-21', '2007-12-24', '2007-12-25', '2007-12-26', '2007-12-27', '2007-12-28', '2008-01-02', '2008-01-03', '2008-01-04', '2008-01-07', '2008-01-08', '2008-01-09', '2008-01-10', '2008-01-11', '2008-01-14', '2008-01-15', '2008-01-16', '2008-01-17', '2008-01-18', '2008-01-21', '2008-01-22', '2008-01-23', '2008-01-24', '2008-01-25', '2008-01-28', '2008-01-29', '2008-01-30', '2008-01-31', '2008-02-01', '2008-02-04', '2008-02-05', '2008-02-13', '2008-02-14', '2008-02-15', '2008-02-18', '2008-02-19', '2008-02-20', '2008-02-21', '2008-02-22', '2008-02-25', '2008-02-26', '2008-02-27', '2008-02-28', '2008-02-29', '2008-03-03', '2008-03-04', '2008-03-05', '2008-03-06', '2008-03-07', '2008-03-10', '2008-03-11', '2008-03-12', '2008-03-13', '2008-03-14', '2008-03-17', '2008-03-18', '2008-03-19', '2008-03-20', '2008-03-21', '2008-03-24', '2008-03-25', '2008-03-26', '2008-03-27', '2008-03-28', '2008-03-31', '2008-04-01', '2008-04-02', '2008-04-03', '2008-04-07', '2008-04-08', '2008-04-09', '2008-04-10', '2008-04-11', '2008-04-14', '2008-04-15', '2008-04-16', '2008-04-17', '2008-04-18', '2008-04-21', '2008-04-22', '2008-04-23', '2008-04-24', '2008-04-25', '2008-04-28', '2008-04-29', '2008-04-30', '2008-05-05', '2008-05-06', '2008-05-07', '2008-05-08', '2008-05-09', '2008-05-12', '2008-05-13', '2008-05-14', '2008-05-15', '2008-05-16', '2008-05-19', '2008-05-20', '2008-05-21', '2008-05-22', '2008-05-23', '2008-05-26', '2008-05-27', '2008-05-28', '2008-05-29', '2008-05-30', '2008-06-02', '2008-06-03', '2008-06-04', '2008-06-05', '2008-06-06', '2008-06-10', '2008-06-11', '2008-06-12', '2008-06-13', '2008-06-16', '2008-06-17', '2008-06-18', '2008-06-19', '2008-06-20', '2008-06-23', '2008-06-24', '2008-06-25', '2008-06-26', '2008-06-27', '2008-06-30', '2008-07-01', '2008-07-02', '2008-07-03', '2008-07-04', '2008-07-07', '2008-07-08', '2008-07-09', '2008-07-10', '2008-07-11', '2008-07-14', '2008-07-15', '2008-07-16', '2008-07-17', '2008-07-18', '2008-07-21', '2008-07-22', '2008-07-23', '2008-07-24', '2008-07-25', '2008-07-28', '2008-07-29', '2008-07-30', '2008-07-31', '2008-08-01', '2008-08-04', '2008-08-05', '2008-08-06', '2008-08-07', '2008-08-08', '2008-08-11', '2008-08-12', '2008-08-13', '2008-08-14', '2008-08-15', '2008-08-18', '2008-08-19', '2008-08-20', '2008-08-21', '2008-08-22', '2008-08-25', '2008-08-26', '2008-08-27', '2008-08-28', '2008-08-29', '2008-09-01', '2008-09-02', '2008-09-03', '2008-09-04', '2008-09-05', '2008-09-08', '2008-09-09', '2008-09-10', '2008-09-11', '2008-09-12', '2008-09-16', '2008-09-17', '2008-09-18', '2008-09-19', '2008-09-22', '2008-09-23', '2008-09-24', '2008-09-25', '2008-09-26', '2008-10-06', '2008-10-07', '2008-10-08', '2008-10-09', '2008-10-10', '2008-10-13', '2008-10-14', '2008-10-15', '2008-10-16', '2008-10-17', '2008-10-20', '2008-10-21', '2008-10-22', '2008-10-23', '2008-10-24', '2008-10-27', '2008-10-28', '2008-10-29', '2008-10-30', '2008-10-31', '2008-11-03', '2008-11-04', '2008-11-05', '2008-11-06', '2008-11-07', '2008-11-10', '2008-11-11', '2008-11-12', '2008-11-13', '2008-11-14', '2008-11-17', '2008-11-18', '2008-11-19', '2008-11-20', '2008-11-21', '2008-11-24', '2008-11-25', '2008-11-26', '2008-11-27', '2008-11-28', '2008-12-01', '2008-12-02', '2008-12-03', '2008-12-04', '2008-12-05', '2008-12-08', '2008-12-09', '2008-12-10', '2008-12-11', '2008-12-12', '2008-12-15', '2008-12-16', '2008-12-17', '2008-12-18', '2008-12-19', '2008-12-22', '2008-12-23', '2008-12-24', '2008-12-25', '2008-12-26', '2008-12-29', '2008-12-30', '2008-12-31', '2009-01-05', '2009-01-06', '2009-01-07', '2009-01-08', '2009-01-09', '2009-01-12', '2009-01-13', '2009-01-14', '2009-01-15', '2009-01-16', '2009-01-19', '2009-01-20', '2009-01-21', '2009-01-22', '2009-01-23', '2009-02-02', '2009-02-03', '2009-02-04', '2009-02-05', '2009-02-06', '2009-02-09', '2009-02-10', '2009-02-11', '2009-02-12', '2009-02-13', '2009-02-16', '2009-02-17', '2009-02-18', '2009-02-19', '2009-02-20', '2009-02-23', '2009-02-24', '2009-02-25', '2009-02-26', '2009-02-27', '2009-03-02', '2009-03-03', '2009-03-04', '2009-03-05', '2009-03-06', '2009-03-09', '2009-03-10', '2009-03-11', '2009-03-12', '2009-03-13', '2009-03-16', '2009-03-17', '2009-03-18', '2009-03-19', '2009-03-20', '2009-03-23', '2009-03-24', '2009-03-25', '2009-03-26', '2009-03-27', '2009-03-30', '2009-03-31', '2009-04-01', '2009-04-02', '2009-04-03', '2009-04-07', '2009-04-08', '2009-04-09', '2009-04-10', '2009-04-13', '2009-04-14', '2009-04-15', '2009-04-16', '2009-04-17', '2009-04-20', '2009-04-21', '2009-04-22', '2009-04-23', '2009-04-24', '2009-04-27', '2009-04-28', '2009-04-29', '2009-04-30', '2009-05-04', '2009-05-05', '2009-05-06', '2009-05-07', '2009-05-08', '2009-05-11', '2009-05-12', '2009-05-13', '2009-05-14', '2009-05-15', '2009-05-18', '2009-05-19', '2009-05-20', '2009-05-21', '2009-05-22', '2009-05-25', '2009-05-26', '2009-05-27', '2009-06-01', '2009-06-02', '2009-06-03', '2009-06-04', '2009-06-05', '2009-06-08', '2009-06-09', '2009-06-10', '2009-06-11', '2009-06-12', '2009-06-15', '2009-06-16', '2009-06-17', '2009-06-18', '2009-06-19', '2009-06-22', '2009-06-23', '2009-06-24', '2009-06-25', '2009-06-26', '2009-06-29', '2009-06-30', '2009-07-01', '2009-07-02', '2009-07-03', '2009-07-06', '2009-07-07', '2009-07-08', '2009-07-09', '2009-07-10', '2009-07-13', '2009-07-14', '2009-07-15', '2009-07-16', '2009-07-17', '2009-07-20', '2009-07-21', '2009-07-22', '2009-07-23', '2009-07-24', '2009-07-27', '2009-07-28', '2009-07-29', '2009-07-30', '2009-07-31', '2009-08-03', '2009-08-04', '2009-08-05', '2009-08-06', '2009-08-07', '2009-08-10', '2009-08-11', '2009-08-12', '2009-08-13', '2009-08-14', '2009-08-17', '2009-08-18', '2009-08-19', '2009-08-20', '2009-08-21', '2009-08-24', '2009-08-25', '2009-08-26', '2009-08-27', '2009-08-28', '2009-08-31', '2009-09-01', '2009-09-02', '2009-09-03', '2009-09-04', '2009-09-07', '2009-09-08', '2009-09-09', '2009-09-10', '2009-09-11', '2009-09-14', '2009-09-15', '2009-09-16', '2009-09-17', '2009-09-18', '2009-09-21', '2009-09-22', '2009-09-23', '2009-09-24', '2009-09-25', '2009-09-28', '2009-09-29', '2009-09-30', '2009-10-09', '2009-10-12', '2009-10-13', '2009-10-14', '2009-10-15', '2009-10-16', '2009-10-19', '2009-10-20', '2009-10-21', '2009-10-22', '2009-10-23', '2009-10-26', '2009-10-27', '2009-10-28', '2009-10-29', '2009-10-30', '2009-11-02', '2009-11-03', '2009-11-04', '2009-11-05', '2009-11-06', '2009-11-09', '2009-11-10', '2009-11-11', '2009-11-12', '2009-11-13', '2009-11-16', '2009-11-17', '2009-11-18', '2009-11-19', '2009-11-20', '2009-11-23', '2009-11-24', '2009-11-25', '2009-11-26', '2009-11-27', '2009-11-30', '2009-12-01', '2009-12-02', '2009-12-03', '2009-12-04', '2009-12-07', '2009-12-08', '2009-12-09', '2009-12-10', '2009-12-11', '2009-12-14', '2009-12-15', '2009-12-16', '2009-12-17', '2009-12-18', '2009-12-21', '2009-12-22', '2009-12-23', '2009-12-24', '2009-12-25', '2009-12-28', '2009-12-29', '2009-12-30', '2009-12-31', '2010-01-04', '2010-01-05', '2010-01-06', '2010-01-07', '2010-01-08', '2010-01-11', '2010-01-12', '2010-01-13', '2010-01-14', '2010-01-15', '2010-01-18', '2010-01-19', '2010-01-20', '2010-01-21', '2010-01-22', '2010-01-25', '2010-01-26', '2010-01-27', '2010-01-28', '2010-01-29', '2010-02-01', '2010-02-02', '2010-02-03', '2010-02-04', '2010-02-05', '2010-02-08', '2010-02-09', '2010-02-10', '2010-02-11', '2010-02-12', '2010-02-22', '2010-02-23', '2010-02-24', '2010-02-25', '2010-02-26', '2010-03-01', '2010-03-02', '2010-03-03', '2010-03-04', '2010-03-05', '2010-03-08', '2010-03-09', '2010-03-10', '2010-03-11', '2010-03-12', '2010-03-15', '2010-03-16', '2010-03-17', '2010-03-18', '2010-03-19', '2010-03-22', '2010-03-23', '2010-03-24', '2010-03-25', '2010-03-26', '2010-03-29', '2010-03-30', '2010-03-31', '2010-04-01', '2010-04-02', '2010-04-06', '2010-04-07', '2010-04-08', '2010-04-09', '2010-04-12', '2010-04-13', '2010-04-14', '2010-04-15', '2010-04-16', '2010-04-19', '2010-04-20', '2010-04-21', '2010-04-22', '2010-04-23', '2010-04-26', '2010-04-27', '2010-04-28', '2010-04-29', '2010-04-30', '2010-05-04', '2010-05-05', '2010-05-06', '2010-05-07', '2010-05-10', '2010-05-11', '2010-05-12', '2010-05-13', '2010-05-14', '2010-05-17', '2010-05-18', '2010-05-19', '2010-05-20', '2010-05-21', '2010-05-24', '2010-05-25', '2010-05-26', '2010-05-27', '2010-05-28', '2010-05-31', '2010-06-01', '2010-06-02', '2010-06-03', '2010-06-04', '2010-06-07', '2010-06-08', '2010-06-09', '2010-06-10', '2010-06-11', '2010-06-17', '2010-06-18', '2010-06-21', '2010-06-22', '2010-06-23', '2010-06-24', '2010-06-25', '2010-06-28', '2010-06-29', '2010-06-30', '2010-07-01', '2010-07-02', '2010-07-05', '2010-07-06', '2010-07-07', '2010-07-08', '2010-07-09', '2010-07-12', '2010-07-13', '2010-07-14', '2010-07-15', '2010-07-16', '2010-07-19', '2010-07-20', '2010-07-21', '2010-07-22', '2010-07-23', '2010-07-26', '2010-07-27', '2010-07-28', '2010-07-29', '2010-07-30', '2010-08-02', '2010-08-03', '2010-08-04', '2010-08-05', '2010-08-06', '2010-08-09', '2010-08-10', '2010-08-11', '2010-08-12', '2010-08-13', '2010-08-16', '2010-08-17', '2010-08-18', '2010-08-19', '2010-08-20', '2010-08-23', '2010-08-24', '2010-08-25', '2010-08-26', '2010-08-27', '2010-08-30', '2010-08-31', '2010-09-01', '2010-09-02', '2010-09-03', '2010-09-06', '2010-09-07', '2010-09-08', '2010-09-09', '2010-09-10', '2010-09-13', '2010-09-14', '2010-09-15', '2010-09-16', '2010-09-17', '2010-09-20', '2010-09-21', '2010-09-27', '2010-09-28', '2010-09-29', '2010-09-30', '2010-10-08', '2010-10-11', '2010-10-12', '2010-10-13', '2010-10-14', '2010-10-15', '2010-10-18', '2010-10-19', '2010-10-20', '2010-10-21', '2010-10-22', '2010-10-25', '2010-10-26', '2010-10-27', '2010-10-28', '2010-10-29', '2010-11-01', '2010-11-02', '2010-11-03', '2010-11-04', '2010-11-05', '2010-11-08', '2010-11-09', '2010-11-10', '2010-11-11', '2010-11-12', '2010-11-15', '2010-11-16', '2010-11-17', '2010-11-18', '2010-11-19', '2010-11-22', '2010-11-23', '2010-11-24', '2010-11-25', '2010-11-26', '2010-11-29', '2010-11-30', '2010-12-01', '2010-12-02', '2010-12-03', '2010-12-06', '2010-12-07', '2010-12-08', '2010-12-09', '2010-12-10', '2010-12-13', '2010-12-14', '2010-12-15', '2010-12-16', '2010-12-17', '2010-12-20', '2010-12-21', '2010-12-22', '2010-12-23', '2010-12-24', '2010-12-27', '2010-12-28', '2010-12-29', '2010-12-30', '2010-12-31', '2011-01-04', '2011-01-05', '2011-01-06', '2011-01-07', '2011-01-10', '2011-01-11', '2011-01-12', '2011-01-13', '2011-01-14', '2011-01-17', '2011-01-18', '2011-01-19', '2011-01-20', '2011-01-21', '2011-01-24', '2011-01-25', '2011-01-26', '2011-01-27', '2011-01-28', '2011-01-31', '2011-02-01', '2011-02-09', '2011-02-10', '2011-02-11', '2011-02-14', '2011-02-15', '2011-02-16', '2011-02-17', '2011-02-18', '2011-02-21', '2011-02-22', '2011-02-23', '2011-02-24', '2011-02-25', '2011-02-28', '2011-03-01', '2011-03-02', '2011-03-03', '2011-03-04', '2011-03-07', '2011-03-08', '2011-03-09', '2011-03-10', '2011-03-11', '2011-03-14', '2011-03-15', '2011-03-16', '2011-03-17', '2011-03-18', '2011-03-21', '2011-03-22', '2011-03-23', '2011-03-24', '2011-03-25', '2011-03-28', '2011-03-29', '2011-03-30', '2011-03-31', '2011-04-01', '2011-04-06', '2011-04-07', '2011-04-08', '2011-04-11', '2011-04-12', '2011-04-13', '2011-04-14', '2011-04-15', '2011-04-18', '2011-04-19', '2011-04-20', '2011-04-21', '2011-04-22', '2011-04-25', '2011-04-26', '2011-04-27', '2011-04-28', '2011-04-29', '2011-05-03', '2011-05-04', '2011-05-05', '2011-05-06', '2011-05-09', '2011-05-10', '2011-05-11', '2011-05-12', '2011-05-13', '2011-05-16', '2011-05-17', '2011-05-18', '2011-05-19', '2011-05-20', '2011-05-23', '2011-05-24', '2011-05-25', '2011-05-26', '2011-05-27', '2011-05-30', '2011-05-31', '2011-06-01', '2011-06-02', '2011-06-03', '2011-06-07', '2011-06-08', '2011-06-09', '2011-06-10', '2011-06-13', '2011-06-14', '2011-06-15', '2011-06-16', '2011-06-17', '2011-06-20', '2011-06-21', '2011-06-22', '2011-06-23', '2011-06-24', '2011-06-27', '2011-06-28', '2011-06-29', '2011-06-30', '2011-07-01', '2011-07-04', '2011-07-05', '2011-07-06', '2011-07-07', '2011-07-08', '2011-07-11', '2011-07-12', '2011-07-13', '2011-07-14', '2011-07-15', '2011-07-18', '2011-07-19', '2011-07-20', '2011-07-21', '2011-07-22', '2011-07-25', '2011-07-26', '2011-07-27', '2011-07-28', '2011-07-29', '2011-08-01', '2011-08-02', '2011-08-03', '2011-08-04', '2011-08-05', '2011-08-08', '2011-08-09', '2011-08-10', '2011-08-11', '2011-08-12', '2011-08-15', '2011-08-16', '2011-08-17', '2011-08-18', '2011-08-19', '2011-08-22', '2011-08-23', '2011-08-24', '2011-08-25', '2011-08-26', '2011-08-29', '2011-08-30', '2011-08-31', '2011-09-01', '2011-09-02', '2011-09-05', '2011-09-06', '2011-09-07', '2011-09-08', '2011-09-09', '2011-09-13', '2011-09-14', '2011-09-15', '2011-09-16', '2011-09-19', '2011-09-20', '2011-09-21', '2011-09-22', '2011-09-23', '2011-09-26', '2011-09-27', '2011-09-28', '2011-09-29', '2011-09-30', '2011-10-10', '2011-10-11', '2011-10-12', '2011-10-13', '2011-10-14', '2011-10-17', '2011-10-18', '2011-10-19', '2011-10-20', '2011-10-21', '2011-10-24', '2011-10-25', '2011-10-26', '2011-10-27', '2011-10-28', '2011-10-31', '2011-11-01', '2011-11-02', '2011-11-03', '2011-11-04', '2011-11-07', '2011-11-08', '2011-11-09', '2011-11-10', '2011-11-11', '2011-11-14', '2011-11-15', '2011-11-16', '2011-11-17', '2011-11-18', '2011-11-21', '2011-11-22', '2011-11-23', '2011-11-24', '2011-11-25', '2011-11-28', '2011-11-29', '2011-11-30', '2011-12-01', '2011-12-02', '2011-12-05', '2011-12-06', '2011-12-07', '2011-12-08', '2011-12-09', '2011-12-12', '2011-12-13', '2011-12-14', '2011-12-15', '2011-12-16', '2011-12-19', '2011-12-20', '2011-12-21', '2011-12-22', '2011-12-23', '2011-12-26', '2011-12-27', '2011-12-28', '2011-12-29', '2011-12-30', '2012-01-04', '2012-01-05', '2012-01-06', '2012-01-09', '2012-01-10', '2012-01-11', '2012-01-12', '2012-01-13', '2012-01-16', '2012-01-17', '2012-01-18', '2012-01-19', '2012-01-20', '2012-01-30', '2012-01-31', '2012-02-01', '2012-02-02', '2012-02-03', '2012-02-06', '2012-02-07', '2012-02-08', '2012-02-09', '2012-02-10', '2012-02-13', '2012-02-14', '2012-02-15', '2012-02-16', '2012-02-17', '2012-02-20', '2012-02-21', '2012-02-22', '2012-02-23', '2012-02-24', '2012-02-27', '2012-02-28', '2012-02-29', '2012-03-01', '2012-03-02', '2012-03-05', '2012-03-06', '2012-03-07', '2012-03-08', '2012-03-09', '2012-03-12', '2012-03-13', '2012-03-14', '2012-03-15', '2012-03-16', '2012-03-19', '2012-03-20', '2012-03-21', '2012-03-22', '2012-03-23', '2012-03-26', '2012-03-27', '2012-03-28', '2012-03-29', '2012-03-30', '2012-04-05', '2012-04-06', '2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12', '2012-04-13', '2012-04-16', '2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20', '2012-04-23', '2012-04-24', '2012-04-25', '2012-04-26', '2012-04-27', '2012-05-02', '2012-05-03', '2012-05-04', '2012-05-07', '2012-05-08', '2012-05-09', '2012-05-10', '2012-05-11', '2012-05-14', '2012-05-15', '2012-05-16', '2012-05-17', '2012-05-18', '2012-05-21', '2012-05-22', '2012-05-23', '2012-05-24', '2012-05-25', '2012-05-28', '2012-05-29', '2012-05-30', '2012-05-31', '2012-06-01', '2012-06-04', '2012-06-05', '2012-06-06', '2012-06-07', '2012-06-08', '2012-06-11', '2012-06-12', '2012-06-13', '2012-06-14', '2012-06-15', '2012-06-18', '2012-06-19', '2012-06-20', '2012-06-21', '2012-06-25', '2012-06-26', '2012-06-27', '2012-06-28', '2012-06-29', '2012-07-02', '2012-07-03', '2012-07-04', '2012-07-05', '2012-07-06', '2012-07-09', '2012-07-10', '2012-07-11', '2012-07-12', '2012-07-13', '2012-07-16', '2012-07-17', '2012-07-18', '2012-07-19', '2012-07-20', '2012-07-23', '2012-07-24', '2012-07-25', '2012-07-26', '2012-07-27', '2012-07-30', '2012-07-31', '2012-08-01', '2012-08-02', '2012-08-03', '2012-08-06', '2012-08-07', '2012-08-08', '2012-08-09', '2012-08-10', '2012-08-13', '2012-08-14', '2012-08-15', '2012-08-16', '2012-08-17', '2012-08-20', '2012-08-21', '2012-08-22', '2012-08-23', '2012-08-24', '2012-08-27', '2012-08-28', '2012-08-29', '2012-08-30', '2012-08-31', '2012-09-03', '2012-09-04', '2012-09-05', '2012-09-06', '2012-09-07', '2012-09-10', '2012-09-11', '2012-09-12', '2012-09-13', '2012-09-14', '2012-09-17', '2012-09-18', '2012-09-19', '2012-09-20', '2012-09-21', '2012-09-24', '2012-09-25', '2012-09-26', '2012-09-27', '2012-09-28', '2012-10-08', '2012-10-09', '2012-10-10', '2012-10-11', '2012-10-12', '2012-10-15', '2012-10-16', '2012-10-17', '2012-10-18', '2012-10-19', '2012-10-22', '2012-10-23', '2012-10-24', '2012-10-25', '2012-10-26', '2012-10-29', '2012-10-30', '2012-10-31', '2012-11-01', '2012-11-02', '2012-11-05', '2012-11-06', '2012-11-07', '2012-11-08', '2012-11-09', '2012-11-12', '2012-11-13', '2012-11-14', '2012-11-15', '2012-11-16', '2012-11-19', '2012-11-20', '2012-11-21', '2012-11-22', '2012-11-23', '2012-11-26', '2012-11-27', '2012-11-28', '2012-11-29', '2012-11-30', '2012-12-03', '2012-12-04', '2012-12-05', '2012-12-06', '2012-12-07', '2012-12-10', '2012-12-11', '2012-12-12', '2012-12-13', '2012-12-14', '2012-12-17', '2012-12-18', '2012-12-19', '2012-12-20', '2012-12-21', '2012-12-24', '2012-12-25', '2012-12-26', '2012-12-27', '2012-12-28', '2012-12-31', '2013-01-04', '2013-01-07', '2013-01-08', '2013-01-09', '2013-01-10', '2013-01-11', '2013-01-14', '2013-01-15', '2013-01-16', '2013-01-17', '2013-01-18', '2013-01-21', '2013-01-22', '2013-01-23', '2013-01-24', '2013-01-25', '2013-01-28', '2013-01-29', '2013-01-30', '2013-01-31', '2013-02-01', '2013-02-04', '2013-02-05', '2013-02-06', '2013-02-07', '2013-02-08', '2013-02-18', '2013-02-19', '2013-02-20', '2013-02-21', '2013-02-22', '2013-02-25', '2013-02-26', '2013-02-27', '2013-02-28', '2013-03-01', '2013-03-04', '2013-03-05', '2013-03-06', '2013-03-07', '2013-03-08', '2013-03-11', '2013-03-12', '2013-03-13', '2013-03-14', '2013-03-15', '2013-03-18', '2013-03-19', '2013-03-20', '2013-03-21', '2013-03-22', '2013-03-25', '2013-03-26', '2013-03-27', '2013-03-28', '2013-03-29', '2013-04-01', '2013-04-02', '2013-04-03', '2013-04-08', '2013-04-09', '2013-04-10', '2013-04-11', '2013-04-12', '2013-04-15', '2013-04-16', '2013-04-17', '2013-04-18', '2013-04-19', '2013-04-22', '2013-04-23', '2013-04-24', '2013-04-25', '2013-04-26', '2013-05-02', '2013-05-03', '2013-05-06', '2013-05-07', '2013-05-08', '2013-05-09', '2013-05-10', '2013-05-13', '2013-05-14', '2013-05-15', '2013-05-16', '2013-05-17', '2013-05-20', '2013-05-21', '2013-05-22', '2013-05-23', '2013-05-24', '2013-05-27', '2013-05-28', '2013-05-29', '2013-05-30', '2013-05-31', '2013-06-03', '2013-06-04', '2013-06-05', '2013-06-06', '2013-06-07', '2013-06-13', '2013-06-14', '2013-06-17', '2013-06-18', '2013-06-19', '2013-06-20', '2013-06-21', '2013-06-24', '2013-06-25', '2013-06-26', '2013-06-27', '2013-06-28', '2013-07-01', '2013-07-02', '2013-07-03', '2013-07-04', '2013-07-05', '2013-07-08', '2013-07-09', '2013-07-10', '2013-07-11', '2013-07-12', '2013-07-15', '2013-07-16', '2013-07-17', '2013-07-18', '2013-07-19', '2013-07-22', '2013-07-23', '2013-07-24', '2013-07-25', '2013-07-26', '2013-07-29', '2013-07-30', '2013-07-31', '2013-08-01', '2013-08-02', '2013-08-05', '2013-08-06', '2013-08-07', '2013-08-08', '2013-08-09', '2013-08-12', '2013-08-13', '2013-08-14', '2013-08-15', '2013-08-16', '2013-08-19', '2013-08-20', '2013-08-21', '2013-08-22', '2013-08-23', '2013-08-26', '2013-08-27', '2013-08-28', '2013-08-29', '2013-08-30', '2013-09-02', '2013-09-03', '2013-09-04', '2013-09-05', '2013-09-06', '2013-09-09', '2013-09-10', '2013-09-11', '2013-09-12', '2013-09-13', '2013-09-16', '2013-09-17', '2013-09-18', '2013-09-23', '2013-09-24', '2013-09-25', '2013-09-26', '2013-09-27', '2013-09-30', '2013-10-08', '2013-10-09', '2013-10-10', '2013-10-11', '2013-10-14', '2013-10-15', '2013-10-16', '2013-10-17', '2013-10-18', '2013-10-21', '2013-10-22', '2013-10-23', '2013-10-24', '2013-10-25', '2013-10-28', '2013-10-29', '2013-10-30', '2013-10-31', '2013-11-01', '2013-11-04', '2013-11-05', '2013-11-06', '2013-11-07', '2013-11-08', '2013-11-11', '2013-11-12', '2013-11-13', '2013-11-14', '2013-11-15', '2013-11-18', '2013-11-19', '2013-11-20', '2013-11-21', '2013-11-22', '2013-11-25', '2013-11-26', '2013-11-27', '2013-11-28', '2013-11-29', '2013-12-02', '2013-12-03', '2013-12-04', '2013-12-05', '2013-12-06', '2013-12-09', '2013-12-10', '2013-12-11', '2013-12-12', '2013-12-13', '2013-12-16', '2013-12-17', '2013-12-18', '2013-12-19', '2013-12-20', '2013-12-23', '2013-12-24', '2013-12-25', '2013-12-26', '2013-12-27', '2013-12-30', '2013-12-31', '2014-01-02', '2014-01-03', '2014-01-06', '2014-01-07', '2014-01-08', '2014-01-09', '2014-01-10', '2014-01-13', '2014-01-14', '2014-01-15', '2014-01-16', '2014-01-17', '2014-01-20', '2014-01-21', '2014-01-22', '2014-01-23', '2014-01-24', '2014-01-27', '2014-01-28', '2014-01-29', '2014-01-30', '2014-02-07', '2014-02-10', '2014-02-11', '2014-02-12', '2014-02-13', '2014-02-14', '2014-02-17', '2014-02-18', '2014-02-19', '2014-02-20', '2014-02-21', '2014-02-24', '2014-02-25', '2014-02-26', '2014-02-27', '2014-02-28', '2014-03-03', '2014-03-04', '2014-03-05', '2014-03-06', '2014-03-07', '2014-03-10', '2014-03-11', '2014-03-12', '2014-03-13', '2014-03-14', '2014-03-17', '2014-03-18', '2014-03-19', '2014-03-20', '2014-03-21', '2014-03-24', '2014-03-25', '2014-03-26', '2014-03-27', '2014-03-28', '2014-03-31', '2014-04-01', '2014-04-02', '2014-04-03', '2014-04-04', '2014-04-08', '2014-04-09', '2014-04-10', '2014-04-11', '2014-04-14', '2014-04-15', '2014-04-16', '2014-04-17', '2014-04-18', '2014-04-21', '2014-04-22', '2014-04-23', '2014-04-24', '2014-04-25', '2014-04-28', '2014-04-29', '2014-04-30', '2014-05-05', '2014-05-06', '2014-05-07', '2014-05-08', '2014-05-09', '2014-05-12', '2014-05-13', '2014-05-14', '2014-05-15', '2014-05-16', '2014-05-19', '2014-05-20', '2014-05-21', '2014-05-22', '2014-05-23', '2014-05-26', '2014-05-27', '2014-05-28', '2014-05-29', '2014-05-30', '2014-06-03', '2014-06-04', '2014-06-05', '2014-06-06', '2014-06-09', '2014-06-10', '2014-06-11', '2014-06-12', '2014-06-13', '2014-06-16', '2014-06-17', '2014-06-18', '2014-06-19', '2014-06-20', '2014-06-23', '2014-06-24', '2014-06-25', '2014-06-26', '2014-06-27', '2014-06-30', '2014-07-01', '2014-07-02', '2014-07-03', '2014-07-04', '2014-07-07', '2014-07-08', '2014-07-09', '2014-07-10', '2014-07-11', '2014-07-14', '2014-07-15', '2014-07-16', '2014-07-17', '2014-07-18', '2014-07-21', '2014-07-22', '2014-07-23', '2014-07-24', '2014-07-25', '2014-07-28', '2014-07-29', '2014-07-30', '2014-07-31', '2014-08-01', '2014-08-04', '2014-08-05', '2014-08-06', '2014-08-07', '2014-08-08', '2014-08-11', '2014-08-12', '2014-08-13', '2014-08-14', '2014-08-15', '2014-08-18', '2014-08-19', '2014-08-20', '2014-08-21', '2014-08-22', '2014-08-25', '2014-08-26', '2014-08-27', '2014-08-28', '2014-08-29', '2014-09-01', '2014-09-02', '2014-09-03', '2014-09-04', '2014-09-05', '2014-09-09', '2014-09-10', '2014-09-11', '2014-09-12', '2014-09-15', '2014-09-16', '2014-09-17', '2014-09-18', '2014-09-19', '2014-09-22', '2014-09-23', '2014-09-24', '2014-09-25', '2014-09-26', '2014-09-29', '2014-09-30', '2014-10-08', '2014-10-09', '2014-10-10', '2014-10-13', '2014-10-14', '2014-10-15', '2014-10-16', '2014-10-17', '2014-10-20', '2014-10-21', '2014-10-22', '2014-10-23', '2014-10-24', '2014-10-27', '2014-10-28', '2014-10-29', '2014-10-30', '2014-10-31', '2014-11-03', '2014-11-04', '2014-11-05', '2014-11-06', '2014-11-07', '2014-11-10', '2014-11-11', '2014-11-12', '2014-11-13', '2014-11-14', '2014-11-17', '2014-11-18', '2014-11-19', '2014-11-20', '2014-11-21', '2014-11-24', '2014-11-25', '2014-11-26', '2014-11-27', '2014-11-28', '2014-12-01', '2014-12-02', '2014-12-03', '2014-12-04', '2014-12-05', '2014-12-08', '2014-12-09', '2014-12-10', '2014-12-11', '2014-12-12', '2014-12-15', '2014-12-16', '2014-12-17', '2014-12-18', '2014-12-19', '2014-12-22', '2014-12-23', '2014-12-24', '2014-12-25', '2014-12-26', '2014-12-29', '2014-12-30', '2014-12-31', '2015-01-05', '2015-01-06', '2015-01-07', '2015-01-08', '2015-01-09', '2015-01-12', '2015-01-13', '2015-01-14', '2015-01-15', '2015-01-16', '2015-01-19', '2015-01-20', '2015-01-21', '2015-01-22', '2015-01-23', '2015-01-26', '2015-01-27', '2015-01-28', '2015-01-29', '2015-01-30', '2015-02-02', '2015-02-03', '2015-02-04', '2015-02-05', '2015-02-06', '2015-02-09', '2015-02-10', '2015-02-11', '2015-02-12', '2015-02-13', '2015-02-16', '2015-02-17', '2015-02-25', '2015-02-26', '2015-02-27', '2015-03-02', '2015-03-03', '2015-03-04', '2015-03-05', '2015-03-06', '2015-03-09', '2015-03-10', '2015-03-11', '2015-03-12', '2015-03-13', '2015-03-16', '2015-03-17', '2015-03-18', '2015-03-19', '2015-03-20', '2015-03-23', '2015-03-24', '2015-03-25', '2015-03-26', '2015-03-27', '2015-03-30', '2015-03-31', '2015-04-01', '2015-04-02', '2015-04-03', '2015-04-07', '2015-04-08', '2015-04-09', '2015-04-10', '2015-04-13', '2015-04-14', '2015-04-15', '2015-04-16', '2015-04-17', '2015-04-20', '2015-04-21', '2015-04-22', '2015-04-23', '2015-04-24', '2015-04-27', '2015-04-28', '2015-04-29', '2015-04-30', '2015-05-04', '2015-05-05', '2015-05-06', '2015-05-07', '2015-05-08', '2015-05-11', '2015-05-12', '2015-05-13', '2015-05-14', '2015-05-15', '2015-05-18', '2015-05-19', '2015-05-20', '2015-05-21', '2015-05-22', '2015-05-25', '2015-05-26', '2015-05-27', '2015-05-28', '2015-05-29', '2015-06-01', '2015-06-02', '2015-06-03', '2015-06-04', '2015-06-05', '2015-06-08', '2015-06-09', '2015-06-10', '2015-06-11', '2015-06-12', '2015-06-15', '2015-06-16', '2015-06-17', '2015-06-18', '2015-06-19', '2015-06-23', '2015-06-24', '2015-06-25', '2015-06-26', '2015-06-29', '2015-06-30', '2015-07-01', '2015-07-02', '2015-07-03', '2015-07-06', '2015-07-07', '2015-07-08', '2015-07-09', '2015-07-10', '2015-07-13', '2015-07-14', '2015-07-15', '2015-07-16', '2015-07-17', '2015-07-20', '2015-07-21', '2015-07-22', '2015-07-23', '2015-07-24', '2015-07-27', '2015-07-28', '2015-07-29', '2015-07-30', '2015-07-31', '2015-08-03', '2015-08-04', '2015-08-05', '2015-08-06', '2015-08-07', '2015-08-10', '2015-08-11', '2015-08-12', '2015-08-13', '2015-08-14', '2015-08-17', '2015-08-18', '2015-08-19', '2015-08-20', '2015-08-21', '2015-08-24', '2015-08-25', '2015-08-26', '2015-08-27', '2015-08-28', '2015-08-31', '2015-09-01', '2015-09-02', '2015-09-07', '2015-09-08', '2015-09-09', '2015-09-10', '2015-09-11', '2015-09-14', '2015-09-15', '2015-09-16', '2015-09-17', '2015-09-18', '2015-09-21', '2015-09-22', '2015-09-23', '2015-09-24', '2015-09-25', '2015-09-28', '2015-09-29', '2015-09-30', '2015-10-08', '2015-10-09', '2015-10-12', '2015-10-13', '2015-10-14', '2015-10-15', '2015-10-16', '2015-10-19', '2015-10-20', '2015-10-21', '2015-10-22', '2015-10-23', '2015-10-26', '2015-10-27', '2015-10-28', '2015-10-29', '2015-10-30', '2015-11-02', '2015-11-03', '2015-11-04', '2015-11-05', '2015-11-06', '2015-11-09', '2015-11-10', '2015-11-11', '2015-11-12', '2015-11-13', '2015-11-16', '2015-11-17', '2015-11-18', '2015-11-19', '2015-11-20', '2015-11-23', '2015-11-24', '2015-11-25', '2015-11-26', '2015-11-27', '2015-11-30', '2015-12-01', '2015-12-02', '2015-12-03', '2015-12-04', '2015-12-07', '2015-12-08', '2015-12-09', '2015-12-10', '2015-12-11', '2015-12-14', '2015-12-15', '2015-12-16', '2015-12-17', '2015-12-18', '2015-12-21', '2015-12-22', '2015-12-23', '2015-12-24', '2015-12-25', '2015-12-28', '2015-12-29', '2015-12-30', '2015-12-31', '2016-01-04', '2016-01-05', '2016-01-06', '2016-01-07', '2016-01-08', '2016-01-11', '2016-01-12', '2016-01-13', '2016-01-14', '2016-01-15', '2016-01-18', '2016-01-19', '2016-01-20', '2016-01-21', '2016-01-22', '2016-01-25', '2016-01-26', '2016-01-27', '2016-01-28', '2016-01-29', '2016-02-01', '2016-02-02', '2016-02-03', '2016-02-04', '2016-02-05', '2016-02-15', '2016-02-16', '2016-02-17', '2016-02-18', '2016-02-19', '2016-02-22', '2016-02-23', '2016-02-24', '2016-02-25', '2016-02-26', '2016-02-29', '2016-03-01', '2016-03-02', '2016-03-03', '2016-03-04', '2016-03-07', '2016-03-08', '2016-03-09', '2016-03-10', '2016-03-11', '2016-03-14', '2016-03-15', '2016-03-16', '2016-03-17', '2016-03-18', '2016-03-21', '2016-03-22', '2016-03-23', '2016-03-24', '2016-03-25', '2016-03-28', '2016-03-29', '2016-03-30', '2016-03-31', '2016-04-01', '2016-04-05', '2016-04-06', '2016-04-07', '2016-04-08', '2016-04-11', '2016-04-12', '2016-04-13', '2016-04-14', '2016-04-15', '2016-04-18', '2016-04-19', '2016-04-20', '2016-04-21', '2016-04-22', '2016-04-25', '2016-04-26', '2016-04-27', '2016-04-28', '2016-04-29', '2016-05-03', '2016-05-04', '2016-05-05', '2016-05-06', '2016-05-09', '2016-05-10', '2016-05-11', '2016-05-12', '2016-05-13', '2016-05-16', '2016-05-17', '2016-05-18', '2016-05-19', '2016-05-20', '2016-05-23', '2016-05-24', '2016-05-25', '2016-05-26', '2016-05-27', '2016-05-30', '2016-05-31', '2016-06-01', '2016-06-02', '2016-06-03', '2016-06-06', '2016-06-07', '2016-06-08', '2016-06-13', '2016-06-14', '2016-06-15', '2016-06-16', '2016-06-17', '2016-06-20', '2016-06-21', '2016-06-22', '2016-06-23', '2016-06-24', '2016-06-27', '2016-06-28', '2016-06-29', '2016-06-30', '2016-07-01', '2016-07-04', '2016-07-05', '2016-07-06', '2016-07-07', '2016-07-08', '2016-07-11', '2016-07-12', '2016-07-13', '2016-07-14', '2016-07-15', '2016-07-18', '2016-07-19', '2016-07-20', '2016-07-21', '2016-07-22', '2016-07-25', '2016-07-26', '2016-07-27', '2016-07-28', '2016-07-29', '2016-08-01', '2016-08-02', '2016-08-03', '2016-08-04', '2016-08-05', '2016-08-08', '2016-08-09', '2016-08-10', '2016-08-11', '2016-08-12', '2016-08-15', '2016-08-16', '2016-08-17', '2016-08-18', '2016-08-19', '2016-08-22', '2016-08-23', '2016-08-24', '2016-08-25', '2016-08-26', '2016-08-29', '2016-08-30', '2016-08-31', '2016-09-01', '2016-09-02', '2016-09-05', '2016-09-06', '2016-09-07', '2016-09-08', '2016-09-09', '2016-09-12', '2016-09-13', '2016-09-14', '2016-09-19', '2016-09-20', '2016-09-21', '2016-09-22', '2016-09-23', '2016-09-26', '2016-09-27', '2016-09-28', '2016-09-29', '2016-09-30', '2016-10-10', '2016-10-11', '2016-10-12', '2016-10-13', '2016-10-14', '2016-10-17', '2016-10-18', '2016-10-19', '2016-10-20', '2016-10-21', '2016-10-24', '2016-10-25', '2016-10-26', '2016-10-27', '2016-10-28', '2016-10-31', '2016-11-01', '2016-11-02', '2016-11-03', '2016-11-04', '2016-11-07', '2016-11-08', '2016-11-09', '2016-11-10', '2016-11-11', '2016-11-14', '2016-11-15', '2016-11-16', '2016-11-17', '2016-11-18', '2016-11-21', '2016-11-22', '2016-11-23', '2016-11-24', '2016-11-25', '2016-11-28', '2016-11-29', '2016-11-30', '2016-12-01', '2016-12-02', '2016-12-05', '2016-12-06', '2016-12-07', '2016-12-08', '2016-12-09', '2016-12-12', '2016-12-13', '2016-12-14', '2016-12-15', '2016-12-16', '2016-12-19', '2016-12-20', '2016-12-21', '2016-12-22', '2016-12-23', '2016-12-26', '2016-12-27', '2016-12-28', '2016-12-29', '2016-12-30', '2017-01-03', '2017-01-04', '2017-01-05', '2017-01-06', '2017-01-09', '2017-01-10', '2017-01-11', '2017-01-12', '2017-01-13', '2017-01-16', '2017-01-17', '2017-01-18', '2017-01-19', '2017-01-20', '2017-01-23', '2017-01-24', '2017-01-25', '2017-01-26', '2017-02-03', '2017-02-06', '2017-02-07', '2017-02-08', '2017-02-09', '2017-02-10', '2017-02-13', '2017-02-14', '2017-02-15', '2017-02-16', '2017-02-17', '2017-02-20', '2017-02-21', '2017-02-22', '2017-02-23', '2017-02-24', '2017-02-27', '2017-02-28', '2017-03-01', '2017-03-02', '2017-03-03', '2017-03-06', '2017-03-07', '2017-03-08', '2017-03-09', '2017-03-10', '2017-03-13', '2017-03-14', '2017-03-15', '2017-03-16', '2017-03-17', '2017-03-20', '2017-03-21', '2017-03-22', '2017-03-23', '2017-03-24', '2017-03-27', '2017-03-28', '2017-03-29', '2017-03-30', '2017-03-31', '2017-04-05', '2017-04-06', '2017-04-07', '2017-04-10', '2017-04-11', '2017-04-12', '2017-04-13', '2017-04-14', '2017-04-17', '2017-04-18', '2017-04-19', '2017-04-20', '2017-04-21', '2017-04-24', '2017-04-25', '2017-04-26', '2017-04-27', '2017-04-28', '2017-05-02', '2017-05-03', '2017-05-04', '2017-05-05', '2017-05-08', '2017-05-09', '2017-05-10', '2017-05-11', '2017-05-12', '2017-05-15', '2017-05-16', '2017-05-17', '2017-05-18', '2017-05-19', '2017-05-22', '2017-05-23', '2017-05-24', '2017-05-25', '2017-05-26', '2017-05-31', '2017-06-01', '2017-06-02', '2017-06-05', '2017-06-06', '2017-06-07', '2017-06-08', '2017-06-09', '2017-06-12', '2017-06-13', '2017-06-14', '2017-06-15', '2017-06-16', '2017-06-19', '2017-06-20', '2017-06-21', '2017-06-22', '2017-06-23', '2017-06-26', '2017-06-27', '2017-06-28', '2017-06-29', '2017-06-30', '2017-07-03', '2017-07-04', '2017-07-05', '2017-07-06', '2017-07-07', '2017-07-10', '2017-07-11', '2017-07-12', '2017-07-13', '2017-07-14', '2017-07-17', '2017-07-18', '2017-07-19', '2017-07-20', '2017-07-21', '2017-07-24', '2017-07-25', '2017-07-26', '2017-07-27', '2017-07-28', '2017-07-31', '2017-08-01', '2017-08-02', '2017-08-03', '2017-08-04', '2017-08-07', '2017-08-08', '2017-08-09', '2017-08-10', '2017-08-11', '2017-08-14', '2017-08-15', '2017-08-16', '2017-08-17', '2017-08-18', '2017-08-21', '2017-08-22', '2017-08-23', '2017-08-24', '2017-08-25', '2017-08-28', '2017-08-29', '2017-08-30', '2017-08-31', '2017-09-01', '2017-09-04', '2017-09-05', '2017-09-06', '2017-09-07', '2017-09-08', '2017-09-11', '2017-09-12', '2017-09-13', '2017-09-14', '2017-09-15', '2017-09-18', '2017-09-19', '2017-09-20', '2017-09-21', '2017-09-22', '2017-09-25', '2017-09-26', '2017-09-27', '2017-09-28', '2017-09-29', '2017-10-09', '2017-10-10', '2017-10-11', '2017-10-12', '2017-10-13', '2017-10-16', '2017-10-17', '2017-10-18', '2017-10-19', '2017-10-20', '2017-10-23', '2017-10-24', '2017-10-25', '2017-10-26', '2017-10-27', '2017-10-30', '2017-10-31', '2017-11-01', '2017-11-02', '2017-11-03', '2017-11-06', '2017-11-07', '2017-11-08', '2017-11-09', '2017-11-10', '2017-11-13', '2017-11-14', '2017-11-15', '2017-11-16', '2017-11-17', '2017-11-20', '2017-11-21', '2017-11-22', '2017-11-23', '2017-11-24', '2017-11-27', '2017-11-28', '2017-11-29', '2017-11-30', '2017-12-01', '2017-12-04', '2017-12-05', '2017-12-06', '2017-12-07', '2017-12-08', '2017-12-11', '2017-12-12', '2017-12-13', '2017-12-14', '2017-12-15', '2017-12-18', '2017-12-19', '2017-12-20', '2017-12-21', '2017-12-22', '2017-12-25', '2017-12-26', '2017-12-27', '2017-12-28', '2017-12-29', '2018-01-02', '2018-01-03', '2018-01-04', '2018-01-05', '2018-01-08', '2018-01-09', '2018-01-10', '2018-01-11', '2018-01-12', '2018-01-15', '2018-01-16', '2018-01-17', '2018-01-18', '2018-01-19', '2018-01-22', '2018-01-23', '2018-01-24', '2018-01-25', '2018-01-26', '2018-01-29', '2018-01-30', '2018-01-31', '2018-02-01', '2018-02-02', '2018-02-05', '2018-02-06', '2018-02-07', '2018-02-08', '2018-02-09', '2018-02-12', '2018-02-13', '2018-02-14', '2018-02-22', '2018-02-23', '2018-02-26', '2018-02-27', '2018-02-28', '2018-03-01', '2018-03-02', '2018-03-05', '2018-03-06', '2018-03-07', '2018-03-08', '2018-03-09', '2018-03-12', '2018-03-13', '2018-03-14', '2018-03-15', '2018-03-16', '2018-03-19', '2018-03-20', '2018-03-21', '2018-03-22', '2018-03-23', '2018-03-26', '2018-03-27', '2018-03-28', '2018-03-29', '2018-03-30', '2018-04-02', '2018-04-03', '2018-04-04', '2018-04-09', '2018-04-10', '2018-04-11', '2018-04-12', '2018-04-13', '2018-04-16', '2018-04-17', '2018-04-18', '2018-04-19', '2018-04-20', '2018-04-23', '2018-04-24', '2018-04-25', '2018-04-26', '2018-04-27', '2018-05-02', '2018-05-03', '2018-05-04', '2018-05-07', '2018-05-08', '2018-05-09', '2018-05-10', '2018-05-11', '2018-05-14', '2018-05-15', '2018-05-16', '2018-05-17', '2018-05-18', '2018-05-21', '2018-05-22', '2018-05-23', '2018-05-24', '2018-05-25', '2018-05-28', '2018-05-29', '2018-05-30', '2018-05-31', '2018-06-01', '2018-06-04', '2018-06-05', '2018-06-06', '2018-06-07', '2018-06-08', '2018-06-11', '2018-06-12', '2018-06-13', '2018-06-14', '2018-06-15', '2018-06-19', '2018-06-20', '2018-06-21', '2018-06-22', '2018-06-25', '2018-06-26', '2018-06-27', '2018-06-28', '2018-06-29', '2018-07-02', '2018-07-03', '2018-07-04', '2018-07-05', '2018-07-06', '2018-07-09', '2018-07-10', '2018-07-11', '2018-07-12', '2018-07-13', '2018-07-16', '2018-07-17', '2018-07-18', '2018-07-19', '2018-07-20', '2018-07-23', '2018-07-24', '2018-07-25', '2018-07-26', '2018-07-27', '2018-07-30', '2018-07-31', '2018-08-01', '2018-08-02', '2018-08-03', '2018-08-06', '2018-08-07', '2018-08-08', '2018-08-09', '2018-08-10', '2018-08-13', '2018-08-14', '2018-08-15', '2018-08-16', '2018-08-17', '2018-08-20', '2018-08-21', '2018-08-22', '2018-08-23', '2018-08-24', '2018-08-27', '2018-08-28', '2018-08-29', '2018-08-30', '2018-08-31', '2018-09-03', '2018-09-04', '2018-09-05', '2018-09-06', '2018-09-07', '2018-09-10', '2018-09-11', '2018-09-12', '2018-09-13', '2018-09-14', '2018-09-17', '2018-09-18', '2018-09-19', '2018-09-20', '2018-09-21', '2018-09-25', '2018-09-26', '2018-09-27', '2018-09-28', '2018-10-08', '2018-10-09', '2018-10-10', '2018-10-11', '2018-10-12', '2018-10-15', '2018-10-16', '2018-10-17', '2018-10-18', '2018-10-19', '2018-10-22', '2018-10-23', '2018-10-24', '2018-10-25', '2018-10-26', '2018-10-29', '2018-10-30', '2018-10-31', '2018-11-01', '2018-11-02', '2018-11-05', '2018-11-06', '2018-11-07', '2018-11-08', '2018-11-09', '2018-11-12', '2018-11-13', '2018-11-14', '2018-11-15', '2018-11-16', '2018-11-19', '2018-11-20', '2018-11-21', '2018-11-22', '2018-11-23', '2018-11-26', '2018-11-27', '2018-11-28', '2018-11-29', '2018-11-30', '2018-12-03', '2018-12-04', '2018-12-05', '2018-12-06', '2018-12-07', '2018-12-10', '2018-12-11', '2018-12-12', '2018-12-13', '2018-12-14', '2018-12-17', '2018-12-18', '2018-12-19', '2018-12-20', '2018-12-21', '2018-12-24', '2018-12-25', '2018-12-26', '2018-12-27', '2018-12-28', '2018-12-31'], towards=-1)[source]
+

获取真实的交易日期,其中,第三个参数towards是表示向前/向后推 +towards=1 日期向后迭代 +towards=-1 日期向前迭代 +@ yutiansut

+
+ +
+
+QUANTAXIS.QAUtil.QADate_trade.QA_util_get_real_datelist(start, end)[source]
+

取数据的真实区间,返回的时候用 start,end=QA_util_get_real_datelist +@yutiansut +2017/8/10

+

当start end中间没有交易日 返回None, None +@yutiansut/ 2017-12-19

+
+ +
+
+QUANTAXIS.QAUtil.QADate_trade.QA_util_get_trade_gap(start, end)[source]
+

返回start_day到end_day中间有多少个交易天 算首尾

+
+ +
+
+QUANTAXIS.QAUtil.QADate_trade.QA_util_get_trade_range(start, end)[source]
+

给出交易具体时间

+
+ +
+
+QUANTAXIS.QAUtil.QADate_trade.QA_util_if_trade(day)[source]
+

日期是否交易

+
+ +
+
+QUANTAXIS.QAUtil.QADate_trade.QA_util_if_tradetime(_time, market='stock_cn', code=None)[source]
+

时间是否交易

+
+ +
+
+

QUANTAXIS.QAUtil.QADict module

+
+
+QUANTAXIS.QAUtil.QADict.QA_util_dict_remove_key(dicts, key)[source]
+

输入一个dict 返回删除后的

+
+ +
+
+

QUANTAXIS.QAUtil.QAList module

+
+
+QUANTAXIS.QAUtil.QAList.QA_util_diff_list(datastruct)[source]
+
+ +
+
+QUANTAXIS.QAUtil.QAList.QA_util_multi_demension_list(row_, col_=0)[source]
+

如果需要创建一个[[],[]], 那就用 row_=2,col=0 +其他时候,返回的都是[[None]]

+
+ +
+
+

QUANTAXIS.QAUtil.QALocalize module

+
+
+

QUANTAXIS.QAUtil.QALogs module

+

QUANTAXIS Log Module +@yutiansut

+

QA_util_log_x is under [QAStandard#0.0.2@602-x] Protocol +QA_util_log_info() +QA_util_log_debug() +QA_util_log_expection()

+
+
+QUANTAXIS.QAUtil.QALogs.QA_util_log_debug(logs)[source]
+

QUANTAXIS Log Module +@yutiansut

+

QA_util_log_x is under [QAStandard#0.0.2@602-x] Protocol

+
+ +
+
+QUANTAXIS.QAUtil.QALogs.QA_util_log_expection(logs)[source]
+

QUANTAXIS Log Module +@yutiansut

+

QA_util_log_x is under [QAStandard#0.0.2@602-x] Protocol

+
+ +
+
+QUANTAXIS.QAUtil.QALogs.QA_util_log_info(logs)[source]
+

QUANTAXIS Log Module +@yutiansut

+

QA_util_log_x is under [QAStandard#0.0.2@602-x] Protocol

+
+ +
+
+

QUANTAXIS.QAUtil.QAMail module

+
+
+QUANTAXIS.QAUtil.QAMail.QA_util_send_mail(msg, title, from_user, from_password, to_addr, smtp)[source]
+

邮件发送

+
+
Arguments:
+
msg {[type]} -- [description] +title {[type]} -- [description] +from_user {[type]} -- [description] +from_password {[type]} -- [description] +to_addr {[type]} -- [description] +smtp {[type]} -- [description]
+
+
+ +
+
+

QUANTAXIS.QAUtil.QAMongo module

+
+
+QUANTAXIS.QAUtil.QAMongo.QA_util_mongo_infos(db=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+
+ +
+
+QUANTAXIS.QAUtil.QAMongo.QA_util_mongo_initial(db=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+
+ +
+
+QUANTAXIS.QAUtil.QAMongo.QA_util_mongo_status(db=Database(MongoClient(host=['127.0.0.1:27017'], document_class=dict, tz_aware=False, connect=True), 'quantaxis'))[source]
+
+ +
+
+

QUANTAXIS.QAUtil.QAParameter module

+

这里定义的是一些常用常量

+
+
+class QUANTAXIS.QAUtil.QAParameter.ACCOUNT_EVENT[source]
+

Bases: object

+

账户事件

+
+
+MAKE_ORDER = 'account_make_order'
+
+ +
+
+SETTLE = 'account_settle'
+
+ +
+
+UPDATE = 'account_update'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.AMOUNT_MODEL[source]
+

Bases: object

+

订单的成交量

+

by_price是按固定成交总额下单,动态计算成交量 +by_amount 按固定成家量下单

+
+
+BY_AMOUNT = 'by_amount'
+
+ +
+
+BY_PRICE = 'by_price'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.BROKER_EVENT[source]
+

Bases: object

+

BROKER事件 +BROKER +有加载数据的任务 load data +撮合成交的任务 broker_trade

+
+
+DAILY_SETTLE = 'broker_dailysettle'
+
+ +
+
+LOAD_DATA = 'load_data'
+
+ +
+
+RECEIVE_ORDER = 'receive_order'
+
+ +
+
+SETTLE = 'broker_settle'
+
+ +
+
+TRADE = 'broker_trade'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.BROKER_TYPE[source]
+

Bases: object

+

执行环境

+

回测 +模拟 +实盘 +随机(按算法/分布随机生成行情)/仅用于训练测试

+
+
+BACKETEST = 'backtest'
+
+ +
+
+RANODM = 'random'
+
+ +
+
+REAL = 'real'
+
+ +
+
+SIMULATION = 'simulation'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.CURRENCY_TYPE[source]
+

Bases: object

+

货币种类

+
+
+AUD = 'aud'
+
+ +
+
+BTC = 'btc'
+
+ +
+
+CAD = 'cad'
+
+ +
+
+EUR = 'eur'
+
+ +
+
+GBP = 'GBP'
+
+ +
+
+HKD = 'hkd'
+
+ +
+
+JPY = 'jpy'
+
+ +
+
+RMB = 'rmb'
+
+ +
+
+USD = 'usd'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.DATASOURCE[source]
+

Bases: object

+

数据来源

+
+
+CCXT = 'ccxt'
+
+ +
+
+CHOICE = 'choice'
+
+ +
+
+EASTMONEY = 'eastmoney'
+
+ +
+
+LOCALFILE = 'localfile'
+
+ +
+
+MONGO = 'mongo'
+
+ +
+
+TDB = 'tdb'
+
+ +
+
+TDX = 'tdx'
+
+ +
+
+THS = 'ths'
+
+ +
+
+TUSHARE = 'tushare'
+
+ +
+
+WIND = 'wind'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.ENGINE_EVENT[source]
+

Bases: object

+

引擎事件

+
+
+BAR_SETTLE = 'bar_settle'
+
+ +
+
+DAILY_SETTLE = 'daily_settle'
+
+ +
+
+MARKET_INIT = 'market_init'
+
+ +
+
+UPCOMING_DATA = 'upcoming_data'
+
+ +
+
+UPDATE = 'update'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.EVENT_TYPE[source]
+

Bases: object

+
+
+ACCOUNT_EVENT = 'account_event'
+
+ +
+
+BROKER_EVENT = 'broker_event'
+
+ +
+
+ENGINE_EVENT = 'engine_event'
+
+ +
+
+MARKET_EVENT = 'market_event'
+
+ +
+
+ORDER_EVENT = 'order_event'
+
+ +
+
+TRADE_EVENT = 'trade_event'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.FREQUENCE[source]
+

Bases: object

+

查询的级别

+

[description]

+
+
+CURRENT = 'current'
+
+ +
+
+DAY = 'day'
+
+ +
+
+FIFTEEN_MIN = '15min'
+
+ +
+
+FIVE_MIN = '5min'
+
+ +
+
+HOUR = '60min'
+
+ +
+
+MONTH = 'month'
+
+ +
+
+ONE_MIN = '1min'
+
+ +
+
+QUARTER = 'quarter'
+
+ +
+
+SIXTY_MIN = '60min'
+
+ +
+
+THIRTY_MIN = '30min'
+
+ +
+
+TICK = 'tick'
+
+ +
+
+WEEK = 'week'
+
+ +
+
+YEAR = 'year'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.MARKET_ERROR[source]
+

Bases: object

+
+
+ACCOUNT_EXIST = 'Account has already exist'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.MARKET_EVENT[source]
+

Bases: object

+

交易前置事件

+
+
+QUERY_ACCOUNT = 'query_account'
+
+ +
+
+QUERY_ASSETS = 'query_assets'
+
+ +
+
+QUERY_CASH = 'query_cash'
+
+ +
+
+QUERY_DATA = 'query_data'
+
+ +
+
+QUERY_ORDER = 'query_order'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.MARKET_TYPE[source]
+

Bases: object

+

市场种类

+

日线 尾数01 +分钟线 尾数02 +tick 尾数03

+

市场: +股票 0 +指数/基金 1 +期货 2 +港股 3 +美股 4 +比特币/加密货币市场 5

+
+
+BOND_CN = 'bond_cn'
+
+ +
+
+CRYPTOCURRENCY = 'cryptocurrency'
+
+ +
+
+FUND_CN = 'fund_cn'
+
+ +
+
+FUTURE_CN = 'future_cn'
+
+ +
+
+INDEX_CN = 'index_cn'
+
+ +
+
+OPTION_CN = 'option_cn'
+
+ +
+
+STOCKOPTION_CN = 'stockoption_cn'
+
+ +
+
+STOCK_CN = 'stock_cn'
+
+ +
+
+STOCK_HK = 'stock_hk'
+
+ +
+
+STOCK_US = 'stock_us'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.ORDER_DIRECTION[source]
+

Bases: object

+

订单的买卖方向

+

BUY 股票 买入 +SELL 股票 卖出 +BUY_OPEN 期货 多开 +BUY_CLOSE 期货 空平(多头平旧仓) +SELL_OPEN 期货 空开 +SELL_CLOSE 期货 多平(空头平旧仓)

+
+
+BUY = 1
+
+ +
+
+BUY_CLOSE = 1
+
+ +
+
+BUY_OPEN = 1
+
+ +
+
+SELL = -1
+
+ +
+
+SELL_CLOSE = -1
+
+ +
+
+SELL_OPEN = -1
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.ORDER_EVENT[source]
+

Bases: object

+

订单事件

+

创建订单 create +交易 trade +撤单 cancel

+
+
+CANCEL = 'cancel'
+
+ +
+
+CREATE = 'create'
+
+ +
+
+TRADE = 'trade'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.ORDER_MODEL[source]
+

Bases: object

+

订单的成交模式

+

LIMIT 限价模式 +MARKET 市价单 # 目前市价单在回测中是bar的开盘价 /实盘里面是五档剩余最优成交价 +CLOSE 收盘单 # 及在bar的收盘时的价格 +NEXT_OPEN 下一个bar的开盘价成交 +STRICT 严格订单 不推荐/仅限回测/是在当前bar的最高价买入/当前bar的最低价卖出

+

@yutiansut/2017-12-18

+
+
+CLOSE = 'close'
+
+ +
+
+LIMIT = 'limit'
+
+ +
+
+MARKET = 'market'
+
+ +
+
+NEXT_OPEN = 'next_open'
+
+ +
+
+STRICT = 'strict'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.ORDER_STATUS[source]
+

Bases: object

+

订单状态

+

status1xx 订单待生成 +status3xx 初始化订单 临时扣除资产(可用现金/可卖股份) +status3xx 订单存活(等待交易) +status2xx 订单完全交易/未完全交易 +status4xx 主动撤单 +status500 订单死亡(每日结算) 恢复临时资产

+

200 委托成功,完全交易 +203 委托成功,未完全成功 +300 刚创建订单的时候 +400 已撤单 +500 服务器撤单/每日结算

+

订单生成(100) -- 进入待成交队列(300) -- 完全成交(200) -- 每日结算(500)-- 死亡 +订单生成(100) -- 进入待成交队列(300) -- 部分成交(203) -- 未成交(300) -- 每日结算(500) -- 死亡 +订单生成(100) -- 进入待成交队列(300) -- 主动撤单(400) -- 每日结算(500) -- 死亡

+
+
+CANCEL_ALL = 400
+
+ +
+
+NEW = 100
+
+ +
+
+QUEUED = 300
+
+ +
+
+SETTLED = 500
+
+ +
+
+SUCCESS_ALL = 200
+
+ +
+
+SUCCESS_PART = 203
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.OUTPUT_FORMAT[source]
+

Bases: object

+

输出格式

+
+
+DATAFRAME = 'dataframe'
+
+ +
+
+DATASTRUCT = 'datastruct'
+
+ +
+
+JSON = 'json'
+
+ +
+
+LIST = 'list'
+
+ +
+
+NDARRAY = 'ndarray'
+
+ +
+
+SERIES = 'series'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.RUNNING_ENVIRONMENT[source]
+

Bases: object

+

执行环境

+

回测 +模拟 +实盘 +随机(按算法/分布随机生成行情)/仅用于训练测试

+
+
+BACKETEST = 'backtest'
+
+ +
+
+RANODM = 'random'
+
+ +
+
+REAL = 'real'
+
+ +
+
+SIMULATION = 'simulation'
+
+ +
+ +
+
+class QUANTAXIS.QAUtil.QAParameter.TRADE_STATUS[source]
+

Bases: object

+

交易状态返回值

+

涨跌停限制: 202 +成功交易 : 200 +当天无交易数据: 500 +订单失败(比如买卖价格超过涨跌停价格范围,交易量过大等等):400

+
+
+FAILED = 400
+
+ +
+
+NO_MARKET_DATA = 500
+
+ +
+
+PRICE_LIMIT = 202
+
+ +
+
+SUCCESS = 200
+
+ +
+ +
+
+

QUANTAXIS.QAUtil.QAPlot module

+
+
+QUANTAXIS.QAUtil.QAPlot.QA_plot_save_html(pic_handle, path, if_open_web)[source]
+
+ +
+
+QUANTAXIS.QAUtil.QAPlot.plot_datastruct(_quotation_base, code=None)[source]
+
+ +
+
+

QUANTAXIS.QAUtil.QARandom module

+
+
+QUANTAXIS.QAUtil.QARandom.QA_util_random_with_topic(topic='Acc', lens=8)[source]
+

生成account随机值

+

Acc+4数字id+4位大小写随机

+
+ +
+
+

QUANTAXIS.QAUtil.QASetting module

+
+
+class QUANTAXIS.QAUtil.QASetting.QA_Setting(ip='127.0.0.1', port=27017)[source]
+

Bases: object

+
+
+change(ip, port)[source]
+
+ +
+
+client
+
+ +
+
+login(user_name, password)[source]
+
+ +
+ +
+
+QUANTAXIS.QAUtil.QASetting.future_ip_list = [{'ip': '112.74.214.43', 'port': 7727}, {'ip': '59.175.238.38', 'port': 7727}, {'ip': '124.74.236.94', 'port': 7721}, {'ip': '218.80.248.229', 'port': 7721}, {'ip': '124.74.236.94', 'port': 7721}, {'ip': '58.246.109.27', 'port': 7721}]
+

['121.14.110.210', '119.147.212.76', '113.105.73.86', '119.147.171.211', '119.147.164.57', '119.147.164.58', '61.49.50.180', '61.49.50.181', +'61.135.142.85', '61.135.149.181', '114.80.80.210', '222.73.49.15', '221.194.181.176']

+
+ +
+
+

QUANTAXIS.QAUtil.QASql module

+
+
+QUANTAXIS.QAUtil.QASql.QA_util_sql_async_mongo_setting(ip='127.0.0.1', port=27017)[source]
+
+ +
+
+QUANTAXIS.QAUtil.QASql.QA_util_sql_mongo_setting(ip='127.0.0.1', port=27017)[source]
+
+ +
+
+

QUANTAXIS.QAUtil.QAText module

+

这里主要是一些关于文本的代码

+

文本分词 +模糊查询 +正则匹配

+
+
+QUANTAXIS.QAUtil.QAText.split_word(input_text, cutall=False)[source]
+

使用jieba分词 将输入的语句分词

+
+ +
+
+

QUANTAXIS.QAUtil.QATransform module

+
+
+QUANTAXIS.QAUtil.QATransform.QA_util_to_json_from_list(data)[source]
+
+ +
+
+QUANTAXIS.QAUtil.QATransform.QA_util_to_json_from_numpy(data)[source]
+
+ +
+
+QUANTAXIS.QAUtil.QATransform.QA_util_to_json_from_pandas(data)[source]
+

需要对于datetime 和date 进行转换, 以免直接被变成了时间戳

+
+ +
+
+QUANTAXIS.QAUtil.QATransform.QA_util_to_list_from_numpy(data)[source]
+
+ +
+
+QUANTAXIS.QAUtil.QATransform.QA_util_to_list_from_pandas(data)[source]
+
+ +
+
+QUANTAXIS.QAUtil.QATransform.QA_util_to_pandas_from_json(data)[source]
+
+ +
+
+QUANTAXIS.QAUtil.QATransform.QA_util_to_pandas_from_list(data)[source]
+
+ +
+
+

QUANTAXIS.QAUtil.QAWeb module

+
+
+class QUANTAXIS.QAUtil.QAWeb.QA_Util_web_pool[source]
+

Bases: object

+
+
+dynamic_optimics()[source]
+
+ +
+
+hot_update()[source]
+
+ +
+
+task_queue()[source]
+
+ +
+ +
+
+QUANTAXIS.QAUtil.QAWeb.QA_util_web_ping(url)[source]
+
+ +
+
+

QUANTAXIS.QAUtil.host module

+
+
+

Module contents

+

" +yutiansut +util tool

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.QAWeb.html b/_build/html/source/QUANTAXIS.QAWeb.html new file mode 100644 index 000000000..8b716a764 --- /dev/null +++ b/_build/html/source/QUANTAXIS.QAWeb.html @@ -0,0 +1,303 @@ + + + + + + + + QUANTAXIS.QAWeb package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS.QAWeb package

+
+

Submodules

+
+
+

QUANTAXIS.QAWeb.QA_Web module

+
+
+QUANTAXIS.QAWeb.QA_Web.hello()[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.main()[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.query_backtest()[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.query_backtest_by_()[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.query_backtest_history()[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.query_day_bfq(code)[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.query_day_hfq(code)[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.query_day_qfq(code)[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.query_k(code)[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.query_min_bfq(code)[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.query_min_qfq(code)[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.realtime()[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.run_backtest()[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.signin()[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.signup()[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.status()[source]
+
+ +
+
+QUANTAXIS.QAWeb.QA_Web.test_message(message)[source]
+
+ +
+
+

QUANTAXIS.QAWeb.chain module

+
+
+class QUANTAXIS.QAWeb.chain.Blockchain[source]
+

Bases: object

+
+
+static hash() → str[source]
+

生成块的 SHA-256 hash值 +:param block: Block

+
+ +
+
+last_block
+
+ +
+
+new_block(proof: int, previous_hash: Union[str, NoneType]) → Dict[str, Any][source]
+

生成新块 +:param proof: The proof given by the Proof of Work algorithm +:param previous_hash: Hash of previous Block +:return: New Block

+
+ +
+
+new_transaction(sender: str, recipient: str, amount: int) → int[source]
+

生成新交易信息,信息将加入到下一个待挖的区块中 +:param sender: Address of the Sender +:param recipient: Address of the Recipient +:param amount: Amount +:return: The index of the Block that will hold this transaction

+
+ +
+
+proof_of_work(last_proof: int) → int[source]
+
+
简单的工作量证明:
+
    +
  • 查找一个 p' 使得 hash(pp') 以4个0开头
  • +
  • p 是上一个块的证明, p' 是当前的证明
  • +
+
+
+
+ +
+
+register_node(address: str) → None[source]
+

Add a new node to the list of nodes +:param address: Address of node. Eg. 'http://192.168.0.5:5000'

+
+ +
+
+resolve_conflicts() → bool[source]
+

共识算法解决冲突 +使用网络中最长的链. +:return: 如果链被取代返回 True, 否则为False

+
+ +
+
+valid_chain(chain: List[Dict[str, Any]]) → bool[source]
+

Determine if a given blockchain is valid +:param chain: A blockchain +:return: True if valid, False if not

+
+ +
+
+static valid_proof(proof: int) → bool[source]
+

验证证明: 是否hash(last_proof, proof)以4个0开头 +:param last_proof: Previous Proof +:param proof: Current Proof +:return: True if correct, False if not.

+
+ +
+ +
+
+QUANTAXIS.QAWeb.chain.consensus()[source]
+
+ +
+
+QUANTAXIS.QAWeb.chain.full_chain()[source]
+
+ +
+
+QUANTAXIS.QAWeb.chain.mine()[source]
+
+ +
+
+QUANTAXIS.QAWeb.chain.new_transaction()[source]
+
+ +
+
+QUANTAXIS.QAWeb.chain.register_nodes()[source]
+
+ +
+
+

Module contents

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/QUANTAXIS.html b/_build/html/source/QUANTAXIS.html new file mode 100644 index 000000000..e4ce9248e --- /dev/null +++ b/_build/html/source/QUANTAXIS.html @@ -0,0 +1,272 @@ + + + + + + + + QUANTAXIS package — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS package

+
+

Subpackages

+
+ +
+
+
+

Module contents

+

QUANTAXIS

+

Quantitative Financial Strategy Framework

+

by yutiansut

+

2017/4/8

+
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/_build/html/source/modules.html b/_build/html/source/modules.html new file mode 100644 index 000000000..be4f6a3b1 --- /dev/null +++ b/_build/html/source/modules.html @@ -0,0 +1,250 @@ + + + + + + + + QUANTAXIS — QUANTAXIS 1.0 documentation + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+

QUANTAXIS

+
+ +
+
+ + +
+
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/conf.py b/conf.py new file mode 100644 index 000000000..0a03ec1f4 --- /dev/null +++ b/conf.py @@ -0,0 +1,196 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/stable/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- +sys.path.insert(0, os.path.abspath('QUANTAXIS')) +project = 'QUANTAXIS' +copyright = '2018, yutiansut' +author = 'yutiansut' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '1.0' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.mathjax', + 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode', + 'sphinx.ext.githubpages', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = 'python' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'QUANTAXISdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'QUANTAXIS.tex', 'QUANTAXIS Documentation', + 'yutiansut', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'quantaxis', 'QUANTAXIS Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'QUANTAXIS', 'QUANTAXIS Documentation', + author, 'QUANTAXIS', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project +epub_author = author +epub_publisher = author +epub_copyright = copyright + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True \ No newline at end of file diff --git a/index.rst b/index.rst new file mode 100644 index 000000000..d69aefa6d --- /dev/null +++ b/index.rst @@ -0,0 +1,20 @@ +.. QUANTAXIS documentation master file, created by + sphinx-quickstart on Mon May 7 21:02:19 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to QUANTAXIS's documentation! +===================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/make.bat b/make.bat new file mode 100644 index 000000000..c6c2fe859 --- /dev/null +++ b/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=QUANTAXIS + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/source/QUANTAXIS.QAARP.rst b/source/QUANTAXIS.QAARP.rst new file mode 100644 index 000000000..58da99219 --- /dev/null +++ b/source/QUANTAXIS.QAARP.rst @@ -0,0 +1,54 @@ +QUANTAXIS.QAARP package +======================= + +Submodules +---------- + +QUANTAXIS.QAARP.QAAccount module +-------------------------------- + +.. automodule:: QUANTAXIS.QAARP.QAAccount + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAARP.QAPortfolio module +---------------------------------- + +.. automodule:: QUANTAXIS.QAARP.QAPortfolio + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAARP.QARisk module +----------------------------- + +.. automodule:: QUANTAXIS.QAARP.QARisk + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAARP.QAStrategy module +--------------------------------- + +.. automodule:: QUANTAXIS.QAARP.QAStrategy + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAARP.QAUser module +----------------------------- + +.. automodule:: QUANTAXIS.QAARP.QAUser + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAARP + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QAAnalysis.rst b/source/QUANTAXIS.QAAnalysis.rst new file mode 100644 index 000000000..eede2424f --- /dev/null +++ b/source/QUANTAXIS.QAAnalysis.rst @@ -0,0 +1,62 @@ +QUANTAXIS.QAAnalysis package +============================ + +Submodules +---------- + +QUANTAXIS.QAAnalysis.QAAnalysis\_block module +--------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_block + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAAnalysis.QAAnalysis\_dataframe module +------------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_dataframe + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAAnalysis.QAAnalysis\_machinelearning module +------------------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_machinelearning + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAAnalysis.QAAnalysis\_series module +---------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_series + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAAnalysis.QAAnalysis\_tick module +-------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_tick + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAAnalysis.QAAnalysis\_trade module +--------------------------------------------- + +.. automodule:: QUANTAXIS.QAAnalysis.QAAnalysis_trade + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAAnalysis + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QABacktest.rst b/source/QUANTAXIS.QABacktest.rst new file mode 100644 index 000000000..adcc84e69 --- /dev/null +++ b/source/QUANTAXIS.QABacktest.rst @@ -0,0 +1,46 @@ +QUANTAXIS.QABacktest package +============================ + +Submodules +---------- + +QUANTAXIS.QABacktest.QAAnalysis module +-------------------------------------- + +.. automodule:: QUANTAXIS.QABacktest.QAAnalysis + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QABacktest.QABacktest module +-------------------------------------- + +.. automodule:: QUANTAXIS.QABacktest.QABacktest + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QABacktest.QAResult module +------------------------------------ + +.. automodule:: QUANTAXIS.QABacktest.QAResult + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QABacktest.backtest\_setting module +--------------------------------------------- + +.. automodule:: QUANTAXIS.QABacktest.backtest_setting + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QABacktest + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QACmd.rst b/source/QUANTAXIS.QACmd.rst new file mode 100644 index 000000000..fc5e3a217 --- /dev/null +++ b/source/QUANTAXIS.QACmd.rst @@ -0,0 +1,22 @@ +QUANTAXIS.QACmd package +======================= + +Submodules +---------- + +QUANTAXIS.QACmd.backtest module +------------------------------- + +.. automodule:: QUANTAXIS.QACmd.backtest + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QACmd + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QAData.proto.rst b/source/QUANTAXIS.QAData.proto.rst new file mode 100644 index 000000000..4c0e1151b --- /dev/null +++ b/source/QUANTAXIS.QAData.proto.rst @@ -0,0 +1,38 @@ +QUANTAXIS.QAData.proto package +============================== + +Submodules +---------- + +QUANTAXIS.QAData.proto.order\_pb2 module +---------------------------------------- + +.. automodule:: QUANTAXIS.QAData.proto.order_pb2 + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.proto.stock\_day\_pb2 module +--------------------------------------------- + +.. automodule:: QUANTAXIS.QAData.proto.stock_day_pb2 + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.proto.stock\_min\_pb2 module +--------------------------------------------- + +.. automodule:: QUANTAXIS.QAData.proto.stock_min_pb2 + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAData.proto + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QAData.rst b/source/QUANTAXIS.QAData.rst new file mode 100644 index 000000000..7721ce6ba --- /dev/null +++ b/source/QUANTAXIS.QAData.rst @@ -0,0 +1,93 @@ +QUANTAXIS.QAData package +======================== + +Subpackages +----------- + +.. toctree:: + + QUANTAXIS.QAData.proto + +Submodules +---------- + +QUANTAXIS.QAData.QADataStruct module +------------------------------------ + +.. automodule:: QUANTAXIS.QAData.QADataStruct + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.base\_datastruct module +---------------------------------------- + +.. automodule:: QUANTAXIS.QAData.base_datastruct + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.data\_fq module +-------------------------------- + +.. automodule:: QUANTAXIS.QAData.data_fq + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.data\_resample module +-------------------------------------- + +.. automodule:: QUANTAXIS.QAData.data_resample + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.dsmethods module +--------------------------------- + +.. automodule:: QUANTAXIS.QAData.dsmethods + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.fundamental module +----------------------------------- + +.. automodule:: QUANTAXIS.QAData.fundamental + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.realtimedata module +------------------------------------ + +.. automodule:: QUANTAXIS.QAData.realtimedata + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.schema module +------------------------------ + +.. automodule:: QUANTAXIS.QAData.schema + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAData.serialize module +--------------------------------- + +.. automodule:: QUANTAXIS.QAData.serialize + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAData + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QAEngine.rst b/source/QUANTAXIS.QAEngine.rst new file mode 100644 index 000000000..7f85c330b --- /dev/null +++ b/source/QUANTAXIS.QAEngine.rst @@ -0,0 +1,38 @@ +QUANTAXIS.QAEngine package +========================== + +Submodules +---------- + +QUANTAXIS.QAEngine.QAEvent module +--------------------------------- + +.. automodule:: QUANTAXIS.QAEngine.QAEvent + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAEngine.QATask module +-------------------------------- + +.. automodule:: QUANTAXIS.QAEngine.QATask + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAEngine.QAThreadEngine module +---------------------------------------- + +.. automodule:: QUANTAXIS.QAEngine.QAThreadEngine + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAEngine + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QAFetch.rst b/source/QUANTAXIS.QAFetch.rst new file mode 100644 index 000000000..7c41e5293 --- /dev/null +++ b/source/QUANTAXIS.QAFetch.rst @@ -0,0 +1,126 @@ +QUANTAXIS.QAFetch package +========================= + +Submodules +---------- + +QUANTAXIS.QAFetch.Fetcher module +-------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.Fetcher + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QACrawler module +---------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QACrawler + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAEastMoney module +------------------------------------ + +.. automodule:: QUANTAXIS.QAFetch.QAEastMoney + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAQuery module +-------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QAQuery + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAQuery\_Advance module +----------------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QAQuery_Advance + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QATdx module +------------------------------ + +.. automodule:: QUANTAXIS.QAFetch.QATdx + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QATdx\_adv module +----------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QATdx_adv + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAThs module +------------------------------ + +.. automodule:: QUANTAXIS.QAFetch.QAThs + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QATushare module +---------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QATushare + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAWind module +------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.QAWind + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.QAfinancial module +------------------------------------ + +.. automodule:: QUANTAXIS.QAFetch.QAfinancial + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.base module +----------------------------- + +.. automodule:: QUANTAXIS.QAFetch.base + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.data\_list module +----------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.data_list + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAFetch.realtime module +--------------------------------- + +.. automodule:: QUANTAXIS.QAFetch.realtime + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAFetch + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QAIndicator.rst b/source/QUANTAXIS.QAIndicator.rst new file mode 100644 index 000000000..afb3be113 --- /dev/null +++ b/source/QUANTAXIS.QAIndicator.rst @@ -0,0 +1,30 @@ +QUANTAXIS.QAIndicator package +============================= + +Submodules +---------- + +QUANTAXIS.QAIndicator.base module +--------------------------------- + +.. automodule:: QUANTAXIS.QAIndicator.base + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAIndicator.indicators module +--------------------------------------- + +.. automodule:: QUANTAXIS.QAIndicator.indicators + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAIndicator + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QAMarket.rst b/source/QUANTAXIS.QAMarket.rst new file mode 100644 index 000000000..5878c0e06 --- /dev/null +++ b/source/QUANTAXIS.QAMarket.rst @@ -0,0 +1,126 @@ +QUANTAXIS.QAMarket package +========================== + +Submodules +---------- + +QUANTAXIS.QAMarket.Broker\_Calender module +------------------------------------------ + +.. automodule:: QUANTAXIS.QAMarket.Broker_Calender + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QABacktestBroker module +------------------------------------------ + +.. automodule:: QUANTAXIS.QAMarket.QABacktestBroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QABroker module +---------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QABroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QADealer module +---------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QADealer + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QAMarket module +---------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QAMarket + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QAOrder module +--------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QAOrder + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QAOrderHandler module +---------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QAOrderHandler + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QARandomBroker module +---------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QARandomBroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QARealBroker module +-------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QARealBroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QASimulatedBroker module +------------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QASimulatedBroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.QATrade module +--------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.QATrade + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.shipaneBroker module +--------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.shipaneBroker + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.shipaneclient module +--------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.shipaneclient + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAMarket.tdxRealBroker module +--------------------------------------- + +.. automodule:: QUANTAXIS.QAMarket.tdxRealBroker + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAMarket + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QASU.rst b/source/QUANTAXIS.QASU.rst new file mode 100644 index 000000000..5693f90fc --- /dev/null +++ b/source/QUANTAXIS.QASU.rst @@ -0,0 +1,78 @@ +QUANTAXIS.QASU package +====================== + +Submodules +---------- + +QUANTAXIS.QASU.main module +-------------------------- + +.. automodule:: QUANTAXIS.QASU.main + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_account module +----------------------------------- + +.. automodule:: QUANTAXIS.QASU.save_account + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_backtest module +------------------------------------ + +.. automodule:: QUANTAXIS.QASU.save_backtest + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_local module +--------------------------------- + +.. automodule:: QUANTAXIS.QASU.save_local + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_tdx module +------------------------------- + +.. automodule:: QUANTAXIS.QASU.save_tdx + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_tdx\_file module +------------------------------------- + +.. automodule:: QUANTAXIS.QASU.save_tdx_file + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.save\_tushare module +----------------------------------- + +.. automodule:: QUANTAXIS.QASU.save_tushare + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QASU.user module +-------------------------- + +.. automodule:: QUANTAXIS.QASU.user + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QASU + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QAUtil.rst b/source/QUANTAXIS.QAUtil.rst new file mode 100644 index 000000000..0625c15d6 --- /dev/null +++ b/source/QUANTAXIS.QAUtil.rst @@ -0,0 +1,190 @@ +QUANTAXIS.QAUtil package +======================== + +Submodules +---------- + +QUANTAXIS.QAUtil.QAAuth module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QAAuth + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QABar module +----------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QABar + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QACfg module +----------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QACfg + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QACode module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QACode + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QACsv module +----------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QACsv + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QADate module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QADate + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QADate\_trade module +------------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QADate_trade + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QADict module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QADict + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAList module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QAList + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QALocalize module +---------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QALocalize + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QALogs module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QALogs + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAMail module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QAMail + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAMongo module +------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QAMongo + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAParameter module +----------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QAParameter + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAPlot module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QAPlot + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QARandom module +-------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QARandom + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QASetting module +--------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QASetting + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QASql module +----------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QASql + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAText module +------------------------------ + +.. automodule:: QUANTAXIS.QAUtil.QAText + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QATransform module +----------------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QATransform + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.QAWeb module +----------------------------- + +.. automodule:: QUANTAXIS.QAUtil.QAWeb + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAUtil.host module +---------------------------- + +.. automodule:: QUANTAXIS.QAUtil.host + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAUtil + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.QAWeb.rst b/source/QUANTAXIS.QAWeb.rst new file mode 100644 index 000000000..7af3d790f --- /dev/null +++ b/source/QUANTAXIS.QAWeb.rst @@ -0,0 +1,30 @@ +QUANTAXIS.QAWeb package +======================= + +Submodules +---------- + +QUANTAXIS.QAWeb.QA\_Web module +------------------------------ + +.. automodule:: QUANTAXIS.QAWeb.QA_Web + :members: + :undoc-members: + :show-inheritance: + +QUANTAXIS.QAWeb.chain module +---------------------------- + +.. automodule:: QUANTAXIS.QAWeb.chain + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: QUANTAXIS.QAWeb + :members: + :undoc-members: + :show-inheritance: diff --git a/source/QUANTAXIS.rst b/source/QUANTAXIS.rst new file mode 100644 index 000000000..e5a40b09e --- /dev/null +++ b/source/QUANTAXIS.rst @@ -0,0 +1,28 @@ +QUANTAXIS package +================= + +Subpackages +----------- + +.. toctree:: + + QUANTAXIS.QAARP + QUANTAXIS.QAAnalysis + QUANTAXIS.QABacktest + QUANTAXIS.QACmd + QUANTAXIS.QAData + QUANTAXIS.QAEngine + QUANTAXIS.QAFetch + QUANTAXIS.QAIndicator + QUANTAXIS.QAMarket + QUANTAXIS.QASU + QUANTAXIS.QAUtil + QUANTAXIS.QAWeb + +Module contents +--------------- + +.. automodule:: QUANTAXIS + :members: + :undoc-members: + :show-inheritance: diff --git a/source/modules.rst b/source/modules.rst new file mode 100644 index 000000000..b09928062 --- /dev/null +++ b/source/modules.rst @@ -0,0 +1,7 @@ +QUANTAXIS +========= + +.. toctree:: + :maxdepth: 4 + + QUANTAXIS