From Research to Production: Complete Strategy Development Workflow
This document provides a complete end-to-end example showing how to go from a strategy idea through backtesting, optimization, and validation, all the way to live trading deployment, covering the entire lifecycle of a quantitative trading strategy.
Full-Process AI Assistance
Every stage of this workflow can be completed with the help of an AI coding assistant. After installing FinLab Skill, AI can assist with writing code, interpreting performance, and troubleshooting errors from strategy conception to live deployment.
Workflow Overview
graph TD
A[策略構想] --> B[資料探索]
B --> C[策略開發]
C --> D[策略優化]
D --> E[深度分析]
E --> F[樣本外測試]
F --> G{通過驗證?}
G -->|是| H[部署前準備]
G -->|否| C
H --> I[實盤交易]
I --> J[績效追蹤]
J --> K{需要調整?}
K -->|是| C
K -->|否| I
Stage 1: Strategy Conception & Initial Research
Strategy Hypothesis
We will develop a "Revenue Growth + Technical Breakout" combination strategy:
- Fundamentals: Revenue is accelerating recently (monthly moving average trending up)
- Technicals: Price breaks above moving averages, confirming momentum
- Risk Control: Exit when price drops below moving average, set 10% stop loss
Data Exploration
First, check whether the required data is complete:
from finlab import data
import pandas as pd
# Load required data
close = data.get('price:收盤價')
rev = data.get('monthly_revenue:當月營收')
# Check data range
print(f"收盤價資料: {close.index[0]} ~ {close.index[-1]}")
print(f"營收資料: {rev.index[0]} ~ {rev.index[-1]}")
# Check missing value ratio
print(f"收盤價缺失值: {close.isna().sum().sum() / close.size * 100:.2f}%")
print(f"營收缺失值: {rev.isna().sum().sum() / rev.size * 100:.2f}%")
# Output:
# 收盤價資料: 2007-04-23 ~ 2024-12-31
# 營收資料: 2000-01-01 ~ 2024-12-01
# 收盤價缺失值: 2.15%
# 營收缺失值: 8.73%
Stage 2: Strategy Development & Backtesting
Writing Strategy Logic
from finlab import data
from finlab.backtest import sim
# 1. Load data
close = data.get('price:收盤價')
rev = data.get('monthly_revenue:當月營收')
# 2. Calculate technical indicators
ma20 = close.average(20)
ma60 = close.average(60)
# 3. Calculate revenue indicators
rev_ma3 = rev.average(3) # 近 3 個月平均營收
rev_ma12 = rev.average(12) # 近 12 個月平均營收
# 4. Define entry conditions
entry_tech = (close > ma20) & (close > ma60) # 技術面:突破均線
entry_fund = (rev_ma3 / rev_ma12) > 1.1 # 基本面:營收加速成長
entry_signal = entry_tech & entry_fund
# 5. Define exit conditions
exit_signal = close < ma20 # 跌破 20 日均線
# 6. Combine entry/exit signals (with stop loss)
position = entry_signal.hold_until(
exit=exit_signal,
stop_loss=0.1 # 停損 10%
)
# 7. Backtest
report = sim(
position,
resample='M', # 每月調整
position_limit=0.1, # 單一持股上限 10%
upload=False,
name="營收成長突破策略 v1.0"
)
# 8. Display performance
report.display()
Preliminary Performance Evaluation
stats = report.get_stats()
print(f"年化報酬率: {stats['daily_mean']*100:.2f}%")
print(f"夏普率: {stats['daily_sharpe']:.2f}")
print(f"最大回撤: {stats['max_drawdown']*100:.2f}%")
print(f"勝率: {stats['win_ratio']*100:.2f}%")
# Example output:
# 年化報酬率: 15.23%
# 夏普率: 0.87
# 最大回撤: -28.45%
# 勝率: 52.3%
Preliminary Assessment
- 15% annualized return is decent, but Sharpe ratio of 0.87 is somewhat low
- Max drawdown of -28% is acceptable
- Next step: optimize the strategy to improve risk-adjusted returns
Stage 3: Strategy Optimization
3.1 Use sim_conditions() to Test Condition Combinations
We add more candidate conditions to find the best combination:
from finlab.optimize.combinations import sim_conditions
# Original conditions
c1 = (close > ma20) & (close > ma60) # 均線多頭
c2 = rev_ma3 / rev_ma12 > 1.1 # 營收加速
# New conditions
pe = data.get('price_earning_ratio:本益比')
c3 = pe < 15 # 低本益比
c4 = close == close.rolling(20).max() # 創 20 日新高
c5 = rev / rev.shift(1) > 0.9 # 營收月增率 > -10%
# Conditions dictionary
conditions = {
'c1': c1, # 均線多頭
'c2': c2, # 營收加速
'c3': c3, # 低本益比
'c4': c4, # 創新高
'c5': c5 # 營收月增率
}
# Test all combinations (31 total)
report_collection = sim_conditions(
conditions=conditions,
hold_until={'exit': exit_signal, 'stop_loss': 0.1},
resample='M',
position_limit=0.1,
upload=False
)
# Visualize comparison
report_collection.plot_stats('heatmap')
3.2 Analyze Optimization Results
# Get performance metrics table
stats_df = report_collection.get_stats()
# Find top 3 combinations
top3 = stats_df.T.sort_values('daily_sharpe', ascending=False).head(3)
print(top3[['daily_mean', 'daily_sharpe', 'max_drawdown', 'win_ratio']])
# Example output:
# daily_mean daily_sharpe max_drawdown win_ratio
# c1 & c2 & c3 0.182 1.35 -0.245 0.561
# c1 & c2 & c5 0.165 1.28 -0.267 0.548
# c1 & c2 0.152 0.87 -0.285 0.523
Optimization Results
The c1 & c2 & c3 (MA bull + Revenue acceleration + Low P/E) combination improved the Sharpe ratio from 0.87 to 1.35, a significant improvement!
3.3 Adopt the Best Combination
# Redefine strategy using the best combination
best_entry = c1 & c2 & c3
position_optimized = best_entry.hold_until(
exit=exit_signal,
stop_loss=0.1
)
report_opt = sim(
position_optimized,
resample='M',
position_limit=0.1,
upload=False,
name="營收成長突破策略 v2.0 (優化後)"
)
3.4 Optimize Stop Loss & Take Profit
Use MAE/MFE analysis to find optimal stop loss/take profit levels:
# Display volatility analysis
report_opt.display_mae_mfe_analysis()
# Get trade records
trades = report_opt.get_trades()
# Analyze MAE/MFE quantiles
mae_q75 = abs(trades['mae'].quantile(0.75))
gmfe_q75 = trades['gmfe'].quantile(0.75)
print(f"MAE Q75: {mae_q75*100:.2f}%") # e.g., 8.5%
print(f"GMFE Q75: {gmfe_q75*100:.2f}%") # e.g., 18.3%
# Adjust stop loss/take profit
position_final = best_entry.hold_until(
exit=exit_signal,
stop_loss=mae_q75 * 1.2, # 停損設為 MAE Q75 * 1.2 = 10.2%
take_profit=gmfe_q75 * 0.8 # 停利設為 GMFE Q75 * 0.8 = 14.6%
)
report_final = sim(
position_final,
resample='M',
position_limit=0.1,
upload=False,
name="營收成長突破策略 v3.0 (最終版)"
)
Stage 4: In-Depth Analysis
4.1 Liquidity Risk Assessment
Check whether the strategy is suitable for large capital:
# Liquidity analysis (assuming 10M TWD capital, minimum 100K shares per entry/exit)
report_final.run_analysis('LiquidityAnalysis', required_volume=100000)
# Example output:
# buy_high sell_low low_volume_stocks 處置股
# entry 0.032 0.008 0.087 0.012
# exit 0.015 0.045 0.092 0.008
Liquidity Review
- Low volume stock ratio of 8.7% -- large capital should be cautious
- Disposition stock ratio of 1.2% -- acceptable
- Recommend adding volume screening conditions
4.2 Annual Stability Analysis
Review strategy performance across different years:
report_final.run_analysis('PeriodStatsAnalysis')
# Output shows Sharpe ratio, return, volatility, etc. for each year
# Check if the strategy performs particularly poorly in certain years
4.3 Alpha/Beta Analysis
Measure the strategy's excess return:
report_final.run_analysis('AlphaBetaAnalysis')
# Displays three sections: overall summary, annual Alpha/Beta, recent Alpha/Beta
# Example output:
# Alpha: 8.20% (annualized excess return)
# Beta: 0.65 (market sensitivity)
To obtain raw values for further analysis:
result = report_final.run_analysis('AlphaBetaAnalysis', display=False)
print(f"Alpha: {result['overall']['alpha']:.2%}")
print(f"Beta: {result['overall']['beta']:.2f}")
Alpha/Beta Assessment
- Alpha of 8.2% is excellent, indicating genuine excess returns
- Beta of 0.65 means the strategy has lower volatility than the market
Stage 5: Out-of-Sample Testing
Split data into training and testing sets to verify the strategy is not overfit:
# Define split date
train_end = '2022-12-31'
test_start = '2023-01-01'
# Training set backtest (2018-2022)
position_train = position_final[position_final.index <= train_end]
report_train = sim(
position_train,
resample='M',
position_limit=0.1,
upload=False,
name="訓練集(2018-2022)"
)
# Test set backtest (2023-2024)
position_test = position_final[position_final.index >= test_start]
report_test = sim(
position_test,
resample='M',
position_limit=0.1,
upload=False,
name="測試集(2023-2024)"
)
# Performance comparison
stats_train = report_train.get_stats()
stats_test = report_test.get_stats()
comparison = pd.DataFrame({
'訓練集': [
stats_train['daily_mean'],
stats_train['daily_sharpe'],
stats_train['max_drawdown'],
stats_train['win_ratio']
],
'測試集': [
stats_test['daily_mean'],
stats_test['daily_sharpe'],
stats_test['max_drawdown'],
stats_test['win_ratio']
]
}, index=['年化報酬率', '夏普率', '最大回撤', '勝率'])
print(comparison)
# Example output:
# 訓練集 測試集
# 年化報酬率 0.182 0.165
# 夏普率 1.35 1.21
# 最大回撤 -0.245 -0.267
# 勝率 0.561 0.542
Out-of-Sample Evaluation Criteria
| Metric | Training vs Testing | Assessment |
|---|---|---|
| Annualized Return | 18.2% vs 16.5% | Pass -- reasonable degradation (<20%) |
| Sharpe Ratio | 1.35 vs 1.21 | Pass -- slight decrease but still > 1 |
| Max Drawdown | -24.5% vs -26.7% | Pass -- small difference |
| Win Rate | 56.1% vs 54.2% | Pass -- stable |
Out-of-Sample Test Passed
Test set performance decreased slightly but remains excellent. The strategy is not overfit and can proceed to deployment!
Stage 6: Pre-Deployment Preparation
6.1 Upload Strategy to Cloud
# Upload the final version to the FinLab platform
report_final.upload(name="營收成長突破策略 v3.0")
# Get position list
position_info = report_final.position_info()
print(f"下期換股日: {position_info['next_trading_date']}")
# position_info keys are stock symbols (e.g., '2330 台積電'), mixed with some metadata keys
# Filter out holdings (exclude metadata keys)
metadata_keys = {'update_date', 'next_trading_date', 'trade_at', 'freq', 'market', 'stop_loss', 'take_profit'}
stocks = {k: v for k, v in position_info.items() if k not in metadata_keys}
print(f"當前持股數: {len(stocks)}")
print("持股清單:")
for symbol, info in stocks.items():
print(f" {symbol}: 權重={info['weight']:.2%}, 狀態={info['status']}")
# Example output:
# 下期換股日: 2025-01-31
# 當前持股數: 8
# 持股清單:
# 2330 台積電: 權重=12.00%, 狀態=hold
# 2317 鴻海: 權重=11.00%, 狀態=hold
# 2454 聯發科: 權重=10.00%, 狀態=hold
# ...
6.2 Prepare Live Capital Allocation
# Assuming 1M TWD live capital
capital = 1000000
# Calculate the amount to invest in each stock
stocks = position_info['stocks']
stocks['amount'] = stocks['position'] * capital
print(stocks[['stock_id', 'position', 'amount']])
# Output:
# stock_id position amount
# 0 2330 0.12 120000
# 1 2317 0.11 110000
# ...
Stage 7: Live Trading
7.1 Set Up Broker Account (Sinopac Securities Example)
from finlab.online.sinopac_account import SinopacAccount
# Set up broker account (environment variables must be configured first; see live trading tutorial)
account = SinopacAccount()
Live Trading Precautions
- For first-time use, test with
view_only=Truefor simulated orders - Confirm broker API keys are correct
- Ensure sufficient funds and credit limits
- Start with small capital for testing
7.2 Calculate Target Positions
from finlab.online.order_executor import Position
# Calculate target positions (round lots)
capital = 1000000 # 實盤資金 100 萬
position = Position.from_report(report_final, capital)
# Or use odd lot trading
position = Position.from_report(report_final, capital, odd_lot=True)
print(position)
# Output: [{'stock_id': '2330', 'quantity': 5, 'order_condition': <OrderCondition.CASH: 1>}, ...]
7.3 Execute Orders
from finlab.online.order_executor import OrderExecutor
# Create order executor
order_executor = OrderExecutor(position, account=account)
# Order preview (view mode, no actual orders placed)
order_executor.create_orders(view_only=True)
# Execute orders (actual orders placed; test during market close for first-time use)
order_executor.create_orders()
# Update limit price (use last trade price as new limit price)
order_executor.update_order_price()
# Cancel all pending orders
order_executor.cancel_orders()
Stage 8: Performance Tracking
8.1 Retrieve Live Trading Records
# Get live positions
account_positions = account.get_position()
print(account_positions)
# Get account total value and cash
account_value = account.get_total_balance()
print(f"帳戶總值: {account_value:,.0f}")
8.2 Monitor Strategy Performance
# Periodically check account status (recommended after each market close)
import pandas as pd
# Record daily account value
daily_value = {
'date': pd.Timestamp.today(),
'account_value': account.get_total_balance(),
'positions': len(account.get_position())
}
print(f"日期: {daily_value['date']}")
print(f"帳戶淨值: {daily_value['account_value']:,.0f}")
print(f"持股檔數: {daily_value['positions']}")
# Compare with backtest
backtest_return = report_final.get_stats()['daily_mean']
print(f"回測年化報酬率: {backtest_return * 100:.2f}%")
8.3 Periodic Review
Recommended monthly review items:
# 1. Check if holdings follow the plan
current_stocks = set(account_positions['stock_id'])
planned_stocks = set(position_info['stocks']['stock_id'])
print(f"計劃持股: {planned_stocks}")
print(f"實際持股: {current_stocks}")
print(f"誤差股票: {planned_stocks.symmetric_difference(current_stocks)}")
# 2. Check if stop loss is triggered
for stock_id, pos in account_positions.items():
entry_price = pos['avg_price']
current_price = pos['current_price']
unrealized_pnl = (current_price / entry_price - 1)
if unrealized_pnl < -0.10: # 停損 10%
print(f"警告: {stock_id} 已觸發停損,未實現損益: {unrealized_pnl*100:.2f}%")
Complete Code Summary
Below is the complete executable code:
# =============================================================================
# From Research to Production: Revenue Growth Breakout Strategy Complete Example
# =============================================================================
from finlab import data
from finlab.backtest import sim
from finlab.optimize.combinations import sim_conditions
# -----------------------------------------------------------------------------
# Stages 1 & 2: Data Loading & Strategy Development
# -----------------------------------------------------------------------------
# Load data
close = data.get('price:收盤價')
rev = data.get('monthly_revenue:當月營收')
pe = data.get('price_earning_ratio:本益比')
# Calculate indicators
ma20 = close.average(20)
ma60 = close.average(60)
rev_ma3 = rev.average(3)
rev_ma12 = rev.average(12)
# Define conditions
c1 = (close > ma20) & (close > ma60) # 均線多頭
c2 = rev_ma3 / rev_ma12 > 1.1 # 營收加速
c3 = pe < 15 # 低本益比
# Exit signal
exit_signal = close < ma20
# -----------------------------------------------------------------------------
# Stage 3: Strategy Optimization
# -----------------------------------------------------------------------------
# Test condition combinations
conditions = {'c1': c1, 'c2': c2, 'c3': c3}
report_collection = sim_conditions(
conditions=conditions,
hold_until={'exit': exit_signal, 'stop_loss': 0.1},
resample='M',
position_limit=0.1,
upload=False
)
# Find the best combination
stats_df = report_collection.get_stats()
top1 = stats_df.T.sort_values('daily_sharpe', ascending=False).index[0]
print(f"最佳組合: {top1}")
# Use the best combination
best_entry = c1 & c2 & c3
# Optimize stop loss/take profit
position_temp = best_entry.hold_until(exit=exit_signal, stop_loss=0.1)
report_temp = sim(position_temp, resample='M', position_limit=0.1, upload=False)
trades = report_temp.get_trades()
mae_q75 = abs(trades['mae'].quantile(0.75))
gmfe_q75 = trades['gmfe'].quantile(0.75)
# Final strategy
position_final = best_entry.hold_until(
exit=exit_signal,
stop_loss=mae_q75 * 1.2,
take_profit=gmfe_q75 * 0.8
)
report_final = sim(
position_final,
resample='M',
position_limit=0.1,
upload=False,
name="營收成長突破策略 v3.0"
)
# -----------------------------------------------------------------------------
# Stage 4: In-Depth Analysis
# -----------------------------------------------------------------------------
# Liquidity analysis
report_final.run_analysis('LiquidityAnalysis', required_volume=100000)
# Volatility analysis
report_final.display_mae_mfe_analysis()
# Period stability
report_final.run_analysis('PeriodStatsAnalysis')
# Alpha/Beta
report_final.run_analysis('AlphaBetaAnalysis')
# -----------------------------------------------------------------------------
# Stage 5: Out-of-Sample Testing
# -----------------------------------------------------------------------------
train_end = '2022-12-31'
test_start = '2023-01-01'
position_train = position_final[position_final.index <= train_end]
position_test = position_final[position_final.index >= test_start]
report_train = sim(position_train, resample='M', position_limit=0.1, upload=False)
report_test = sim(position_test, resample='M', position_limit=0.1, upload=False)
print("訓練集績效:", report_train.get_stats()['daily_sharpe'])
print("測試集績效:", report_test.get_stats()['daily_sharpe'])
# -----------------------------------------------------------------------------
# Stage 6: Pre-Deployment Preparation
# -----------------------------------------------------------------------------
# Upload to cloud
report_final.upload(name="營收成長突破策略 v3.0")
# Get position list
position_info = report_final.position_info()
metadata_keys = {'update_date', 'next_trading_date', 'trade_at', 'freq', 'market', 'stop_loss', 'take_profit'}
stocks = {k: v for k, v in position_info.items() if k not in metadata_keys}
print("下期持股:")
for symbol, info in stocks.items():
print(f" {symbol}: 權重={info['weight']:.2%}")
# -----------------------------------------------------------------------------
# Stage 7: Live Trading (requires broker account setup)
# -----------------------------------------------------------------------------
# from finlab.online.sinopac_account import SinopacAccount
# from finlab.online.order_executor import OrderExecutor
#
# account = SinopacAccount() # 需先設定環境變數
# position = Position.from_report(report_final, 1000000)
# executor = OrderExecutor(position, account)
# executor.create_orders(view_only=True) # 先用 view_only 測試
# -----------------------------------------------------------------------------
# Stage 8: Performance Tracking
# -----------------------------------------------------------------------------
# Periodically run the following code to review live status:
# account_value = account.get_total_value()
# print(f"帳戶總值: {account_value}")
Key Takeaways
Development Stage Checklist
- [ ] Clear strategy hypothesis: Has a clear logical basis (technical/fundamental/institutional)
- [ ] Data integrity check: Confirm data range is sufficient and missing value ratio is reasonable
- [ ] Acceptable initial backtest performance: Annualized return > 10%, Sharpe ratio > 0.5
- [ ] Condition combination optimization: Use
sim_conditions()to find the best combination - [ ] Stop loss/take profit optimization: Use MAE/MFE analysis to set reasonable levels
Validation Stage Checklist
- [ ] Liquidity risk: Low volume ratio < 20%, disposition stock ratio < 5%
- [ ] Annual stability: No consecutive years of extremely poor performance
- [ ] Alpha > 0: Strategy has excess returns
- [ ] Out-of-sample test passed: Test set performance degradation < 30%, Sharpe ratio still > 1
Deployment Stage Checklist
- [ ] Strategy uploaded to cloud: Can review position list anytime
- [ ] Broker account setup complete: API keys correct, permissions granted
- [ ] Tested with simulated orders first: Confirmed order logic is correct
- [ ] Small capital test: Tested with small amounts for 1-2 months
- [ ] Regular review mechanism: Set up monthly live performance review
Further Learning
After completing this workflow, you can explore:
- Machine Learning Strategy: ML Strategy Complete Workflow (Advanced)
- Multi-Strategy Portfolio: Multi-Strategy Portfolio Management (Advanced)
- Custom Analysis Modules: Strategy Analysis Module Guide
- Custom Market Backtesting: Custom Market Object Guide
Common Error Handling Checklist
When executing the complete workflow, make sure to perform error checks at each stage. Below are key checkpoints and solutions:
Stages 1-2: Data Loading & Backtesting
Common Errors:
- KeyError: 'price:收盤價' -- API token not set or incorrect data table name
- Data is empty or has too many missing values
- Backtest has no trade records (entry conditions too strict)
Validation Methods:
try:
# 1. Check data loading
close = data.get('price:收盤價')
if close.empty:
raise ValueError("❌ 資料為空,請檢查 API token")
missing_ratio = close.isna().sum().sum() / close.size
if missing_ratio > 0.1:
print(f"⚠️ 警告:缺失值比例 {missing_ratio:.1%} > 10%")
# 2. Check entry signals
entry_count = entry_signal.sum(axis=1).mean()
if entry_count < 1:
print("⚠️ 警告:進場條件過嚴,平均每日 < 1 檔股票")
print("建議:放寬條件或使用 .is_largest(N) 確保固定檔數")
# 3. Check backtest results
report = sim(position, resample='M', position_limit=0.1)
trades = report.get_trades()
if len(trades) == 0:
raise ValueError("❌ 策略無任何交易記錄,請檢查進場條件")
print(f"✅ 回測成功:{len(trades)} 筆交易")
except KeyError as e:
print(f"❌ 找不到資料表:{e}")
print("請至 https://ai.finlab.tw/database 確認資料表名稱")
print("或檢查 API token 是否正確設定")
except ValueError as e:
print(f"❌ 資料驗證失敗:{e}")
Detailed Error Handling: See Data Download Error Handling
Stage 3: Strategy Optimization
Common Errors:
- sim_conditions() takes too long due to too many combinations
- Condition definitions are incorrect (inconsistent date ranges)
Validation Methods:
# Limit the number of combinations (< 50)
conditions = {
'c1': c1,
'c2': c2,
'c3': c3,
# Maximum 5 conditions (2^5 = 32 combinations)
}
# Estimate execution time
num_combinations = 2**len(conditions) - 1
print(f"將測試 {num_combinations} 種組合,預估時間:約 {num_combinations * 30 / 60:.1f} 分鐘")
if num_combinations > 100:
print("⚠️ 警告:組合數量過多,建議先測試部分條件")
Detailed Error Handling: See Strategy Optimization Error Handling
Stage 5: Out-of-Sample Testing
Common Errors: - Training and test set date ranges overlap - Test set performance differs too much from training set (overfitting)
Validation Methods:
# Check date ranges
train_end = '2022-12-31'
test_start = '2023-01-01'
position_train = position_final[position_final.index <= train_end]
position_test = position_final[position_final.index >= test_start]
# Confirm no overlap
if position_train.index[-1] >= position_test.index[0]:
raise ValueError("❌ 訓練集與測試集日期重疊!")
# Check performance difference
sharpe_train = report_train.get_stats()['daily_sharpe']
sharpe_test = report_test.get_stats()['daily_sharpe']
degradation = (sharpe_train - sharpe_test) / sharpe_train
if degradation > 0.5:
print(f"⚠️ 警告:夏普率衰退 {degradation:.1%} > 50%,可能過度配適")
print("建議:")
print("1. 簡化策略條件")
print("2. 增加訓練集資料範圍")
print("3. 使用交叉驗證")
Detailed Error Handling: See Backtest Error Handling
Stage 7: Live Trading
Common Errors: - Broker account connection failure (wrong API key, expired certificate) - Insufficient funds or too many positions - Orders rejected (disposition stocks not pledged, limit-up/down locked)
Safety Checklist:
# Pre-trading safety checks
def pre_trading_checks(position, account):
"""實盤下單前安全檢查"""
print("=== 實盤下單安全檢查 ===\n")
# 1. Check number of positions
if len(position) > 30:
raise ValueError(f"❌ 持倉過多({len(position)} 檔),建議 < 30 檔")
# 2. Check available funds
available = account.get_balance()
required = position.total_value # 假設此方法存在
if required > available * 0.9:
raise ValueError(f"❌ 資金不足!需要 {required:,.0f},可用 {available:,.0f}")
# 3. Check account connection
try:
account.get_position()
except Exception as e:
raise ConnectionError(f"❌ 券商帳戶連線失敗:{e}")
print("✅ 所有檢查通過\n")
# Execute checks
try:
pre_trading_checks(position_info, account)
# Preview first (no actual orders)
executor.create_orders(view_only=True)
# Execute after confirmation (uncomment)
# executor.create_orders()
except (ValueError, ConnectionError) as e:
print(f"\n{e}")
print("請修正問題後再執行下單")
Detailed Error Handling: See Live Trading Error Handling
Final Reminder for Live Trading
Before placing orders, confirm the following:
- Strategy has passed out-of-sample testing
- Tested with a simulated account for at least 1 week
- Initial capital does not exceed 10-20% of total capital
- Stop loss mechanism is in place to avoid catastrophic losses
- Monitor positions and order status daily
Errors can lead to financial losses! Please proceed with caution!