{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import datetime\n",
    "import json\n",
    "import time\n",
    "\n",
    "#  动量选股\n",
    "from jqdata import *\n",
    "\n",
    "import fun\n",
    "\n",
    "print(time.strftime(\"%Y-%m-%d %H:%M:%S\", time.localtime()))\n",
    "\n",
    "res_stocks = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 去除上市不满半年的股票\n",
    "all_stocks = get_all_securities()\n",
    "all_stocks = all_stocks[all_stocks['start_date'] < (datetime.date.today() - datetime.timedelta(days=180))]\n",
    "\n",
    "# 筛选市值大于 100 亿的\n",
    "df_val = get_fundamentals(query(valuation.code, valuation.market_cap).filter(valuation.market_cap >= 100).order_by(\n",
    "            # 按市值降序排列\n",
    "            valuation.market_cap.desc()\n",
    "        ), date=None)\n",
    "mc_stocks = list(df_val['code'])\n",
    "print('市值大于 50亿 股票数量：', len(mc_stocks))\n",
    "\n",
    "# 收入净利润增长的公司\n",
    "# df_ind = get_fundamentals(query(\n",
    "#     indicator.code, indicator.pubDate, indicator.statDate, indicator.eps, indicator.inc_revenue_year_on_year,\n",
    "#     indicator.inc_operation_profit_year_on_year, indicator.inc_net_profit_year_on_year)\n",
    "#                  .filter(indicator.inc_net_profit_year_on_year > 0)\n",
    "#                  .order_by(indicator.inc_net_profit_year_on_year.desc())\n",
    "#                  , date=None)\n",
    "# ind_stocks = list(df_ind['code'])\n",
    "# print('净利润增长的股票数量：', len(ind_stocks))\n",
    "\n",
    "df_stocks = set(mc_stocks) # & set(ind_stocks)\n",
    "\n",
    "run_codes = []\n",
    "for code in list(all_stocks.index):\n",
    "    if code in df_stocks:\n",
    "        run_codes.append(code)\n",
    "\n",
    "print('最终筛选运行股票数量：', len(run_codes))\n",
    "\n",
    "# 获取股票行情信息\n",
    "stock_bars = get_bars(run_codes, count=20, unit='1d',fields=['date', 'open','high','low','close'], include_now=True, end_dt=None, df=True)\n",
    "# 计算股票 20 日涨跌幅\n",
    "stock_20rate_rank = []\n",
    "for code in run_codes:\n",
    "    try:\n",
    "        bar = stock_bars.loc[(code, slice(None)),:]\n",
    "        if len(bar) == 20:\n",
    "            rate = (bar['close'].iloc[-1] - bar['close'].iloc[0]) / bar['close'].iloc[0]\n",
    "            stock_20rate_rank.append({'code': code, 'rate': rate})\n",
    "    except KeyError:\n",
    "        pass\n",
    "# 涨跌幅排序\n",
    "stock_20rate_rank.sort(key=lambda r:r['rate'], reverse=True)\n",
    "# 选取排名前 200 选手\n",
    "stocks = stock_20rate_rank[0:200]\n",
    "rank_stocks = list(map(lambda s:s['code'], stocks))\n",
    "# 筛选基金持股或北向持股的股票\n",
    "stocks_all = []\n",
    "for code in rank_stocks:\n",
    "    if fun.stock_jj_bx_share_ok(code):\n",
    "        stocks_all.append(code)\n",
    "\n",
    "print('基金筛选后剩余股票数量：', len(stocks_all))\n",
    "# 获取股票行情信息\n",
    "stocks_industry = get_industry(security=stocks_all)\n",
    "stocks_concept = get_concept(security=stocks_all, date=datetime.datetime.now())\n",
    "# 按照行业概念汇总股票列表\n",
    "concept_stocks = {}\n",
    "industry_stocks = {}\n",
    "for code in stocks_industry:\n",
    "    hy = stocks_industry[code]\n",
    "    if 'jq_l2' not in hy:\n",
    "        continue\n",
    "    hy_code = hy['jq_l2']['industry_code']\n",
    "    hy_name = hy['jq_l2']['industry_name']\n",
    "    if hy_code not in industry_stocks:\n",
    "        industry_stocks[hy_code] = {'hy_code': hy_code, 'hy_name': hy_name, 'cf_stocks': [code]}\n",
    "        industry_stocks[hy_code]['all_stocks'] = get_industry_stocks(hy_code)\n",
    "    else:\n",
    "        industry_stocks[hy_code]['cf_stocks'].append(code)\n",
    "# 计算行业动量分值\n",
    "for hy in industry_stocks:\n",
    "    # 成分股票数量 * ( 成分股票数量 / 行业股票数量 )\n",
    "    industry_stocks[hy]['score'] = len(industry_stocks[hy]['cf_stocks']) * (len(industry_stocks[hy]['cf_stocks']) / len(industry_stocks[hy]['all_stocks']))\n",
    "\n",
    "# 动量值排序\n",
    "industry_ranks = sorted(industry_stocks.items(), key=lambda d:d[1]['score'], reverse=True)\n",
    "\n",
    "for code in stocks_concept:\n",
    "    co = stocks_concept[code]\n",
    "    for _info in co['jq_concept']:\n",
    "        co_code = _info['concept_code']\n",
    "        co_name = _info['concept_name']\n",
    "        if co_name in ['深股通', '转融券标的', '融资融券', '沪股通', 'MSCI', '国家大基金持股']:\n",
    "            continue\n",
    "        if co_code not in concept_stocks:\n",
    "            concept_stocks[co_code] = {'co_code': co_code, 'co_name': co_name, 'cf_stocks': [code]}\n",
    "            concept_stocks[co_code]['all_stocks'] = get_concept_stocks(co_code)\n",
    "        else:\n",
    "            concept_stocks[co_code]['cf_stocks'].append(code)\n",
    "\n",
    "# 计算概念动量分值\n",
    "for co in concept_stocks:\n",
    "    # 成分股票数量 * ( 成分股票数量 / 行业股票数量 )\n",
    "    concept_stocks[co]['score'] = len(concept_stocks[co]['cf_stocks']) * (len(concept_stocks[co]['cf_stocks']) / len(concept_stocks[co]['all_stocks']))\n",
    "\n",
    "# 动量值排序\n",
    "concept_ranks = sorted(concept_stocks.items(), key=lambda d:d[1]['score'], reverse=True)\n",
    "\n",
    "# 获取成分股票名称\n",
    "for hy in industry_ranks:\n",
    "    stock_names = []\n",
    "    for _c in hy[1]['cf_stocks']:\n",
    "        stock = get_security_info(_c)\n",
    "        stock_names.append(stock.display_name)\n",
    "    hy[1]['cf_names'] = stock_names\n",
    "\n",
    "# 获取概念股票名称\n",
    "for co in concept_ranks:\n",
    "    stock_names = []\n",
    "    for _c in co[1]['cf_stocks']:\n",
    "        stock = get_security_info(_c)\n",
    "        stock_names.append(stock.display_name)\n",
    "    co[1]['cf_names'] = stock_names"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 输出动量排行榜单\n",
    "print(\"行业名称/分数/成分/总数\")\n",
    "for hy in industry_ranks:\n",
    "    print(\"%s/%s/%s/%s\" % (hy[1]['hy_name'], hy[1]['score'], len(hy[1]['cf_stocks']), len(hy[1]['all_stocks'])))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "print(json.dumps(industry_ranks, ensure_ascii=False))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 输出动量排行榜单\n",
    "print(\"概念名称/分数/成分/总数\")\n",
    "for co in concept_ranks:\n",
    "    print(\"%s/%s/%s/%s\" % (co[1]['co_name'], co[1]['score'], len(co[1]['cf_stocks']), len(co[1]['all_stocks'])))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "print(json.dumps(concept_ranks, ensure_ascii=False))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "print('行业热门股票')\n",
    "# 获取分值 大于 5 的股票列表\n",
    "high_stocks = []\n",
    "rank_stocks = []\n",
    "\n",
    "for hy in industry_ranks[0:10]:\n",
    "    high_stocks += hy[1]['cf_stocks'][0:3]\n",
    "    rank_stocks += hy[1]['cf_stocks']\n",
    "print('最热股票数量：', len(high_stocks))\n",
    "print('排行股票数量：', len(rank_stocks))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "print('概念热门股票')\n",
    "# 获取分值 大于 5 的股票列表\n",
    "co_high_stocks = []\n",
    "co_rank_stocks = []\n",
    "for co in concept_ranks[0:10]:\n",
    "    co_high_stocks += co[1]['cf_stocks'][0:3]\n",
    "    co_rank_stocks += co[1]['cf_stocks']\n",
    "print('最热股票数量：', len(co_high_stocks))\n",
    "print('排行股票数量：', len(co_rank_stocks))\n",
    "\n",
    "\n",
    "print(' * ' * 20)\n",
    "double_high_stocks = set(high_stocks) & set(co_high_stocks)\n",
    "double_rank_stocks = set(rank_stocks) & set(co_rank_stocks)\n",
    "print('热门重合股票：', fun.stock_names(double_high_stocks))\n",
    "print('排行重合股票：', fun.stock_names(double_rank_stocks))\n",
    "print(' * ' * 20)\n",
    "\n",
    "high_stocks += co_high_stocks\n",
    "rank_stocks += co_rank_stocks\n",
    "high_stocks = list(set(high_stocks))\n",
    "rank_stocks = list(set(rank_stocks))\n",
    "print('最热股票数量：', len(high_stocks))\n",
    "print('排行股票数量：', len(rank_stocks))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%print('概念热门股票')\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "# 输出符合条件的股票列表\n",
    "_run_codes = []\n",
    "for code in run_codes:\n",
    "    _run_codes.append(fun.reformat_code(code))\n",
    "print(json.dumps(_run_codes, ensure_ascii=False))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "${KERNEL_SPEC_DISPLAY_NAME}",
   "language": "${KERNEL_SPEC_LANGUAGE}",
   "name": "${KERNEL_SPEC_NAME}"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}