# xueqiou_trader **Repository Path**: li-xingguo11111/xueqiou_trader ## Basic Information - **Project Name**: xueqiou_trader - **Description**: 雪球跟单交易系统 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 5 - **Forks**: 10 - **Created**: 2024-11-22 - **Last Updated**: 2025-08-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # xueqiou_trader #### 介绍 雪球跟单交易系统是一种基于雪球组合调仓操作的自动交易工具,旨在帮助用户实现与雪球组合同步的持仓和交易操作。下面将具体介绍雪球跟单交易系统: 软件概述:雪球跟单交易系统是一个专为电脑端设计的程序,它通过模拟键盘鼠标控制来操作同花顺客户端进行交易。该系统不具备独立的交易功能,而是依托于同花顺交易软件,通过键盘和鼠标的模拟操作来执行交易指令。 使用方式:在使用雪球跟单交易系统之前,用户需要先登录雪球账号,并关注想要跟单的组合。同时,用户还需要获取雪球用户的ID和Cookies,以及设置相关的交易参数,如默认买入价格、卖出价格等。 功能特点: 雪球跟单交易系统支持多种交易策略,包括按比例跟单、固定资金跟单等,用户可以根据自己的需求选择合适的策略。 该系统能够实时跟踪雪球组合的调仓信息,并根据用户设定的交易参数自动下单,实现与雪球组合的同步操作。 为了提高下单速度,雪球跟单交易系统内置了上千个帐号的Cookie,并不断更新去失效,从而解决了取数据延时的问题。 应用场景: 适用于希望跟随雪球组合进行投资的用户,特别是那些缺乏时间或专业知识进行独立投资的用户。 对于希望实现自动化交易、减少人为干预的用户来说,雪球跟单交易系统也是一个不错的选择。 总的来说,雪球跟单交易系统是一个功能强大、操作简便的自动交易工具,它能够帮助用户实现与雪球组合的同步操作,提高投资效率和收益。然而,需要注意的是,任何投资都存在风险,用户在使用该系统时应谨慎评估自己的风险承受能力和投资目标。 #### 软件架构 软件架构说明 #### 安装教程 下载内容就可以找作者获取 如果感觉设置太麻烦可以找我直接获取文件,直接联系我 xtquant文件太大上传不了,可以加我微信直接获取qmt_trader 微信 下载链接https://mp.weixin.qq.com/s/_AZh7PNclMgW4iHXa6uHIQ ![输入图片说明](wxd907020ae283acfb8ea9dc6a3ce2806.png) 公众号 https://mp.weixin.qq.com/s/_SYpBLNr4dtZtvj8ydtBrw ![输入图片说明](gzh0afc7359810df252a349fa707fede19.png) 知识星球,更多的内容在知识星球,链接 https://t.zsxq.com/19VzjjXNi ![输入图片说明](zsxqaf9edcf23b037f07f7f372641c34e21.png) #### 使用说明 ### 1安装qmt,同花顺也可以 ![输入图片说明](1image.png) ### 2登录qmt选择极简模式,独立交易也可以 ![输入图片说明](2image.png) 登录的界面 ![输入图片说明](4image.png) ### 3安装第三方库 点击文件夹下面的安装第三方库bat自动安装 ![输入图片说明](5image.png) 安装的结果 ![输入图片说明](6image.png) ### 4设置qmt路径账户 1设置qmt路径 ![输入图片说明](7image.png) 点击qmt的属性获取路径 ![输入图片说明](8image.png) 路径的写法D:/国金QMT交易端模拟/userdata_mini 2输入资金登录的账户 ![输入图片说明](9image.png) ### 5获取雪球的cookie,大概一个月更新一次 1登录雪球 ![输入图片说明](10image.png) 2随便搜索一个标的比如600031 ![输入图片说明](11image.png) 安F12打开开发者模式 ![输入图片说明](12image.png) 点击日线行情,选择kline开头的文件 ![输入图片说明](13image.png) 点击标头 ![输入图片说明](14image.png) 选择cookie,复制 ![输入图片说明](44444image.png) 复制cookie ``` cookiesu=241715400714727; device_id=a3ef10a376ef5247ffa076b3f60cda63; s=cb127hrtpz; bid=f1b5e01be977a7023f9ec859cdf24ad4_lw1xly5z; remember=1; xq_is_login=1; u=1342909666; xq_a_token=4cb9ea35172c969e53e16becd84783d07dd569ac; xqat=4cb9ea35172c969e53e16becd84783d07dd569ac; xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOjEzNDI5MDk2NjYsImlzcyI6InVjIiwiZXhwIjoxNzMzODgwMjIxLCJjdG0iOjE3MzEyODgyMjEyMTQsImNpZCI6ImQ5ZDBuNEFadXAifQ.jwZZVBSE-vMNgFLghZGUzfj6GMlW1V9lRak2yRNQB3Bx5Kz4Ecx2JXgUbLO7PettSlnmeVku-SCgDoggd8tXXUuNhNgIssTY2X_Ri7ubXOSEiKbyzpIzvJ_iB3KbY42Ygbin_m_yAdYKDzEUAZW5G7B9X2zvX_m7WQauzg_MhxIPkiHvgJrb__dNBifryqZ-FfjAn4BALsAkji-nOGgc1U3pCKLj1b9AuTBr1pkm88T4AMkz3sW7pGFvHoAu-MN4ZJ6TBefpj1ebtRH_z96yPt7WbnDCjnmUFfvOLnp-hBDeM_5MQgk0aHpzKRCNSoWDpKPXkajAlcLENN7eOundbA; xq_r_token=c05530c2c0380c37709e0b3b06662477bfc23f9c; Hm_lvt_1db88642e346389874251b5a1eded6e3=1731288223,1731840407,1732024990,1732255359; HMACCOUNT=1E48DC618B10065B; is_overseas=0; Hm_lpvt_1db88642e346389874251b5a1eded6e3=1732255462; ssxmod_itna=Yq0x9D2DnQq4uDRxBcDB4DKM7+DylnDWwAb4KhHyw75DsY6DSxGKidDqxBnm64xI37KY4qoHPsnrnqqUtADIA4UlluPKj1IDB3DEx06iTWQxiiSDCeDIDWeDiDG4GmDqGtDpxG=DjlUzzSP5Dbxi3XxiaDGeDeZF8DY5DhxDCnBPDwx0CRhxDBhrA7AikmCYwzxoz78yqQ+D4XxG1840H+WdKXrE6B+hsQS3jPSb8DlI2DCIzBZ5778hCDUHhaecDpPWxTY4QNGDxrADK=aFTinnDKBxPTODrY70ik2x4TGxDihDK9HK44D=; ssxmod_itna2=Yq0x9D2DnQq4uDRxBcDB4DKM7+DylnDWwAb4KhHywYik6=7DlOeo4j+hv2=4I2NOD8ErXkbm6A5Iw3m=BrXANime2=455Yuq9wagEikRxgt/G9=2hm2CZFIOEtCDK2prWuu0iyeF8Qhj2NYFkNhzGEVIf3hS4rCz0Gh+0NKt8bhiB3=wCd+eTuLIwYzClAq5B2ciqb4O+W5z=iC3ThZKGveNTKPURD2Wie8euqC7Gd1dw=qR49hrAbe5P=4WjULWD=eWcNfnP8A0StNt0ohQgI3oamRmZhuaiQemkIVSR5zP4AkFUr6Xxj8p47+D5+4fej8ed4A/KG7+WLKDtRH+KbnShvUBa34lATKN+Z+4ZBPT0BCUqj94zW9TWy77bH7qT+WeUB=+ngR+C8eeFbGW+C/WF7ciAA8Y0=cnbRWWiefBwsjaNkYEewxH3TC0m3ubaibXRuFOWGcQ+iOQYZiM7RqNWEQYi7gPoZ0l0G5jEIKnkobsY4ih5hFTw+0wmObcWFiyrK9THlCWmKHSs3EsmoCjj/BmQkWHu9FlEQvrxlRqiqqsTbCM7S8r1fQywEAKHjeXS3w8ws+7UVMCBW0Ixv+44gZY6TUwq48xDKq3YOHdDqnjtZun9m3ZGGTvI9QsP7O6T=s5nCmDGXQrGDD7=DYKKeD= ``` 复制到程序里面的雪球设置的cookie ![输入图片说明](16image.png) ### 6选择雪球组合支持多组合,多组合用逗号隔开就可以 复制组合id ![输入图片说明](17image.png) 复制到程序里面 ![输入图片说明](18image.png) 其他的参数随便写 ![输入图片说明](19image.png) ### 7运行实盘交易 1点击雪球跟单.py ![输入图片说明](20image.png) 运行的效果 ![输入图片说明](21image.png) ``` 账号类型 资金账户 可用金额 冻结金额 持仓市值 总资产 0 2 55001947 19963916.27 0.0 12488.2 19976394.29 不开同步持股 策略12 2024-11-22今天没有交易数据 剔除黑名单______________*************************_______________________ 没有交易股票池************* 没有需要下单的数据************************** 持仓数量: 15 账号类型 资金账号 证券代码 股票余额 可用余额 成本价 参考成本价 市值 0 2 55001947 113598 10 10 126.090 126.090 1248.00 1 2 55001947 113667 10 10 124.441 124.441 1234.39 2 2 55001947 113674 10 10 124.343 124.343 1233.88 3 2 55001947 113688 10 10 129.403 129.403 1280.57 4 2 55001947 118048 10 10 125.346 125.346 1239.49 5 2 55001947 600228 0 0 NaN NaN 0.00 6 2 55001947 888880 0 0 NaN NaN 0.00 7 2 55001947 000925 0 0 NaN NaN 0.00 8 2 55001947 123035 10 10 129.782 129.782 1286.40 9 2 55001947 123100 10 10 120.099 120.099 1192.32 10 2 55001947 127072 10 10 124.001 124.001 1230.29 11 2 55001947 128070 10 10 125.647 125.647 1258.01 12 2 55001947 128083 10 10 129.416 129.416 1283.84 13 2 55001947 300250 0 0 NaN NaN 0.00 14 2 55001947 301083 0 0 NaN NaN 0.00 剔除黑名单********** 账号类型 资金账号 证券代码 股票余额 可用余额 成本价 参考成本价 市值 黑名单 0 2 55001947 113598 10 10 126.090 126.090 1248.00 否 1 2 55001947 113667 10 10 124.441 124.441 1234.39 否 2 2 55001947 113674 10 10 124.343 124.343 1233.88 否 3 2 55001947 113688 10 10 129.403 129.403 1280.57 否 4 2 55001947 118048 10 10 125.346 125.346 1239.49 否 8 2 55001947 123035 10 10 129.782 129.782 1286.40 否 9 2 55001947 123100 10 10 120.099 120.099 1192.32 否 10 2 55001947 127072 10 10 124.001 124.001 1230.29 否 11 2 55001947 128070 10 10 125.647 125.647 1258.01 否 12 2 55001947 128083 10 10 129.416 129.416 1283.84 否 账号类型 资金账户 可用金额 冻结金额 持仓市值 总资产 0 2 55001947 19963916.27 0.0 12487.19 19976393.03 ``` ### 8实盘调仓组合 点击我们的组合,点击调仓 ![输入图片说明](22image.png) 调整组合 ![输入图片说明](23image.png) 确认调整组合 ![输入图片说明](24image.png) 下单的结果 ``` 不开同步持股 策略12 2024-11-22今天有交易数据 id rebalancing_id stock_id stock_name stock_symbol ... proactive created_at updated_at target_volume prev_target_volume 0 242034812 182292889 1000023 中信证券 SH600030 ... True 2024-11-22 06:16:27.112 2024-11-22 0.002819 0.004535 1 242034813 182292889 1001086 平安银行 SZ000001 ... True 2024-11-22 06:16:27.112 2024-11-22 0.004374 0.014101 2 242034814 182292889 1061144 沪深300成长ETF SH562310 ... True 2024-11-22 06:16:27.112 2024-11-22 0.191942 0.302503 3 242034815 182292889 1000027 招商银行 SH600036 ... True 2024-11-22 06:16:27.112 2024-11-22 0.008476 0.003904 [4 rows x 21 columns] 剔除黑名单______________*************************_______________________ id rebalancing_id stock_id stock_name stock_symbol volume price ... updated_at target_volume prev_target_volume 证券代码 adjust 黑名单 品种 0 242034812 182292889 1000023 中信证券 SH600030 0.002819 30.98 ... 2024-11-22 0.002819 0.004535 600030 -4.1 否 stock 1 242034813 182292889 1001086 平安银行 SZ000001 0.004374 11.41 ... 2024-11-22 0.004374 0.014101 000001 -9 否 stock 2 242034814 182292889 1061144 沪深300成长ETF SH562310 0.191942 0.78 ... 2024-11-22 0.191942 0.302503 562310 -7 否 fund 3 242034815 182292889 1000027 招商银行 SH600036 0.008476 36.8 ... 2024-11-22 0.008476 0.003904 600036 13.37 否 stock [4 rows x 25 columns] 没有下单的交易***************************** id rebalancing_id stock_id stock_name stock_symbol volume price ... target_volume prev_target_volume 证券代码 adjust 黑名单 品种 交易情 况 0 242034812 182292889 1000023 中信证券 SH600030 0.002819 30.98 ... 0.002819 0.004535 600030 -4.1 否 stock 没有下单 1 242034813 182292889 1001086 平安银行 SZ000001 0.004374 11.41 ... 0.004374 0.014101 000001 -9.0 否 stock 没有下单 2 242034814 182292889 1061144 沪深300成长ETF SH562310 0.191942 0.78 ... 0.191942 0.302503 562310 -7.0 否 fund 没有下单 [3 rows x 26 columns] ``` 下单的结果 ![输入图片说明](24image.png) ### 三参数设置 1分析配置参数 ``` { "软件授权码":"0xc369da8e2ecf9855c95753ae45545744965b3c28bec30e2b2f17d790df09112653285972d7c6481a13f4f48a301db283c8bbbb59dfdc851ea002a855ffac45adb88e8b314b2db6f25ae5bc690ae4c30a8d96277daec437d92c2096a469b7fcb028ac7a4ee04f3b463a8785ea96e7586dbabd9b75c0fc02ba0a6ba80c655e111f8733", "交易系统设置":"*********************************************", "交易系统选择":"ths/qmt", "交易系统":"qmt", "交易品种":"全部", "交易品种说明":["stock","fund","bond","全部"], "同花顺下单路径":"C:/同花顺软件/同花顺/xiadan.exe", "识别软件安装位置":"C:/Program Files/Tesseract-OCR/tesseract", "qmt路径":"D:/国金QMT交易端模拟/userdata_mini", "qmt账户":"55001947", "qmt账户类型":"STOCK", "证券公司交易设置":"兼容老牌证券公司可转债1手为单位", "是否开启特殊证券公司交易设置":"否", "发送方式选择":"钉钉/qq", "发送方式":"qq", "发送qq":"1752515969@qq.com", "qq掩码":"jgyhavzupyglecaf", "接收qq":"71080306@qq.com", "钉钉账户token":["ab5d0a609429a786b9a849cefd5db60c0ef2f17f2ec877a60bea5f8480d86b1b"], "交易时间段":4, "交易开始时间":9, "交易结束时间":24, "是否参加集合竞价":"否", "开始交易分钟":0, "黑名单":[] } ``` 2跟单设置 ``` { "雪球跟单":"跟单原理", "原理":"比重变大默认买入,变小默认卖出,持股不追加,支持多策略跟单", "雪球cookie":"cookiesu=241715400714727; device_id=a3ef10a376ef5247ffa076b3f60cda63; s=cb127hrtpz; bid=f1b5e01be977a7023f9ec859cdf24ad4_lw1xly5z; remember=1; xq_is_login=1; u=1342909666; xq_a_token=4cb9ea35172c969e53e16becd84783d07dd569ac; xqat=4cb9ea35172c969e53e16becd84783d07dd569ac; xq_id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1aWQiOjEzNDI5MDk2NjYsImlzcyI6InVjIiwiZXhwIjoxNzMzODgwMjIxLCJjdG0iOjE3MzEyODgyMjEyMTQsImNpZCI6ImQ5ZDBuNEFadXAifQ.jwZZVBSE-vMNgFLghZGUzfj6GMlW1V9lRak2yRNQB3Bx5Kz4Ecx2JXgUbLO7PettSlnmeVku-SCgDoggd8tXXUuNhNgIssTY2X_Ri7ubXOSEiKbyzpIzvJ_iB3KbY42Ygbin_m_yAdYKDzEUAZW5G7B9X2zvX_m7WQauzg_MhxIPkiHvgJrb__dNBifryqZ-FfjAn4BALsAkji-nOGgc1U3pCKLj1b9AuTBr1pkm88T4AMkz3sW7pGFvHoAu-MN4ZJ6TBefpj1ebtRH_z96yPt7WbnDCjnmUFfvOLnp-hBDeM_5MQgk0aHpzKRCNSoWDpKPXkajAlcLENN7eOundbA; xq_r_token=c05530c2c0380c37709e0b3b06662477bfc23f9c; Hm_lvt_1db88642e346389874251b5a1eded6e3=1730687821,1731288223,1731840407,1732024990; HMACCOUNT=1E48DC618B10065B; is_overseas=0; Hm_lpvt_1db88642e346389874251b5a1eded6e3=1732030144; ssxmod_itna=eqGxyDuQGQG=eAKitDXFDHYyP1mFeYeqDnGj7nix=nx0yDePGzDAxn40iDtr1T4D54FYjDbeYUt+Aqee=Cxjxo7iFDnphGUY06qPDHxY=DU1+4o3D485GwD0eG+DD4DWDmeODnxAQDjxDdupHs/a5Dbxi3uxiaDGeDe=HkDY5DhxDCcYKDwx0C9rDDBriEeibCiD2+i3Kpl2EzYDgDqQ5D9goDsxhUeQ5IM9dx44gjcIAd6x0kdq0O/2yGm2gP9rBso8xadm9iH64Q3DmemeRWWlnDYlmqKWha=7nDN0rdq1NDir+3E=GDD=; ssxmod_itna2=eqGxyDuQGQG=eAKitDXFDHYyP1mFeYeqDnGj7nix=DnFdYeDsmedDLitDGu1jlGkeUOGmQD6QYAhki87Do+KyiCkvemPIFSImKRfbfgyPmGCdONKMDXLvqIdGjiIknqfti4x0mIIChfUbIRUMj8fqvw8A5bQ3Ah7h0heT3GK+orD3AEiDLfDpXG0EhXK8A403=2t30k30GOtRePrhTei0AwiBjTA+Uw9Efg/Poo0h7Cr4+zlahAmBcAgPo1zPWaTtvXIpE1E4hfMxif7doXkFHF2ruXV/eOKfcHyrFKUqWUHYAmRNLfb4aK0Reb2FmNQA74+R/9iGHDraxDbxc4=3Y+Wn45BElrqiidD07MdPGxam0DBGebB=zBd3BavQpLjo7ED/0DTw7MYxjroyQvB7ND7=DYKxeD=", "组合名称":["12"], "组合id":["ZH3368671"], "不同策略间隔更新时间":0, "同步持股说明":"同步持股就是买入目前的持股,不然就同步成交", "资金模式":"雪球", "资金模式说明":"雪球/自定义", "雪球资金设置":"设置**********************", "账户跟单比例":0.38, "自定义资金设置":"设置————————下面设置分析配置是参考,保持和分析配置里面一样————————————————", "交易模式":"金额", "固定交易资金":10000, "持有金额限制":10000, "下单价格说明":"最新价*********************", "下单的价格":"最新价", "固定交易数量":10000, "持有限制":10000, "持股限制":100, "下单交易模式":"立马下单", "下单交易模式说明":"立马下单/通过综合交易模型", "是否需要清空缓存":"否", "特别提醒":"qmt的路径一点要设置对,不然可能删除其他的内容", "桌面路径":"C:/Users/Administrator/Desktop", "特殊交易标的":["560350","563360","562310","563300"] } ``` ### 2源代码,利用小果交易系统可以加入再说下去下载 ``` from trader_tool.stock_data import stock_data from trader_tool.bond_cov_data import bond_cov_data from trader_tool.shape_analysis import shape_analysis from trader_tool.analysis_models import analysis_models import pandas as pd from trader_tool.ths_rq import ths_rq from tqdm import tqdm import numpy as np import json from trader_tool import jsl_data from qmt_trader.qmt_trader_ths import qmt_trader_ths from xgtrader.xgtrader import xgtrader from trader_tool.ths_rq import ths_rq from trader_tool.ths_board_concept_data import ths_board_concept_data from trader_tool.unification_data import unification_data import os import pandas as pd from trader_tool.dfcf_etf_data import dfcf_etf_data from trader_tool.xueqie_data import xueqie_data from datetime import datetime from trader_tool.base_func import base_func from qmt_trader.qmt_data import qmt_data import shutil import schedule import time class xueqie_trader: def __init__(self,trader_tool='qmt',exe='C:/同花顺软件/同花顺/xiadan.exe',tesseract_cmd='C:/Program Files/Tesseract-OCR/tesseract', qq='1029762153@qq.com',open_set='否',qmt_path='D:/国金证券QMT交易端/userdata_mini', qmt_account='8882514071',qmt_account_type='STOCK',name='customize_trading_strategies'): ''' 雪球跟单模型 ''' self.exe=exe self.tesseract_cmd=tesseract_cmd self.qq=qq self.trader_tool=trader_tool self.open_set=open_set self.qmt_path=qmt_path self.qmt_account=qmt_account self.qmt_account_type=qmt_account_type if trader_tool=='ths': self.trader=xgtrader(exe=self.exe,tesseract_cmd=self.tesseract_cmd,open_set=open_set) else: self.trader=qmt_trader_ths(path=qmt_path,account=qmt_account,account_type=qmt_account_type) self.stock_data=stock_data() self.bond_cov_data=bond_cov_data() self.ths_rq=ths_rq() self.path=os.path.dirname(os.path.abspath(__file__)) self.ths_board_concept_data=ths_board_concept_data() self.name=name self.data=unification_data(trader_tool='ths') self.data=self.data.get_unification_data() self.dfcf_etf_data=dfcf_etf_data() #滑点 self.trader.slippage=0.01 self.base_func=base_func() self.trader.connect() def save_position(self): ''' 保存持股数据 ''' with open(r'分析配置.json',encoding='utf-8') as f: com=f.read() text=json.loads(com) del_df=pd.read_excel(r'{}\黑名单\黑名单.xlsx'.format(self.path),dtype='object') del_trader_stock=text['黑名单'] if del_df.shape[0]>0: del_df['证券代码']=del_df['证券代码'].apply(lambda x : str(x).split('.')[0]) del_df['证券代码']=del_df['证券代码'].apply(lambda x: '0'*(6-len(str(x)))+str(x)) del_stock_list=del_df['证券代码'].tolist() else: del_stock_list=[] for del_stock in del_trader_stock: del_stock_list.append(del_stock) trader_type=text['交易品种'] def select_del_stock_list(x): if str(x)[:6] in del_stock_list: return '是' else: return '否' df=self.trader.position() try: if df==False: print('获取持股失败') except: if df.shape[0]>0: if trader_type=='全部': df=df else: df['选择']=df['证券代码'].apply(self.trader.select_data_type) df=df[df['选择']==trader_type] print(df) df=df[df['可用余额']>=10] df['黑名单']=df['证券代码'].apply(select_del_stock_list) df=df[df['黑名单']=='否'] print('剔除黑名单**********') df.to_excel(r'持股数据\持股数据.xlsx') return df else: df=pd.DataFrame() df['账号类型']=None df['资金账号']=None df['证券代码']=None df['股票余额']=None df['可用余额']=None df['成本价']=None df['市值']=None df['选择']=None df['持股天数']=None df['交易状态']=None df['明细']=None df['证券名称']=None df['冻结数量']=None df['市价']=None df['盈亏']=None df['盈亏比(%)']=None df['当日买入']=None df['当日卖出']=None df.to_excel(r'持股数据\持股数据.xlsx') return df def save_balance(self): ''' 保持账户数据 ''' df=self.trader.balance() df.to_excel(r'账户数据\账户数据.xlsx') return df def get_disk_port_data(self,stock='600031.SH',data_type='卖一'): price=self.data.get_spot_data(stock=stock)['最新价'] return price def get_del_buy_sell_data(self,name='',assembly_id='ZH3223683'): ''' 处理交易数据 ''' with open(r'{}\雪球跟单设置.json'.format(self.path),encoding='utf-8') as f: com=f.read() text=json.loads(com) cookie=text['雪球cookie'] models=xueqie_data(cookie=cookie,assembly_id=assembly_id) df=pd.read_excel(r'持股数据\持股数据.xlsx',dtype='object') df1=df[df['股票余额']>=10] df1['证券代码']=df1['证券代码'].astype(str) hold_stock_list=df1['证券代码'].tolist() df=models.get_hist_move() try: now_date=str(datetime.now())[:10] except Exception as e: print(e) trader_time=self.stock_data.get_trader_date_list() now_date=trader_time[-1] if df.shape[0]>0: print('不开同步持股') df['updated_at']=pd.to_datetime(df['updated_at'],unit='ms') df['created_at']=pd.to_datetime(df['created_at'],unit='ms') df['updated_at']=df['updated_at'].apply(lambda x:str(x)[:10]) df1=df[df['updated_at']==now_date] if df1.shape[0]>0: print('策略{} {}今天有交易数据'.format(name,now_date)) print(df1) df=df1 df['证券代码']=df['stock_symbol'].apply(lambda x:str(x)[2:]) df['证券代码']=df['证券代码'].astype(str) df['prev_weight']=df['prev_weight'].fillna(0) df['adjust']=df['target_weight']-df['prev_weight'] df=df.sort_values(by='created_at',ascending=True) df.to_excel(r'{}\原始数据\原始数据.xlsx'.format(self.path)) else: print('策略{} {}今天没有交易数据'.format(name,now_date)) df=pd.DataFrame() df.to_excel(r'{}\原始数据\原始数据.xlsx'.format(self.path)) else: print('策略{} {}今天没有交易数据'.format(name,now_date)) df=pd.DataFrame() df.to_excel(r'{}\原始数据\原始数据.xlsx'.format(self.path)) def get_del_not_trader_stock(self): ''' 剔除黑名单 ''' print('剔除黑名单______________*************************_______________________') with open(r'分析配置.json',encoding='utf-8') as f: com=f.read() text=json.loads(com) del_df=pd.read_excel(r'{}\黑名单\黑名单.xlsx'.format(self.path),dtype='object') del_trader_stock=text['黑名单'] if del_df.shape[0]>0: del_df['证券代码']=del_df['证券代码'].apply(lambda x : str(x).split('.')[0]) del_df['证券代码']=del_df['证券代码'].apply(lambda x: '0'*(6-len(str(x)))+str(x)) del_stock_list=del_df['证券代码'].tolist() else: del_stock_list=[] for del_stock in del_trader_stock: del_stock_list.append(del_stock) def select_del_stock_list(x): if str(x)[:6] in del_stock_list: return '是' else: return '否' df=pd.read_excel(r'{}\原始数据\原始数据.xlsx'.format(self.path),dtype='object') if df.shape[0]>0: df['证券代码']=df['证券代码'].apply(lambda x: '0'*(6-len(str(x)))+str(x)) try: del df['Unnamed: 0'] except: pass df['黑名单']=df['证券代码'].apply(select_del_stock_list) df=df[df['黑名单']=='否'] #隔离策略 df['证券代码']=df['证券代码'].apply(lambda x: '0'*(6-len(str(x)))+str(x)) df['品种']=df['证券代码'].apply(lambda x: self.trader.select_data_type(x)) df.to_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path)) print(df) else: df=pd.DataFrame() df.to_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path)) def get_trader_data(self): ''' 获取交易数据 ''' with open(r'{}\雪球跟单设置.json'.format(self.path),encoding='utf-8') as f: com=f.read() text=json.loads(com) adjust_ratio=text['账户跟单比例'] disk_ptice=text['下单的价格'] other_stock=text['特殊交易标的'] df=pd.read_excel(r'{}\交易股票池\交易股票池.xlsx'.format(self.path)) try: df['证券代码']=df['证券代码'].apply(lambda x: '0'*(6-len(str(x)))+str(x)) except: pass try: del df['Unnamed: 0'] except: pass trader_log=pd.read_excel(r'{}\跟单记录\跟单记录.xlsx'.format(self.path)) try: trader_log['证券代码']=trader_log['证券代码'].apply(lambda x: '0'*(6-len(str(x)))+str(x)) except: pass try: del trader_log['Unnamed: 0'] except: pass if df.shape[0]>0: if trader_log.shape[0]>0: trader_id_list=trader_log['id'].tolist() else: trader_id_list=[] df['交易情况']=df['id'].apply(lambda x : '已经下单' if x in trader_id_list else '没有下单') df=df[df['交易情况']=='没有下单'] print('没有下单的交易*****************************') print(df) if df.shape[0]>0: df['证券名称']=df['stock_name'] df['自动价格']='是' df['价格']=df['price'] df['交易类型']='数量' df['交易方向']=df['adjust'].apply(lambda x : 'buy' if x>=0 else 'sell') df['交易状态']=df['交易方向'].apply(lambda x :'未买' if x=='buy' else '未卖') amount_list=[] for stock ,trader,adjust,target_weight, in zip(df['证券代码'],df['交易方向'],df['adjust'],df['target_weight']): try: stock=str(stock) try: price=self.get_disk_port_data(stock=stock,data_type=disk_ptice) if str(stock)[:6] in other_stock: price=price/10 else: price=price except Exception as e: print(e,'((((((((((((((获取盘口数据有问题(((())))))))))))))))))') price=self.data.get_spot_data(stock=stock)['最新价'] if str(stock)[:6] in other_stock: price=price/10 else: price=price #adjust=(adjust*adjust_ratio)/100 adjust=(target_weight*adjust_ratio)/100 if trader=='buy': trader_type,trader_amount,price=self.trader.order_target_percent(stock=stock,target_percent=adjust,price=price) print(trader_type,trader_amount,price,'))))))))))))))))))))))))))') if trader_type=='buy' and trader_amount>=10: #trader_type,amount,price=self.trader.order_percent(stock=stock,price=price,percent=adjust,trader_type=trader) amount_list.append(trader_amount) else: amount_list.append(0) elif trader=='sell': adjust=abs(adjust) trader_type,trader_amount,price=self.trader.order_target_percent(stock=stock,target_percent=adjust,price=price) if trader_type=='sell' and trader_amount>=10: #trader_type,amount,price=self.trader.order_percent(stock=stock,price=price,percent=adjust,trader_type=trader) amount_list.append(trader_amount) else: amount_list.append(0) else: amount_list.append(0) except Exception as e: print(e) amount_list.append(0) df['数量']=amount_list not_trader=df[df['数量']<=0] #数量为0的不进入下单记录 df=df[df['数量']>=10] print('下单股票池))))))))))))))))))))))))') print(df) print('下单数量为0的标的可能没有持股,可能账户没有资金等待下次成交########################################################') print(not_trader) df.to_excel(r'{}\下单股票池\下单股票池.xlsx'.format(self.path)) trader_log=pd.concat([trader_log,df],ignore_index=True) trader_log.to_excel(r'{}\跟单记录\跟单记录.xlsx'.format(self.path)) else: print('没有需要下单标度******************') df=pd.DataFrame() df.to_excel(r'{}\下单股票池\下单股票池.xlsx'.format(self.path)) else: print('没有交易股票池*************') df=pd.DataFrame() df.to_excel(r'{}\下单股票池\下单股票池.xlsx'.format(self.path)) def start_trader_on(self): ''' 开始下单 ''' with open(r'{}\雪球跟单设置.json'.format(self.path),encoding='utf-8') as f: com=f.read() text=json.loads(com) disk_ptice=text['下单的价格'] other_stock=text['特殊交易标的'] df=pd.read_excel(r'{}\下单股票池\下单股票池.xlsx'.format(self.path)) try: df['证券代码']=df['证券代码'].apply(lambda x: '0'*(6-len(str(x)))+str(x)) except: pass try: del df['Unnamed: 0'] except: pass #资金模式 cash_models=text['资金模式'] #下单模式 trader_models=text['下单交易模式'] #自定义资金设置 data_type=text['交易模式'] value=text['固定交易资金'] limit_value=text['持有金额限制'] amount1=text['固定交易数量'] limit_amount=text['持股限制'] if df.shape[0]>0: df['证券代码']=df['证券代码'].astype(str) #print(df['证券代码']) df['证券代码']=df['证券代码'].apply(lambda x: '0'*(6-len(str(x)))+str(x)) if cash_models=='雪球' and trader_models=='通过综合交易模型': buy_df=df[df['交易方向']=='buy'] if buy_df.shape[0]>0: buy_df=buy_df[['证券代码','证券名称','自动价格','价格','交易类型','数量','交易状态']] buy_df.to_excel(r'自定义买入股票\自定义买入股票.xlsx') else: print('{} {} 没有买入股票'.format(cash_models,trader_models)) sell_df=df[df['交易方向']=='sell'] if sell_df.shape[0]>0: sell_df=sell_df[['证券代码','证券名称','自动价格','价格','交易类型','数量','交易状态']] sell_df.to_excel(r'自定义卖出股票\自定义卖出股票.xlsx') else: print('{} {} 没有卖出股票'.format(cash_models,trader_models)) elif cash_models=='自定义' and trader_models=='通过综合交易模型': buy_df=df[df['交易方向']=='buy'] if buy_df.shape[0]>0: buy_df=buy_df[['证券代码','证券名称','交易状态']] buy_df.to_excel(r'买入股票\买入股票.xlsx') else: print('{} {} 没有买入股票'.format(cash_models,trader_models)) sell_df=df[df['交易方向']=='sell'] if sell_df.shape[0]>0: sell_df=sell_df[['证券代码','证券名称','交易状态']] sell_df.to_excel(r'卖出股票\卖出股票.xlsx') else: print('{} {} 没有卖出股票'.format(cash_models,trader_models)) #先卖在买 elif cash_models=='雪球' and trader_models=='立马下单': sell_df=df[df['交易方向']=='sell'] if sell_df.shape[0]>0: for stock,amount in zip(sell_df['证券代码'],sell_df['数量']): try: price=self.get_disk_port_data(stock=stock,data_type=disk_ptice) if str(stock)[:6] in other_stock: price=price/10 else: price=price except Exception as e: print(e,'((((((((((((((获取盘口数据有问题(((())))))))))))))))))') price=self.data.get_spot_data(stock=stock)['最新价'] if str(stock)[:6] in other_stock: price=price/10 else: price=price try: self.trader.sell(security=stock,price=price,amount=amount) print('{} {} 卖出 股票{} 数量{} 价格{}'.format(cash_models,trader_models,stock,amount,price)) except Exception as e: print(e) print('{} {} 卖出 股票{} 有问题'.format(cash_models,trader_models,stock)) else: print('{} {} 没有卖出股票'.format(cash_models,trader_models)) buy_df=df[df['交易方向']=='buy'] if buy_df.shape[0]>0: for stock,amount in zip(buy_df['证券代码'],buy_df['数量']): try: price=self.get_disk_port_data(stock=stock,data_type=disk_ptice) if str(stock)[:6] in other_stock: price=price/10 else: price=price except Exception as e: print(e,'((((((((((((((获取盘口数据有问题(((())))))))))))))))))') try: price=self.data.get_spot_data(stock=stock)['最新价'] if str(stock)[:6] in other_stock: price=price/10 else: price=price self.trader.buy(security=stock,price=price,amount=amount) print('{} {} 买入 股票{} 数量{} 价格{}'.format(cash_models,trader_models,stock,amount,price)) except Exception as e: print(e) print(print('{} {} 买入 股票{} 有问题'.format(cash_models,trader_models,stock))) else: print('{} {} 没有买入股票'.format(cash_models,trader_models)) #先卖在买 elif cash_models=='自定义' and trader_models=='立马下单': sell_df=df[df['交易方向']=='sell'] if sell_df.shape[0]>0: for stock in sell_df['证券代码'].tolist(): try: price=self.get_disk_port_data(stock=stock,data_type=disk_ptice) if str(stock)[:6] in other_stock: price=price/10 else: price=price except Exception as e: print(e,'((((((((((((((获取盘口数据有问题(((())))))))))))))))))') price=self.data.get_spot_data(stock=stock)['最新价'] if str(stock)[:6] in other_stock: price=price/10 else: price=price try: trader_type,amount,price=self.trader.check_av_target_trader(data_type=data_type,trader_type='sell', amount=amount1,limit_volume=limit_amount,value=value,limit_value=limit_value, stock=stock,price=price) if trader_type=='sell': self.trader.sell(security=stock,price=price,amount=amount) print('{} {} 卖出 股票{} 数量{} 价格{}'.format(cash_models,trader_models,stock,amount,price)) else: print('{} {} 卖出 股票{} 数量{} 价格{} 不可以交易'.format(cash_models,trader_models,stock)) except Exception as e: print(e) print(print('{} {} 卖出 股票{} 有问题'.format(cash_models,trader_models,stock))) else: print('{} {} 没有卖出股票'.format(cash_models,trader_models)) buy_df=df[df['交易方向']=='buy'] if buy_df.shape[0]>0: for stock,amount in zip(buy_df['证券代码'],buy_df['数量']): try: price=self.get_disk_port_data(stock=stock,data_type=disk_ptice) if str(stock)[:6] in other_stock: price=price/10 else: price=price except Exception as e: print(e,'((((((((((((((获取盘口数据有问题(((())))))))))))))))))') price=self.data.get_spot_data(stock=stock)['最新价'] if str(stock)[:6] in other_stock: price=price/10 else: price=price try: trader_type,amount,price=self.trader.check_av_target_trader(data_type=data_type,trader_type='buy', amount=amount1,limit_volume=limit_amount,value=value,limit_value=limit_value, stock=stock,price=price) if trader_type=='buy': self.trader.buy(security=stock,price=price,amount=amount) print('{} {} 买入 股票{} 数量{} 价格{}'.format(cash_models,trader_models,stock,amount,price)) else: print('{} {} 买入 股票{} 数量{} 价格{} 不可以交易'.format(cash_models,trader_models,stock)) except Exception as e: print(e) print(print('{} {} 买入 股票{} 有问题'.format(cash_models,trader_models,stock))) else: print('{} {} 没有买入股票'.format(cash_models,trader_models)) else: print('未知的下单模式***********************') else: print('没有需要下单的数据**************************') # def delete_folder_contents_path(self,folder_path): # for item in os.listdir(folder_path): # item_path = os.path.join(folder_path, item) # if os.path.isfile(item_path): # os.remove(item_path) # print('{}删除成功'.format(item)) # elif os.path.isdir(item_path): # shutil.rmtree(item_path) # print('{}删除成功'.format(item)) # else: # print(item,'文件夹为空') # def delete_folder_contents(self): # ''' # 删除缓存内容 # ''' # print('删除缓存内容*********************') # import shutil # with open(r'分析配置.json',encoding='utf-8') as f: # com=f.read() # text=json.loads(com) # with open(r'{}\雪球跟单设置.json'.format(self.path),encoding='utf-8') as f: # com=f.read() # text1=json.loads(com) # qmt_path=text['qmt路径'] # desktop_path=text1['桌面路径'] # try: # os.makedirs(name=r'{}\del_data'.format(desktop_path)) # except: # pass # del_com=r'{}\del_data'.format(desktop_path) # del_com=del_com.replace('\\',"/") # all_path=os.listdir(path=qmt_path) # if len(all_path)>0: # for path in all_path: # if path[:5]=='down_': # del_path=os.path.join(qmt_path, path) # del_path=del_path.replace('\\',"/") # try: # shutil.move(del_path,del_com) # except Exception as e: # print(e) # else: # pass # try: # shutil.rmtree(r'{}'.format(del_com)) # except: # pass # else: # print('文件夹下面没有文件') def update_all_data(self): ''' 更新策略数据 ''' if self.base_func.check_is_trader_date_1(): import time with open(r'{}\雪球跟单设置.json'.format(self.path),encoding='utf-8') as f: com=f.read() text=json.loads(com) name_list=text['组合名称'] zu_list=text['组合id'] update_time=text['不同策略间隔更新时间'] for name,zu in zip(name_list,zu_list): try: print(self.save_position()) except Exception as e: print(e) try: print(self.save_balance()) except Exception as e: print(e) self.get_del_buy_sell_data(name=name,assembly_id=zu) self.get_del_not_trader_stock() self.get_trader_data() self.start_trader_on() # self.delete_folder_contents() time.sleep(update_time*60) else: print('雪球跟单{} 目前不是交易时间***************'.format(datetime.now())) if __name__=='__main__': ''' 跟单 ''' with open('分析配置.json','r+',encoding='utf-8') as f: com=f.read() text=json.loads(com) trader_tool=text['交易系统'] exe=text['同花顺下单路径'] tesseract_cmd=text['识别软件安装位置'] qq=text['发送qq'] open_set=text['是否开启特殊证券公司交易设置'] qmt_path=text['qmt路径'] qmt_account=text['qmt账户'] qmt_account_type=text['qmt账户类型'] trader=xueqie_trader(trader_tool=trader_tool,exe=exe,tesseract_cmd=tesseract_cmd,qq=qq, open_set=open_set,qmt_path=qmt_path,qmt_account=qmt_account, qmt_account_type=qmt_account_type) schedule.every(0.08).minutes.do(trader.update_all_data) while True: schedule.run_pending() time.sleep(1) ``` #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) 6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)