양적 거래 및 프로그램적 거래에서
대부분의 헤지 트레이딩은 두 가지 거래 품종의 가격 차이에 기반합니다. 헤지 트레이딩의 개념, 원칙 및 세부 사항은 양적 거래 분야에 진출한 트레이더에게 매우 명확하지 않을 수 있습니다. 괜찮습니다. 이 지식을 마스터하기 위해 FMZ 퀀트 플랫폼에서 제공하는 "데이터 과학 연구 환경" 도구를 사용하십시오.
FMZ 퀀트 웹사이트 대시보드 페이지에서, 이 도구의 페이지로 이동하기 위해
여기 이 분석 파일을 직접 업로드했습니다.
이 분석 파일은 스팟-퓨처스 헤지 트레이딩에서 개점 및 폐쇄 포지션의 프로세스의 분석입니다. 선물 측면 거래소는 OKEX이며 계약은 분기 계약입니다; 스팟 측면 거래소는 OKEX 스팟 거래소입니다. 거래 쌍은 BTC_USDT입니다. 다음 특정 분석 환경 파일에는 파이썬과 자바스크립트 두 가지 버전이 포함되어 있습니다.
from fmz import * task = VCtx('''backtest start: 2019-09-19 00:00:00 end: 2019-09-28 12:00:00 period: 15m exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD", "stocks":1}, {"eid":"OKEX","currency":"BTC_USDT","balance":10000,"stocks":0}] ''') # Create a backtest environment import matplotlib.pyplot as plt import numpy as np # Imported drawing library matplotlib and numpy library
exchanges[0].SetContractType("quarter") # The first exchange object OKEX futures (eid: Futures_OKCoin) calls the function that sets the current contract, set to the quarterly contract initQuarterAcc = exchanges[0].GetAccount() # Account information at the OKEX Futures Exchange, recorded in the variable initQuarterAcc initQuarterAcc
{'Balance': 0.0, 'FrozenBalance': 0.0, 'Stocks': 1.0, 'FrozenStocks': 0.0}
initSpotAcc = exchanges[1].GetAccount() # Account information at the OKEX spot exchange, recorded in the variable initSpotAcc initSpotAcc
{'Balance': 10000.0, 'FrozenBalance': 0.0, 'Stocks': 0.0, 'FrozenStocks': 0.0}
quarterTicker1 = exchanges[0].GetTicker() # Get the futures exchange market quotes, recorded in the variable quarterTicker1 quarterTicker1
{'Time': 1568851210000, 'High': 10441.25002, 'Low': 10441.25, 'Sell': 10441.25002, 'Buy': 10441.25, 'Last': 10441.25001, 'Volume': 1772.0, 'OpenInterest': 0.0}
spotTicker1 = exchanges[1].GetTicker() # Get the spot exchange market quotes, recorded in the variable spotTicker1 spotTicker1
{'Time': 1568851210000, 'High': 10156.60000002, 'Low': 10156.6, 'Sell': 10156.60000002, 'Buy': 10156.6, 'Last': 10156.60000001, 'Volume': 7.4443, 'OpenInterest': 0.0}
quarterTicker1.Buy - spotTicker1.Sell # The price difference between Short selling futures and Buying long spots
284.64999997999985
exchanges[0].SetDirection("sell") # Set up the futures exchange, the trading direction is short quarterId1 = exchanges[0].Sell(quarterTicker1.Buy, 10) # The futures are short-selled, the order quantity is 10 contracts, and the returned order ID is recorded in the variable quarterId1. exchanges[0].GetOrder(quarterId1) # Query the order details of the futures order ID is quarterId1
{'Id': 1, 'Price': 10441.25, 'Amount': 10.0, 'DealAmount': 10.0, 'AvgPrice': 10441.25, 'Type': 1, 'Offset': 0, 'Status': 1, 'ContractType': b'quarter'}
spotAmount = 10 * 100 / quarterTicker1.Buy # Calculate the number of cryptocurrency equivalent to 10 contracts, as the spots amount of the order placed spotId1 = exchanges[1].Buy(spotTicker1.Sell, spotAmount) # Spot exchange placing order exchanges[1].GetOrder(spotId1) # Query the order details of the spot order ID as spotId1
{'Id': 1, 'Price': 10156.60000002, 'Amount': 0.0957, 'DealAmount': 0.0957, 'AvgPrice': 10156.60000002, 'Type': 0, 'Offset': 0, 'Status': 1, 'ContractType': b'BTC_USDT_OKEX'}
It can be seen that the orders of the order quarterId1 and the spotId1 are all completely filled, that is, the opening position of the hedge is completed.
Sleep(1000 * 60 * 60 * 24 * 7) # Hold the position for a while, wait for the difference to become smaller and close the position.
After the waiting time has elapsed, prepare to close the position. Get the current quotes
quarterTicker2
,spotTicker2
and print. The trading direction of the futures exchange object is set to close short positions:exchanges[0].SetDirection("closesell")
to close the position. Print the details of the closing positions, showing that the closing position is completely done.
quarterTicker2 = exchanges[0].GetTicker() # Get the current market quotes of the futures exchange, recorded in the variable quarterTicker2 quarterTicker2
{'Time': 1569456010000, 'High': 8497.20002, 'Low': 8497.2, 'Sell': 8497.20002, 'Buy': 8497.2, 'Last': 8497.20001, 'Volume': 4311.0, 'OpenInterest': 0.0}
spotTicker2 = exchanges[1].GetTicker() # Get the current spot exchange market quotes, recorded in the variable spotTicker2 spotTicker2
{'Time': 1569456114600, 'High': 8444.70000001, 'Low': 8444.69999999, 'Sell': 8444.70000001, 'Buy': 8444.69999999, 'Last': 8444.7, 'Volume': 78.6273, 'OpenInterest': 0.0}
quarterTicker2.Sell - spotTicker2.Buy # The price difference of closing position between Short position of futures and the Long position of spot
52.5000200100003
exchanges[0].SetDirection("closesell") # Set the current trading direction of the futures exchange to close short position quarterId2 = exchanges[0].Buy(quarterTicker2.Sell, 10) # The futures exchange closing positions, and records the order ID, recorded to the variable quarterId2 exchanges[0].GetOrder(quarterId2) # Query futures closing position orders detail
{'Id': 2, 'Price': 8497.20002, 'Amount': 10.0, 'DealAmount': 10.0, 'AvgPrice': 8493.95335, 'Type': 0, 'Offset': 1, 'Status': 1, 'ContractType': b'quarter'}
spotId2 = exchanges[1].Sell(spotTicker2.Buy, spotAmount) # The spot exchange place order to closing positions, and records the order ID, recorded to the variable spotId2 exchanges[1].GetOrder(spotId2) # Query spots closing order details
{'Id': 2, 'Price': 8444.69999999, 'Amount': 0.0957, 'DealAmount': 0.0957, 'AvgPrice': 8444.69999999, 'Type': 1, 'Offset': 0, 'Status': 1, 'ContractType': b'BTC_USDT_OKEX'}
nowQuarterAcc = exchanges[0].GetAccount() # Get current futures exchange account information, recorded in the variable nowQuarterAcc nowQuarterAcc
{'Balance': 0.0, 'FrozenBalance': 0.0, 'Stocks': 1.021786026184, 'FrozenStocks': 0.0}
nowSpotAcc = exchanges[1].GetAccount() # Get current spot exchange account information, recorded in the variable nowSpotAcc nowSpotAcc
{'Balance': 9834.74705446, 'FrozenBalance': 0.0, 'Stocks': 0.0, 'FrozenStocks': 0.0}
Calculate the profit and loss of this hedging operation by comparing the initial account with the current account.
diffStocks = abs(nowQuarterAcc.Stocks - initQuarterAcc.Stocks) diffBalance = nowSpotAcc.Balance - initSpotAcc.Balance if nowQuarterAcc.Stocks - initQuarterAcc.Stocks > 0 : print("profit:", diffStocks * spotTicker2.Buy + diffBalance) else : print("profit:", diffBalance - diffStocks * spotTicker2.Buy)
收益: 18.72350977580652
Below we look at why the hedge is profitable. We can see the chart drawn, the futures price is the blue line, the spot price is the orange line, both prices are falling, and the futures price is falling faster than the spot price.
xQuarter = [1, 2] yQuarter = [quarterTicker1.Buy, quarterTicker2.Sell] xSpot = [1, 2] ySpot = [spotTicker1.Sell, spotTicker2.Buy] plt.plot(xQuarter, yQuarter, linewidth=5) plt.plot(xSpot, ySpot, linewidth=5) plt.show()
<Figure size 432x288 with 1 Axes>
Let us look at the changes in the price difference. The difference is 284 when the hedge is opened (that is, shorting the futures, longing the spot), reaching 52 when the position is closed (the futures short positions are closed, and the spot long positions are closed). The difference is from big to small.
xDiff = [1, 2] yDiff = [quarterTicker1.Buy - spotTicker1.Sell, quarterTicker2.Sell - spotTicker2.Buy] plt.plot(xDiff, yDiff, linewidth=5) plt.show()
<Figure size 432x288 with 1 Axes>
Let me give an example, a1 is the futures price of time 1, and b1 is the spot price of time 1. A2 is the futures price at time 2, and b2 is the spot price at time 2.
As long as a1-b1, that is, the futures-spot price difference of time 1 is greater than the futures-spot price difference of a2-b2 of time 2, a1 - a2 > b1 - b2 can be introduced. There are three cases: (the futures-spot holding position are the same size)
a1 - a2 is greater than 0, b1 - b2 is greater than 0, a1 - a2 is the difference in futures profit, b1 - b2 is the difference in spot loss (because the spot is long position, the price of opening position is higher than the price of closing position, therefore, the position loses money), but the futures profit is greater than the spot loss. So the overall trading operation is profitable. This case corresponds to the chart in step In[8]
.
a1 - a2 is greater than 0, b1 - b2 is less than 0, a1 - a2 is the difference of futures profit, b1 - b2 is the difference of spot profit (b1 - b2 is less than 0, indicating that b2 is greater than b1, that is, the price of opening the position is low, the price of selling the position is high, so the position make profit)
a1 - a2 is less than 0, b1 - b2 is less than 0, a1 - a2 is the difference of futures losses, b1 - b2 is the difference of spot profit due to a1 - a2 > b1 - b2, the absolute value of a1 - a2 is less than b1 - b2 Absolute value, the profit of the spot is greater than the loss of the futures. So the overall trading operation is profitable.
There is no case where a1 - a2 is less than 0 and b1 - b2 is greater than 0, because a1 - a2 > b1 - b2 have been defined. Similarly, if a1 - a2 is equal to 0, since a1 - a2 > b1 - b2 is defined, b1 - b2 must be less than 0. Therefore, as long as the futures are short position and the spot are long position in a long-term hedging method, which meets the conditions a1 - b1 > a2 - b2, the opening and closing position operation is the profit hedging.
For example, the following model is one of the cases:
a1 = 10 b1 = 5 a2 = 11 b2 = 9 if a1 - b1 > a2 - b2: print(a1 - a2 > b1 - b2) xA = [1, 2] yA = [a1, a2] xB = [1, 2] yB = [b1, b2] plt.plot(xA, yA, linewidth=5) plt.plot(xB, yB, linewidth=5) plt.show()
True <Figure size 432x288 with 1 Axes>
연구 환경은 파이썬뿐만 아니라 자바스크립트도 지원합니다 아래에는 자바스크립트 연구 환경의 예도 있습니다.
// Import the required package, click "Save Backtest Settings" on the FMZ Quant "Strategy Editing Page" to get the string configuration and convert it to an object. var fmz = require("fmz") // Automatically import talib, TA, plot library after import var task = fmz.VCtx({ start: '2019-09-19 00:00:00', end: '2019-09-28 12:00:00', period: '15m', exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD","stocks":1},{"eid":"OKEX","currency":"BTC_USDT","balance":10000,"stocks":0}] })
exchanges[0].SetContractType("quarter") // The first exchange object OKEX futures (eid: Futures_OKCoin) calls the function that sets the current contract, set to the quarterly contract var initQuarterAcc = exchanges[0].GetAccount() // Account information at the OKEX Futures Exchange, recorded in the variable initQuarterAcc initQuarterAcc
{ Balance: 0, FrozenBalance: 0, Stocks: 1, FrozenStocks: 0 }
var initSpotAcc = exchanges[1].GetAccount() // Account information at the OKEX spot exchange, recorded in the variable initSpotAcc initSpotAcc
{ Balance: 10000, FrozenBalance: 0, Stocks: 0, FrozenStocks: 0 }
var quarterTicker1 = exchanges[0].GetTicker() // Get the futures exchange market quotes, recorded in the variable quarterTicker1 quarterTicker1
{ Time: 1568851210000, High: 10441.25002, Low: 10441.25, Sell: 10441.25002, Buy: 10441.25, Last: 10441.25001, Volume: 1772, OpenInterest: 0 }
var spotTicker1 = exchanges[1].GetTicker() // Get the spot exchange market quotes, recorded in the variable spotTicker1 spotTicker1
{ Time: 1568851210000, High: 10156.60000002, Low: 10156.6, Sell: 10156.60000002, Buy: 10156.6, Last: 10156.60000001, Volume: 7.4443, OpenInterest: 0 }
quarterTicker1.Buy - spotTicker1.Sell // the price difference between Short selling futures and long buying spot
284.64999997999985
exchanges[0].SetDirection("sell") // Set up the futures exchange, the trading direction is shorting var quarterId1 = exchanges[0].Sell(quarterTicker1.Buy, 10) // The futures are short-selled, the order quantity is 10 contracts, and the returned order ID is recorded in the variable quarterId1. exchanges[0].GetOrder(quarterId1) // Query the order details of the futures order ID is quarterId1
{ Id: 1, Price: 10441.25, Amount: 10, DealAmount: 10, AvgPrice: 10441.25, Type: 1, Offset: 0, Status: 1, ContractType: 'quarter' }
var spotAmount = 10 * 100 / quarterTicker1.Buy // Calculate the number of cryptocurrency equivalent to 10 contracts, as the amount of the order placed var spotId1 = exchanges[1].Buy(spotTicker1.Sell, spotAmount) // Spot exchange placing order exchanges[1].GetOrder(spotId1) // Query the order details of the spot order ID as spotId1
{ Id: 1, Price: 10156.60000002, Amount: 0.0957, DealAmount: 0.0957, AvgPrice: 10156.60000002, Type: 0, Offset: 0, Status: 1, ContractType: 'BTC_USDT_OKEX' }
It can be seen that the orders of the order quarterId1 and the spotId1 are all completely filled, that is, the opening of the hedge is completed.
Sleep(1000 * 60 * 60 * 24 * 7) // Hold the position for a while, wait for the difference to become smaller and close the position.
等待时间过后,准备平仓。获取当前的行情
quarterTicker2
、spotTicker2
并且打印。 期货交易所对象的交易方向设置为平空仓:exchanges[0].SetDirection("closesell")
下单平仓。 打印平仓订单的详情,显示平仓订单完全成交,平仓完成。
var quarterTicker2 = exchanges[0].GetTicker() // Get the current market quote of the futures exchange, recorded in the variable quarterTicker2 quarterTicker2
{ Time: 1569456010000, High: 8497.20002, Low: 8497.2, Sell: 8497.20002, Buy: 8497.2, Last: 8497.20001, Volume: 4311, OpenInterest: 0 }
var spotTicker2 = exchanges[1].GetTicker() // Get the current spot exchange market quotes, recorded in the variable spotTicker2 spotTicker2
{ Time: 1569456114600, High: 8444.70000001, Low: 8444.69999999, Sell: 8444.70000001, Buy: 8444.69999999, Last: 8444.7, Volume: 78.6273, OpenInterest: 0 }
quarterTicker2.Sell - spotTicker2.Buy // the price difference between the short position of futures and the long position of spot
52.5000200100003
exchanges[0].SetDirection("closesell") // Set the current trading direction of the futures exchange to close short position var quarterId2 = exchanges[0].Buy(quarterTicker2.Sell, 10) // The futures exchange place orders to close position, and records the order ID, recorded to the variable quarterId2 exchanges[0].GetOrder(quarterId2) // Query futures closing position order details
{ Id: 2, Price: 8497.20002, Amount: 10, DealAmount: 10, AvgPrice: 8493.95335, Type: 0, Offset: 1, Status: 1, ContractType: 'quarter' }
var spotId2 = exchanges[1].Sell(spotTicker2.Buy, spotAmount) // The spot exchange place orders to close position, and records the order ID, recorded to the variable spotId2 exchanges[1].GetOrder(spotId2) // Query spot closing position order details
{ Id: 2, Price: 8444.69999999, Amount: 0.0957, DealAmount: 0.0957, AvgPrice: 8444.69999999, Type: 1, Offset: 0, Status: 1, ContractType: 'BTC_USDT_OKEX' }
var nowQuarterAcc = exchanges[0].GetAccount() // Get current futures exchange account information, recorded in the variable nowQuarterAcc nowQuarterAcc
{ Balance: 0, FrozenBalance: 0, Stocks: 1.021786026184, FrozenStocks: 0 }
var nowSpotAcc = exchanges[1].GetAccount() // Get current spot exchange account information, recorded in the variable nowSpotAcc nowSpotAcc
{ Balance: 9834.74705446, FrozenBalance: 0, Stocks: 0, FrozenStocks: 0 }
Calculate the profit and loss of this hedging operation by comparing the initial account with the current account.
var diffStocks = Math.abs(nowQuarterAcc.Stocks - initQuarterAcc.Stocks) var diffBalance = nowSpotAcc.Balance - initSpotAcc.Balance if (nowQuarterAcc.Stocks - initQuarterAcc.Stocks > 0) { console.log("profit:", diffStocks * spotTicker2.Buy + diffBalance) } else { console.log("profit:", diffBalance - diffStocks * spotTicker2.Buy) }
收益: 18.72350977580652
Below we look at why the hedge is profitable. We can see the chart drawn, the futures price is the blue line, the spot price is the orange line, both prices are falling, and the futures price is falling faster than the spot price.
var objQuarter = { "index" : [1, 2], // The index 1 for the first moment, the opening position time, and 2 for the closing position time. "arrPrice" : [quarterTicker1.Buy, quarterTicker2.Sell], } var objSpot = { "index" : [1, 2], "arrPrice" : [spotTicker1.Sell, spotTicker2.Buy], } plot([{name: 'quarter', x: objQuarter.index, y: objQuarter.arrPrice}, {name: 'spot', x: objSpot.index, y: objSpot.arrPrice}])
Let us look at the changes in the price difference. The difference is 284 when the hedge is opened (that is, shorting the futures, longing the spot), reaching 52 when the position is closed (the futures short positions are closed, and the spot long positions are closed). The difference is from big to small.
var arrDiffPrice = [quarterTicker1.Buy - spotTicker1.Sell, quarterTicker2.Sell - spotTicker2.Buy] plot(arrDiffPrice)
Let me give an example, a1 is the futures price of time 1, and b1 is the spot price of time 1. A2 is the futures price at time 2, and b2 is the spot price at time 2.
As long as a1-b1, that is, the futures-spot price difference of time 1 is greater than the futures-spot price difference of a2-b2 of time 2, a1 - a2 > b1 - b2 can be introduced. There are three cases: (the futures-spot holding position are the same size)
a1 - a2 is greater than 0, b1 - b2 is greater than 0, a1 - a2 is the difference in futures profit, b1 - b2 is the difference in spot loss (because the spot is long position, the price of opening position is higher than the price of closing position, therefore, the position loses money), but the futures profit is greater than the spot loss. So the overall trading operation is profitable. This case corresponds to the chart in step In[8]
.
a1 - a2 is greater than 0, b1 - b2 is less than 0, a1 - a2 is the difference of futures profit, b1 - b2 is the difference of spot profit (b1 - b2 is less than 0, indicating that b2 is greater than b1, that is, the price of opening the position is low, the price of selling the position is high, so the position make profit)
a1 - a2 is less than 0, b1 - b2 is less than 0, a1 - a2 is the difference of futures losses, b1 - b2 is the difference of spot profit due to a1 - a2 > b1 - b2, the absolute value of a1 - a2 is less than b1 - b2 Absolute value, the profit of the spot is greater than the loss of the futures. So the overall trading operation is profitable.
There is no case where a1 - a2 is less than 0 and b1 - b2 is greater than 0, because a1 - a2 > b1 - b2 have been defined. Similarly, if a1 - a2 is equal to 0, since a1 - a2 > b1 - b2 is defined, b1 - b2 must be less than 0. Therefore, as long as the futures are short position and the spot are long position in a long-term hedging method, which meets the conditions a1 - b1 > a2 - b2, the opening and closing position operation is the profit hedging.
For example, the following model is one of the cases:
var a1 = 10 var b1 = 5 var a2 = 11 var b2 = 9 // a1 - b1 > a2 - b2 get : a1 - a2 > b1 - b2 var objA = { "index" : [1, 2], "arrPrice" : [a1, a2], } var objB = { "index" : [1, 2], "arrPrice" : [b1, b2], } plot([{name : "a", x : objA.index, y : objA.arrPrice}, {name : "b", x : objB.index, y : objB.arrPrice}])