Repository navigation
Releases: Mind2Money/PropfirmVIPCopyUpdates
Release list
v1.7.0
简体中文
网页登录可以记住账号密码:每个连接使用自己固定的独立浏览器配置(保存在数据目录),不再在登录后删除。Edge/Chrome 自带的「保存密码」和 Tradovate 的网站数据保留在其中,之后的网页登录会自动填写账号密码;程序不读取、不保存密码。
首次登录成功后窗口保持打开,等待浏览器的保存提示:关闭窗口、浏览器写入密码库或 60 秒后自动关闭;浏览器写入过一次后,之后的登录很快自动关闭。等待期间连接状态显示「等待保存密码」。
连接页新增「清除记住的登录」按钮和「记住登录」列;删除连接时一并删除该连接的浏览器配置。该连接的登录窗口仍开着时,不会再次启动或删除它。
修复:在图表上移动独立的止盈/止损单(撤旧单再挂新单)后,部分跟随账户可能收不到新的止盈或止损。原因是程序撤单后核对最终成交量时,会断开并重连账户数据连接;在重连的约一两秒内,补挂的保护单被当作「未同步」而放弃,同期主账户新挂的单也被记为「断线期间遗漏」。现在核对改为另开一条临时连接读取快照,原连接保持在线、照常推送和下单,快照与期间收到的事件合并后临时连接即关闭。真实断线时的处理不变。
跟随单在发送前被拒(连接未同步、对冲或日盈亏上限等拦截)时,日志新增「跟随单未发送」记录及原因代码,订单面板「本轮未发送,原因见日志」现在有对应记录。
挂单的止盈止损现在会提前出现在跟随账户里:主账户给尚未成交的挂单补上止盈或止损时,程序撤销跟随账户尚未成交的入场单,把入场和止盈止损作为一个 OSO 重新挂出;止盈止损处于未激活(Suspended)状态,入场成交后才生效。重挂会让限价入场失去原来的排队位置;从撤单到重挂,需要等撤单生效并核对最终成交量(通常一到几秒),这期间跟随账户没有入场单。如果这期间入场单有成交,已成交部分照旧在成交后挂出止盈止损,被撤掉的剩余数量不再补挂,日志会记录。重挂会被拒绝时(单笔上限、对冲、日盈亏上限等),保留原入场单,止盈止损照旧等成交后再挂。主账户一次性下出的带止盈止损挂单本来就按 OSO 复制,行为不变。
新增微信推送(Server酱):在设置中保存 SendKey(Windows 加密保存,之后只显示前后几位)并打开推送后,成交(开仓、加仓、减仓、平仓、止盈、止损)、下单/撤单/改单、异常与安全提醒、跟单组启停会推送到微信;每类事件和账户范围(主账户和跟随账户、只推主账户、所有已连接账户)都可在设置中选择。推送内容包含账户名、合约、方向、数量和价格,指令类提醒写明是哪个请求(改单、撤单或平仓,订单号、类型、价格、数量)和券商给出的原因;消息保存在 Server酱 的服务器上。同一笔交易在各账户的事件合并成一条,异常提醒立即发送;同一原因的提醒 30 分钟内只推一次,每个结果未知的请求都会推送;Server酱 拒绝推送(如 SendKey 无效或当日额度用完)时当天停止推送并在设置中显示原因。默认关闭,模拟模式不推送。
修复:主账户撤销未成交的带止盈止损挂单时,跟随账户中对未激活止盈止损的改单(券商先挂起,等入场成交再执行)会被券商停止(ExecutionStopped),日志原先记为「指令被拒」警告。现在止盈止损随入场单一起撤销、且没有成交时,这类改单记为「已被取代」(普通信息,不推送);撤单还在进行时先等待,超过确认时限仍记为被拒;止盈止损仍在而改单被停止时,照旧记为被拒。
跟单组页改版:每组先列一行组名(主题色、较大字号、加粗)和组的运行状态,主账户(粗体)和跟随账户(常规字体)以树形连线列在其下。原「操作」按钮改为组行上的「停止」/「实盘启动」按钮(实盘启动仍需输入完整组名)和「⋯」(组的运行状态与其余操作:全平当前组、编辑、账户身份核对、重新核对状态、删除跟单组)。折叠箭头现在收起整组成员。
English
Browser login can remember the username and password: each connection signs in through its own fixed, isolated browser profile in the data folder instead of a temporary one. Edge/Chrome's own "save password" and Tradovate's site data stay there, so later logins fill in the username and password; the application neither reads nor stores the password.
After the first sign-in the window stays open for the browser's save prompt and closes when you close it, once the browser writes its password store, or after 60 seconds; once the browser has written it, later logins close shortly after sign-in. The connection shows "Saving password" meanwhile.
The Connections page adds "Forget saved login" and a "Saved login" column; removing a connection deletes its profile. A profile whose login window is still open is neither launched into nor deleted.
Fixed: after a standalone target or stop was moved on the chart (the old order cancelled, a new one placed), a follower could miss the new target or stop. Checking a cancelled order's final quantity disconnected and reconnected the account data connection; during those one or two seconds a released protective order was dropped as "not synchronized", and an order the leader placed meanwhile was logged as missed while disconnected. The check now reads its snapshot on a separate temporary connection: the existing connection stays up, keeps delivering events and accepts orders, and the temporary connection closes once its snapshot is merged with the events received meanwhile. Real disconnects are handled as before.
A follower order refused before sending (connection not synchronized, hedge or daily-limit guard) now writes "Follower order not sent" with its reason code, so the order board's "Not sent this run; see the log" has a matching entry.
A pending order's target and stop now show on the follower right away: when the leader adds a target or stop to an unfilled pending entry, the follower's unfilled entry is cancelled and placed again together with them as one OSO; the target and stop stay inactive (Suspended) until the entry fills. The new placement loses a limit entry's queue position, and between the cancel and the new placement (the cancel taking effect plus a final-quantity check, typically one to a few seconds) there is no follower entry. If the entry executes meanwhile, the filled quantity gets its target and stop after the fill as before, the cancelled remainder is not placed again, and the log records it. When the new placement would be refused (size limit, hedge or daily-limit guard), the resting entry is kept and its target and stop still wait for the fill. Pending orders the leader places with their target and stop in one request were already copied as an OSO and are unchanged.
New WeChat pushes (Server酱): after saving a SendKey in Settings (encrypted with Windows; only its first and last characters are shown again) and turning pushes on, fills (opens, adds, reductions, closes, targets and stops), orders (placed, cancelled, changed), alerts and group starts and stops are pushed to WeChat; each event kind and the accounts (leaders and followers, leaders only, or all connected accounts) can be chosen in Settings. Pushes include account names, contracts, sides, quantities and prices, a request alert names the request (change, cancel or close; order, type, prices, quantity) and the broker's reason, and pushes are stored on Server酱's servers. One trade's events across accounts make one message and alerts go out at once; an alert repeating for the same cause goes out at most once per 30 minutes, while every unknown request outcome is pushed; when Server酱 refuses a push (for example an invalid SendKey or a used-up daily quota), pushes stop for the day and Settings shows the reason. Off by default; simulation never pushes.
Fixed: when the leader cancelled an unfilled pending entry with a target and stop, the broker stopped (ExecutionStopped) the follower's changes to the inactive target and stop that it was holding until the entry filled, and the log reported them as refused requests. Now, once the target and stop have been cancelled with their entry without executions, such a change is logged as superseded (information, no push); while the cancel is still arriving it waits, and at the confirmation deadline it is still a refusal. A change stopped while the target or stop remains is a refusal as before.
Copy groups page redesign: each group starts with its own row (the name in the accent color, larger and bold, with the group's run state); the leader (bold) and the followers (regular) hang below on tree lines. The Actions button became a Stop / Start live button on the group row (Start live still asks for the exact group name) and a ⋯ button for the group's state and its other actions (flatten this group, edit, account identity review, reconcile, delete group). The fold arrow now folds all of a group's members.
Commits
- test: let placement events land before a broker reports copies unacknowledged (d606b76)
- chore: release v1.7.0 (e7867a7)
- feat: give each copy group its own row with a start/stop button (2751f24)
- fix: key push alerts on every reason field and each unknown request (d0eb881)
- fix: settle stopped held bracket changes and sharpen push alerts (a1745f3)
- fix: push a repeating alert once per window (e6c2883)
- feat: push account activity to WeChat through Server酱 (1153714)
- feat: place a pending entry's late target and stop as an inactive OSO (0d877c7)
- fix: read evidence snapshots beside the live stream (21cd157)
- feat: remember the browser login per connection (2fe5584)
- chore: point updatesInfo at v1.6.2 (7b2a4c9)
v1.6.2
简体中文
跟单组页改为一张表列出全部跟单组:每组主账户行显示组名、主账户、运行状态及自己的净值与盈亏,跟随账户以树形连线缩进列在其下,可点箭头折叠;主账户行的「操作」按钮弹出该组的状态与全部操作(实盘启动/停止、全平、编辑、账户身份核对、重新核对、删除)。页面横幅与组卡片移除,工具栏只保留当前组选择(作用于规则与计划页签)、刷新和新建。
所有表格的数值列表头改为与数值一起右对齐。
「操作」弹出层支持键盘:打开时焦点落在第一个可用操作上,Esc 关闭并回到「操作」按钮;折叠箭头可用 Tab 聚焦。点表格任一行也会把该行所属组设为当前组。
窗口可以缩到最小尺寸以下:小于 880×600 时整个工作区(含字体)等比缩小而不是裁切。跟单方式与合约映射拆成两列。
English
The group page lists every group in one table: each leader row shows the group name, the leader account, the run state and its own equity and P&L, its followers hang below on drawn tree lines and fold with the chevron, and the row's Actions button opens the group's state and every action (start live/stop, flatten, edit, identity review, reconcile, delete). The page banner and group card are gone; the toolbar keeps the current-group selector (for the rule and schedule tabs), refresh and new group.
Numeric column headers in every table are right-aligned over their values.
The Actions popup works from the keyboard: the first available action takes focus, Escape closes it and returns to the Actions button, and the fold chevron is reachable with Tab. Selecting any row also makes its group current.
The window can shrink below its minimum: under 880×600 the whole workspace, fonts included, scales down instead of clipping. Copy mode and contract mapping are separate columns.
Commits
- chore: release v1.6.2 (2646e0d)
- feat: keyboard access for the Actions popup and row-driven current group (68db65f)
- feat: list every copy group in one member tree with an Actions popup (a62bab2)
- feat: compact group page, member tree with the leader, and workspace scaling (2d54508)
- chore: point updatesInfo at v1.6.1 (654081e)
- test: allow the DPAPI round trip two minutes on slow CI runners (f2cb092)
v1.6.1
简体中文
高缩放比例的笔记本:窗口启动时不再超出屏幕(默认尺寸放不下就最大化,最小尺寸降为 880×600);显示密度新增默认的「跟随窗口」,较小或较矮的窗口自动使用紧凑模式;侧栏品牌名过长时换行显示。
跟单组编辑器的主账户与跟随账户下拉框显示账户净值、同步状态以及该账户已在哪些跟单组中担任主账户或跟随(未加入则标明)。
修复 Pine 策略市价入场模式下“一笔交易结束后下一笔不下单”的问题:同一入场 ID 的新交易在前一笔仍在与券商核对(止损/止盈是否真的成交)时,其模拟成交被当成旧记录的成交而丢弃,账户空仓而模拟持仓。现在每条镜像记录记住所属交易序号,新交易的市价入场等旧交易核对完成(未成交的真实出场先按市价平掉)后再发送;预挂单模式下在挂单送达券商前就成交的模拟入场同样按市价入场,并记为 ENTRY_FILLED_BEFORE_RESTING。
修复下单后紧接着的多余改价:math.round_to_mintick 与按跳数计算的止盈止损价带有二进制浮点残差(如 4089.1000000000004),券商回报 4089.1 时被当作价格变化而重复改价,导致 CONFIRMATION_TIMEOUT、MODIFY_UNCONFIRMED 与 ExecutionStopped 拒绝。现在这些价格按合约最小跳动取整,镜像发送和比较的价格也按跳动对齐。
修复市价入场的 OSO(入场+止盈+止损)复制到跟随账户后保护单被软件自己撤掉的问题:跟随账户的 OSO 刚提交、券商仍报告为 PendingNew 时,若恰好赶上核对(启动后每 30 秒一次)或主账户改单,退出容量按“入场未成交、保护单未挂起”算成 0,两条保护单以 exit-capacity 撤销,持仓失去保护。现在券商确认前的 OSO 保护单、以及入场成交已到而持仓回报未到时的保护单,不再按容量改小或撤销;容量撤单在发送前会重新核对。
English
Laptops at high scaling: the window no longer starts larger than the screen (it opens maximized when the default size does not fit; the minimum is now 880×600), the new default density "Follow window" switches small or short windows to compact automatically, and a long brand name wraps in the sidebar.
The copy-group editor's leader and follower drop-downs show each account's equity, sync state and the groups it already leads or follows (or that it is in none).
Fixed Pine strategies in market entry mode not placing the next trade after one ended: when the script re-entered under the same entry id while the earlier trade was still being verified against the broker (did its stop or target really fill?), the new simulated fill was taken for the old record's and dropped, leaving the account flat while the emulator held a position. Every mirror record now remembers the trade serial it mirrors; the new trade's market entry waits until the ended trade is settled (an unfilled real exit is closed at market first) and is then sent. In resting mode a simulated entry that fills before its order reached the broker now enters at market the same way, noted as ENTRY_FILLED_BEFORE_RESTING.
Fixed the spurious price changes sent right after an entry: math.round_to_mintick and tick-based profit/loss levels carried binary floating-point residue (4089.1000000000004) that looked like a changed price once the broker reported 4089.1, causing CONFIRMATION_TIMEOUT, MODIFY_UNCONFIRMED and ExecutionStopped rejections. These prices now snap to the contract tick, and the mirror sends and compares tick-aligned prices.
Fixed the app cancelling the follower's protection of a copied market-entry OSO (entry with target and stop): when a reconciliation (every 30 seconds after a start) or a leader change ran while Tradovate still reported the just-placed OSO as PendingNew, the exit capacity was read as zero (entry unfilled, brackets not yet suspended) and both brackets were cancelled as exit-capacity, leaving the position unprotected. OSO brackets the broker has not acknowledged yet, and protection whose entry fill arrived before the position report, are no longer shrunk or cancelled for capacity; a capacity cancel is checked again just before it is sent.
Commits
- chore: release v1.6.1 (447fe11)
- test: defer a source change made while the follower OSO is unacknowledged (5a26698)
- fix: keep native OSO brackets the broker has not acknowledged yet (3a459b0)
- feat: fit small logical screens (laptops at high scaling) (3c50125)
- feat: show equity, sync state and group membership in the group editor account lists (5e38b95)
- fix: place the next Pine market entry after a trade ends and stop residue modifies (e96d317)
- chore: point updatesInfo at v1.6.0 (a15b7e2)
v1.6.0
简体中文
浮盈浮亏改按平仓方向的买卖价计算:多头按买一价、空头按卖一价标记,不再使用最新成交价(最新成交可能落在价差另一侧,市价平仓的实际成交会低于按最新成交价估算的数值)。
缺少该侧报价时持仓视为未标记(等待行情),日盈亏上限改用券商资金快照判断,不会用最新成交价顶替;只含最新成交的报价沿用上一次的买卖价。
日盈亏上限的触发记录新增触发时各持仓的标记方向、标记价、最新成交价与持仓均价,便于与平仓结果比对。
软件加固:改为专有许可(不再是 AGPL)。私有引擎在构建期先混淆改名再 AES-256-GCM 加密,运行时在可执行文件内解密,公开发布不含可读源码;每次构建产出的反混淆
sourcemap 作为私有“map 表”,只随私有仓库发布保留,绝不进入公开更新源。首次启动新增许可协议确认(拒绝即退出),接受记录带版本与时间戳。构建默认用 PowerShell 对可执行文件自签名(自签名不受信任,SmartScreen 仍会提示未知发布者;可用 BT_SIGN_PFX/BT_SIGN_THUMBPRINT 换真证书,或 BT_SIGN=off 关闭)。可执行文件经单文件压缩与 gzip 引擎覆盖层压缩,体积约 108MB。
产品名统一为 PropFirmVIP Tradovate:可执行文件为 PropFirmVIP-Tradovate.exe,引擎为 PropFirmVIP-Tradovate.Engine.exe,窗口标题、通知、浏览器登录临时目录、诊断日志文件名与
%LOCALAPPDATA%\\PropFirmVIP-Tradovate 偏好/引擎缓存目录随之更名(旧目录的 desktop.json 首次启动时自动沿用)。
修复网页登录成功后因“登录浏览器清理未完成”而登录失败的问题:浏览器关闭后先以调试端口确认已退出,只有端口仍响应或文件持续占用时才调用 PowerShell
进程清理,因此 PowerShell 被拦截、缓慢或损坏的电脑也能完成登录;临时目录删除会在占用期间限时重试。浏览器已关闭而目录暂时删不掉时,登录照常完成,
连接页列出该目录,可以管理员身份删除(UAC 确认)或打开所在文件夹手动删除;每次启动和网页登录前自动重试。浏览器仍可能在运行时仍判登录失败。
登录失败与目录残留会写入操作日志(只含原因代码和目录随机名,不含本机路径)。
English
Open P&L is now marked at the side a market close would take: a long at the bid, a short at the offer, no longer the last trade (which can print
on the far side of the spread and overstate what the close realizes). A quote missing that side leaves the position unmarked (awaiting quotes) and
the daily limit falls back to the broker's funds snapshot; the last trade never stands in, and a trade-only quote keeps the last known sides.
The daily-limit breach entry now records each position's side, mark, last trade and average price at the trigger for comparison with the close.
Hardening: relicensed to proprietary (no longer AGPL). The private engine is obfuscated then AES-256-GCM encrypted at build time and decrypted inside the
executable at run time, so public releases carry no readable source; each build's de-obfuscation sourcemaps are the private map, kept for the private repository
release only and never shipped to the public update feed. First run now requires accepting the license agreement (declining exits), recorded with version and
timestamp. The build self-signs the executable by default via PowerShell (self-signed certificates are untrusted, so SmartScreen still warns; set
BT_SIGN_PFX/BT_SIGN_THUMBPRINT for a real certificate or BT_SIGN=off to skip). The executable is compressed — a compressed single-file bundle and a
gzip engine overlay — to about 108MB.
The product is now PropFirmVIP Tradovate everywhere: the executable is PropFirmVIP-Tradovate.exe, the engine PropFirmVIP-Tradovate.Engine.exe, and the window title,
notifications, browser-login profile folder, diagnostic log file name and the %LOCALAPPDATA%\\PropFirmVIP-Tradovate preferences/engine cache follow
(a desktop.json left by the BatchTradovate-named builds is adopted on first start).
A completed browser login no longer fails with "login browser cleanup did not finish": after the browser closes, its debug port confirms
the exit, and the PowerShell process cleanup runs only when that port still answers or files stay busy, so hosts where PowerShell is blocked,
slow or broken can sign in. Removing the temporary folder retries busy files for a bounded time. When the browser has closed but the folder
cannot be removed yet, the login completes and the Connections page lists the folder with administrator removal (UAC confirmation) and
an Open folder action; every start and browser login retries it. A browser that may still be running still fails the login. Failed logins
and leftover folders are journaled with cause codes and the folder's random name, without local paths.
Commits
- fix: make the release build pass on CI (af317da)
- chore: release v1.6.0 (908ea02)
- docs: update hardening notes for self-signing and compression (60f4455)
- perf: gzip the engine overlay to shrink the executable (902b4aa)
- feat: mark open P&L at the closing side (bid for longs, offer for shorts) (58929c9)
- feat: self-sign the executable by default via PowerShell (f059ba2)
- perf: compress the single-file bundle to shrink the executable (90e5d98)
- docs: add the first-run license screenshot and README note (53ad29c)
- docs: document the hardening (license, engine encryption, map, EULA, signing) (6376064)
- feat: wire optional Authenticode code signing into the build (5648af1)
- feat: gate first run on accepting the proprietary license (6122197)
- feat: emit the private de-obfuscation map beside the executable (39c3050)
- feat: obfuscate engine sources and emit a private sourcemap (9123638)
- feat: encrypt embedded engine assets with AES-256-GCM at build (9ec6cb3)
- fix: tolerate slow loopback refusals when confirming the login browser closed (5be8e80)
- chore: relicense from AGPL-3.0 to proprietary (15e3605)
- fix: keep browser logins when only the profile folder is left (5e012c0)
- chore: stamp log exports with the propfirmvip-tradovate format id (1e281bc)
- chore: point updatesInfo at v1.5.1 (e5c15a3)
- feat: rename the product to PropFirmVIP Tradovate (0870738)