今天要學習虛擬貨幣的現貨和期貨交易,這就像農業中的現金交易和期約交易。爸爸賣菜有兩種方式:一是現場賣給菜販(現貨),二是提前和餐廳簽約未來交貨(期貨)。兩種方式各有優缺點,讓我們來深入了解!
現貨交易就像在市場上直接買賣真實的貨物:
class SpotTrading:
"""現貨交易系統"""
def __init__(self, initial_balance=10000):
self.balance = initial_balance
self.holdings = {} # {symbol: quantity}
self.transaction_history = []
def buy_spot(self, symbol, quantity, price):
"""買入現貨"""
total_cost = quantity * price
fee = total_cost * 0.001 # 0.1% 手續費
if self.balance >= total_cost + fee:
self.balance -= (total_cost + fee)
if symbol in self.holdings:
self.holdings[symbol] += quantity
else:
self.holdings[symbol] = quantity
self.transaction_history.append({
'type': 'buy',
'symbol': symbol,
'quantity': quantity,
'price': price,
'fee': fee,
'timestamp': 'now'
})
return True, f"成功買入 {quantity} {symbol}"
else:
return False, "餘額不足"
def sell_spot(self, symbol, quantity, price):
"""賣出現貨"""
if symbol in self.holdings and self.holdings[symbol] >= quantity:
total_value = quantity * price
fee = total_value * 0.001
net_receive = total_value - fee
self.balance += net_receive
self.holdings[symbol] -= quantity
if self.holdings[symbol] == 0:
del self.holdings[symbol]
self.transaction_history.append({
'type': 'sell',
'symbol': symbol,
'quantity': quantity,
'price': price,
'fee': fee,
'timestamp': 'now'
})
return True, f"成功賣出 {quantity} {symbol}"
else:
return False, "持有量不足"
def get_portfolio_value(self, current_prices):
"""計算投資組合總值"""
portfolio_value = self.balance
for symbol, quantity in self.holdings.items():
if symbol in current_prices:
portfolio_value += quantity * current_prices[symbol]
return portfolio_value
def calculate_unrealized_pnl(self, current_prices):
"""計算未實現損益"""
unrealized_pnl = {}
total_unrealized = 0
for symbol, quantity in self.holdings.items():
if symbol in current_prices:
# 計算平均成本
buy_transactions = [t for t in self.transaction_history
if t['symbol'] == symbol and t['type'] == 'buy']
if buy_transactions:
total_cost = sum(t['quantity'] * t['price'] for t in buy_transactions)
total_quantity = sum(t['quantity'] for t in buy_transactions)
avg_cost = total_cost / total_quantity
current_value = quantity * current_prices[symbol]
cost_basis = quantity * avg_cost
pnl = current_value - cost_basis
unrealized_pnl[symbol] = {
'quantity': quantity,
'avg_cost': avg_cost,
'current_price': current_prices[symbol],
'unrealized_pnl': pnl,
'pnl_percentage': pnl / cost_basis if cost_basis > 0 else 0
}
total_unrealized += pnl
return unrealized_pnl, total_unrealized
# 使用示例
spot_trader = SpotTrading()
# 買入 BTC
spot_trader.buy_spot('BTC', 0.1, 50000)
spot_trader.buy_spot('ETH', 2, 3000)
# 查看投資組合
current_prices = {'BTC': 55000, 'ETH': 3200}
portfolio_value = spot_trader.get_portfolio_value(current_prices)
unrealized_pnl, total_pnl = spot_trader.calculate_unrealized_pnl(current_prices)
print(f"投資組合總值: ${portfolio_value:.2f}")
print(f"總未實現損益: ${total_pnl:.2f}")
期貨是標準化的未來交易合約:
class FuturesTrading:
"""期貨交易系統"""
def __init__(self, initial_balance=10000):
self.balance = initial_balance
self.positions = {} # {symbol: {'side': 'long/short', 'size': quantity, 'entry_price': price}}
self.used_margin = 0
self.transaction_history = []
def calculate_required_margin(self, symbol, size, price, leverage=10):
"""計算所需保證金"""
notional_value = size * price
required_margin = notional_value / leverage
return required_margin
def open_position(self, symbol, side, size, price, leverage=10):
"""開倉"""
required_margin = self.calculate_required_margin(symbol, size, price, leverage)
fee = size * price * 0.0004 # 0.04% 手續費
available_balance = self.balance - self.used_margin
if available_balance >= required_margin + fee:
# 更新保證金使用
self.used_margin += required_margin
self.balance -= fee
# 記錄部位
position_key = f"{symbol}_{side}"
if position_key in self.positions:
# 加倉
old_pos = self.positions[position_key]
total_size = old_pos['size'] + size
weighted_price = (old_pos['size'] * old_pos['entry_price'] +
size * price) / total_size
self.positions[position_key] = {
'side': side,
'size': total_size,
'entry_price': weighted_price,
'leverage': leverage,
'margin': old_pos['margin'] + required_margin
}
else:
# 新倉
self.positions[position_key] = {
'side': side,
'size': size,
'entry_price': price,
'leverage': leverage,
'margin': required_margin
}
self.transaction_history.append({
'type': 'open',
'symbol': symbol,
'side': side,
'size': size,
'price': price,
'leverage': leverage,
'margin': required_margin,
'fee': fee,
'timestamp': 'now'
})
return True, f"成功開倉 {side} {size} {symbol}"
else:
return False, "保證金不足"
def close_position(self, symbol, side, size, price):
"""平倉"""
position_key = f"{symbol}_{side}"
if position_key not in self.positions:
return False, "無對應部位"
position = self.positions[position_key]
if position['size'] < size:
return False, "平倉數量超過持倉"
# 計算損益
if side == 'long':
pnl = size * (price - position['entry_price'])
else: # short
pnl = size * (position['entry_price'] - price)
# 計算手續費
fee = size * price * 0.0004
net_pnl = pnl - fee
# 釋放保證金
margin_released = (size / position['size']) * position['margin']
self.used_margin -= margin_released
# 更新餘額
self.balance += net_pnl + margin_released
# 更新部位
if position['size'] == size:
# 完全平倉
del self.positions[position_key]
else:
# 部分平倉
remaining_ratio = (position['size'] - size) / position['size']
self.positions[position_key]['size'] -= size
self.positions[position_key]['margin'] *= remaining_ratio
self.transaction_history.append({
'type': 'close',
'symbol': symbol,
'side': side,
'size': size,
'price': price,
'pnl': pnl,
'fee': fee,
'net_pnl': net_pnl,
'timestamp': 'now'
})
return True, f"平倉成功,淨損益: ${net_pnl:.2f}"
def calculate_unrealized_pnl(self, current_prices):
"""計算未實現損益"""
total_unrealized_pnl = 0
position_details = {}
for position_key, position in self.positions.items():
symbol = position_key.split('_')[0]
side = position['side']
if symbol in current_prices:
current_price = current_prices[symbol]
entry_price = position['entry_price']
size = position['size']
if side == 'long':
unrealized_pnl = size * (current_price - entry_price)
else: # short
unrealized_pnl = size * (entry_price - current_price)
total_unrealized_pnl += unrealized_pnl
position_details[position_key] = {
'symbol': symbol,
'side': side,
'size': size,
'entry_price': entry_price,
'current_price': current_price,
'unrealized_pnl': unrealized_pnl,
'margin': position['margin']
}
return position_details, total_unrealized_pnl
def check_margin_call(self, current_prices, maintenance_margin_ratio=0.5):
"""檢查保證金追繳"""
_, unrealized_pnl = self.calculate_unrealized_pnl(current_prices)
current_equity = self.balance + unrealized_pnl
required_maintenance = self.used_margin * maintenance_margin_ratio
if current_equity < required_maintenance:
return True, f"保證金追繳警告!當前權益: ${current_equity:.2f}, 需要: ${required_maintenance:.2f}"
return False, "保證金充足"
# 使用示例
futures_trader = FuturesTrading()
# 開多倉 BTC
success, msg = futures_trader.open_position('BTC', 'long', 1, 50000, leverage=10)
print(msg)
# 開空倉 ETH
futures_trader.open_position('ETH', 'short', 5, 3000, leverage=5)
# 檢查未實現損益
current_prices = {'BTC': 52000, 'ETH': 2900}
positions, total_pnl = futures_trader.calculate_unrealized_pnl(current_prices)
print(f"總未實現損益: ${total_pnl:.2f}")
# 檢查保證金狀況
margin_call, msg = futures_trader.check_margin_call(current_prices)
print(f"保證金狀況: {msg}")
class TradingStrategyComparison:
"""交易策略適用性比較"""
def __init__(self):
self.strategy_suitability = {
'buy_and_hold': {
'spot': 10, # 最適合現貨
'futures': 3, # 不適合期貨(有到期日)
'reason': '長期持有策略需要避免展倉成本'
},
'swing_trading': {
'spot': 7, # 適合現貨
'futures': 8, # 更適合期貨
'reason': '中期交易可利用期貨的槓桿優勢'
},
'day_trading': {
'spot': 5, # 一般適合
'futures': 9, # 非常適合
'reason': '日內交易適合利用期貨的高流動性和槓桿'
},
'scalping': {
'spot': 6, # 勉強適合
'futures': 9, # 非常適合
'reason': '剝頭皮需要高頻交易和槓桿放大微利'
},
'arbitrage': {
'spot': 8, # 適合
'futures': 9, # 非常適合
'reason': '套利策略需要靈活的做空能力'
},
'hedging': {
'spot': 5, # 有限適用
'futures': 10, # 完美適合
'reason': '對沖需要衍生品工具'
}
}
def get_recommendation(self, strategy, capital_size, risk_tolerance):
"""獲取策略建議"""
strategy_info = self.strategy_suitability.get(strategy, {})
recommendation = {
'strategy': strategy,
'spot_score': strategy_info.get('spot', 0),
'futures_score': strategy_info.get('futures', 0),
'reason': strategy_info.get('reason', ''),
}
# 根據資金規模調整建議
if capital_size < 10000:
recommendation['note'] = '小資金建議先從現貨開始學習'
elif capital_size > 100000:
recommendation['note'] = '大資金可考慮期貨提高資金效率'
# 根據風險承受度調整
if risk_tolerance == 'low':
recommendation['futures_score'] *= 0.5
elif risk_tolerance == 'high':
recommendation['futures_score'] *= 1.2
return recommendation
# 策略建議示例
comparator = TradingStrategyComparison()
strategies = ['buy_and_hold', 'day_trading', 'arbitrage']
for strategy in strategies:
rec = comparator.get_recommendation(strategy, capital_size=50000, risk_tolerance='medium')
print(f"\n{strategy}:")
print(f"現貨適合度: {rec['spot_score']}/10")
print(f"期貨適合度: {rec['futures_score']:.1f}/10")
print(f"原因: {rec['reason']}")
class BasisAnalysis:
"""基差分析工具"""
def __init__(self):
self.basis_history = []
def calculate_basis(self, spot_price, futures_price, days_to_expiry):
"""計算基差和年化基差率"""
basis = futures_price - spot_price
basis_rate = basis / spot_price
annualized_basis_rate = basis_rate * (365 / days_to_expiry)
return {
'basis': basis,
'basis_rate': basis_rate,
'annualized_basis_rate': annualized_basis_rate,
'contango': basis > 0, # 正價差(期貨>現貨)
'backwardation': basis < 0 # 逆價差(期貨<現貨)
}
def identify_arbitrage_opportunity(self, spot_price, futures_price,
days_to_expiry, risk_free_rate=0.05):
"""識別套利機會"""
basis_info = self.calculate_basis(spot_price, futures_price, days_to_expiry)
# 理論期貨價格(考慮無風險利率)
theoretical_futures = spot_price * (1 + risk_free_rate * days_to_expiry / 365)
# 套利機會判斷
if futures_price > theoretical_futures * 1.01: # 期貨溢價>1%
return {
'opportunity': True,
'strategy': 'sell_futures_buy_spot',
'expected_profit': futures_price - theoretical_futures,
'profit_rate': (futures_price - theoretical_futures) / spot_price,
'action': '賣期貨,買現貨'
}
elif futures_price < theoretical_futures * 0.99: # 期貨折價>1%
return {
'opportunity': True,
'strategy': 'buy_futures_sell_spot',
'expected_profit': theoretical_futures - futures_price,
'profit_rate': (theoretical_futures - futures_price) / spot_price,
'action': '買期貨,賣現貨'
}
else:
return {
'opportunity': False,
'reason': '基差在合理範圍內'
}
# 基差分析示例
basis_analyzer = BasisAnalysis()
# 分析套利機會
spot_price = 50000
futures_price = 50800
days_to_expiry = 30
opportunity = basis_analyzer.identify_arbitrage_opportunity(
spot_price, futures_price, days_to_expiry
)
if opportunity['opportunity']:
print(f"發現套利機會!")
print(f"策略: {opportunity['action']}")
print(f"預期利潤: ${opportunity['expected_profit']:.2f}")
print(f"利潤率: {opportunity['profit_rate']:.2%}")
else:
print(f"無套利機會: {opportunity['reason']}")
class RiskManagementComparison:
"""現貨與期貨風險管理比較"""
def __init__(self):
self.spot_risks = {
'market_risk': '價格下跌風險,最大損失100%',
'liquidity_risk': '流動性不足時難以快速出場',
'custody_risk': '錢包安全、交易所風險',
'regulatory_risk': '監管變化影響'
}
self.futures_risks = {
'market_risk': '槓桿放大損失,可能超過本金',
'liquidity_risk': '保證金追繳、強制平倉',
'basis_risk': '現貨期貨價差變動風險',
'rollover_risk': '展倉成本和時機風險',
'counterparty_risk': '交易對手違約風險'
}
def calculate_risk_metrics(self, position_type, position_size, entry_price,
current_price, leverage=1):
"""計算風險指標"""
if position_type == 'spot':
unrealized_pnl = position_size * (current_price - entry_price)
max_loss = position_size * entry_price # 最大損失為本金
margin_requirement = position_size * entry_price
else: # futures
if leverage > 1:
notional_value = position_size * entry_price
margin_requirement = notional_value / leverage
unrealized_pnl = position_size * (current_price - entry_price)
# 期貨最大損失可能超過保證金
max_loss = float('inf') # 理論上無限
else:
return self.calculate_risk_metrics('spot', position_size,
entry_price, current_price, 1)
return {
'unrealized_pnl': unrealized_pnl,
'pnl_percentage': unrealized_pnl / (position_size * entry_price),
'margin_requirement': margin_requirement,
'max_loss': max_loss,
'leverage': leverage,
'position_type': position_type
}
def recommend_stop_loss(self, position_type, leverage=1, risk_tolerance='medium'):
"""建議停損設定"""
if position_type == 'spot':
if risk_tolerance == 'low':
return 0.05 # 5%
elif risk_tolerance == 'medium':
return 0.10 # 10%
else:
return 0.15 # 15%
else: # futures
base_stop = self.recommend_stop_loss('spot', 1, risk_tolerance)
adjusted_stop = base_stop / leverage # 槓桿越高,停損越嚴格
return max(adjusted_stop, 0.02) # 最少2%
# 風險比較示例
risk_manager = RiskManagementComparison()
# 比較現貨和期貨風險
spot_metrics = risk_manager.calculate_risk_metrics(
'spot', 1, 50000, 48000
)
futures_metrics = risk_manager.calculate_risk_metrics(
'futures', 1, 50000, 48000, leverage=10
)
print("現貨交易風險:")
print(f"未實現損益: ${spot_metrics['unrealized_pnl']:.2f}")
print(f"損益百分比: {spot_metrics['pnl_percentage']:.2%}")
print(f"保證金需求: ${spot_metrics['margin_requirement']:.2f}")
print("\n期貨交易風險:")
print(f"未實現損益: ${futures_metrics['unrealized_pnl']:.2f}")
print(f"損益百分比: {futures_metrics['pnl_percentage']:.2%}")
print(f"保證金需求: ${futures_metrics['margin_requirement']:.2f}")
# 停損建議
spot_stop = risk_manager.recommend_stop_loss('spot', risk_tolerance='medium')
futures_stop = risk_manager.recommend_stop_loss('futures', leverage=10, risk_tolerance='medium')
print(f"\n停損建議:")
print(f"現貨停損: {spot_stop:.1%}")
print(f"期貨停損: {futures_stop:.1%}")
今天我們深入比較了虛擬貨幣的現貨和期貨交易,就像比較現金買賣和期約交易的差異。重要要點:
現貨交易特點:
期貨交易特點:
選擇建議:
風險控制重點:
明天我們將學習合約中的槓桿與資金費率,進一步了解期貨交易的細節!
下一篇:Day 21 - 合約中的槓桿與現金費率