feat: comprehensive FAQ rewrite with navigation fix

- Add HeaderBar to FAQ page for proper navigation
- Rewrite FAQ with 9 categories and ~50 Q&A items
- Add EN/ZH translations for all FAQ content
- Remove China-specific references
- Update AI model names (GPT-5.2)
- Update description to include crypto and US stock markets
This commit is contained in:
tinkle-community
2025-12-14 23:12:09 +08:00
parent da1d905a31
commit f901f954d9
3 changed files with 896 additions and 527 deletions

View File

@@ -59,18 +59,26 @@ function getModelDisplayName(modelId: string): string {
} }
// Helper function to get exchange display name from exchange ID (UUID) // Helper function to get exchange display name from exchange ID (UUID)
function getExchangeDisplayNameFromList(exchangeId: string | undefined, exchanges: Exchange[] | undefined): string { function getExchangeDisplayNameFromList(
exchangeId: string | undefined,
exchanges: Exchange[] | undefined
): string {
if (!exchangeId) return 'Unknown' if (!exchangeId) return 'Unknown'
const exchange = exchanges?.find(e => e.id === exchangeId) const exchange = exchanges?.find((e) => e.id === exchangeId)
if (!exchange) return exchangeId.substring(0, 8).toUpperCase() + '...' if (!exchange) return exchangeId.substring(0, 8).toUpperCase() + '...'
const typeName = exchange.exchange_type?.toUpperCase() || exchange.name const typeName = exchange.exchange_type?.toUpperCase() || exchange.name
return exchange.account_name ? `${typeName} - ${exchange.account_name}` : typeName return exchange.account_name
? `${typeName} - ${exchange.account_name}`
: typeName
} }
// Helper function to get exchange type from exchange ID (UUID) - for TradingView charts // Helper function to get exchange type from exchange ID (UUID) - for TradingView charts
function getExchangeTypeFromList(exchangeId: string | undefined, exchanges: Exchange[] | undefined): string { function getExchangeTypeFromList(
exchangeId: string | undefined,
exchanges: Exchange[] | undefined
): string {
if (!exchangeId) return 'BINANCE' if (!exchangeId) return 'BINANCE'
const exchange = exchanges?.find(e => e.id === exchangeId) const exchange = exchanges?.find((e) => e.id === exchangeId)
if (!exchange) return 'BINANCE' // Default to BINANCE for charts if (!exchange) return 'BINANCE' // Default to BINANCE for charts
return exchange.exchange_type?.toUpperCase() || 'BINANCE' return exchange.exchange_type?.toUpperCase() || 'BINANCE'
} }
@@ -288,7 +296,52 @@ function App() {
return <RegisterPage /> return <RegisterPage />
} }
if (route === '/faq') { if (route === '/faq') {
return <FAQPage /> return (
<div
className="min-h-screen"
style={{ background: '#0B0E11', color: '#EAECEF' }}
>
<HeaderBar
isLoggedIn={!!user}
currentPage="faq"
language={language}
onLanguageChange={setLanguage}
user={user}
onLogout={logout}
onPageChange={(page: Page) => {
if (page === 'competition') {
window.history.pushState({}, '', '/competition')
setRoute('/competition')
setCurrentPage('competition')
} else if (page === 'traders') {
window.history.pushState({}, '', '/traders')
setRoute('/traders')
setCurrentPage('traders')
} else if (page === 'trader') {
window.history.pushState({}, '', '/dashboard')
setRoute('/dashboard')
setCurrentPage('trader')
} else if (page === 'faq') {
window.history.pushState({}, '', '/faq')
setRoute('/faq')
} else if (page === 'backtest') {
window.history.pushState({}, '', '/backtest')
setRoute('/backtest')
setCurrentPage('backtest')
} else if (page === 'strategy') {
window.history.pushState({}, '', '/strategy')
setRoute('/strategy')
setCurrentPage('strategy')
} else if (page === 'debate') {
window.history.pushState({}, '', '/debate')
setRoute('/debate')
setCurrentPage('debate')
}
}}
/>
<FAQPage />
</div>
)
} }
if (route === '/reset-password') { if (route === '/reset-password') {
return <ResetPasswordPage /> return <ResetPasswordPage />
@@ -453,7 +506,13 @@ function App() {
/> />
{/* Main Content */} {/* Main Content */}
<main className={currentPage === 'debate' ? 'h-[calc(100vh-64px)] mt-16' : 'max-w-[1920px] mx-auto px-6 py-6 pt-24'}> <main
className={
currentPage === 'debate'
? 'h-[calc(100vh-64px)] mt-16'
: 'max-w-[1920px] mx-auto px-6 py-6 pt-24'
}
>
{currentPage === 'competition' ? ( {currentPage === 'competition' ? (
<CompetitionPage /> <CompetitionPage />
) : currentPage === 'traders' ? ( ) : currentPage === 'traders' ? (
@@ -498,7 +557,8 @@ function App() {
</main> </main>
{/* Footer - Hidden on debate page */} {/* Footer - Hidden on debate page */}
{currentPage !== 'debate' && <footer {currentPage !== 'debate' && (
<footer
className="mt-16" className="mt-16"
style={{ borderTop: '1px solid #2B3139', background: '#181A20' }} style={{ borderTop: '1px solid #2B3139', background: '#181A20' }}
> >
@@ -531,7 +591,12 @@ function App() {
e.currentTarget.style.borderColor = '#2B3139' e.currentTarget.style.borderColor = '#2B3139'
}} }}
> >
<svg width="18" height="18" viewBox="0 0 16 16" fill="currentColor"> <svg
width="18"
height="18"
viewBox="0 0 16 16"
fill="currentColor"
>
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" /> <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z" />
</svg> </svg>
GitHub GitHub
@@ -558,7 +623,12 @@ function App() {
e.currentTarget.style.borderColor = '#2B3139' e.currentTarget.style.borderColor = '#2B3139'
}} }}
> >
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"> <svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" /> <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
</svg> </svg>
Twitter Twitter
@@ -585,14 +655,20 @@ function App() {
e.currentTarget.style.borderColor = '#2B3139' e.currentTarget.style.borderColor = '#2B3139'
}} }}
> >
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"> <svg
width="16"
height="16"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z" /> <path d="M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z" />
</svg> </svg>
Telegram Telegram
</a> </a>
</div> </div>
</div> </div>
</footer>} </footer>
)}
</div> </div>
) )
} }
@@ -633,7 +709,9 @@ function TraderDetailsPage({
exchanges?: Exchange[] exchanges?: Exchange[]
}) { }) {
const [closingPosition, setClosingPosition] = useState<string | null>(null) const [closingPosition, setClosingPosition] = useState<string | null>(null)
const [selectedChartSymbol, setSelectedChartSymbol] = useState<string | undefined>(undefined) const [selectedChartSymbol, setSelectedChartSymbol] = useState<
string | undefined
>(undefined)
const [chartUpdateKey, setChartUpdateKey] = useState<number>(0) const [chartUpdateKey, setChartUpdateKey] = useState<number>(0)
const chartSectionRef = useRef<HTMLDivElement>(null) const chartSectionRef = useRef<HTMLDivElement>(null)
@@ -641,7 +719,8 @@ function TraderDetailsPage({
const handleClosePosition = async (symbol: string, side: string) => { const handleClosePosition = async (symbol: string, side: string) => {
if (!selectedTraderId) return if (!selectedTraderId) return
const confirmMsg = language === 'zh' const confirmMsg =
language === 'zh'
? `确定要平仓 ${symbol} ${side === 'LONG' ? '多仓' : '空仓'} 吗?` ? `确定要平仓 ${symbol} ${side === 'LONG' ? '多仓' : '空仓'} 吗?`
: `Are you sure you want to close ${symbol} ${side === 'LONG' ? 'LONG' : 'SHORT'} position?` : `Are you sure you want to close ${symbol} ${side === 'LONG' ? 'LONG' : 'SHORT'} position?`
@@ -656,14 +735,21 @@ function TraderDetailsPage({
setClosingPosition(symbol) setClosingPosition(symbol)
try { try {
await api.closePosition(selectedTraderId, symbol, side) await api.closePosition(selectedTraderId, symbol, side)
notify.success(language === 'zh' ? '平仓成功' : 'Position closed successfully') notify.success(
language === 'zh' ? '平仓成功' : 'Position closed successfully'
)
// 使用 SWR mutate 刷新数据而非重新加载页面 // 使用 SWR mutate 刷新数据而非重新加载页面
await Promise.all([ await Promise.all([
mutate(`positions-${selectedTraderId}`), mutate(`positions-${selectedTraderId}`),
mutate(`account-${selectedTraderId}`), mutate(`account-${selectedTraderId}`),
]) ])
} catch (err: unknown) { } catch (err: unknown) {
const errorMsg = err instanceof Error ? err.message : (language === 'zh' ? '平仓失败' : 'Failed to close position') const errorMsg =
err instanceof Error
? err.message
: language === 'zh'
? '平仓失败'
: 'Failed to close position'
notify.error(errorMsg) notify.error(errorMsg)
} finally { } finally {
setClosingPosition(null) setClosingPosition(null)
@@ -828,7 +914,10 @@ function TraderDetailsPage({
style={{ color: '#EAECEF' }} style={{ color: '#EAECEF' }}
> >
<PunkAvatar <PunkAvatar
seed={getTraderAvatar(selectedTrader.trader_id, selectedTrader.trader_name)} seed={getTraderAvatar(
selectedTrader.trader_id,
selectedTrader.trader_name
)}
size={48} size={48}
className="rounded-lg" className="rounded-lg"
/> />
@@ -884,7 +973,10 @@ function TraderDetailsPage({
<span> <span>
Exchange:{' '} Exchange:{' '}
<span className="font-semibold" style={{ color: '#EAECEF' }}> <span className="font-semibold" style={{ color: '#EAECEF' }}>
{getExchangeDisplayNameFromList(selectedTrader.exchange_id, exchanges)} {getExchangeDisplayNameFromList(
selectedTrader.exchange_id,
exchanges
)}
</span> </span>
</span> </span>
<span></span> <span></span>
@@ -961,7 +1053,10 @@ function TraderDetailsPage({
traderId={selectedTrader.trader_id} traderId={selectedTrader.trader_id}
selectedSymbol={selectedChartSymbol} selectedSymbol={selectedChartSymbol}
updateKey={chartUpdateKey} updateKey={chartUpdateKey}
exchangeId={getExchangeTypeFromList(selectedTrader.exchange_id, exchanges)} exchangeId={getExchangeTypeFromList(
selectedTrader.exchange_id,
exchanges
)}
/> />
</div> </div>
@@ -1004,25 +1099,46 @@ function TraderDetailsPage({
<th className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-center"> <th className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-center">
{language === 'zh' ? '操作' : 'Action'} {language === 'zh' ? '操作' : 'Action'}
</th> </th>
<th className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right" title={t('entryPrice', language)}> <th
className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right"
title={t('entryPrice', language)}
>
{language === 'zh' ? '入场价' : 'Entry'} {language === 'zh' ? '入场价' : 'Entry'}
</th> </th>
<th className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right" title={t('markPrice', language)}> <th
className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right"
title={t('markPrice', language)}
>
{language === 'zh' ? '标记价' : 'Mark'} {language === 'zh' ? '标记价' : 'Mark'}
</th> </th>
<th className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right" title={t('quantity', language)}> <th
className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right"
title={t('quantity', language)}
>
{language === 'zh' ? '数量' : 'Qty'} {language === 'zh' ? '数量' : 'Qty'}
</th> </th>
<th className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right" title={t('positionValue', language)}> <th
className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right"
title={t('positionValue', language)}
>
{language === 'zh' ? '价值' : 'Value'} {language === 'zh' ? '价值' : 'Value'}
</th> </th>
<th className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-center" title={t('leverage', language)}> <th
className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-center"
title={t('leverage', language)}
>
{language === 'zh' ? '杠杆' : 'Lev.'} {language === 'zh' ? '杠杆' : 'Lev.'}
</th> </th>
<th className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right" title={t('unrealizedPnL', language)}> <th
className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right"
title={t('unrealizedPnL', language)}
>
{language === 'zh' ? '未实现盈亏' : 'uPnL'} {language === 'zh' ? '未实现盈亏' : 'uPnL'}
</th> </th>
<th className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right" title={t('liqPrice', language)}> <th
className="px-1 pb-3 font-semibold text-gray-400 whitespace-nowrap text-right"
title={t('liqPrice', language)}
>
{language === 'zh' ? '强平价' : 'Liq.'} {language === 'zh' ? '强平价' : 'Liq.'}
</th> </th>
</tr> </tr>
@@ -1037,7 +1153,10 @@ function TraderDetailsPage({
setChartUpdateKey(Date.now()) setChartUpdateKey(Date.now())
// Smooth scroll to chart with ref // Smooth scroll to chart with ref
if (chartSectionRef.current) { if (chartSectionRef.current) {
chartSectionRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' }) chartSectionRef.current.scrollIntoView({
behavior: 'smooth',
block: 'start',
})
} }
}} }}
> >
@@ -1069,12 +1188,17 @@ function TraderDetailsPage({
<button <button
type="button" type="button"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); // Prevent row click e.stopPropagation() // Prevent row click
handleClosePosition(pos.symbol, pos.side.toUpperCase()) handleClosePosition(
pos.symbol,
pos.side.toUpperCase()
)
}} }}
disabled={closingPosition === pos.symbol} disabled={closingPosition === pos.symbol}
className="btn-danger inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-semibold transition-all hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed mx-auto" className="btn-danger inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-semibold transition-all hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed mx-auto"
title={language === 'zh' ? '平仓' : 'Close Position'} title={
language === 'zh' ? '平仓' : 'Close Position'
}
> >
{closingPosition === pos.symbol ? ( {closingPosition === pos.symbol ? (
<Loader2 className="w-3 h-3 animate-spin" /> <Loader2 className="w-3 h-3 animate-spin" />
@@ -1227,7 +1351,6 @@ function TraderDetailsPage({
</div> </div>
{/* 右侧结束 */} {/* 右侧结束 */}
</div> </div>
</div> </div>
) )
} }

View File

@@ -4,7 +4,9 @@ import {
TrendingUp, TrendingUp,
Wrench, Wrench,
Bot, Bot,
Database, Shield,
Monitor,
Zap,
GitBranch, GitBranch,
} from 'lucide-react' } from 'lucide-react'
import type { LucideIcon } from 'lucide-react' import type { LucideIcon } from 'lucide-react'
@@ -23,17 +25,24 @@ export interface FAQCategory {
} }
/** /**
* FAQ 数据配置 * FAQ Data Configuration
* - titleKey: 分类标题的翻译键 * Comprehensive FAQ covering all aspects of NOFX
* - questionKey: 问题的翻译键
* - answerKey: 答案的翻译键
* *
* 所有文本内容都通过翻译键从 i18n/translations.ts 获取 * Categories:
* 1. Getting Started - Basic concepts and overview
* 2. Installation - Setup methods and requirements
* 3. Configuration - AI models, exchanges, strategies
* 4. Trading - How trading works, common issues
* 5. Technical Issues - Troubleshooting common problems
* 6. Security - API keys, encryption, best practices
* 7. Features - Strategy Studio, Backtest, Debate Arena
* 8. Contributing - How to contribute to the project
*/ */
export const faqCategories: FAQCategory[] = [ export const faqCategories: FAQCategory[] = [
// ===== 1. GETTING STARTED =====
{ {
id: 'basics', id: 'getting-started',
titleKey: 'faqCategoryBasics', titleKey: 'faqCategoryGettingStarted',
icon: BookOpen, icon: BookOpen,
items: [ items: [
{ {
@@ -41,64 +50,49 @@ export const faqCategories: FAQCategory[] = [
questionKey: 'faqWhatIsNOFX', questionKey: 'faqWhatIsNOFX',
answerKey: 'faqWhatIsNOFXAnswer', answerKey: 'faqWhatIsNOFXAnswer',
}, },
{
id: 'how-does-it-work',
questionKey: 'faqHowDoesItWork',
answerKey: 'faqHowDoesItWorkAnswer',
},
{
id: 'is-it-profitable',
questionKey: 'faqIsProfitable',
answerKey: 'faqIsProfitableAnswer',
},
{ {
id: 'supported-exchanges', id: 'supported-exchanges',
questionKey: 'faqSupportedExchanges', questionKey: 'faqSupportedExchanges',
answerKey: 'faqSupportedExchangesAnswer', answerKey: 'faqSupportedExchangesAnswer',
}, },
{ {
id: 'is-profitable', id: 'supported-ai-models',
questionKey: 'faqIsProfitable', questionKey: 'faqSupportedAIModels',
answerKey: 'faqIsProfitableAnswer', answerKey: 'faqSupportedAIModelsAnswer',
}, },
{
id: 'multiple-traders',
questionKey: 'faqMultipleTraders',
answerKey: 'faqMultipleTradersAnswer',
},
],
},
{
id: 'contributing',
titleKey: 'faqCategoryContributing',
icon: GitBranch,
items: [
{
id: 'github-projects-tasks',
questionKey: 'faqGithubProjectsTasks',
answerKey: 'faqGithubProjectsTasksAnswer',
},
{
id: 'contribute-pr-guidelines',
questionKey: 'faqContributePR',
answerKey: 'faqContributePRAnswer',
},
],
},
{
id: 'setup',
titleKey: 'faqCategorySetup',
icon: Settings,
items: [
{ {
id: 'system-requirements', id: 'system-requirements',
questionKey: 'faqSystemRequirements', questionKey: 'faqSystemRequirements',
answerKey: 'faqSystemRequirementsAnswer', answerKey: 'faqSystemRequirementsAnswer',
}, },
],
},
// ===== 2. INSTALLATION =====
{ {
id: 'need-coding', id: 'installation',
questionKey: 'faqNeedCoding', titleKey: 'faqCategoryInstallation',
answerKey: 'faqNeedCodingAnswer', icon: Settings,
items: [
{
id: 'how-to-install',
questionKey: 'faqHowToInstall',
answerKey: 'faqHowToInstallAnswer',
}, },
{ {
id: 'get-api-keys', id: 'windows-installation',
questionKey: 'faqGetApiKeys', questionKey: 'faqWindowsInstallation',
answerKey: 'faqGetApiKeysAnswer', answerKey: 'faqWindowsInstallationAnswer',
},
{
id: 'use-subaccount',
questionKey: 'faqUseSubaccount',
answerKey: 'faqUseSubaccountAnswer',
}, },
{ {
id: 'docker-deployment', id: 'docker-deployment',
@@ -106,26 +100,72 @@ export const faqCategories: FAQCategory[] = [
answerKey: 'faqDockerDeploymentAnswer', answerKey: 'faqDockerDeploymentAnswer',
}, },
{ {
id: 'balance-shows-zero', id: 'manual-installation',
questionKey: 'faqBalanceZero', questionKey: 'faqManualInstallation',
answerKey: 'faqBalanceZeroAnswer', answerKey: 'faqManualInstallationAnswer',
}, },
{ {
id: 'testnet-issues', id: 'server-deployment',
questionKey: 'faqTestnet', questionKey: 'faqServerDeployment',
answerKey: 'faqTestnetAnswer', answerKey: 'faqServerDeploymentAnswer',
},
{
id: 'update-nofx',
questionKey: 'faqUpdateNOFX',
answerKey: 'faqUpdateNOFXAnswer',
}, },
], ],
}, },
// ===== 3. CONFIGURATION =====
{
id: 'configuration',
titleKey: 'faqCategoryConfiguration',
icon: Zap,
items: [
{
id: 'configure-ai-models',
questionKey: 'faqConfigureAIModels',
answerKey: 'faqConfigureAIModelsAnswer',
},
{
id: 'configure-exchanges',
questionKey: 'faqConfigureExchanges',
answerKey: 'faqConfigureExchangesAnswer',
},
{
id: 'binance-api-setup',
questionKey: 'faqBinanceAPISetup',
answerKey: 'faqBinanceAPISetupAnswer',
},
{
id: 'hyperliquid-setup',
questionKey: 'faqHyperliquidSetup',
answerKey: 'faqHyperliquidSetupAnswer',
},
{
id: 'create-strategy',
questionKey: 'faqCreateStrategy',
answerKey: 'faqCreateStrategyAnswer',
},
{
id: 'create-trader',
questionKey: 'faqCreateTrader',
answerKey: 'faqCreateTraderAnswer',
},
],
},
// ===== 4. TRADING =====
{ {
id: 'trading', id: 'trading',
titleKey: 'faqCategoryTrading', titleKey: 'faqCategoryTrading',
icon: TrendingUp, icon: TrendingUp,
items: [ items: [
{ {
id: 'no-trades', id: 'how-ai-decides',
questionKey: 'faqNoTrades', questionKey: 'faqHowAIDecides',
answerKey: 'faqNoTradesAnswer', answerKey: 'faqHowAIDecidesAnswer',
}, },
{ {
id: 'decision-frequency', id: 'decision-frequency',
@@ -133,56 +173,53 @@ export const faqCategories: FAQCategory[] = [
answerKey: 'faqDecisionFrequencyAnswer', answerKey: 'faqDecisionFrequencyAnswer',
}, },
{ {
id: 'custom-strategy', id: 'no-trades-executing',
questionKey: 'faqCustomStrategy', questionKey: 'faqNoTradesExecuting',
answerKey: 'faqCustomStrategyAnswer', answerKey: 'faqNoTradesExecutingAnswer',
}, },
{ {
id: 'max-positions', id: 'only-short-positions',
questionKey: 'faqMaxPositions', questionKey: 'faqOnlyShortPositions',
answerKey: 'faqMaxPositionsAnswer', answerKey: 'faqOnlyShortPositionsAnswer',
}, },
{ {
id: 'margin-insufficient', id: 'leverage-settings',
questionKey: 'faqMarginInsufficient', questionKey: 'faqLeverageSettings',
answerKey: 'faqMarginInsufficientAnswer', answerKey: 'faqLeverageSettingsAnswer',
}, },
{ {
id: 'high-fees', id: 'stop-loss-take-profit',
questionKey: 'faqHighFees', questionKey: 'faqStopLossTakeProfit',
answerKey: 'faqHighFeesAnswer', answerKey: 'faqStopLossTakeProfitAnswer',
}, },
{ {
id: 'no-take-profit', id: 'multiple-traders',
questionKey: 'faqNoTakeProfit', questionKey: 'faqMultipleTraders',
answerKey: 'faqNoTakeProfitAnswer', answerKey: 'faqMultipleTradersAnswer',
},
{
id: 'ai-costs',
questionKey: 'faqAICosts',
answerKey: 'faqAICostsAnswer',
}, },
], ],
}, },
// ===== 5. TECHNICAL ISSUES =====
{ {
id: 'technical', id: 'technical-issues',
titleKey: 'faqCategoryTechnical', titleKey: 'faqCategoryTechnicalIssues',
icon: Wrench, icon: Wrench,
items: [ items: [
{
id: 'binance-api-failed',
questionKey: 'faqBinanceApiFailed',
answerKey: 'faqBinanceApiFailedAnswer',
},
{
id: 'binance-position-mode',
questionKey: 'faqBinancePositionMode',
answerKey: 'faqBinancePositionModeAnswer',
},
{ {
id: 'port-in-use', id: 'port-in-use',
questionKey: 'faqPortInUse', questionKey: 'faqPortInUse',
answerKey: 'faqPortInUseAnswer', answerKey: 'faqPortInUseAnswer',
}, },
{ {
id: 'frontend-loading', id: 'frontend-not-loading',
questionKey: 'faqFrontendLoading', questionKey: 'faqFrontendNotLoading',
answerKey: 'faqFrontendLoadingAnswer', answerKey: 'faqFrontendNotLoadingAnswer',
}, },
{ {
id: 'database-locked', id: 'database-locked',
@@ -190,78 +227,150 @@ export const faqCategories: FAQCategory[] = [
answerKey: 'faqDatabaseLockedAnswer', answerKey: 'faqDatabaseLockedAnswer',
}, },
{ {
id: 'ai-learning-failed', id: 'talib-not-found',
questionKey: 'faqAiLearningFailed', questionKey: 'faqTALibNotFound',
answerKey: 'faqAiLearningFailedAnswer', answerKey: 'faqTALibNotFoundAnswer',
}, },
{ {
id: 'config-not-effective', id: 'ai-api-timeout',
questionKey: 'faqConfigNotEffective', questionKey: 'faqAIAPITimeout',
answerKey: 'faqConfigNotEffectiveAnswer', answerKey: 'faqAIAPITimeoutAnswer',
},
{
id: 'binance-position-mode',
questionKey: 'faqBinancePositionMode',
answerKey: 'faqBinancePositionModeAnswer',
},
{
id: 'balance-shows-zero',
questionKey: 'faqBalanceShowsZero',
answerKey: 'faqBalanceShowsZeroAnswer',
},
{
id: 'docker-pull-failed',
questionKey: 'faqDockerPullFailed',
answerKey: 'faqDockerPullFailedAnswer',
}, },
], ],
}, },
// ===== 6. SECURITY =====
{ {
id: 'ai', id: 'security',
titleKey: 'faqCategoryAI', titleKey: 'faqCategorySecurity',
icon: Shield,
items: [
{
id: 'api-key-storage',
questionKey: 'faqAPIKeyStorage',
answerKey: 'faqAPIKeyStorageAnswer',
},
{
id: 'encryption-details',
questionKey: 'faqEncryptionDetails',
answerKey: 'faqEncryptionDetailsAnswer',
},
{
id: 'security-best-practices',
questionKey: 'faqSecurityBestPractices',
answerKey: 'faqSecurityBestPracticesAnswer',
},
{
id: 'can-nofx-steal-funds',
questionKey: 'faqCanNOFXStealFunds',
answerKey: 'faqCanNOFXStealFundsAnswer',
},
],
},
// ===== 7. FEATURES =====
{
id: 'features',
titleKey: 'faqCategoryFeatures',
icon: Monitor,
items: [
{
id: 'strategy-studio',
questionKey: 'faqStrategyStudio',
answerKey: 'faqStrategyStudioAnswer',
},
{
id: 'backtest-lab',
questionKey: 'faqBacktestLab',
answerKey: 'faqBacktestLabAnswer',
},
{
id: 'debate-arena',
questionKey: 'faqDebateArena',
answerKey: 'faqDebateArenaAnswer',
},
{
id: 'competition-mode',
questionKey: 'faqCompetitionMode',
answerKey: 'faqCompetitionModeAnswer',
},
{
id: 'chain-of-thought',
questionKey: 'faqChainOfThought',
answerKey: 'faqChainOfThoughtAnswer',
},
],
},
// ===== 8. AI MODELS =====
{
id: 'ai-models',
titleKey: 'faqCategoryAIModels',
icon: Bot, icon: Bot,
items: [ items: [
{ {
id: 'which-models', id: 'which-ai-model-best',
questionKey: 'faqWhichModels', questionKey: 'faqWhichAIModelBest',
answerKey: 'faqWhichModelsAnswer', answerKey: 'faqWhichAIModelBestAnswer',
}, },
{ {
id: 'api-costs', id: 'custom-ai-api',
questionKey: 'faqApiCosts', questionKey: 'faqCustomAIAPI',
answerKey: 'faqApiCostsAnswer', answerKey: 'faqCustomAIAPIAnswer',
}, },
{ {
id: 'multiple-models', id: 'ai-hallucinations',
questionKey: 'faqMultipleModels', questionKey: 'faqAIHallucinations',
answerKey: 'faqMultipleModelsAnswer', answerKey: 'faqAIHallucinationsAnswer',
}, },
{ {
id: 'ai-learning', id: 'compare-ai-models',
questionKey: 'faqAiLearning', questionKey: 'faqCompareAIModels',
answerKey: 'faqAiLearningAnswer', answerKey: 'faqCompareAIModelsAnswer',
},
{
id: 'only-short-positions',
questionKey: 'faqOnlyShort',
answerKey: 'faqOnlyShortAnswer',
},
{
id: 'model-selection',
questionKey: 'faqModelSelection',
answerKey: 'faqModelSelectionAnswer',
}, },
], ],
}, },
// ===== 9. CONTRIBUTING =====
{ {
id: 'data', id: 'contributing',
titleKey: 'faqCategoryData', titleKey: 'faqCategoryContributing',
icon: Database, icon: GitBranch,
items: [ items: [
{ {
id: 'data-storage', id: 'how-to-contribute',
questionKey: 'faqDataStorage', questionKey: 'faqHowToContribute',
answerKey: 'faqDataStorageAnswer', answerKey: 'faqHowToContributeAnswer',
}, },
{ {
id: 'api-key-security', id: 'pr-guidelines',
questionKey: 'faqApiKeySecurity', questionKey: 'faqPRGuidelines',
answerKey: 'faqApiKeySecurityAnswer', answerKey: 'faqPRGuidelinesAnswer',
}, },
{ {
id: 'export-history', id: 'bounty-program',
questionKey: 'faqExportHistory', questionKey: 'faqBountyProgram',
answerKey: 'faqExportHistoryAnswer', answerKey: 'faqBountyProgramAnswer',
}, },
{ {
id: 'get-help', id: 'report-bugs',
questionKey: 'faqGetHelp', questionKey: 'faqReportBugs',
answerKey: 'faqGetHelpAnswer', answerKey: 'faqReportBugsAnswer',
}, },
], ],
}, },

View File

@@ -96,7 +96,8 @@ export const translations = {
// Backtest Page // Backtest Page
backtestPage: { backtestPage: {
title: 'Backtest Lab', title: 'Backtest Lab',
subtitle: 'Pick a model + time range to replay the full AI decision loop.', subtitle:
'Pick a model + time range to replay the full AI decision loop.',
start: 'Start Backtest', start: 'Start Backtest',
starting: 'Starting...', starting: 'Starting...',
quickRanges: { quickRanges: {
@@ -215,7 +216,8 @@ export const translations = {
title: 'AI Decision Trail', title: 'AI Decision Trail',
subtitle: 'Showing last {count} cycles', subtitle: 'Showing last {count} cycles',
empty: 'No records yet', empty: 'No records yet',
emptyHint: 'The AI thought & execution log will appear once the run starts.', emptyHint:
'The AI thought & execution log will appear once the run starts.',
}, },
charts: { charts: {
equityTitle: 'Equity Curve', equityTitle: 'Equity Curve',
@@ -378,13 +380,20 @@ export const translations = {
lighterApiKeyPrivateKey: 'API Key Private Key', lighterApiKeyPrivateKey: 'API Key Private Key',
enterLighterWalletAddress: 'Enter Ethereum wallet address (0x...)', enterLighterWalletAddress: 'Enter Ethereum wallet address (0x...)',
enterLighterPrivateKey: 'Enter L1 private key (32 bytes)', enterLighterPrivateKey: 'Enter L1 private key (32 bytes)',
enterLighterApiKeyPrivateKey: 'Enter API Key private key (40 bytes, optional)', enterLighterApiKeyPrivateKey:
lighterWalletAddressDesc: 'Your Ethereum wallet address for account identification', 'Enter API Key private key (40 bytes, optional)',
lighterPrivateKeyDesc: 'L1 private key for account identification (32-byte ECDSA key)', lighterWalletAddressDesc:
lighterApiKeyPrivateKeyDesc: 'API Key private key for transaction signing (40-byte Poseidon2 key)', 'Your Ethereum wallet address for account identification',
lighterApiKeyOptionalNote: 'Without API Key, system will use limited V1 mode', lighterPrivateKeyDesc:
lighterV1Description: 'Basic Mode - Limited functionality, testing framework only', 'L1 private key for account identification (32-byte ECDSA key)',
lighterV2Description: 'Full Mode - Supports Poseidon2 signing and real trading', lighterApiKeyPrivateKeyDesc:
'API Key private key for transaction signing (40-byte Poseidon2 key)',
lighterApiKeyOptionalNote:
'Without API Key, system will use limited V1 mode',
lighterV1Description:
'Basic Mode - Limited functionality, testing framework only',
lighterV2Description:
'Full Mode - Supports Poseidon2 signing and real trading',
lighterPrivateKeyImported: 'LIGHTER private key imported', lighterPrivateKeyImported: 'LIGHTER private key imported',
// Exchange names // Exchange names
@@ -520,12 +529,13 @@ export const translations = {
leaveBlankForDefault: 'Leave blank to use default API address', leaveBlankForDefault: 'Leave blank to use default API address',
modelConfigInfo1: modelConfigInfo1:
'• For official API, only API Key is required, leave other fields blank', '• For official API, only API Key is required, leave other fields blank',
modelConfigInfo2: '• Custom Base URL and Model Name only needed for third-party proxies', modelConfigInfo2:
modelConfigInfo3: '• Custom Base URL and Model Name only needed for third-party proxies',
'• API Key is encrypted and stored securely', modelConfigInfo3: '• API Key is encrypted and stored securely',
defaultModel: 'Default model', defaultModel: 'Default model',
applyApiKey: 'Apply API Key', applyApiKey: 'Apply API Key',
kimiApiNote: 'Kimi requires API Key from international site (moonshot.ai), China region keys are not compatible', kimiApiNote:
'Kimi requires API Key from international site (moonshot.ai), China region keys are not compatible',
leaveBlankForDefaultModel: 'Leave blank to use default model', leaveBlankForDefaultModel: 'Leave blank to use default model',
customModelName: 'Model Name (Optional)', customModelName: 'Model Name (Optional)',
customModelNamePlaceholder: 'e.g.: deepseek-chat, qwen3-max, gpt-4o', customModelNamePlaceholder: 'e.g.: deepseek-chat, qwen3-max, gpt-4o',
@@ -794,168 +804,228 @@ export const translations = {
faqContactUs: 'Join our community or check our GitHub for more help', faqContactUs: 'Join our community or check our GitHub for more help',
// FAQ Categories // FAQ Categories
faqCategoryBasics: 'General Questions', faqCategoryGettingStarted: 'Getting Started',
faqCategoryContributing: 'Contributing & Tasks', faqCategoryInstallation: 'Installation',
faqCategorySetup: 'Setup & Configuration', faqCategoryConfiguration: 'Configuration',
faqCategoryTrading: 'Trading Questions', faqCategoryTrading: 'Trading',
faqCategoryTechnical: 'Technical Issues', faqCategoryTechnicalIssues: 'Technical Issues',
faqCategoryAI: 'AI & Model Questions', faqCategorySecurity: 'Security',
faqCategoryData: 'Data & Privacy', faqCategoryFeatures: 'Features',
faqCategoryAIModels: 'AI Models',
faqCategoryContributing: 'Contributing',
// FAQ Questions & Answers - General // ===== GETTING STARTED =====
faqWhatIsNOFX: 'What is NOFX?', faqWhatIsNOFX: 'What is NOFX?',
faqWhatIsNOFXAnswer: faqWhatIsNOFXAnswer:
'NOFX is an AI-powered cryptocurrency trading bot that uses large language models (LLMs) to make trading decisions on futures markets.', 'NOFX is an open-source AI-powered trading operating system for cryptocurrency and US stock markets. It uses large language models (LLMs) like DeepSeek, GPT, Claude, Gemini to analyze market data and make autonomous trading decisions. Key features include: multi-AI model support, multi-exchange trading, visual strategy builder, backtesting, and AI debate arena for consensus decisions.',
faqSupportedExchanges: 'Which exchanges are supported?', faqHowDoesItWork: 'How does NOFX work?',
faqSupportedExchangesAnswer: faqHowDoesItWorkAnswer:
'Binance Futures, Hyperliquid, and Aster DEX are supported. More exchanges coming soon.', 'NOFX works in 5 steps: 1) Configure AI models and exchange API credentials; 2) Create a trading strategy (coin selection, indicators, risk controls); 3) Create a "Trader" combining AI model + Exchange + Strategy; 4) Start the trader - it will analyze market data at regular intervals and make buy/sell/hold decisions; 5) Monitor performance on the dashboard. The AI uses Chain of Thought reasoning to explain each decision.',
faqIsProfitable: 'Is NOFX profitable?', faqIsProfitable: 'Is NOFX profitable?',
faqIsProfitableAnswer: faqIsProfitableAnswer:
'AI trading is experimental and not guaranteed to be profitable. Always start with small amounts and never invest more than you can afford to lose.', 'AI trading is experimental and NOT guaranteed to be profitable. Cryptocurrency futures are highly volatile and risky. NOFX is designed for educational and research purposes. We strongly recommend: starting with small amounts (10-50 USDT), never investing more than you can afford to lose, thoroughly testing with backtests before live trading, and understanding that past performance does not guarantee future results.',
faqMultipleTraders: 'Can I run multiple traders simultaneously?', faqSupportedExchanges: 'Which exchanges are supported?',
faqMultipleTradersAnswer: faqSupportedExchangesAnswer:
'Yes! NOFX supports running multiple traders with different configurations, AI models, and trading strategies.', 'CEX (Centralized): Binance Futures, Bybit, OKX, Bitget. DEX (Decentralized): Hyperliquid, Aster DEX, Lighter. Each exchange has different features - Binance has the most liquidity, Hyperliquid is fully on-chain with no KYC required. Check the documentation for setup guides for each exchange.',
// Contributing & Community faqSupportedAIModels: 'Which AI models are supported?',
faqGithubProjectsTasks: 'How to use GitHub Projects and pick up tasks?', faqSupportedAIModelsAnswer:
faqGithubProjectsTasksAnswer: 'NOFX supports 7+ AI models: DeepSeek (recommended for cost/performance), Alibaba Qwen, OpenAI (GPT-5.2), Anthropic Claude, Google Gemini, xAI Grok, and Kimi (Moonshot). You can also use any OpenAI-compatible API endpoint. Each model has different strengths - DeepSeek is cost-effective, OpenAI models are powerful but expensive, Claude excels at reasoning.',
'Roadmap: https://github.com/orgs/NoFxAiOS/projects/3 • Task Dashboard: https://github.com/orgs/NoFxAiOS/projects/5 • Steps: Open links → filter by labels (good first issue / help wanted / frontend / backend) → read Description & Acceptance Criteria → comment "assign me" or self-assign → Fork the repo → sync your fork\'s dev with upstream/dev → create a feature branch from your fork\'s dev → push to your fork → open PR (base: NoFxAiOS/nofx:dev ← compare: your-username/nofx:feat/your-topic) → reference Issue (Closes #123) and use the proper template.',
faqContributePR: 'How to properly submit PRs and contribute?',
faqContributePRAnswer:
"Guidelines: • Fork first; branch from your fork's dev (avoid direct commits to upstream main) • Branch naming: feat/..., fix/..., docs/...; Conventional Commits • Run checks before PR: npm --prefix web run lint && npm --prefix web run build • For UI changes, attach screenshots or a short video • Choose the proper PR template (frontend/backend/docs/general) • Open PR from your fork to NoFxAiOS/nofx:dev and link Issue (Closes #123) • Keep rebasing onto upstream/dev; ensure CI passes; prefer small, focused PRs • Read CONTRIBUTING.md and .github/PR_TITLE_GUIDE.md",
// Setup & Configuration
faqSystemRequirements: 'What are the system requirements?', faqSystemRequirements: 'What are the system requirements?',
faqSystemRequirementsAnswer: faqSystemRequirementsAnswer:
'OS: Linux, macOS, or Windows (Docker recommended); RAM: 2GB minimum, 4GB recommended; Disk: 1GB for application + logs; Network: Stable internet connection.', 'Minimum: 2 CPU cores, 2GB RAM, 1GB disk space, stable internet. Recommended: 4GB RAM for running multiple traders. Supported OS: Linux, macOS, or Windows (via Docker or WSL2). Docker is the easiest installation method. For manual installation, you need Go 1.21+, Node.js 18+, and TA-Lib library.',
faqNeedCoding: 'Do I need coding experience?', // ===== INSTALLATION =====
faqNeedCodingAnswer: faqHowToInstall: 'How do I install NOFX?',
'No! NOFX has a web UI for all configuration. However, basic command line knowledge helps with setup and troubleshooting.', faqHowToInstallAnswer:
'Easiest method (Linux/macOS): Run "curl -fsSL https://raw.githubusercontent.com/NoFxAiOS/nofx/main/install.sh | bash" - this installs Docker containers automatically. Then open http://127.0.0.1:3000 in your browser. For manual installation or development, clone the repository and follow the README instructions.',
faqGetApiKeys: 'How do I get API keys?', faqWindowsInstallation: 'How do I install on Windows?',
faqGetApiKeysAnswer: faqWindowsInstallationAnswer:
'For Binance: Account → API Management → Create API → Enable Futures. For Hyperliquid: Visit Hyperliquid App → API Settings. For Aster DEX: Configure main wallet address (User), API wallet address (Signer), and private key (Private Key).', 'Three options: 1) Docker Desktop (Recommended) - Install Docker Desktop, then run "docker compose -f docker-compose.prod.yml up -d" in PowerShell; 2) WSL2 - Install Windows Subsystem for Linux, then follow Linux installation; 3) Docker in WSL2 - Best of both worlds, run the install script in WSL2 terminal. Access via http://127.0.0.1:3000',
faqUseSubaccount: 'Should I use a subaccount?',
faqUseSubaccountAnswer:
'Recommended: Yes, use a subaccount dedicated to NOFX for better risk isolation. However, note that some subaccounts have restrictions (e.g., 5x max leverage on Binance).',
faqDockerDeployment: 'Docker deployment keeps failing', faqDockerDeployment: 'Docker deployment keeps failing',
faqDockerDeploymentAnswer: faqDockerDeploymentAnswer:
'Common issues: Network connection problems, dependency installation failures, insufficient memory (needs at least 2C2G). If stuck at "go build", try: docker compose down && docker compose build --no-cache && docker compose up -d', 'Common solutions: 1) Check Docker is running: "docker info"; 2) Ensure sufficient memory (2GB minimum); 3) If stuck on "go build", try: "docker compose down && docker compose build --no-cache && docker compose up -d"; 4) Check logs: "docker compose logs -f"; 5) For slow pulls, configure a Docker mirror in daemon.json.',
faqBalanceZero: 'Account balance shows 0', faqManualInstallation: 'How do I install manually for development?',
faqBalanceZeroAnswer: faqManualInstallationAnswer:
'Funds are likely in spot account instead of futures account, or locked in savings products. You need to manually transfer funds to futures account in Binance.', 'Prerequisites: Go 1.21+, Node.js 18+, TA-Lib. Steps: 1) Clone repo: "git clone https://github.com/NoFxAiOS/nofx.git"; 2) Install backend deps: "go mod download"; 3) Install frontend deps: "cd web && npm install"; 4) Build backend: "go build -o nofx"; 5) Run backend: "./nofx"; 6) Run frontend (new terminal): "cd web && npm run dev". Access at http://127.0.0.1:3000',
faqTestnet: 'Can I use testnet for testing?', faqServerDeployment: 'How do I deploy to a remote server?',
faqTestnetAnswer: faqServerDeploymentAnswer:
'Testnet is not supported at the moment. We recommend using real trading with small amounts (10-50 USDT) for testing.', 'Run the install script on your server - it auto-detects the server IP. Access via http://YOUR_SERVER_IP:3000. For HTTPS: 1) Use Cloudflare (free) - add domain, create A record pointing to server IP, set SSL to "Flexible"; 2) Enable TRANSPORT_ENCRYPTION=true in .env for browser-side encryption; 3) Access via https://your-domain.com',
// Trading Questions faqUpdateNOFX: 'How do I update NOFX?',
faqNoTrades: "Why isn't my trader making any trades?", faqUpdateNOFXAnswer:
faqNoTradesAnswer: 'For Docker: Run "docker compose pull && docker compose up -d" to pull latest images and restart. For manual installation: "git pull && go build -o nofx" for backend, "cd web && npm install && npm run build" for frontend. Your configurations in data.db are preserved during updates.',
'Common reasons: AI decided to "wait" due to market conditions; Insufficient balance or margin; Position limits reached (default: max 3 positions); Check troubleshooting guide for detailed diagnostics.',
// ===== CONFIGURATION =====
faqConfigureAIModels: 'How do I configure AI models?',
faqConfigureAIModelsAnswer:
'Go to Config page → AI Models section. For each model: 1) Get API key from the provider (links provided in UI); 2) Enter API key; 3) Optionally customize base URL and model name; 4) Save. API keys are encrypted before storage. Test the connection after saving to verify it works.',
faqConfigureExchanges: 'How do I configure exchange connections?',
faqConfigureExchangesAnswer:
'Go to Config page → Exchanges section. Click "Add Exchange", select exchange type, and enter credentials. For CEX (Binance/Bybit/OKX): Need API Key + Secret Key (+ Passphrase for OKX). For DEX (Hyperliquid/Aster/Lighter): Need wallet address and private key. Always enable only necessary permissions (Futures Trading) and consider IP whitelisting.',
faqBinanceAPISetup: 'How do I set up Binance API correctly?',
faqBinanceAPISetupAnswer:
'Important steps: 1) Create API key in Binance → API Management; 2) Enable ONLY "Enable Futures" permission; 3) Consider adding IP whitelist for security; 4) CRITICAL: Switch to Hedge Mode (双向持仓) in Futures settings → Preferences → Position Mode; 5) Ensure funds are in Futures wallet (not Spot). Common error -4061 means you need Hedge Mode.',
faqHyperliquidSetup: 'How do I set up Hyperliquid?',
faqHyperliquidSetupAnswer:
'Hyperliquid is a decentralized exchange requiring wallet authentication. Steps: 1) Go to app.hyperliquid.xyz; 2) Connect your wallet; 3) Generate an API wallet (recommended) or use your main wallet; 4) Copy the wallet address and private key; 5) In NOFX, add Hyperliquid exchange with these credentials. No KYC required, fully on-chain.',
faqCreateStrategy: 'How do I create a trading strategy?',
faqCreateStrategyAnswer:
'Go to Strategy Studio: 1) Coin Source - select which coins to trade (static list, AI500 pool, or OI Top ranking); 2) Indicators - enable technical indicators (EMA, MACD, RSI, ATR, Volume, OI, Funding Rate); 3) Risk Controls - set leverage limits, max positions, margin usage cap, position size limits; 4) Custom Prompt (optional) - add specific instructions for the AI. Save and assign to a trader.',
faqCreateTrader: 'How do I create and start a trader?',
faqCreateTraderAnswer:
'Go to Traders page: 1) Click "Create Trader"; 2) Select AI Model (must be configured first); 3) Select Exchange (must be configured first); 4) Select Strategy (or use default); 5) Set decision interval (e.g., 5 minutes); 6) Save, then click "Start" to begin trading. Monitor performance on Dashboard page.',
// ===== TRADING =====
faqHowAIDecides: 'How does the AI make trading decisions?',
faqHowAIDecidesAnswer:
'The AI uses Chain of Thought (CoT) reasoning in 4 steps: 1) Position Analysis - reviews current holdings and P/L; 2) Risk Assessment - checks account margin, available balance; 3) Opportunity Evaluation - analyzes market data, indicators, candidate coins; 4) Final Decision - outputs specific action (buy/sell/hold) with reasoning. You can view the full reasoning in decision logs.',
faqDecisionFrequency: 'How often does the AI make decisions?', faqDecisionFrequency: 'How often does the AI make decisions?',
faqDecisionFrequencyAnswer: faqDecisionFrequencyAnswer:
'Configurable! Default is every 3-5 minutes. Too frequent = overtrading, too slow = missed opportunities.', 'Configurable per trader, default is 3-5 minutes. Considerations: Too frequent (1-2 min) = overtrading, high fees; Too slow (30+ min) = missed opportunities. Recommended: 5 minutes for active trading, 15-30 minutes for swing trading. The AI may decide to "hold" (no action) in many cycles.',
faqCustomStrategy: 'Can I customize the trading strategy?', faqNoTradesExecuting: "Why isn't my trader executing any trades?",
faqCustomStrategyAnswer: faqNoTradesExecutingAnswer:
'Yes! You can adjust leverage settings, modify coin selection pool, change decision intervals, and customize system prompts (advanced).', 'Common causes: 1) AI decided to wait (check decision logs for reasoning); 2) Insufficient balance in futures account; 3) Max positions limit reached (default: 3); 4) Exchange API issues (check error messages); 5) Strategy constraints too restrictive. Check Dashboard → Decision Logs for detailed AI reasoning each cycle.',
faqMaxPositions: "What's the maximum number of concurrent positions?", faqOnlyShortPositions: 'Why is the AI only opening short positions?',
faqMaxPositionsAnswer: faqOnlyShortPositionsAnswer:
'Default: 3 positions. This is a soft limit defined in the AI prompt, not hard-coded.', 'This is usually due to Binance Position Mode. Solution: Switch to Hedge Mode (双向持仓) in Binance Futures → Preferences → Position Mode. You must close all positions first. After switching, the AI can open both long and short positions independently.',
faqMarginInsufficient: 'Margin is insufficient error (code=-2019)', faqLeverageSettings: 'How do leverage settings work?',
faqMarginInsufficientAnswer: faqLeverageSettingsAnswer:
'Common causes: Funds not transferred to futures account; Leverage set too high (default 20-50x); Existing positions using margin; Need to transfer USDT from spot to futures account first.', 'Leverage is set in Strategy → Risk Controls: BTC/ETH leverage (typically 5-20x) and Altcoin leverage (typically 3-10x). Higher leverage = higher risk and potential returns. Subaccounts may have restrictions (e.g., Binance subaccounts limited to 5x). The AI respects these limits when placing orders.',
faqHighFees: 'Trading fees are too high', faqStopLossTakeProfit: 'Does NOFX support stop-loss and take-profit?',
faqHighFeesAnswer: faqStopLossTakeProfitAnswer:
'NOFX default 3-minute scan interval can cause frequent trading. Solutions: Increase decision interval to 5-10 minutes; Optimize system prompt to reduce overtrading; Adjust leverage to reduce position sizes.', 'The AI can suggest stop-loss/take-profit levels in its decisions, but these are guidance-based rather than hard-coded exchange orders. The AI monitors positions each cycle and may decide to close based on P/L. For guaranteed stop-loss, you can set exchange-level orders manually or adjust the strategy prompt to be more conservative.',
faqNoTakeProfit: "AI doesn't close profitable positions", faqMultipleTraders: 'Can I run multiple traders?',
faqNoTakeProfitAnswer: faqMultipleTradersAnswer:
'AI may believe the trend will continue. The system lacks trailing stop-loss feature currently. You can manually close positions or adjust the system prompt to be more conservative with profit-taking.', 'Yes! NOFX supports running 20+ concurrent traders. Each trader can have different: AI model, exchange account, strategy, decision interval. Use this to A/B test strategies, compare AI models, or diversify across exchanges. Monitor all traders on the Competition page.',
// Technical Issues faqAICosts: 'How much do AI API calls cost?',
faqBinanceApiFailed: 'Binance API call failed (code=-2015)', faqAICostsAnswer:
faqBinanceApiFailedAnswer: 'Approximate daily costs per trader (5-min intervals): DeepSeek: $0.10-0.50; Qwen: $0.20-0.80; OpenAI: $2-5; Claude: $1-3. Costs depend on prompt length and response tokens. DeepSeek offers the best cost/performance ratio. Longer decision intervals reduce costs.',
'Error: "Invalid API-key, IP, or permissions for action". Solutions: Add server IP to Binance API whitelist; Check API permissions (needs Read + Futures Trading); Ensure using futures API not unified account API; VPN IP might be unstable.',
faqBinancePositionMode: 'Binance Position Mode Error (code=-4061)', // ===== TECHNICAL ISSUES =====
faqBinancePositionModeAnswer: faqPortInUse: 'Port 8080 or 3000 already in use',
'Error: "Order\'s position side does not match user\'s setting". Solution: Switch to Hedge Mode (双向持仓) in Binance Futures settings. You must close all positions first before switching.',
faqPortInUse: "Backend won't start / Port already in use",
faqPortInUseAnswer: faqPortInUseAnswer:
'Check what\'s using port 8080 with "lsof -i :8080" and change the port in your .env file with NOFX_BACKEND_PORT=8081.', 'Check what\'s using the port: "lsof -i :8080" (macOS/Linux) or "netstat -ano | findstr 8080" (Windows). Kill the process or change ports in .env: NOFX_BACKEND_PORT=8081, NOFX_FRONTEND_PORT=3001. Restart with "docker compose down && docker compose up -d".',
faqFrontendLoading: 'Frontend shows "Loading..." forever', faqFrontendNotLoading: 'Frontend shows "Loading..." forever',
faqFrontendLoadingAnswer: faqFrontendNotLoadingAnswer:
'Check if backend is running with "curl http://localhost:8080/api/health". Should return {"status":"ok"}. If not, check the troubleshooting guide.', 'Backend may not be running or reachable. Check: 1) "curl http://127.0.0.1:8080/api/health" should return {"status":"ok"}; 2) "docker compose ps" to verify containers are running; 3) Check backend logs: "docker compose logs nofx-backend"; 4) Ensure firewall allows port 8080.',
faqDatabaseLocked: 'Database locked error', faqDatabaseLocked: 'Database locked error',
faqDatabaseLockedAnswer: faqDatabaseLockedAnswer:
'Stop all NOFX processes with "docker compose down" or "pkill nofx", then restart with "docker compose up -d".', 'Multiple processes accessing SQLite simultaneously. Solution: 1) Stop all processes: "docker compose down" or "pkill nofx"; 2) Remove lock files if present: "rm -f data/data.db-wal data/data.db-shm"; 3) Restart: "docker compose up -d". Only one backend instance should access the database.',
faqAiLearningFailed: 'AI learning data failed to load', faqTALibNotFound: 'TA-Lib not found during build',
faqAiLearningFailedAnswer: faqTALibNotFoundAnswer:
'Causes: TA-Lib library not properly installed; Insufficient historical data (need completed trades); Environment configuration issues. Install TA-Lib: pip install TA-Lib or check system dependencies.', 'TA-Lib is required for technical indicators. Install: macOS: "brew install ta-lib"; Ubuntu/Debian: "sudo apt-get install libta-lib0-dev"; CentOS: "yum install ta-lib-devel". After installing, rebuild: "go build -o nofx". Docker images include TA-Lib pre-installed.',
faqConfigNotEffective: 'Configuration changes not taking effect', faqAIAPITimeout: 'AI API timeout or connection refused',
faqConfigNotEffectiveAnswer: faqAIAPITimeoutAnswer:
'For Docker: Need to rebuild with "docker compose down && docker compose up -d --build". For PM2: Restart with "pm2 restart all". Check configuration file format and path are correct.', 'Check: 1) API key is valid (test with curl); 2) Network can reach API endpoint (ping/curl); 3) API provider is not down (check status page); 4) VPN/firewall not blocking; 5) Rate limits not exceeded. Default timeout is 120 seconds.',
// AI & Model Questions faqBinancePositionMode: 'Binance error code -4061 (Position Mode)',
faqWhichModels: 'Which AI models are supported?', faqBinancePositionModeAnswer:
faqWhichModelsAnswer: 'Error: "Order\'s position side does not match user\'s setting". You\'re in One-way Mode but NOFX requires Hedge Mode. Fix: 1) Close ALL positions first; 2) Binance Futures → Settings (gear icon) → Preferences → Position Mode → Switch to "Hedge Mode" (双向持仓); 3) Restart your trader.',
'DeepSeek (recommended for cost/performance), Qwen (Alibaba Cloud), and Custom OpenAI-compatible APIs (can be used for OpenAI, Claude via proxy, or other providers).',
faqApiCosts: 'How much do API calls cost?', faqBalanceShowsZero: 'Account balance shows 0',
faqApiCostsAnswer: faqBalanceShowsZeroAnswer:
'Depends on your model and decision frequency: DeepSeek: ~$0.10-0.50 per day (1 trader, 5min intervals); Qwen: ~$0.20-0.80 per day; Custom API (e.g., OpenAI GPT-4): ~$2-5 per day. Estimates based on typical usage.', 'Funds are likely in Spot wallet, not Futures wallet. Solution: 1) In Binance, go to Wallet → Futures → Transfer; 2) Transfer USDT from Spot to Futures; 3) Refresh NOFX dashboard. Also check: funds not locked in savings/staking products.',
faqMultipleModels: 'Can I use multiple AI models?', faqDockerPullFailed: 'Docker image pull failed or slow',
faqMultipleModelsAnswer: faqDockerPullFailedAnswer:
'Yes! Each trader can use a different AI model. You can even A/B test different models.', 'Docker Hub can be slow in some regions. Solutions: 1) Configure a Docker mirror in /etc/docker/daemon.json: {"registry-mirrors": ["https://mirror.gcr.io"]}; 2) Restart Docker; 3) Retry pull. Alternatively, use GitHub Container Registry (ghcr.io) which may have better connectivity in your region.',
faqAiLearning: 'Does the AI learn from its mistakes?', // ===== SECURITY =====
faqAiLearningAnswer: faqAPIKeyStorage: 'How are API keys stored?',
'Yes, to some extent. NOFX provides historical performance feedback in each decision prompt, allowing the AI to adjust its strategy.', faqAPIKeyStorageAnswer:
'API keys are encrypted using AES-256-GCM before storage in the local SQLite database. The encryption key (DATA_ENCRYPTION_KEY) is stored in your .env file. Keys are decrypted only in memory when needed for API calls. Never share your data.db or .env files.',
faqOnlyShort: 'AI only opens short positions, no long positions', faqEncryptionDetails: 'What encryption does NOFX use?',
faqOnlyShortAnswer: faqEncryptionDetailsAnswer:
'The default system prompt contains "Don\'t have a long bias! Shorting is one of your core tools" which may cause this. Also affected by 4-hour timeframe data and model training bias. You can modify the system prompt to be more balanced.', 'NOFX uses multiple encryption layers: 1) AES-256-GCM for database storage (API keys, secrets); 2) RSA-2048 for optional transport encryption (browser to server); 3) JWT for authentication tokens. Keys are generated during installation. Enable TRANSPORT_ENCRYPTION=true for HTTPS environments.',
faqModelSelection: 'Which DeepSeek version should I use?', faqSecurityBestPractices: 'What are security best practices?',
faqModelSelectionAnswer: faqSecurityBestPracticesAnswer:
"DeepSeek V3 is recommended for best performance. Alternatives: DeepSeek R1 (reasoning model, slower but better logic), SiliconFlow's DeepSeek (alternative API provider). Most users report good results with V3.", 'Recommended: 1) Use exchange API keys with IP whitelist and minimal permissions (Futures Trading only); 2) Use dedicated subaccount for NOFX; 3) Enable TRANSPORT_ENCRYPTION for remote deployments; 4) Never share .env or data.db files; 5) Use HTTPS with valid certificates; 6) Regularly rotate API keys; 7) Monitor account activity.',
// Data & Privacy faqCanNOFXStealFunds: 'Can NOFX steal my funds?',
faqDataStorage: 'Where is my data stored?', faqCanNOFXStealFundsAnswer:
faqDataStorageAnswer: 'NOFX is open-source (AGPL-3.0 license) - you can audit all code on GitHub. API keys are stored locally on YOUR machine, never sent to external servers. NOFX only has the permissions you grant via API keys. For maximum safety: use API keys with trading-only permissions (no withdrawal), enable IP whitelist, use a dedicated subaccount.',
'All data is stored locally on your machine in SQLite databases: data.db (all configurations and trade history), and decision_logs/ (AI decision records).',
faqApiKeySecurity: 'Is my API key secure?', // ===== FEATURES =====
faqApiKeySecurityAnswer: faqStrategyStudio: 'What is Strategy Studio?',
'API keys are stored in local databases. Never share your databases or .env files. We recommend using API keys with IP whitelist restrictions.', faqStrategyStudioAnswer:
'Strategy Studio is a visual strategy builder where you configure: 1) Coin Sources - which cryptocurrencies to trade (static list, AI500 top coins, OI ranking); 2) Technical Indicators - EMA, MACD, RSI, ATR, Volume, Open Interest, Funding Rate; 3) Risk Controls - leverage limits, position sizing, margin caps; 4) Custom Prompts - specific instructions for AI. No coding required.',
faqExportHistory: 'Can I export my trading history?', faqBacktestLab: 'What is Backtest Lab?',
faqExportHistoryAnswer: faqBacktestLabAnswer:
'Yes! Trading data is in SQLite format. You can query it directly with: sqlite3 trading.db "SELECT * FROM trades;"', 'Backtest Lab tests your strategy against historical data without risking real funds. Features: 1) Configure AI model, date range, initial balance; 2) Watch real-time progress with equity curve; 3) View metrics: Return %, Max Drawdown, Sharpe Ratio, Win Rate; 4) Analyze individual trades and AI reasoning. Essential for validating strategies before live trading.',
faqGetHelp: 'Where can I get help?', faqDebateArena: 'What is Debate Arena?',
faqGetHelpAnswer: faqDebateArenaAnswer:
'Check GitHub Discussions, join our Telegram Community, or open an issue on GitHub.', 'Debate Arena lets multiple AI models debate trading decisions before execution. Setup: 1) Choose 2-5 AI models; 2) Assign personalities (Bull, Bear, Analyst, Contrarian, Risk Manager); 3) Watch them debate in rounds; 4) Final decision based on consensus voting. Useful for high-conviction trades where you want multiple perspectives.',
faqCompetitionMode: 'What is Competition Mode?',
faqCompetitionModeAnswer:
'Competition page shows a real-time leaderboard of all your traders. Compare: ROI, P&L, Sharpe ratio, win rate, number of trades. Use this to A/B test different AI models, strategies, or configurations. Traders can be marked as "Show in Competition" to appear on the leaderboard.',
faqChainOfThought: 'What is Chain of Thought (CoT)?',
faqChainOfThoughtAnswer:
"Chain of Thought is the AI's reasoning process, visible in decision logs. The AI explains its thinking in 4 steps: 1) Current position analysis; 2) Account risk assessment; 3) Market opportunity evaluation; 4) Final decision rationale. This transparency helps you understand WHY the AI made each decision, useful for improving strategies.",
// ===== AI MODELS =====
faqWhichAIModelBest: 'Which AI model should I use?',
faqWhichAIModelBestAnswer:
'Recommended: DeepSeek for best cost/performance ratio ($0.10-0.50/day). Alternatives: OpenAI for best reasoning but expensive ($2-5/day); Claude for nuanced analysis; Qwen for competitive pricing. You can run multiple traders with different models to compare. Check the Competition page to see which performs best for your strategy.',
faqCustomAIAPI: 'Can I use a custom AI API?',
faqCustomAIAPIAnswer:
'Yes! NOFX supports any OpenAI-compatible API. In Config → AI Models → Custom API: 1) Enter your API endpoint URL (e.g., https://your-api.com/v1); 2) Enter API key; 3) Specify model name. This works with self-hosted models, alternative providers, or Claude via third-party proxies.',
faqAIHallucinations: 'What about AI hallucinations?',
faqAIHallucinationsAnswer:
'AI models can sometimes produce incorrect or fabricated information ("hallucinations"). NOFX mitigates this by: 1) Providing structured prompts with real market data; 2) Enforcing JSON output format for decisions; 3) Validating orders before execution. However, AI trading is experimental - always monitor decisions and don\'t rely solely on AI judgment.',
faqCompareAIModels: 'How do I compare different AI models?',
faqCompareAIModelsAnswer:
'Create multiple traders with different AI models but same strategy/exchange. Run them simultaneously and compare on Competition page. Metrics to watch: ROI, win rate, Sharpe ratio, max drawdown. Alternatively, use Backtest Lab to test models against same historical data. The Debate Arena also shows how different models reason about the same situation.',
// ===== CONTRIBUTING =====
faqHowToContribute: 'How can I contribute to NOFX?',
faqHowToContributeAnswer:
'NOFX is open-source and welcomes contributions! Ways to contribute: 1) Code - fix bugs, add features (check GitHub Issues); 2) Documentation - improve guides, translate; 3) Bug Reports - report issues with details; 4) Feature Ideas - suggest improvements. Start with issues labeled "good first issue". All contributors may receive airdrop rewards.',
faqPRGuidelines: 'What are the PR guidelines?',
faqPRGuidelinesAnswer:
'PR Process: 1) Fork repo to your account; 2) Create feature branch from dev: "git checkout -b feat/your-feature"; 3) Make changes, run lint: "npm --prefix web run lint"; 4) Commit with Conventional Commits format; 5) Push and create PR to NoFxAiOS/nofx:dev; 6) Reference related issue (Closes #123); 7) Wait for review. Keep PRs small and focused.',
faqBountyProgram: 'Is there a bounty program?',
faqBountyProgramAnswer:
'Yes! Contributors receive airdrop rewards based on contributions: Code commits (highest weight), bug fixes, feature suggestions, documentation. Issues with "bounty" label have cash rewards. After completing work, submit a Bounty Claim. Check CONTRIBUTING.md for details on the reward structure.',
faqReportBugs: 'How do I report bugs?',
faqReportBugsAnswer:
'For bugs: Open a GitHub Issue with: 1) Clear description of the problem; 2) Steps to reproduce; 3) Expected vs actual behavior; 4) System info (OS, Docker version, browser); 5) Relevant logs. For SECURITY vulnerabilities: Do NOT open public issues - DM @Web3Tinkle on Twitter instead.',
// Web Crypto Environment Check // Web Crypto Environment Check
environmentCheck: { environmentCheck: {
@@ -1462,8 +1532,10 @@ export const translations = {
enterLighterApiKeyPrivateKey: '請輸入 API Key 私鑰40 字節,可選)', enterLighterApiKeyPrivateKey: '請輸入 API Key 私鑰40 字節,可選)',
lighterWalletAddressDesc: '您的以太坊錢包地址,用於識別賬戶', lighterWalletAddressDesc: '您的以太坊錢包地址,用於識別賬戶',
lighterPrivateKeyDesc: 'L1 私鑰用於賬戶識別32 字節 ECDSA 私鑰)', lighterPrivateKeyDesc: 'L1 私鑰用於賬戶識別32 字節 ECDSA 私鑰)',
lighterApiKeyPrivateKeyDesc: 'API Key 私鑰用於簽名交易40 字節 Poseidon2 私鑰)', lighterApiKeyPrivateKeyDesc:
lighterApiKeyOptionalNote: '如果不提供 API Key系統將使用功能受限的 V1 模式', 'API Key 私鑰用於簽名交易40 字節 Poseidon2 私鑰)',
lighterApiKeyOptionalNote:
'如果不提供 API Key系統將使用功能受限的 V1 模式',
lighterV1Description: '基本模式 - 功能受限,僅用於測試框架', lighterV1Description: '基本模式 - 功能受限,僅用於測試框架',
lighterV2Description: '完整模式 - 支持 Poseidon2 簽名和真實交易', lighterV2Description: '完整模式 - 支持 Poseidon2 簽名和真實交易',
lighterPrivateKeyImported: 'LIGHTER 私鑰已導入', lighterPrivateKeyImported: 'LIGHTER 私鑰已導入',
@@ -1565,7 +1637,8 @@ export const translations = {
noExchangesConfigured: '暂无已配置的交易所', noExchangesConfigured: '暂无已配置的交易所',
signalSource: '信号源', signalSource: '信号源',
signalSourceConfig: '信号源配置', signalSourceConfig: '信号源配置',
coinPoolDescription: '用于获取 AI500 数据源的 API 地址,留空则不使用此数据源', coinPoolDescription:
'用于获取 AI500 数据源的 API 地址,留空则不使用此数据源',
oiTopDescription: '用于获取持仓量排行数据的API地址留空则不使用此信号源', oiTopDescription: '用于获取持仓量排行数据的API地址留空则不使用此信号源',
information: '说明', information: '说明',
signalSourceInfo1: signalSourceInfo1:
@@ -1584,11 +1657,13 @@ export const translations = {
customBaseURLPlaceholder: '自定义API基础URL如: https://api.openai.com/v1', customBaseURLPlaceholder: '自定义API基础URL如: https://api.openai.com/v1',
leaveBlankForDefault: '留空则使用默认API地址', leaveBlankForDefault: '留空则使用默认API地址',
modelConfigInfo1: '• 使用官方 API 时,只需填写 API Key其他字段留空即可', modelConfigInfo1: '• 使用官方 API 时,只需填写 API Key其他字段留空即可',
modelConfigInfo2: '• 自定义 Base URL 和 Model Name 仅在使用第三方代理时需要填写', modelConfigInfo2:
'• 自定义 Base URL 和 Model Name 仅在使用第三方代理时需要填写',
modelConfigInfo3: '• API Key 加密存储,不会明文展示', modelConfigInfo3: '• API Key 加密存储,不会明文展示',
defaultModel: '默认模型', defaultModel: '默认模型',
applyApiKey: '申请 API Key', applyApiKey: '申请 API Key',
kimiApiNote: 'Kimi 需要从国际站申请 API Key (moonshot.ai),中国区 Key 不通用', kimiApiNote:
'Kimi 需要从国际站申请 API Key (moonshot.ai),中国区 Key 不通用',
leaveBlankForDefaultModel: '留空使用默认模型名称', leaveBlankForDefaultModel: '留空使用默认模型名称',
customModelName: 'Model Name (可选)', customModelName: 'Model Name (可选)',
customModelNamePlaceholder: '例如: deepseek-chat, qwen3-max, gpt-4o', customModelNamePlaceholder: '例如: deepseek-chat, qwen3-max, gpt-4o',
@@ -1715,7 +1790,8 @@ export const translations = {
signIn: '登录', signIn: '登录',
signUp: '注册', signUp: '注册',
registrationClosed: '注册已关闭', registrationClosed: '注册已关闭',
registrationClosedMessage: '平台当前不开放新用户注册,如需访问请联系管理员获取账号。', registrationClosedMessage:
'平台当前不开放新用户注册,如需访问请联系管理员获取账号。',
// Hero Section // Hero Section
githubStarsInDays: '3 天内 2.5K+ GitHub Stars', githubStarsInDays: '3 天内 2.5K+ GitHub Stars',
@@ -1809,7 +1885,8 @@ export const translations = {
candidateCoins: '候选币种', candidateCoins: '候选币种',
candidateCoinsZeroWarning: '候选币种数量为 0', candidateCoinsZeroWarning: '候选币种数量为 0',
possibleReasons: '可能原因:', possibleReasons: '可能原因:',
coinPoolApiNotConfigured: 'AI500 数据源 API 未配置或无法访问(请检查信号源设置)', coinPoolApiNotConfigured:
'AI500 数据源 API 未配置或无法访问(请检查信号源设置)',
apiConnectionTimeout: 'API连接超时或返回数据为空', apiConnectionTimeout: 'API连接超时或返回数据为空',
noCustomCoinsAndApiFailed: '未配置自定义币种且API获取失败', noCustomCoinsAndApiFailed: '未配置自定义币种且API获取失败',
solutions: '解决方案:', solutions: '解决方案:',
@@ -1828,168 +1905,228 @@ export const translations = {
faqContactUs: '加入我们的社区或查看 GitHub 获取更多帮助', faqContactUs: '加入我们的社区或查看 GitHub 获取更多帮助',
// FAQ Categories // FAQ Categories
faqCategoryBasics: '基础问题', faqCategoryGettingStarted: '入门指南',
faqCategoryContributing: '贡献与任务', faqCategoryInstallation: '安装部署',
faqCategorySetup: '安装与配置', faqCategoryConfiguration: '配置设置',
faqCategoryTrading: '交易问题', faqCategoryTrading: '交易相关',
faqCategoryTechnical: '技术问题', faqCategoryTechnicalIssues: '技术问题',
faqCategoryAI: 'AI与模型问题', faqCategorySecurity: '安全相关',
faqCategoryData: '数据与隐私', faqCategoryFeatures: '功能介绍',
faqCategoryAIModels: 'AI 模型',
faqCategoryContributing: '参与贡献',
// FAQ Questions & Answers - General // ===== 入门指南 =====
faqWhatIsNOFX: 'NOFX 是什么?', faqWhatIsNOFX: 'NOFX 是什么?',
faqWhatIsNOFXAnswer: faqWhatIsNOFXAnswer:
'NOFX 是一个 AI 驱动的加密货币交易机器人使用大语言模型LLM在期货市场进行交易决策。', 'NOFX 是一个开源的 AI 驱动交易操作系统支持加密货币和美股市场。它使用大语言模型LLM如 DeepSeek、GPT、Claude、Gemini 来分析市场数据,进行自主交易决策。核心功能包括:多 AI 模型支持、多交易所交易、可视化策略构建器、回测系统、以及用于共识决策的 AI 辩论竞技场。',
faqSupportedExchanges: '支持哪些交易所', faqHowDoesItWork: 'NOFX 是如何工作的',
faqSupportedExchangesAnswer: faqHowDoesItWorkAnswer:
'支持币安合约Binance Futures、Hyperliquid 和 Aster DEX。更多交易所开发中。', 'NOFX 分 5 步工作1配置 AI 模型和交易所 API 凭证2创建交易策略币种选择、指标、风控3创建"交易员",组合 AI 模型 + 交易所 + 策略4启动交易员 - 它会定期分析市场数据并做出买入/卖出/持有决策5在仪表板上监控表现。AI 使用思维链Chain of Thought推理来解释每个决策。',
faqIsProfitable: 'NOFX 能盈利吗?', faqIsProfitable: 'NOFX 能盈利吗?',
faqIsProfitableAnswer: faqIsProfitableAnswer:
'AI 交易是实验性的,不保证盈利。请始终用小额资金测试,不要投入超过承受能力的资金。', 'AI 交易是实验性的,不保证盈利。加密货币期货波动性大、风险高。NOFX 仅用于教育和研究目的。我们强烈建议从小额开始10-50 USDT,不要投入超过承受能力的资金,在实盘交易前充分回测,并理解过去的表现不代表未来的结果。',
faqMultipleTraders: '可以同时运行多个交易员吗', faqSupportedExchanges: '支持哪些交易所',
faqMultipleTradersAnswer: faqSupportedExchangesAnswer:
'可以NOFX 支持运行多个交易员,每个可配置不同的 AI 模型和交易策略。', 'CEX中心化币安合约、Bybit、OKX、Bitget。DEX去中心化Hyperliquid、Aster DEX、Lighter。每个交易所有不同特点 - 币安流动性最好Hyperliquid 完全链上无需 KYC。查看文档获取各交易所的设置指南。',
// Contributing & Community faqSupportedAIModels: '支持哪些 AI 模型?',
faqGithubProjectsTasks: '如何在 GitHub Projects 中领取任务?', faqSupportedAIModelsAnswer:
faqGithubProjectsTasksAnswer: 'NOFX 支持 7+ 种 AI 模型DeepSeek推荐性价比、阿里云通义千问、OpenAIGPT-5.2、Anthropic Claude、Google Gemini、xAI Grok、Kimi月之暗面。您也可以使用任何 OpenAI 兼容的 API 端点。每个模型各有优势 - DeepSeek 性价比高OpenAI 能力强但贵Claude 擅长推理。',
'路线图https://github.com/orgs/NoFxAiOS/projects/3 任务看板https://github.com/orgs/NoFxAiOS/projects/5 步骤:打开链接 → 按标签筛选good first issue / help wanted / frontend / backend→ 阅读描述与验收标准 → 评论“assign me”或自助分配 → Fork 仓库 → 同步你 fork 的 dev 与 upstream/dev → 从你 fork 的 dev 创建特性分支 → 推送到你的 fork → 打开 PRbaseNoFxAiOS/nofx:dev ← compare你的用户名/nofx:feat/your-topic→ 关联 IssueCloses #123并选择正确模板。',
faqContributePR: '如何规范地提交 PR 并参与贡献?',
faqContributePRAnswer:
'规范:• 先 Fork在你的 fork 的 dev 分支上创建特性分支(避免直接向上游 main 提交)• 分支命名feat/...、fix/...、docs/...;提交信息遵循 Conventional Commits • PR 前运行检查npm --prefix web run lint && npm --prefix web run build • 涉及 UI 变更请附截图/短视频 • 选择正确 PR 模板frontend/backend/docs/general• 从你的 fork 发起到 NoFxAiOS/nofx:dev并在 PR 中关联 IssueCloses #123• 持续 rebase 到 upstream/dev确保 CI 通过;尽量保持 PR 小而聚焦 • 参考 CONTRIBUTING.md 与 .github/PR_TITLE_GUIDE.md',
// Setup & Configuration
faqSystemRequirements: '系统要求是什么?', faqSystemRequirements: '系统要求是什么?',
faqSystemRequirementsAnswer: faqSystemRequirementsAnswer:
'操作系统Linux、macOS 或 Windows推荐 Docker);内存:最低 2GB推荐 4GB硬盘应用 + 日志需要 1GB网络稳定的互联网连接。', '最低配置2 核 CPU2GB 内存1GB 硬盘稳定网络。推荐4GB 内存用于运行多个交易员。支持系统Linux、macOS 或 Windows通过 Docker 或 WSL2。Docker 是最简单的安装方式。手动安装需要 Go 1.21+、Node.js 18+ 和 TA-Lib 库。',
faqNeedCoding: '需要编程经验吗?', // ===== 安装部署 =====
faqNeedCodingAnswer: faqHowToInstall: '如何安装 NOFX',
'不需要NOFX 有 Web 界面进行所有配置。但基础的命令行知识有助于安装和故障排查。', faqHowToInstallAnswer:
'最简单的方法Linux/macOS运行 "curl -fsSL https://raw.githubusercontent.com/NoFxAiOS/nofx/main/install.sh | bash" - 这会自动安装 Docker 容器。然后在浏览器中打开 http://127.0.0.1:3000。手动安装或开发请克隆仓库并按照 README 说明操作。',
faqGetApiKeys: '如何获取 API 密钥', faqWindowsInstallation: 'Windows 如何安装',
faqGetApiKeysAnswer: faqWindowsInstallationAnswer:
'币安:账户 → API 管理 → 创建 API → 启用合约。Hyperliquid访问 Hyperliquid App → API 设置。Aster DEX配置主钱包地址User、API 钱包地址Signer和私钥Private Key。', '三种方式1Docker Desktop推荐- 安装 Docker Desktop然后在 PowerShell 中运行 "docker compose -f docker-compose.prod.yml up -d"2WSL2 - 安装 Windows 子系统 Linux然后按 Linux 方式安装3WSL2 + Docker - 两全其美,在 WSL2 终端运行安装脚本。通过 http://127.0.0.1:3000 访问。',
faqUseSubaccount: '应该使用子账户吗?',
faqUseSubaccountAnswer:
'推荐:是的,使用专门的子账户运行 NOFX 可以更好地隔离风险。但请注意,某些子账户有限制(例如币安子账户最高 5 倍杠杆)。',
faqDockerDeployment: 'Docker 部署一直失败', faqDockerDeployment: 'Docker 部署一直失败',
faqDockerDeploymentAnswer: faqDockerDeploymentAnswer:
'常见问题:网络连接问题、依赖安装失败、内存不足(需要至少 2C2G如果卡在 "go build" 不动尝试docker compose down && docker compose build --no-cache && docker compose up -d', '常见解决方案1检查 Docker 是否运行:"docker info"2确保足够内存最少 2GB3如果卡在 "go build",尝试:"docker compose down && docker compose build --no-cache && docker compose up -d"4查看日志"docker compose logs -f"5拉取较慢时在 daemon.json 配置 Docker 镜像。',
faqBalanceZero: '账户余额显示为 0', faqManualInstallation: '如何手动安装用于开发?',
faqBalanceZeroAnswer: faqManualInstallationAnswer:
'资金可能在现货账户而非合约账户,或被理财功能锁定。您需要在币安手动将资金划转到合约账户。', '前置条件Go 1.21+、Node.js 18+、TA-Lib。步骤1克隆仓库"git clone https://github.com/NoFxAiOS/nofx.git"2安装后端依赖"go mod download"3安装前端依赖"cd web && npm install"4构建后端"go build -o nofx"5运行后端"./nofx"6运行前端新终端"cd web && npm run dev"。访问 http://127.0.0.1:3000',
faqTestnet: '可以使用测试网测试吗', faqServerDeployment: '如何部署到远程服务器',
faqTestnetAnswer: faqServerDeploymentAnswer:
'暂时不支持测试网。我们建议使用真实交易但小额资金10-50 USDT进行测试。', '在服务器上运行安装脚本 - 它会自动检测服务器 IP。通过 http://服务器IP:3000 访问。配置 HTTPS1使用 Cloudflare免费- 添加域名,创建 A 记录指向服务器 IPSSL 设为"灵活"2在 .env 中启用 TRANSPORT_ENCRYPTION=true 进行浏览器端加密3通过 https://你的域名.com 访问。',
// Trading Questions faqUpdateNOFX: '如何更新 NOFX',
faqNoTrades: '为什么我的交易员不开仓?', faqUpdateNOFXAnswer:
faqNoTradesAnswer: 'Docker 方式:运行 "docker compose pull && docker compose up -d" 拉取最新镜像并重启。手动安装:后端 "git pull && go build -o nofx",前端 "cd web && npm install && npm run build"。data.db 中的配置在更新时会保留。',
'常见原因AI 根据市场情况决定"等待";余额或保证金不足;达到持仓上限(默认最多 3 个仓位);查看故障排查指南了解详细诊断。',
// ===== 配置设置 =====
faqConfigureAIModels: '如何配置 AI 模型?',
faqConfigureAIModelsAnswer:
'进入配置页面 → AI 模型部分。对于每个模型1从提供商获取 API 密钥界面提供链接2输入 API 密钥3可选自定义基础 URL 和模型名称4保存。API 密钥在存储前会加密。保存后测试连接以验证。',
faqConfigureExchanges: '如何配置交易所连接?',
faqConfigureExchangesAnswer:
'进入配置页面 → 交易所部分。点击"添加交易所"选择类型并输入凭证。CEX币安/Bybit/OKX需要 API Key + Secret KeyOKX 还需要 Passphrase。DEXHyperliquid/Aster/Lighter需要钱包地址和私钥。务必只启用必要权限合约交易并考虑 IP 白名单。',
faqBinanceAPISetup: '如何正确设置币安 API',
faqBinanceAPISetupAnswer:
'重要步骤1在币安 → API 管理中创建 API 密钥2仅启用"启用合约"权限3考虑添加 IP 白名单增强安全4关键在合约设置 → 偏好设置 → 持仓模式中切换为双向持仓模式5确保资金在合约钱包不是现货。-4061 错误表示需要双向持仓模式。',
faqHyperliquidSetup: '如何设置 Hyperliquid',
faqHyperliquidSetupAnswer:
'Hyperliquid 是去中心化交易所需要钱包认证。步骤1访问 app.hyperliquid.xyz2连接钱包3生成 API 钱包推荐或使用主钱包4复制钱包地址和私钥5在 NOFX 中添加 Hyperliquid 交易所并填入凭证。无需 KYC完全链上。',
faqCreateStrategy: '如何创建交易策略?',
faqCreateStrategyAnswer:
'进入策略工作室1币种来源 - 选择交易哪些币静态列表、AI500 池或 OI 排行2指标 - 启用技术指标EMA、MACD、RSI、ATR、成交量、OI、资金费率3风控 - 设置杠杆限制、最大持仓数、保证金使用上限、仓位大小限制4自定义提示词可选- 为 AI 添加特定指令。保存后分配给交易员。',
faqCreateTrader: '如何创建并启动交易员?',
faqCreateTraderAnswer:
'进入交易员页面1点击"创建交易员"2选择 AI 模型需先配置3选择交易所需先配置4选择策略或使用默认5设置决策间隔如 5 分钟6保存然后点击"启动"开始交易。在仪表板页面监控表现。',
// ===== 交易相关 =====
faqHowAIDecides: 'AI 如何做出交易决策?',
faqHowAIDecidesAnswer:
'AI 使用思维链CoT推理分 4 步1持仓分析 - 审查当前持仓和盈亏2风险评估 - 检查账户保证金、可用余额3机会评估 - 分析市场数据、指标、候选币种4最终决策 - 输出具体操作(买入/卖出/持有)及理由。您可以在决策日志中查看完整推理过程。',
faqDecisionFrequency: 'AI 多久做一次决策?', faqDecisionFrequency: 'AI 多久做一次决策?',
faqDecisionFrequencyAnswer: faqDecisionFrequencyAnswer:
'配置默认是每 3-5 分钟。太频繁 = 过度交易,太慢 = 错过机会。', '每个交易员可单独配置默认 3-5 分钟。考虑因素太频繁1-2 分钟)= 过度交易、手续费高太慢30+ 分钟)= 错过机会。建议:活跃交易 5 分钟,波段交易 15-30 分钟。AI 在很多周期可能决定"持有"(不操作)。',
faqCustomStrategy: '可以自定义交易策略吗', faqNoTradesExecuting: '为什么交易员不执行任何交易',
faqCustomStrategyAnswer: faqNoTradesExecutingAnswer:
'可以!您可以调整杠杆设置、修改币种选择池、更改决策间隔、自定义系统提示词(高级)。', '常见原因1AI 决定等待查看决策日志了解原因2合约账户余额不足3达到最大持仓数限制默认34交易所 API 问题检查错误信息5策略约束太严格。查看仪表板 → 决策日志了解每个周期的 AI 推理详情。',
faqMaxPositions: '最多可以同时持有多少个仓位', faqOnlyShortPositions: '为什么 AI 只开空单',
faqMaxPositionsAnswer: faqOnlyShortPositionsAnswer:
'默认3 个仓位。这是 AI 提示词中的软限制,不是硬编码。', '通常是因为币安持仓模式问题。解决方案:在币安合约 → 偏好设置 → 持仓模式中切换为双向持仓。必须先平掉所有持仓。切换后AI 可以独立开多单和空单。',
faqMarginInsufficient: '保证金不足错误 (code=-2019)', faqLeverageSettings: '杠杆设置如何工作?',
faqMarginInsufficientAnswer: faqLeverageSettingsAnswer:
'常见原因:资金未划转到合约账户;杠杆倍数设置过高(默认 20-50 倍);已有持仓占用保证金;需要先从现货账户划转 USDT 到合约账户。', '杠杆在策略 → 风控中设置BTC/ETH 杠杆(通常 5-20 倍)和山寨币杠杆(通常 3-10 倍)。更高杠杆 = 更高风险和潜在收益。子账户可能有限制(如币安子账户限制 5 倍。AI 下单时会遵守这些限制。',
faqHighFees: '交易手续费太高', faqStopLossTakeProfit: 'NOFX 支持止损止盈吗?',
faqHighFeesAnswer: faqStopLossTakeProfitAnswer:
'NOFX 默认 3 分钟扫描间隔会导致频繁交易。解决方案:将决策间隔增加到 5-10 分钟;优化系统提示词减少过度交易;调整杠杆降低仓位大小。', 'AI 可以在决策中建议止损/止盈价位但这是基于指导而非交易所硬编码订单。AI 每个周期监控持仓,可能根据盈亏决定平仓。如需保证止损,可以手动在交易所设置订单,或调整策略提示词使其更保守。',
faqNoTakeProfit: 'AI 不平掉盈利的仓位', faqMultipleTraders: '可以运行多个交易员吗?',
faqNoTakeProfitAnswer: faqMultipleTradersAnswer:
'AI 可能认为趋势会继续。系统目前缺少移动止盈功能。您可以手动平仓或调整系统提示词使其在获利时更保守。', '可以NOFX 支持运行 20+ 个并发交易员。每个交易员可以有不同的AI 模型、交易所账户、策略、决策间隔。用于 A/B 测试策略、比较 AI 模型或跨交易所分散风险。在竞赛页面监控所有交易员。',
// Technical Issues faqAICosts: 'AI API 调用费用是多少?',
faqBinanceApiFailed: '币安 API 调用失败 (code=-2015)', faqAICostsAnswer:
faqBinanceApiFailedAnswer: '每个交易员每天大约费用5 分钟间隔DeepSeek$0.10-0.50Qwen$0.20-0.80OpenAI$2-5Claude$1-3。费用取决于提示词长度和响应 token 数。DeepSeek 性价比最高。更长的决策间隔可降低费用。',
'错误:"Invalid API-key, IP, or permissions for action"。解决方案:将服务器 IP 添加到币安 API 白名单;检查 API 权限(需要读取 + 合约交易);确保使用合约 API 而非统一账户 APIVPN IP 可能不稳定。',
faqBinancePositionMode: '币安持仓模式错误 (code=-4061)', // ===== 技术问题 =====
faqBinancePositionModeAnswer: faqPortInUse: '端口 8080 或 3000 被占用',
'错误信息:"Order\'s position side does not match user\'s setting"。解决方法:切换为双向持仓模式。登录币安合约 → 点击右上角偏好设置 → 选择持仓模式 → 双向持仓。注意:先平掉所有持仓。',
faqPortInUse: '后端无法启动 / 端口被占用',
faqPortInUseAnswer: faqPortInUseAnswer:
'使用 "lsof -i :8080" 查看占用端口的进程在 .env 中修改端口NOFX_BACKEND_PORT=8081。', '查看占用端口的进程macOS/Linux 用 "lsof -i :8080"Windows 用 "netstat -ano | findstr 8080"。终止进程在 .env 中修改端口NOFX_BACKEND_PORT=8081、NOFX_FRONTEND_PORT=3001。然后 "docker compose down && docker compose up -d" 重启。',
faqFrontendLoading: '前端一直显示"加载中..."', faqFrontendNotLoading: '前端一直显示"加载中..."',
faqFrontendLoadingAnswer: faqFrontendNotLoadingAnswer:
'使用 "curl http://localhost:8080/api/health" 检查后端是否运行。应该返回 {"status":"ok"}。如果不是,查看故障排查指南。', '后端可能未运行或无法访问。检查1"curl http://127.0.0.1:8080/api/health" 返回 {"status":"ok"}2"docker compose ps" 验证容器运行中3查看后端日志"docker compose logs nofx-backend"4确保防火墙允许 8080 端口。',
faqDatabaseLocked: '数据库锁定错误', faqDatabaseLocked: '数据库锁定错误',
faqDatabaseLockedAnswer: faqDatabaseLockedAnswer:
'使用 "docker compose down" 或 "pkill nofx" 停止所有 NOFX 进程,然后使用 "docker compose up -d" 重启。', '多个进程同时访问 SQLite 导致。解决方案1停止所有进程"docker compose down" 或 "pkill nofx"2如有锁文件删除"rm -f data/data.db-wal data/data.db-shm"3重启"docker compose up -d"。只能有一个后端实例访问数据库。',
faqAiLearningFailed: 'AI 学习数据加载失败', faqTALibNotFound: '构建时找不到 TA-Lib',
faqAiLearningFailedAnswer: faqTALibNotFoundAnswer:
'原因:TA-Lib 库未正确安装;历史数据不足(需要完成交易);环境配置问题。安装 TA-Libpip install TA-Lib 或检查系统依赖。', 'TA-Lib 是技术指标所需。安装macOS"brew install ta-lib"Ubuntu/Debian"sudo apt-get install libta-lib0-dev"CentOS"yum install ta-lib-devel"。安装后重新构建:"go build -o nofx"。Docker 镜像已预装 TA-Lib。',
faqConfigNotEffective: '配置文件修改不生效', faqAIAPITimeout: 'AI API 超时或连接被拒绝',
faqConfigNotEffectiveAnswer: faqAIAPITimeoutAnswer:
'Docker 需要重新构建:"docker compose down && docker compose up -d --build"。PM2 需要重启:"pm2 restart all"。检查配置文件格式和路径是否正确。', '检查1API 密钥有效(用 curl 测试2网络能访问 API 端点ping/curl3API 提供商未宕机查看状态页4VPN/防火墙未阻止5未超过速率限制。默认超时 120 秒。',
// AI & Model Questions faqBinancePositionMode: '币安错误代码 -4061持仓模式',
faqWhichModels: '支持哪些 AI 模型?', faqBinancePositionModeAnswer:
faqWhichModelsAnswer: '错误:"Order\'s position side does not match user\'s setting"。您处于单向持仓模式,但 NOFX 需要双向持仓模式。修复1先平掉所有持仓2币安合约 → 设置(齿轮图标)→ 偏好设置 → 持仓模式 → 切换为"双向持仓"3重启交易员。',
'DeepSeek推荐性价比、Qwen阿里云通义千问、自定义 OpenAI 兼容 API可用于 OpenAI、通过代理的 Claude 或其他提供商)。',
faqApiCosts: 'API 调用成本是多少?', faqBalanceShowsZero: '账户余额显示 0',
faqApiCostsAnswer: faqBalanceShowsZeroAnswer:
'取决于您的模型和决策频率DeepSeek每天约 $0.10-0.501 个交易员5 分钟间隔Qwen每天约 $0.20-0.80;自定义 API例如 OpenAI GPT-4每天约 $2-5。基于典型使用的估算。', '资金可能在现货钱包而非合约钱包。解决方案1在币安进入钱包 → 合约 → 划转2将 USDT 从现货划转到合约3刷新 NOFX 仪表板。也检查:资金未被理财/质押产品锁定。',
faqMultipleModels: '可以使用多个 AI 模型吗?', faqDockerPullFailed: 'Docker 镜像拉取失败或缓慢',
faqMultipleModelsAnswer: faqDockerPullFailedAnswer:
'可以!每个交易员可以使用不同的 AI 模型。您甚至可以 A/B 测试不同模型。', 'Docker Hub 在某些地区可能较慢。解决方案1在 /etc/docker/daemon.json 配置 Docker 镜像:{"registry-mirrors": ["https://mirror.gcr.io"]}2重启 Docker3重试拉取。或使用 GitHub Container Registryghcr.io在您的地区可能连接更好。',
faqAiLearning: 'AI 会从错误中学习吗?', // ===== 安全相关 =====
faqAiLearningAnswer: faqAPIKeyStorage: 'API 密钥如何存储?',
'会的在一定程度上。NOFX 在每次决策提示中提供历史表现反馈,允许 AI 调整策略。', faqAPIKeyStorageAnswer:
'API 密钥使用 AES-256-GCM 加密后存储在本地 SQLite 数据库中。加密密钥DATA_ENCRYPTION_KEY存储在您的 .env 文件中。密钥仅在 API 调用需要时在内存中解密。切勿分享您的 data.db 或 .env 文件。',
faqOnlyShort: 'AI 只开空单,不开多单', faqEncryptionDetails: 'NOFX 使用什么加密?',
faqOnlyShortAnswer: faqEncryptionDetailsAnswer:
'默认系统提示词包含"不要有做多偏见!做空是你的核心工具之一",可能导致此问题。还受 4 小时周期数据和模型训练偏向性影响。您可以修改系统提示词使其更平衡。', 'NOFX 使用多层加密1AES-256-GCM 用于数据库存储API 密钥、密钥2RSA-2048 用于可选的传输加密浏览器到服务器3JWT 用于认证令牌。密钥在安装时生成。HTTPS 环境启用 TRANSPORT_ENCRYPTION=true。',
faqModelSelection: '应该使用哪个 DeepSeek 版本', faqSecurityBestPractices: '安全最佳实践是什么',
faqModelSelectionAnswer: faqSecurityBestPracticesAnswer:
'推荐使用 DeepSeek V3 以获得最佳性能。备选DeepSeek R1推理模型较慢但逻辑更好、SiliconFlow 的 DeepSeek备用 API 提供商)。大多数用户反馈 V3 效果良好。', '建议1使用带 IP 白名单和最小权限(仅合约交易)的交易所 API 密钥2为 NOFX 使用专用子账户3远程部署启用 TRANSPORT_ENCRYPTION4切勿分享 .env 或 data.db 文件5使用有效证书的 HTTPS6定期轮换 API 密钥7监控账户活动。',
// Data & Privacy faqCanNOFXStealFunds: 'NOFX 会盗取我的资金吗?',
faqDataStorage: '我的数据存储在哪里?', faqCanNOFXStealFundsAnswer:
faqDataStorageAnswer: 'NOFX 是开源的AGPL-3.0 许可)- 您可以在 GitHub 审计所有代码。API 密钥存储在您的机器本地从不发送到外部服务器。NOFX 只有您通过 API 密钥授予的权限。为最大安全:使用仅交易权限(无提现)的 API 密钥,启用 IP 白名单,使用专用子账户。',
'所有数据都本地存储在您的机器上,使用 SQLite 数据库data.db所有配置和交易历史、decision_logs/AI 决策记录)。',
faqApiKeySecurity: 'API 密钥安全吗?', // ===== 功能介绍 =====
faqApiKeySecurityAnswer: faqStrategyStudio: '什么是策略工作室?',
'API 密钥存储在本地数据库中。永远不要分享您的数据库或 .env 文件。我们建议使用带 IP 白名单限制的 API 密钥。', faqStrategyStudioAnswer:
'策略工作室是可视化策略构建器您可以配置1币种来源 - 交易哪些加密货币静态列表、AI500 热门币、OI 排行2技术指标 - EMA、MACD、RSI、ATR、成交量、持仓量、资金费率3风控 - 杠杆限制、仓位大小、保证金上限4自定义提示词 - AI 的特定指令。无需编程。',
faqExportHistory: '可以导出交易历史吗', faqBacktestLab: '什么是回测实验室',
faqExportHistoryAnswer: faqBacktestLabAnswer:
'可以!交易数据是 SQLite 格式。您可以直接查询sqlite3 trading.db "SELECT * FROM trades;"', '回测实验室用历史数据测试您的策略无需冒真金风险。功能1配置 AI 模型、日期范围、初始余额2实时观看进度和权益曲线3查看指标收益率、最大回撤、夏普比率、胜率4分析单笔交易和 AI 推理。实盘交易前验证策略的必备工具。',
faqGetHelp: '在哪里可以获得帮助', faqDebateArena: '什么是辩论竞技场',
faqGetHelpAnswer: faqDebateArenaAnswer:
'查看 GitHub Discussions、加入 Telegram 社区或在 GitHub 上提出 issue。', '辩论竞技场让多个 AI 模型在执行前辩论交易决策。设置1选择 2-5 个 AI 模型2分配角色多头、空头、分析师、逆向者、风险经理3观看他们多轮辩论4基于共识投票做最终决策。适用于需要多角度考虑的高确信度交易。',
faqCompetitionMode: '什么是竞赛模式?',
faqCompetitionModeAnswer:
'竞赛页面显示所有交易员的实时排行榜。比较ROI、盈亏、夏普比率、胜率、交易次数。用于 A/B 测试不同 AI 模型、策略或配置。交易员可标记为"在竞赛中显示"以出现在排行榜上。',
faqChainOfThought: '什么是思维链CoT',
faqChainOfThoughtAnswer:
'思维链是 AI 的推理过程可在决策日志中查看。AI 分 4 步解释思考1当前持仓分析2账户风险评估3市场机会评估4最终决策理由。这种透明度帮助您理解 AI 为什么做出每个决策,有助于改进策略。',
// ===== AI 模型 =====
faqWhichAIModelBest: '应该使用哪个 AI 模型?',
faqWhichAIModelBestAnswer:
'推荐DeepSeek 性价比最高(每天 $0.10-0.50。备选OpenAI 推理能力最强但贵(每天 $2-5Claude 适合细致分析Qwen 价格有竞争力。您可以运行多个交易员使用不同模型进行比较。查看竞赛页面看哪个对您的策略表现最好。',
faqCustomAIAPI: '可以使用自定义 AI API 吗?',
faqCustomAIAPIAnswer:
'可以NOFX 支持任何 OpenAI 兼容的 API。在配置 → AI 模型 → 自定义 API 中1输入 API 端点 URL如 https://your-api.com/v12输入 API 密钥3指定模型名称。适用于自托管模型、替代提供商或通过第三方代理的 Claude。',
faqAIHallucinations: 'AI 幻觉问题怎么办?',
faqAIHallucinationsAnswer:
'AI 模型有时会产生不正确或虚构的信息("幻觉"。NOFX 通过以下方式缓解1提供带真实市场数据的结构化提示词2强制 JSON 输出格式3执行前验证订单。但 AI 交易是实验性的 - 始终监控决策,不要完全依赖 AI 判断。',
faqCompareAIModels: '如何比较不同 AI 模型?',
faqCompareAIModelsAnswer:
'创建多个交易员,使用不同 AI 模型但相同策略/交易所。同时运行并在竞赛页面比较。关注指标ROI、胜率、夏普比率、最大回撤。或者使用回测实验室用相同历史数据测试模型。辩论竞技场也展示不同模型对同一情况的推理方式。',
// ===== 参与贡献 =====
faqHowToContribute: '如何为 NOFX 做贡献?',
faqHowToContributeAnswer:
'NOFX 是开源项目欢迎贡献贡献方式1代码 - 修复 bug、添加功能查看 GitHub Issues2文档 - 改进指南、翻译3Bug 报告 - 详细报告问题4功能建议 - 提出改进意见。从标记为"good first issue"的问题开始。所有贡献者可能获得空投奖励。',
faqPRGuidelines: 'PR 指南是什么?',
faqPRGuidelinesAnswer:
'PR 流程1Fork 仓库到您的账户2从 dev 创建功能分支:"git checkout -b feat/your-feature"3修改代码运行 lint"npm --prefix web run lint"4使用 Conventional Commits 格式提交5推送并创建 PR 到 NoFxAiOS/nofx:dev6关联相关 issueCloses #1237等待审核。保持 PR 小而聚焦。',
faqBountyProgram: '有赏金计划吗?',
faqBountyProgramAnswer:
'有贡献者根据贡献获得空投奖励代码提交权重最高、bug 修复、功能建议、文档。带"bounty"标签的 issue 有现金奖励。完成工作后提交 Bounty Claim。查看 CONTRIBUTING.md 了解奖励结构详情。',
faqReportBugs: '如何报告 bug',
faqReportBugsAnswer:
'Bug 报告:在 GitHub 开 Issue包含1问题清晰描述2复现步骤3预期 vs 实际行为4系统信息OS、Docker 版本、浏览器5相关日志。安全漏洞不要开公开 issue - 请在 Twitter 私信 @Web3Tinkle。',
// Web Crypto Environment Check // Web Crypto Environment Check
environmentCheck: { environmentCheck: {