From b145471895e4ef834b99e7e1ee997fe767319045 Mon Sep 17 00:00:00 2001 From: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Date: Sun, 2 Nov 2025 05:53:01 +0800 Subject: [PATCH 1/3] =?UTF-8?q?docs(adaptive):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=95=B8=E6=93=9A=E8=A7=A3=E9=87=8B=E5=92=8C=E5=8F=83=E8=80=83?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B=EF=BC=8C=E6=8E=A1=E7=94=A8"=E8=A7=A3?= =?UTF-8?q?=E9=87=8B+=E5=8F=83=E8=80=83"=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 改動說明: - 新增「數據框架說明」章節:詳細說明 4 個時間框架的覆蓋時間和用途 * 3分鐘序列(30分鐘):實時價格、放量檢測、買賣壓力 * 15分鐘序列(2.5小時):震盪區間識別 * 1小時序列(10小時):中期趨勢確認 * 4小時序列(40小時):大趨勢判斷 - 新增「關鍵數據解讀」章節: * BuySellRatio 含義和參考範圍(0.6-0.7 強買壓,0.3-0.4 強賣壓) * 成交量分析:放量檢測標準(1.5-2 倍平均) * RSI 參考範圍:根據市場波動性調整(震盪市 30-40/60-70) - 新增「入場信號參考示例」章節: * 震盪策略入場信號(區間下沿做多、上沿做空) * 趨勢策略入場信號(趨勢突破參考) - 補充「避免低質量信號」: * 新增:震盪市在區間中部交易(應等待區間邊界) * 新增:缺乏買賣壓力確認(BuySellRatio 中性時謹慎) 設計哲學: - 採用「解釋 + 參考示例」方式,而非硬編碼固定規則 - 所有參考數值都明確標註「你可以根據市場狀態自主調整」 - 強調根據市場波動性、趨勢強度自主判斷 - 激發 AI 的判斷能力,而非限制其靈活性 - 通過夏普比率反饋實現自我進化 改動統計: - 原文件:259 行 - 新文件:366 行(+107 行) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- prompts/adaptive.txt | 115 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 4 deletions(-) diff --git a/prompts/adaptive.txt b/prompts/adaptive.txt index 279e9584..5e594c3e 100644 --- a/prompts/adaptive.txt +++ b/prompts/adaptive.txt @@ -190,10 +190,115 @@ 只在强信号时开仓,不确定就观望。 你拥有的完整数据: -- 原始序列:3分钟价格序列(MidPrices数组) + 4小时K线序列 -- 技术序列:EMA20序列、MACD序列、RSI7序列、RSI14序列 -- 资金序列:成交量序列、持仓量(OI)序列、资金费率 -- 买卖压力:BuySellRatio 序列 + +## 数据框架说明 + +你会收到 4 个时间框架的序列数据(每个包含最近 10 个数据点): + +1. **3分钟序列**(覆盖最近 30 分钟) + - 价格数据:MidPrices, EMA20, MACD, RSI7, RSI14 + - 成交量:Volumes 序列 + - 买卖压力:BuySellRatios 序列 + - 用途:实时价格波动、短期放量检测、即时买卖压力 + +2. **15分钟序列**(覆盖最近 2.5 小时) + - 价格数据:MidPrices, EMA20, MACD, RSI7, RSI14 + - 用途:短期震荡区间识别、寻找支撑压力位 + +3. **1小时序列**(覆盖最近 10 小时) + - 价格数据:MidPrices, EMA20, MACD, RSI7, RSI14 + - 用途:中期趋势确认、关键技术位识别 + +4. **4小时序列**(覆盖最近 40 小时) + - 价格数据:MidPrices, EMA20 vs EMA50, ATR, Volume, MACD, RSI14 + - 用途:大趋势判断、波动率评估 + +5. **资金数据** + - 持仓量(OI)变化、资金费率、成交量对比 + +## 关键数据解读 + +### BuySellRatio(买卖压力比) + +**含义**:反映主动买卖力量对比 +- 1.0 = 完全买方主导(所有成交都是主动买入) +- 0.0 = 完全卖方主导(所有成交都是主动卖出) +- 0.5 = 买卖力量平衡 + +**参考范围**(你可以根据市场状态自主调整): +- 强买压:通常 > 0.6-0.7 +- 强卖压:通常 < 0.3-0.4 +- 中性:0.4-0.6 + +**重要提示**: +- 高波动/牛市环境:可能需要 > 0.7 才算强买压 +- 低波动/震荡市:> 0.6 可能就足够 +- 结合成交量一起看(放量 + 买压 = 更可靠) +- 观察连续性(连续 2-3 根 K 线方向一致更可靠) + +### 成交量分析(放量检测) + +**含义**:价格变化伴随的成交量 +- 放量 = 成交量显著增加 +- 缩量 = 成交量显著减少 + +**参考标准**(你可以自主调整): +- 放量:当前成交量 > 最近平均成交量的 1.5-2 倍 +- 连续放量:2-3 根 K 线都显著放量 + +**重要提示**: +- 放量突破更可靠(成交量确认价格方向) +- 缩量上涨要警惕(可能动能不足) +- 结合 BuySellRatio 判断放量性质(买盘放量 vs 卖盘放量) + +### RSI(相对强弱指标) + +**含义**:价格超买超卖程度 +- 0-100 范围 +- 50 = 中性 + +**参考范围**(你应该根据市场波动性调整): +- 震荡市超卖:通常 30-40 +- 震荡市超买:通常 60-70 +- 趋势市超卖:可能需要 < 30 +- 趋势市超买:可能需要 > 70 + +**重要提示**: +- 高波动时期应使用更极端的阈值 +- 低波动时期可以放宽标准 +- 结合其他指标综合判断(不要只看 RSI) + +## 入场信号参考示例 + +以下是参考示例,具体数值由你根据市场状态自主判断: + +### 震荡策略入场信号 + +**区间下沿做多参考**: +- RSI 显示超卖(参考:30-40,高波动时可能要 < 30) +- 买卖压力开始偏向买方(参考:> 0.5-0.6) +- 价格接近支撑位(15m EMA20 下方、前低、整数关口) +- 可能伴随放量(成交量增加 > 1.5 倍) + +**区间上沿做空参考**: +- RSI 显示超买(参考:60-70,高波动时可能要 > 70) +- 买卖压力开始偏向卖方(参考:< 0.4-0.5) +- 价格接近压力位(15m EMA20 上方、前高、整数关口) +- 可能伴随放量(成交量增加 > 1.5 倍) + +### 趋势策略入场信号 + +**趋势突破参考**: +- 多时间框架共振(15m/1h/4h 方向一致) +- 连续放量(2-3 根 K 线成交量 > 1.5 倍平均) +- 买卖压力极端(BuySellRatio > 0.7 或 < 0.3) +- 价格突破关键位(EMA20、前高前低) + +**重要原则**: +- 以上数值仅为参考,不是固定规则 +- 你应该根据当前市场状态(波动率、趋势强度)自主调整 +- 多维度交叉验证比单一指标更可靠 +- 综合信心度 ≥ 75 才开仓 分析方法(完全由你自主决定): - 首先判断市场状态(震荡/趋势) @@ -206,8 +311,10 @@ 避免低质量信号: - 单一维度(只看一个指标) - 相互矛盾(涨但量萎缩) +- 震荡市在区间中部交易(应等待区间边界,胜率更高) - 市场状态不明确 - 刚平仓不久(<15分钟) +- 缺乏买卖压力确认(BuySellRatio 中性时谨慎开仓) - 未识别关键技术位 # 夏普比率自我进化 From f15d82b13a5f9dc1dd0f16f4b62f2804b21945c4 Mon Sep 17 00:00:00 2001 From: ZhouYongyou <128128010+zhouyongyou@users.noreply.github.com> Date: Sun, 2 Nov 2025 06:03:56 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E5=BE=A9=E7=94=9F=E7=94=A2?= =?UTF-8?q?=E9=8C=AF=E8=AA=A4=EF=BC=9A=E5=88=AA=E9=99=A4=20adaptive.txt=20?= =?UTF-8?q?=E4=B8=AD=E4=B8=8D=E6=94=AF=E6=8C=81=E7=9A=84=E5=8B=95=E6=85=8B?= =?UTF-8?q?=E8=AA=BF=E6=95=B4=E5=8A=9F=E8=83=BD=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 問題:AI 生成 update_stop_loss 決策但被拒絕為無效動作 原因:adaptive.txt 描述了動態止損功能,但 dev 分支代碼未實現 刪除內容: - 震盪策略:追蹤止損(持倉中動態調整)段落 - 趨勢策略:分批止盈、追蹤止損段落 - 策略選擇:追蹤止損計劃 - 持倉動態調整範例 結果:提示詞與代碼功能完全匹配,避免 AI 生成無效決策 相關 issue:生產環境報錯 '无效的action:update_stop_loss' 後續計劃:在 feature/partial-close-dynamic-tpsl 測試完成後再合併動態功能 --- prompts/adaptive.txt | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/prompts/adaptive.txt b/prompts/adaptive.txt index 5e594c3e..7cbe73d5 100644 --- a/prompts/adaptive.txt +++ b/prompts/adaptive.txt @@ -73,15 +73,9 @@ 3. 止损设置: - 固定 0.8-1%(紧密止损) -4. 追踪止损(持仓中动态调整): -- 浮盈达到 0.8% → 止损移到成本价(保证不亏) -- 浮盈达到 1.2% → 止损移到 +0.5%(锁定一半利润) -- 价格距离技术位 < 0.3% → 立即主动平仓(避免回撤) - -5. 示例(做多): +4. 示例(做多): - 入场:100,000,15m EMA20: 101,200(+1.2%) - 决策:止盈 101,100(技术位前 0.1%),而非 102,000 -- 持仓:价格到 101,000(+1.0%)→ 止损移到 100,000 - 持仓:价格到 101,100(距离 EMA20 仅 0.1%)→ 立即平仓 退出信号: @@ -112,23 +106,15 @@ 2. 止盈设置逻辑: - 如果技术位距离 < 5% → 止盈设在技术位前 0.2% -- 如果技术位在 5-10% → 分两批止盈(第一批技术位,第二批 10%) -- 如果技术位距离 > 10% → 使用追踪止损,让利润奔跑 +- 如果技术位在 5-10% → 止盈设在技术位前 0.2% +- 如果技术位距离 > 10% → 止盈设在 8-10% 左右 3. 止损设置: - 固定 1.5-2%(给足震荡空间) -4. 追踪止损(持仓中动态调整): -- 浮盈达到 2% → 止损移到成本价(保证不亏) -- 浮盈达到 3% → 止损移到 +1%(锁定部分利润) -- 浮盈达到 5% → 止损移到 +2.5%(让利润奔跑,但保护已有收益) -- 价格距离技术位 < 0.5% → 考虑主动平仓或分批平仓 - -5. 示例(做多): +4. 示例(做多): - 入场:100,000,4h EMA20: 104,500(+4.5%) -- 决策:第一目标 104,300(技术位前),第二目标 110,000(+10%) -- 持仓:价格到 102,000(+2%)→ 止损移到 100,000 -- 持仓:价格到 104,300(接近技术位)→ 主动平仓或分批平仓 50% +- 决策:止盈 104,300(技术位前 0.2%),止损 98,000(-2%) 退出信号: - 多时间框架方向开始矛盾 → 趋势减弱,获利离场 @@ -141,12 +127,10 @@ 2. 策略选择: '选择策略 A/B(理由:...)' 3. 技术位分析: '上方压力位:101,200(15m EMA20),下方支撑位:99,500(最近低点)' 4. 止盈止损: '止盈 101,100(技术位前 0.1%),止损 99,200(-0.8%)' -5. 追踪止损计划: '浮盈 0.8% 时移动止损到成本价' 重要提醒: - 价格很可能在技术位(EMA20、前高前低、整数关口)遇阻或反弹 - 宁可少赚 0.5%,也不要从 +1.5% 回撤到止损 -- 持仓中主动调整止损,锁定利润 # 交易频率认知 @@ -361,6 +345,5 @@ - 目标是夏普比率,不是交易频率 - 先判断市场状态,再选择策略 - 技术位优先,避免在压力/支撑前回撤 -- 持仓中主动调整止损,锁定利润 - 宁可错过,不做低质量交易 - 风险回报比1:3是底线 From 9a604f9b27cc8ac5b50d4e6c01ed80bc9de9a097 Mon Sep 17 00:00:00 2001 From: zbhan Date: Sat, 1 Nov 2025 18:25:44 -0400 Subject: [PATCH 3/3] feat: pr validation --- .github/labeler.yml | 127 +++++ .github/labels.yml | 180 +++++++ .github/workflows/pr-checks-advisory.yml | 331 ++++++++++++ .github/workflows/pr-checks.yml | 237 +++++++++ CONTRIBUTING.md | 481 ++++++++++++++++++ docs/community/HOW_TO_MIGRATE_YOUR_PR.md | 272 ++++++++++ .../community/HOW_TO_MIGRATE_YOUR_PR.zh-CN.md | 272 ++++++++++ docs/community/MIGRATION_ANNOUNCEMENT.md | 358 +++++++++++++ .../community/MIGRATION_ANNOUNCEMENT.zh-CN.md | 358 +++++++++++++ docs/community/PR_COMMENT_TEMPLATE.md | 173 +++++++ docs/community/README.md | 14 + docs/i18n/zh-CN/CONTRIBUTING.md | 481 ++++++++++++++++++ docs/maintainers/PROJECT_MANAGEMENT.md | 398 +++++++++++++++ docs/maintainers/PROJECT_MANAGEMENT.zh-CN.md | 398 +++++++++++++++ docs/maintainers/PR_REVIEW_GUIDE.md | 458 +++++++++++++++++ docs/maintainers/PR_REVIEW_GUIDE.zh-CN.md | 457 +++++++++++++++++ docs/maintainers/README.md | 51 ++ docs/maintainers/README.zh-CN.md | 51 ++ docs/maintainers/SETUP_GUIDE.md | 381 ++++++++++++++ docs/maintainers/SETUP_GUIDE.zh-CN.md | 381 ++++++++++++++ scripts/pr-check.sh | 413 +++++++++++++++ scripts/pr-fix.sh | 335 ++++++++++++ 22 files changed, 6607 insertions(+) create mode 100644 .github/labeler.yml create mode 100644 .github/labels.yml create mode 100644 .github/workflows/pr-checks-advisory.yml create mode 100644 .github/workflows/pr-checks.yml create mode 100644 CONTRIBUTING.md create mode 100644 docs/community/HOW_TO_MIGRATE_YOUR_PR.md create mode 100644 docs/community/HOW_TO_MIGRATE_YOUR_PR.zh-CN.md create mode 100644 docs/community/MIGRATION_ANNOUNCEMENT.md create mode 100644 docs/community/MIGRATION_ANNOUNCEMENT.zh-CN.md create mode 100644 docs/community/PR_COMMENT_TEMPLATE.md create mode 100644 docs/i18n/zh-CN/CONTRIBUTING.md create mode 100644 docs/maintainers/PROJECT_MANAGEMENT.md create mode 100644 docs/maintainers/PROJECT_MANAGEMENT.zh-CN.md create mode 100644 docs/maintainers/PR_REVIEW_GUIDE.md create mode 100644 docs/maintainers/PR_REVIEW_GUIDE.zh-CN.md create mode 100644 docs/maintainers/README.md create mode 100644 docs/maintainers/README.zh-CN.md create mode 100644 docs/maintainers/SETUP_GUIDE.md create mode 100644 docs/maintainers/SETUP_GUIDE.zh-CN.md create mode 100755 scripts/pr-check.sh create mode 100755 scripts/pr-fix.sh diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000..89bcae3f --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,127 @@ +# Auto-labeler configuration +# Automatically adds labels based on changed files + +# Area: Frontend +'area: frontend': + - changed-files: + - any-glob-to-any-file: + - 'web/**/*' + - '*.tsx' + - '*.ts' + - '*.jsx' + - '*.js' + - '*.css' + +# Area: Backend +'area: backend': + - changed-files: + - any-glob-to-any-file: + - '**/*.go' + - 'go.mod' + - 'go.sum' + - 'cmd/**/*' + - 'internal/**/*' + - 'pkg/**/*' + +# Area: Exchange +'area: exchange': + - changed-files: + - any-glob-to-any-file: + - 'internal/exchange/**/*' + - 'pkg/exchange/**/*' + - '**/binance*.go' + - '**/hyperliquid*.go' + - '**/aster*.go' + - '**/okx*.go' + - '**/bybit*.go' + +# Area: AI +'area: ai': + - changed-files: + - any-glob-to-any-file: + - 'internal/ai/**/*' + - 'pkg/ai/**/*' + - '**/deepseek*.go' + - '**/qwen*.go' + - '**/openai*.go' + - '**/claude*.go' + +# Area: API +'area: api': + - changed-files: + - any-glob-to-any-file: + - 'internal/api/**/*' + - 'pkg/api/**/*' + - '**/handler*.go' + - '**/router*.go' + +# Area: Security +'area: security': + - changed-files: + - any-glob-to-any-file: + - '**/auth*.go' + - '**/jwt*.go' + - '**/encryption*.go' + - '**/crypto*.go' + - 'SECURITY.md' + +# Area: Database +'area: database': + - changed-files: + - any-glob-to-any-file: + - 'internal/database/**/*' + - 'internal/db/**/*' + - '**/migration*.go' + - '**/*.sql' + - '**/schema*.go' + +# Area: UI/UX +'area: ui/ux': + - changed-files: + - any-glob-to-any-file: + - 'web/src/components/**/*' + - 'web/src/pages/**/*' + - '**/*.css' + - '**/style*.ts' + +# Area: Deployment +'area: deployment': + - changed-files: + - any-glob-to-any-file: + - 'Dockerfile' + - 'docker-compose*.yml' + - '.github/workflows/**/*' + - 'start.sh' + - '**/*deploy*.md' + +# Type: Documentation +'type: documentation': + - changed-files: + - any-glob-to-any-file: + - 'docs/**/*' + - '*.md' + - 'README*' + - 'CHANGELOG*' + - 'CONTRIBUTING.md' + - 'CODE_OF_CONDUCT.md' + +# Type: Test +'type: test': + - changed-files: + - any-glob-to-any-file: + - '**/*_test.go' + - 'test/**/*' + - '**/*.test.ts' + - '**/*.test.tsx' + - '**/*.spec.ts' + +# Dependencies +'dependencies': + - changed-files: + - any-glob-to-any-file: + - 'go.mod' + - 'go.sum' + - 'package.json' + - 'package-lock.json' + - 'web/package.json' + - 'web/package-lock.json' diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 00000000..26cadba4 --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,180 @@ +# GitHub Labels Configuration +# Use https://github.com/crazy-max/ghaction-github-labeler to sync labels + +# Priority Labels +- name: "priority: critical" + color: "d73a4a" + description: "Critical priority - requires immediate attention" + +- name: "priority: high" + color: "ff6b6b" + description: "High priority - should be addressed soon" + +- name: "priority: medium" + color: "fbca04" + description: "Medium priority - normal queue" + +- name: "priority: low" + color: "0e8a16" + description: "Low priority - nice to have" + +# Type Labels +- name: "type: bug" + color: "d73a4a" + description: "Something isn't working" + +- name: "type: feature" + color: "a2eeef" + description: "New feature or request" + +- name: "type: enhancement" + color: "84b6eb" + description: "Improvement to existing feature" + +- name: "type: documentation" + color: "0075ca" + description: "Documentation improvements" + +- name: "type: security" + color: "ee0701" + description: "Security-related changes" + +- name: "type: performance" + color: "f9d0c4" + description: "Performance improvements" + +- name: "type: refactor" + color: "fbca04" + description: "Code refactoring" + +- name: "type: test" + color: "c5def5" + description: "Test-related changes" + +# Status Labels +- name: "status: needs review" + color: "fbca04" + description: "PR is ready for review" + +- name: "status: needs changes" + color: "d93f0b" + description: "PR needs changes based on review" + +- name: "status: on hold" + color: "fef2c0" + description: "PR/issue is on hold" + +- name: "status: in progress" + color: "0e8a16" + description: "Currently being worked on" + +- name: "status: blocked" + color: "d93f0b" + description: "Blocked by another issue/PR" + +# Area Labels (aligned with roadmap) +- name: "area: security" + color: "ee0701" + description: "Security enhancements (Phase 1.1)" + +- name: "area: ai" + color: "7057ff" + description: "AI capabilities and models (Phase 1.2)" + +- name: "area: exchange" + color: "0075ca" + description: "Exchange integrations (Phase 1.3)" + +- name: "area: architecture" + color: "d4c5f9" + description: "Project structure refactoring (Phase 1.4)" + +- name: "area: ui/ux" + color: "c2e0c6" + description: "User experience improvements (Phase 1.5)" + +- name: "area: frontend" + color: "bfdadc" + description: "Frontend (React/TypeScript)" + +- name: "area: backend" + color: "c5def5" + description: "Backend (Go)" + +- name: "area: api" + color: "0e8a16" + description: "API endpoints" + +- name: "area: database" + color: "f9d0c4" + description: "Database changes" + +- name: "area: deployment" + color: "fbca04" + description: "Deployment and CI/CD" + +# Special Labels +- name: "good first issue" + color: "7057ff" + description: "Good for newcomers" + +- name: "help wanted" + color: "008672" + description: "Extra attention is needed" + +- name: "bounty" + color: "1d76db" + description: "Bounty available for this issue" + +- name: "bounty: claimed" + color: "5319e7" + description: "Bounty has been claimed" + +- name: "bounty: paid" + color: "0e8a16" + description: "Bounty has been paid" + +- name: "RFC" + color: "d4c5f9" + description: "Request for Comments - needs discussion" + +- name: "breaking change" + color: "d73a4a" + description: "Includes breaking changes" + +- name: "duplicate" + color: "cfd3d7" + description: "This issue or pull request already exists" + +- name: "invalid" + color: "e4e669" + description: "This doesn't seem right" + +- name: "wontfix" + color: "ffffff" + description: "This will not be worked on" + +- name: "dependencies" + color: "0366d6" + description: "Dependency updates" + +# Roadmap Phases +- name: "roadmap: phase-1" + color: "0e8a16" + description: "Core Infrastructure Enhancement" + +- name: "roadmap: phase-2" + color: "fbca04" + description: "Testing & Stability" + +- name: "roadmap: phase-3" + color: "0075ca" + description: "Universal Market Expansion" + +- name: "roadmap: phase-4" + color: "7057ff" + description: "Advanced AI & Automation" + +- name: "roadmap: phase-5" + color: "d73a4a" + description: "Enterprise & Scaling" diff --git a/.github/workflows/pr-checks-advisory.yml b/.github/workflows/pr-checks-advisory.yml new file mode 100644 index 00000000..1c352233 --- /dev/null +++ b/.github/workflows/pr-checks-advisory.yml @@ -0,0 +1,331 @@ +name: PR Checks (Advisory) + +on: + pull_request: + types: [opened, synchronize, reopened] + branches: [main, dev] + +# These checks are advisory only - they won't block PR merging +# Results will be posted as comments to help contributors improve their PRs + +jobs: + pr-info: + name: PR Information + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Check PR title format + id: check-title + run: | + PR_TITLE="${{ github.event.pull_request.title }}" + + # Check if title follows conventional commits + if echo "$PR_TITLE" | grep -qE "^(feat|fix|docs|style|refactor|perf|test|chore|ci|security)(\(.+\))?: .+"; then + echo "status=✅ Good" >> $GITHUB_OUTPUT + echo "message=PR title follows Conventional Commits format" >> $GITHUB_OUTPUT + else + echo "status=⚠️ Suggestion" >> $GITHUB_OUTPUT + echo "message=Consider using Conventional Commits format: type(scope): description" >> $GITHUB_OUTPUT + fi + + - name: Calculate PR size + id: pr-size + run: | + ADDITIONS=${{ github.event.pull_request.additions }} + DELETIONS=${{ github.event.pull_request.deletions }} + TOTAL=$((ADDITIONS + DELETIONS)) + + if [ $TOTAL -lt 100 ]; then + echo "size=🟢 Small" >> $GITHUB_OUTPUT + echo "label=size: small" >> $GITHUB_OUTPUT + elif [ $TOTAL -lt 500 ]; then + echo "size=🟡 Medium" >> $GITHUB_OUTPUT + echo "label=size: medium" >> $GITHUB_OUTPUT + else + echo "size=🔴 Large" >> $GITHUB_OUTPUT + echo "label=size: large" >> $GITHUB_OUTPUT + echo "suggestion=Consider breaking this into smaller PRs for easier review" >> $GITHUB_OUTPUT + fi + echo "lines=$TOTAL" >> $GITHUB_OUTPUT + + - name: Post advisory comment + uses: actions/github-script@v7 + with: + script: | + const titleStatus = '${{ steps.check-title.outputs.status }}'; + const titleMessage = '${{ steps.check-title.outputs.message }}'; + const prSize = '${{ steps.pr-size.outputs.size }}'; + const prLines = '${{ steps.pr-size.outputs.lines }}'; + const sizeSuggestion = '${{ steps.pr-size.outputs.suggestion }}' || ''; + + let comment = '## 🤖 PR Advisory Feedback\n\n'; + comment += 'Thank you for your contribution! Here\'s some automated feedback to help improve your PR:\n\n'; + comment += '### PR Title\n'; + comment += titleStatus + ' ' + titleMessage + '\n\n'; + comment += '### PR Size\n'; + comment += prSize + ' (' + prLines + ' lines changed)\n'; + if (sizeSuggestion) { + comment += '\n💡 **Suggestion:** ' + sizeSuggestion + '\n'; + } + comment += '\n---\n\n'; + comment += '### 📖 New PR Management System\n\n'; + comment += 'We\'re introducing a new PR management system! These checks are **advisory only** and won\'t block your PR.\n\n'; + comment += '**Want to check your PR against new standards?**\n'; + comment += '```bash\n'; + comment += '# Run the PR health check tool\n'; + comment += './scripts/pr-check.sh\n'; + comment += '```\n\n'; + comment += 'This tool will:\n'; + comment += '- 🔍 Analyze your PR (doesn\'t modify anything)\n'; + comment += '- ✅ Show what\'s already good\n'; + comment += '- ⚠️ Point out issues\n'; + comment += '- 💡 Give specific suggestions on how to fix\n\n'; + comment += '**Learn more:**\n'; + comment += '- [Migration Guide](https://github.com/tinkle-community/nofx/blob/dev/docs/community/MIGRATION_ANNOUNCEMENT.md)\n'; + comment += '- [Contributing Guidelines](https://github.com/tinkle-community/nofx/blob/dev/CONTRIBUTING.md)\n\n'; + comment += '**Questions?** Just ask in the comments! We\'re here to help. 🙏\n\n'; + comment += '---\n\n'; + comment += '*This is an automated message. It won\'t affect your PR being merged.*'; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); + + backend-checks: + name: Backend Checks (Advisory) + runs-on: ubuntu-latest + permissions: + pull-requests: write + continue-on-error: true + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.21' + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y libta-lib-dev || true + go mod download || true + + - name: Check Go formatting + id: go-fmt + continue-on-error: true + run: | + UNFORMATTED=$(gofmt -l . 2>/dev/null || echo "") + if [ -n "$UNFORMATTED" ]; then + echo "status=⚠️ Needs formatting" >> $GITHUB_OUTPUT + echo "files<> $GITHUB_OUTPUT + echo "$UNFORMATTED" | head -10 >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + else + echo "status=✅ Good" >> $GITHUB_OUTPUT + echo "files=" >> $GITHUB_OUTPUT + fi + + - name: Run go vet + id: go-vet + continue-on-error: true + run: | + if go vet ./... 2>&1 | tee vet-output.txt; then + echo "status=✅ Good" >> $GITHUB_OUTPUT + echo "output=" >> $GITHUB_OUTPUT + else + echo "status=⚠️ Issues found" >> $GITHUB_OUTPUT + echo "output<> $GITHUB_OUTPUT + cat vet-output.txt | head -20 >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + fi + + - name: Run tests + id: go-test + continue-on-error: true + run: | + if go test ./... -v 2>&1 | tee test-output.txt; then + echo "status=✅ Passed" >> $GITHUB_OUTPUT + echo "output=" >> $GITHUB_OUTPUT + else + echo "status=⚠️ Failed" >> $GITHUB_OUTPUT + echo "output<> $GITHUB_OUTPUT + cat test-output.txt | tail -30 >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + fi + + - name: Post backend feedback + if: always() + uses: actions/github-script@v7 + with: + script: | + const fmtStatus = '${{ steps.go-fmt.outputs.status }}' || '⚠️ Skipped'; + const vetStatus = '${{ steps.go-vet.outputs.status }}' || '⚠️ Skipped'; + const testStatus = '${{ steps.go-test.outputs.status }}' || '⚠️ Skipped'; + const fmtFiles = `${{ steps.go-fmt.outputs.files }}`; + const vetOutput = `${{ steps.go-vet.outputs.output }}`; + const testOutput = `${{ steps.go-test.outputs.output }}`; + + let comment = '## 🔧 Backend Checks (Advisory)\n\n'; + comment += '### Go Formatting\n'; + comment += fmtStatus + '\n'; + if (fmtFiles) { + comment += '\nFiles needing formatting:\n```\n' + fmtFiles + '\n```\n'; + } + comment += '\n### Go Vet\n'; + comment += vetStatus + '\n'; + if (vetOutput) { + comment += '\n```\n' + vetOutput.substring(0, 500) + '\n```\n'; + } + comment += '\n### Tests\n'; + comment += testStatus + '\n'; + if (testOutput) { + comment += '\n```\n' + testOutput.substring(0, 1000) + '\n```\n'; + } + comment += '\n---\n\n'; + comment += '💡 **To fix locally:**\n'; + comment += '```bash\n'; + comment += '# Format code\n'; + comment += 'go fmt ./...\n\n'; + comment += '# Check for issues\n'; + comment += 'go vet ./...\n\n'; + comment += '# Run tests\n'; + comment += 'go test ./...\n'; + comment += '```\n\n'; + comment += '*These checks are advisory and won\'t block merging. Need help? Just ask!*'; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); + + frontend-checks: + name: Frontend Checks (Advisory) + runs-on: ubuntu-latest + permissions: + pull-requests: write + continue-on-error: true + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Check if web directory exists + id: check-web + run: | + if [ -d "web" ]; then + echo "exists=true" >> $GITHUB_OUTPUT + else + echo "exists=false" >> $GITHUB_OUTPUT + fi + + - name: Install dependencies + if: steps.check-web.outputs.exists == 'true' + working-directory: ./web + continue-on-error: true + run: npm ci + + - name: Run linter + if: steps.check-web.outputs.exists == 'true' + id: lint + working-directory: ./web + continue-on-error: true + run: | + if npm run lint 2>&1 | tee lint-output.txt; then + echo "status=✅ Good" >> $GITHUB_OUTPUT + echo "output=" >> $GITHUB_OUTPUT + else + echo "status=⚠️ Issues found" >> $GITHUB_OUTPUT + echo "output<> $GITHUB_OUTPUT + cat lint-output.txt | head -20 >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + fi + + - name: Type check + if: steps.check-web.outputs.exists == 'true' + id: typecheck + working-directory: ./web + continue-on-error: true + run: | + if npm run type-check 2>&1 | tee typecheck-output.txt; then + echo "status=✅ Good" >> $GITHUB_OUTPUT + echo "output=" >> $GITHUB_OUTPUT + else + echo "status=⚠️ Issues found" >> $GITHUB_OUTPUT + echo "output<> $GITHUB_OUTPUT + cat typecheck-output.txt | head -20 >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + fi + + - name: Build + if: steps.check-web.outputs.exists == 'true' + id: build + working-directory: ./web + continue-on-error: true + run: | + if npm run build 2>&1 | tee build-output.txt; then + echo "status=✅ Success" >> $GITHUB_OUTPUT + echo "output=" >> $GITHUB_OUTPUT + else + echo "status=⚠️ Failed" >> $GITHUB_OUTPUT + echo "output<> $GITHUB_OUTPUT + cat build-output.txt | tail -20 >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + fi + + - name: Post frontend feedback + if: always() && steps.check-web.outputs.exists == 'true' + uses: actions/github-script@v7 + with: + script: | + const lintStatus = '${{ steps.lint.outputs.status }}' || '⚠️ Skipped'; + const typecheckStatus = '${{ steps.typecheck.outputs.status }}' || '⚠️ Skipped'; + const buildStatus = '${{ steps.build.outputs.status }}' || '⚠️ Skipped'; + const lintOutput = `${{ steps.lint.outputs.output }}`; + const typecheckOutput = `${{ steps.typecheck.outputs.output }}`; + const buildOutput = `${{ steps.build.outputs.output }}`; + + let comment = '## ⚛️ Frontend Checks (Advisory)\n\n'; + comment += '### Linting\n'; + comment += lintStatus + '\n'; + if (lintOutput) { + comment += '\n```\n' + lintOutput.substring(0, 500) + '\n```\n'; + } + comment += '\n### Type Checking\n'; + comment += typecheckStatus + '\n'; + if (typecheckOutput) { + comment += '\n```\n' + typecheckOutput.substring(0, 500) + '\n```\n'; + } + comment += '\n### Build\n'; + comment += buildStatus + '\n'; + if (buildOutput) { + comment += '\n```\n' + buildOutput.substring(0, 500) + '\n```\n'; + } + comment += '\n---\n\n'; + comment += '💡 **To fix locally:**\n'; + comment += '```bash\n'; + comment += 'cd web\n\n'; + comment += '# Fix linting issues\n'; + comment += 'npm run lint -- --fix\n\n'; + comment += '# Check types\n'; + comment += 'npm run type-check\n\n'; + comment += '# Test build\n'; + comment += 'npm run build\n'; + comment += '```\n\n'; + comment += '*These checks are advisory and won\'t block merging. Need help? Just ask!*'; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml new file mode 100644 index 00000000..a3141835 --- /dev/null +++ b/.github/workflows/pr-checks.yml @@ -0,0 +1,237 @@ +name: PR Checks + +on: + pull_request: + types: [opened, synchronize, reopened, edited] + branches: + - dev + - main + +jobs: + # Validate PR title and description + validate-pr: + name: Validate PR Format + runs-on: ubuntu-latest + steps: + - name: Check PR title format + uses: amannn/action-semantic-pull-request@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + types: | + feat + fix + docs + style + refactor + perf + test + chore + ci + security + scopes: | + exchange + trader + ai + api + ui + frontend + backend + security + deps + requireScope: false + + - name: Check PR size + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + const additions = pr.additions; + const deletions = pr.deletions; + const total = additions + deletions; + + let label = ''; + let comment = ''; + + if (total < 300) { + label = 'size: small'; + comment = '✅ This PR is **small** and easy to review!'; + } else if (total < 1000) { + label = 'size: medium'; + comment = '⚠️ This PR is **medium** sized. Consider breaking it into smaller PRs if possible.'; + } else { + label = 'size: large'; + comment = '🚨 This PR is **large** (>' + total + ' lines changed). Please consider breaking it into smaller, focused PRs for easier review.'; + } + + // Add size label + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + labels: [label] + }); + + // Add comment for large PRs + if (total >= 1000) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: comment + }); + } + + # Backend tests + backend-tests: + name: Backend Tests (Go) + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.21' + + - name: Install TA-Lib + run: | + sudo apt-get update + sudo apt-get install -y libta-lib-dev + + - name: Cache Go modules + uses: actions/cache@v4 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Download dependencies + run: go mod download + + - name: Run go fmt + run: | + if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then + echo "Please run 'go fmt' on your code" + gofmt -s -l . + exit 1 + fi + + - name: Run go vet + run: go vet ./... + + - name: Run tests + run: go test -v -race -coverprofile=coverage.out ./... + + - name: Build + run: go build -v -o nofx + + - name: Upload coverage + uses: codecov/codecov-action@v4 + with: + file: ./coverage.out + flags: backend + + # Frontend tests + frontend-tests: + name: Frontend Tests (React/TypeScript) + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Cache Node modules + uses: actions/cache@v4 + with: + path: web/node_modules + key: ${{ runner.os }}-node-${{ hashFiles('web/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Install dependencies + working-directory: ./web + run: npm ci + + - name: Run linter + working-directory: ./web + run: npm run lint + + - name: Run type check + working-directory: ./web + run: npm run type-check || true # Don't fail on type errors for now + + - name: Build + working-directory: ./web + run: npm run build + + # Auto-label based on files changed + auto-label: + name: Auto Label PR + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: actions/labeler@v5 + with: + configuration-path: .github/labeler.yml + repo-token: ${{ secrets.GITHUB_TOKEN }} + + # Check for security issues + security-check: + name: Security Scan + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + scan-type: 'fs' + scan-ref: '.' + format: 'sarif' + output: 'trivy-results.sarif' + + - name: Upload Trivy results + uses: github/codeql-action/upload-sarif@v3 + if: always() + with: + sarif_file: 'trivy-results.sarif' + + # Check for secrets in code + secrets-check: + name: Check for Secrets + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Run Gitleaks + uses: gitleaks/gitleaks-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # All checks passed + all-checks: + name: All Checks Passed + runs-on: ubuntu-latest + needs: [validate-pr, backend-tests, frontend-tests, security-check, secrets-check] + if: always() + steps: + - name: Check all jobs + run: | + if [ "${{ contains(needs.*.result, 'failure') }}" == "true" ]; then + echo "Some checks failed" + exit 1 + else + echo "All checks passed!" + fi diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..31fc7c02 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,481 @@ +# 🤝 Contributing to NOFX + +**Language:** [English](CONTRIBUTING.md) | [中文](docs/i18n/zh-CN/CONTRIBUTING.md) + +Thank you for your interest in contributing to NOFX! This document provides guidelines and workflows for contributing to the project. + +--- + +## 📑 Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [How Can I Contribute?](#how-can-i-contribute) +- [Development Workflow](#development-workflow) +- [PR Submission Guidelines](#pr-submission-guidelines) +- [Coding Standards](#coding-standards) +- [Commit Message Guidelines](#commit-message-guidelines) +- [Review Process](#review-process) +- [Bounty Program](#bounty-program) + +--- + +## 📜 Code of Conduct + +This project adheres to the [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. + +--- + +## 🎯 How Can I Contribute? + +### 1. Report Bugs 🐛 + +- Use the [Bug Report Template](.github/ISSUE_TEMPLATE/bug_report.md) +- Check if the bug has already been reported +- Include detailed reproduction steps +- Provide environment information (OS, Go version, etc.) + +### 2. Suggest Features ✨ + +- Use the [Feature Request Template](.github/ISSUE_TEMPLATE/feature_request.md) +- Explain the use case and benefits +- Check if it aligns with the [project roadmap](docs/roadmap/README.md) + +### 3. Submit Pull Requests 🔧 + +Before submitting a PR, please check the following: + +#### ✅ **Accepted Contributions** + +**High Priority** (aligned with roadmap): +- 🔒 Security enhancements (encryption, authentication, RBAC) +- 🧠 AI model integrations (GPT-4, Claude, Gemini Pro) +- 🔗 Exchange integrations (OKX, Bybit, Lighter, EdgeX) +- 📊 Trading data APIs (AI500, OI analysis, NetFlow) +- 🎨 UI/UX improvements (mobile responsiveness, charts) +- ⚡ Performance optimizations +- 🐛 Bug fixes +- 📝 Documentation improvements + +**Medium Priority:** +- ✅ Test coverage improvements +- 🌐 Internationalization (new language support) +- 🔧 Build/deployment tooling +- 📈 Monitoring and logging enhancements + +#### ❌ **Not Accepted** (without prior discussion) + +- Major architectural changes without RFC (Request for Comments) +- Features not aligned with project roadmap +- Breaking changes without migration path +- Code that introduces new dependencies without justification +- Experimental features without opt-in flag + +**⚠️ Important:** For major features, please open an issue for discussion **before** starting work. + +--- + +## 🛠️ Development Workflow + +### 1. Fork and Clone + +```bash +# Fork the repository on GitHub +# Then clone your fork +git clone https://github.com/YOUR_USERNAME/nofx.git +cd nofx + +# Add upstream remote +git remote add upstream https://github.com/tinkle-community/nofx.git +``` + +### 2. Create a Feature Branch + +```bash +# Update your local dev branch +git checkout dev +git pull upstream dev + +# Create a new branch +git checkout -b feature/your-feature-name +# or +git checkout -b fix/your-bug-fix +``` + +**Branch Naming Convention:** +- `feature/` - New features +- `fix/` - Bug fixes +- `docs/` - Documentation updates +- `refactor/` - Code refactoring +- `perf/` - Performance improvements +- `test/` - Test updates +- `chore/` - Build/config changes + +### 3. Set Up Development Environment + +```bash +# Install Go dependencies +go mod download + +# Install frontend dependencies +cd web +npm install +cd .. + +# Install TA-Lib (required) +# macOS: +brew install ta-lib + +# Ubuntu/Debian: +sudo apt-get install libta-lib0-dev +``` + +### 4. Make Your Changes + +- Follow the [coding standards](#coding-standards) +- Write tests for new features +- Update documentation as needed +- Keep commits focused and atomic + +### 5. Test Your Changes + +```bash +# Run backend tests +go test ./... + +# Build backend +go build -o nofx + +# Run frontend in dev mode +cd web +npm run dev + +# Build frontend +npm run build +``` + +### 6. Commit Your Changes + +Follow the [commit message guidelines](#commit-message-guidelines): + +```bash +git add . +git commit -m "feat: add support for OKX exchange integration" +``` + +### 7. Push and Create PR + +```bash +# Push to your fork +git push origin feature/your-feature-name + +# Go to GitHub and create a Pull Request +# Use the PR template and fill in all sections +``` + +--- + +## 📝 PR Submission Guidelines + +### Before Submitting + +- [ ] Code compiles successfully (`go build` and `npm run build`) +- [ ] All tests pass (`go test ./...`) +- [ ] No linting errors (`go fmt`, `go vet`) +- [ ] Documentation is updated +- [ ] Commits follow conventional commits format +- [ ] Branch is rebased on latest `dev` + +### PR Title Format + +Use [Conventional Commits](https://www.conventionalcommits.org/) format: + +``` +(): + +Examples: +feat(exchange): add OKX exchange integration +fix(trader): resolve position tracking bug +docs(readme): update installation instructions +perf(ai): optimize prompt generation +refactor(core): extract common exchange interface +``` + +**Types:** +- `feat` - New feature +- `fix` - Bug fix +- `docs` - Documentation +- `style` - Code style (formatting, no logic change) +- `refactor` - Code refactoring +- `perf` - Performance improvement +- `test` - Test updates +- `chore` - Build/config changes +- `ci` - CI/CD changes +- `security` - Security improvements + +### PR Description + +Use the [PR template](.github/PULL_REQUEST_TEMPLATE.md) and ensure: + +1. **Clear description** of what and why +2. **Type of change** is marked +3. **Related issues** are linked +4. **Testing steps** are documented +5. **Screenshots** for UI changes +6. **All checkboxes** are completed + +### PR Size + +Keep PRs focused and reasonably sized: + +- ✅ **Small PR** (< 300 lines): Ideal, fast review +- ⚠️ **Medium PR** (300-1000 lines): Acceptable, may take longer +- ❌ **Large PR** (> 1000 lines): Please break into smaller PRs + +--- + +## 💻 Coding Standards + +### Go Code + +```go +// ✅ Good: Clear naming, proper error handling +func ConnectToExchange(apiKey, secret string) (*Exchange, error) { + if apiKey == "" || secret == "" { + return nil, fmt.Errorf("API credentials are required") + } + + client, err := createClient(apiKey, secret) + if err != nil { + return nil, fmt.Errorf("failed to create client: %w", err) + } + + return &Exchange{client: client}, nil +} + +// ❌ Bad: Poor naming, no error handling +func ce(a, s string) *Exchange { + c := createClient(a, s) + return &Exchange{client: c} +} +``` + +**Best Practices:** +- Use meaningful variable names +- Handle all errors explicitly +- Add comments for complex logic +- Follow Go idioms and conventions +- Run `go fmt` before committing +- Use `go vet` and `golangci-lint` + +### TypeScript/React Code + +```typescript +// ✅ Good: Type-safe, clear naming +interface TraderConfig { + id: string; + exchange: 'binance' | 'hyperliquid' | 'aster'; + aiModel: string; + enabled: boolean; +} + +const TraderCard: React.FC<{ trader: TraderConfig }> = ({ trader }) => { + const [isRunning, setIsRunning] = useState(false); + + const handleStart = async () => { + try { + await startTrader(trader.id); + setIsRunning(true); + } catch (error) { + console.error('Failed to start trader:', error); + } + }; + + return
...
; +}; + +// ❌ Bad: No types, unclear naming +const TC = (props) => { + const [r, setR] = useState(false); + const h = () => { startTrader(props.t.id); setR(true); }; + return
...
; +}; +``` + +**Best Practices:** +- Use TypeScript strict mode +- Define interfaces for all data structures +- Avoid `any` type +- Use functional components with hooks +- Follow React best practices +- Run `npm run lint` before committing + +### File Structure + +``` +NOFX/ +├── cmd/ # Main applications +├── internal/ # Private code +│ ├── exchange/ # Exchange adapters +│ ├── trader/ # Trading logic +│ ├── ai/ # AI integrations +│ └── api/ # API handlers +├── pkg/ # Public libraries +├── web/ # Frontend +│ ├── src/ +│ │ ├── components/ +│ │ ├── pages/ +│ │ ├── hooks/ +│ │ └── utils/ +│ └── public/ +└── docs/ # Documentation +``` + +--- + +## 📋 Commit Message Guidelines + +### Format + +``` +(): + + + +