{"id":19324300,"url":"https://github.com/easin/wsctp","last_synced_at":"2026-02-14T08:31:25.417Z","repository":{"id":261806733,"uuid":"885416611","full_name":"easin/wsctp","owner":"easin","description":"上期所api二次封装，提供websocket和redis队列交互","archived":false,"fork":false,"pushed_at":"2024-11-08T14:52:29.000Z","size":3712,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-08T09:53:54.835Z","etag":null,"topics":["ctp","ctpapi","redis","websocket"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/easin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-08T14:44:43.000Z","updated_at":"2024-11-13T18:12:53.000Z","dependencies_parsed_at":"2024-11-08T15:35:27.338Z","dependency_job_id":null,"html_url":"https://github.com/easin/wsctp","commit_stats":null,"previous_names":["easin/wsctp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/easin/wsctp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easin%2Fwsctp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easin%2Fwsctp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easin%2Fwsctp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easin%2Fwsctp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/easin","download_url":"https://codeload.github.com/easin/wsctp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/easin%2Fwsctp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29440311,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T07:24:13.446Z","status":"ssl_error","status_checked_at":"2026-02-14T07:23:58.969Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ctp","ctpapi","redis","websocket"],"created_at":"2024-11-10T02:04:30.371Z","updated_at":"2026-02-14T08:31:25.400Z","avatar_url":"https://github.com/easin.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e 本项目是基于上期所的api的websocket和redis消息队列的封装，方便期货自动交易，量化交易\n\u003e\n\u003e \n\u003e\n\u003e \u003cfont color=\"red\"\u003e本项目使用上期所提供的c++接口二次封装，提供websocket和redis消息桥接，方便不想使用c++的js或者python选手也能调用自动下单的一些相关命令\u003c/font\u003e\n\u003e\n\u003e 在本项目提供了两种方式和ctp交互：\n\u003e\n\u003e 1.使用websocket的js调用方式\n\u003e\n\u003e 2.直接python、js或者其他语言把消息推到redis里，本程序会自动消费消息，并做相应的处理\n\n\n\n#### 1.安装依赖、编译\n\n```shell\nset VCPKG_DEFAULT_TRIPLET=x64-windows\nvcpkg install uwebsockets:x64-windows\nvcpkg install cpp-redis:x64-windows\n```\n\n\n\n```shell\n#相关依赖的版本：\nyaml-cpp:x64-windows                              0.8.0#1\nuwebsockets:x64-windows                           20.67.0\nnlohmann-json:x64-windows                         3.11.3#1\nfmt:x64-windows                                   11.0.2#1\ncpp-redis:x64-windows                             4.3.1#5\n```\n\n\n\n\n#### 2.配置账号\n\n根目录下有config.yaml和 dev.yaml、simnow.yaml\n\nconfig.yaml里直接配置需要使用的环境的配置文件即可，例如想使用开发环境的配置dev.yaml，则配置config.yaml里的根节点为dev\n```yaml\nprofile: dev\n```\n\ndev.yaml的配置目前分为两类：账号类，系统配置类：redis和websocket配置。请注意自己要使用，请换成自己的账号和授权码\n\n```yaml\naccount:\n  FrontAddr: \"tcp://59.36.3.115:27226\"\n  FrontMdAddr: \"tcp://59.36.3.115:27236\"\n  BrokerID: \"8080\"\n  UserID: \"21013\"\n  Password: \"zwy123321\"\n  InvestorID: \"21013\"\n  UserProductInfo: \"test\"\n  AuthCode: \"0000000000000000\"\n  AppID: \"client_fo_1.0.0\"\n  InstrumentID: \"sr2505\"\n  ExchangeID: \"CZCE\"\n  bIsUsingUdp: 1\n  bIsMulticast: 0\nsys:\n  #redis信息\n  REDIS_HOST: \"192.168.1.214\"\n  REDIS_DB: 11\n  REDIS_PORT: 8379\n  REDIS_POOL_SIZE: 3\n  REDIS_RECONNECT_TIMES: 16\n  REDIS_INTERVAL_SECONDES: 10\n  #websocket 端口\n  WEBSOCKET_PORT: 5001\n  #ws心跳秒数\n  HEART_INTERVAL: 3\n  #日志级别，参见\n  #define SPDLOG_LEVEL_TRACE 0\n  #define SPDLOG_LEVEL_DEBUG 1\n  #define SPDLOG_LEVEL_INFO 2\n  #define SPDLOG_LEVEL_WARN 3\n  #define SPDLOG_LEVEL_ERROR 4\n  #define SPDLOG_LEVEL_CRITICAL 5\n  #define SPDLOG_LEVEL_OFF 6\n  LOG_LEVEL: 1\n```\n\n\n\n#### 3.运行\n\n先启动客户端：双击exe，在启动js前端\n\njs前端调用代码：\n\n```js\n\n    const connect = () =\u003e {\n      const reconnectInterval = 5000; // 重连间隔时间，单位为毫秒\n      // 尝试连接WebSocket服务器\n        socket.value = new WebSocket(localStorage.getItem(\"ctpWsUrl\"));\n        socket.value.onopen = (event) =\u003e {\n          console.log('WebSocket连接已打开:', event);\n        };\n\n        socket.value.onmessage = (event) =\u003e {\n          if(event.data==\"无相\"){\n            if (socket.value \u0026\u0026 socket.value.readyState === WebSocket.OPEN) {\n              console.log('心跳收到：',event.data);\n              socket.value.send(\"无我\");\n            }\n          }\n          else{\n            const data = JSON.parse(event.data);\n            console.log('收到服务器消息:', data);\n            if(data.success){\n              // 检查消息类型是否为qryTradingAccount\n              if (data.type === 'qryTradingAccount') {\n                          balance.value = data.data.balance; // 更新账户余额\n                          available.value = data.data.available; // 更新可用资金\n                        }\n              // 持仓\n              if (data.type === 'qryInvestorPosition') {\n                positions.value = data.data;\n              }\n            }\n          }\n        \n          \n          \n        };\n\n        socket.value.onclose = (event) =\u003e {\n          console.log('WebSocket连接已关闭:', event);\n          // 当连接关闭时，尝试重新连接\n          setTimeout(connect, reconnectInterval);\n        };\n\n        socket.value.onerror = (error) =\u003e {\n          console.error('WebSocket发生错误:', error);\n          // 发生错误时，关闭连接并尝试重新连接\n          if (socket.value) {\n            socket.value.close();\n          }\n        };\n      };\n\n\n    \n    // 发送消息到服务器\n    const sendMessage = (message) =\u003e {\n      console.log(socket.value);\n      console.log(socket.value.readyState);\n      if (socket.value \u0026\u0026 socket.value.readyState === WebSocket.OPEN) {\n        socket.value.send(JSON.stringify(message));\n      } else {\n        // connect();\n        console.error('WebSocket连接尚未打开。');\n      }\n    };\n    // 查询持仓的方法\n    const qryInvestorPosition = () =\u003e {\n      const currentTime = new Date().toISOString();\n      const message = {\n        type: \"qryInvestorPosition\",\n        time: currentTime\n      };\n\n      sendMessage(message);\n    };\n\n```\n\n\n\n\n\n#### 4.待办清单\n\n- [x] 账号信息使用配置文件灵活切换\n\n- [x] 自动登入，并且确认结算单\n\n- [x] 查询持仓\n\n- [x] 下单【含开平】（市价单、限价单）\n\n- [x] websocket连接，长连接，心跳检测\n\n- [ ] 撤单\n\n  \n\n#### 5.运行截图\n\n##### 前端：\n![image-20241108214849804](images/image-20241108214849804.png)\n\n后端：\n\n![image-20241108214245609](images/image-20241108214245609.png)\n\n![image-20241108214327926](images/image-20241108214327926.png)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasin%2Fwsctp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feasin%2Fwsctp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feasin%2Fwsctp/lists"}