워렌 버핏의 멘토인 벤자민 그레이엄은 책에서 동적 균형 거래 방식을 언급했습니다.
거래 방식은 매우 간단합니다. 자금의 50%를 주식 펀드에 투자하고 나머지 50%를 채권 펀드에 투자합니다. 즉 주식과 채권은 서로 절반을 차지합니다. - 고정된 간격 또는 시장 변화에 따라 자산 재균형을 수행하여 주식 자산과 채권 자산의 비율을 원래 1:1로 회복합니다. 이 전략의 논리, 언제 구매하고 판매하고 얼마나 구매하고 판매하는지를 포함합니다.
이 방법에서는 채권 펀드의 변동성은 실제로 주식 변동성보다 훨씬 낮습니다. 그래서 채권은 여기서 " 참조 앵커 "로 사용됩니다. 즉 채권에 의해 주가가 너무 많이 상승했는지 너무 적게 상승했는지 측정하기 위해서입니다. 주식 가격이 상승하면 주식의 시장 가치는 채권의 시장 가치보다 커질 것입니다. 두 가지의 시장 가치 비율이 설정된 임계치를 초과하면 전체 지위가 재조정되며 주식이 판매되고 채권이 구매되므로 주식과 채권의 시장 가치 비율이 원래 1:1로 돌아갈 것입니다. 반대로 주식 가격이 하락하면 주식의 시장 가치는 채권의 시장 가치보다 작을 것입니다. 두 가지의 시장 가치 비율이 설정된 임계치를 초과하면 전체 지위가 재조정되며 주식이 구입되고 채권이 판매되므로 주식과 채권의 시장 가치 비율이 원래 1:1로 돌아갈 것입니다. 이 방법으로 우리는 주식 성장의 열매를 즐길 수 있고 동적으로 주식과 채권 사이의 비율을 균형을 맞추어 자산 변동성을 줄일 수 있습니다. 가치 투자의 선구자로서 그레이엄은 우리에게 좋은 아이디어를 제공했습니다. 이것은 완전한 전략이기 때문에 왜 디지털 통화에서 사용하지 않습니까?
블록체인 자산 BTC의 동적 균형 전략
전략 논리
이 방법으로, BTC가 상승하거나 하락하든 상관없이, 우리는 항상 계좌 잔액과 BTC의 시장 가치를 동적으로 동일하게 유지합니다. BTC가 하락하면, 우리는 구매하고, 다시 상승하면, 우리는 잔액처럼 판매합니다.
그래서, 어떻게 코드를 구현합니까? 우리는 예를 들어 FMZ 양자 거래 플랫폼을 가지고, 먼저 전략 프레임워크를 살펴보자:
// function to cancel orders
function CancelPendingOrders() {}
// function to place an order
function onTick() {}
// main function
function main() {
// filter non-important information
SetErrorFilter("GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout");
while (true) { // polling mode
if (onTick()) { // execute onTick function
CancelPendingOrders(); // cancel the outstanding pending orders
Log(_C(exchange.GetAccount)); // print the current account information
}
Sleep(LoopInterval * 1000); // sleep
}
}
전체 전략 프레임워크는 실제로 매우 간단합니다. 주요 기능, ONTICK 주문 배치 기능, CANCELPENDINGORDERS 기능, 필요한 매개 변수를 포함합니다.
// order-placing function
function onTick() {
var acc = _C(exchange.GetAccount); // obtain account information
var ticker = _C(exchange.GetTicker); // obtain Tick data
var spread = ticker.Sell - ticker.Buy; // obtain bid ask spread of Tick data
// 0.5 times of the difference between the account balance and the current position value
var diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell)) / 2;
var ratio = diffAsset / acc.Balance; // diffAsset / account balance
LogStatus('ratio:', ratio, _D()); // Print ratio and current time
if (Math.abs(ratio) < threshold) { // If the absolute value of the ratio is less than the specified threshold
return false; // return false
}
if (ratio > 0) { // if ratio > 0
var buyPrice = _N(ticker.Sell + spread, ZPrecision); // Calculate the price of an order
var buyAmount = _N(diffAsset / buyPrice, XPrecision); // Calculate the order quantity
if (buyAmount < MinStock) { // If the order quantity is less than the minimum transaction quantity
return false; // return false
}
exchange.Buy(buyPrice, buyAmount, diffAsset, ratio); // Purchase order
} else {
var sellPrice = _N(ticker.Buy - spread, ZPrecision); // Calculate the price of an order
var sellAmount = _N(-diffAsset / sellPrice, XPrecision); // Calculate the order quantity
if (sellAmount < MinStock) { // If the order quantity is less than the minimum transaction quantity
return false; // return false
}
exchange.Sell(sellPrice, sellAmount, diffAsset, ratio); // Sell and place an order
}
return true; // return true
}
주문 거래 논리는 잘 조직되어 있으며 모든 댓글이 코드에 기록되었습니다. 확대하기 위해 이미지를 클릭할 수 있습니다.
주요 과정은 다음과 같습니다.
// Withdrawal function
function CancelPendingOrders() {
Sleep(1000); // Sleep for 1 second
var ret = false;
while (true) {
var orders = null;
// Obtain the unsettled order array continuously. If an exception is returned, continue to obtain
while (!(orders = exchange.GetOrders())) {
Sleep(1000); // Sleep for 1 second
}
if (orders.length == 0) { // If the order array is empty
return ret; // Return to order withdrawal status
}
for (var j = 0; j < orders.length; j++) { // Iterate through the array of unfilled orders
exchange.CancelOrder(orders[j].Id); // Cancel unfilled orders in sequence
ret = true;
if (j < (orders.length - 1)) {
Sleep(1000); // Sleep for 1 second
}
}
}
}
인출 모듈은 더 간단합니다. 단계는 다음과 같습니다.
// Backtest environment
/*backtest
start: 2018-01-01 00:00:00
end: 2018-08-01 11:00:00
period: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
// Order withdrawal function
function CancelPendingOrders() {
Sleep(1000); // Sleep for 1 second
var ret = false;
while (true) {
var orders = null;
// Obtain the unsettled order array continuously. If an exception is returned, continue to obtain
while (!(orders = exchange.GetOrders())) {
Sleep(1000); // Sleep for 1 second
}
if (orders.length == 0) { // If the order array is empty
return ret; // Return to order withdrawal status
}
for (var j = 0; j < orders.length; j++) { // Iterate through the array of unfilled orders
exchange.CancelOrder(orders[j].Id); // Cancel unfilled orders in sequence
ret = true;
if (j < (orders.length - 1)) {
Sleep(1000); // Sleep for 1 second
}
}
}
}
// Order function
function onTick() {
var acc = _C(exchange.GetAccount); // obtain account information
var ticker = _C(exchange.GetTicker); // obtain Tick data
var spread = ticker.Sell - ticker.Buy; // obtain bid ask spread of Tick data
// 0.5 times of the difference between the account balance and the current position value
var diffAsset = (acc.Balance - (acc.Stocks * ticker.Sell)) / 2;
var ratio = diffAsset / acc.Balance; // diffAsset / account balance
LogStatus('ratio:', ratio, _D()); // Print ratio and current time
if (Math.abs(ratio) < threshold) { // If the absolute value of ratio is less than the specified threshold
return false; // return false
}
if (ratio > 0) { // if ratio > 0
var buyPrice = _N(ticker.Sell + spread, ZPrecision); // Calculate the order price
var buyAmount = _N(diffAsset / buyPrice, XPrecision); // Calculate the order quantity
if (buyAmount < MinStock) { // If the order quantity is less than the minimum trading quantity
return false; // return false
}
exchange.Buy(buyPrice, buyAmount, diffAsset, ratio); // buy order
} else {
var sellPrice = _N(ticker.Buy - spread, ZPrecision); // Calculate the order price
var sellAmount = _N(-diffAsset / sellPrice, XPrecision); // Calculate the order quantity
if (sellAmount < MinStock) { // If the order quantity is less than the minimum trading quantity
return false; // return false
}
exchange.Sell(sellPrice, sellAmount, diffAsset, ratio); // sell order
}
return true; // return true
}
// main function
function main() {
// Filter non-important information
SetErrorFilter("GetRecords:|GetOrders:|GetDepth:|GetAccount|:Buy|Sell|timeout");
while (true) { // Polling mode
if (onTick()) { // Execute onTick function
CancelPendingOrders(); // Cancel pending orders
Log(_C(exchange.GetAccount)); // Print current account information
}
Sleep(LoopInterval * 1000); // sleep
}
}
외부 매개 변수
다음으로, 이 간단한 동적 균형 전략이 작동하는지 확인하기 위해 테스트 해 봅시다. 다음은 참조를 위해 BTC의 역사적 데이터에 대한 백테스트입니다.
백테스팅 환경
백테스팅 성능
백테스팅 곡선
백테스트 기간 동안 BTC는 최대 70% 이상의 최대 감소에도 불구하고 최대 8 개월 동안 계속 하락했으며 많은 투자자들이 블록체인 자산에 대한 신뢰를 잃게되었습니다. 이 전략의 누적 수익률은 최대 160%이며 연간 수익 위험 비율은 5을 초과합니다. 그러한 간단한 투자 전략의 경우 투자 수익률은 완전한 위치에있는 대부분의 사람들의 수익률을 초과했습니다.
전략의 소스 코드는 FMZ Quant 공식 웹사이트에 공개되었습니다.https://www.fmz.com/strategy/110545설정할 필요가 없습니다, 당신은 온라인으로 직접 백테스팅 할 수 있습니다.
이 문서의 동적 균형 전략은 매우 간단한 투자 방법인 하나의 핵심 매개 변수 (약수) 만 가지고 있습니다. 그것은 과도한 수익을 추구하는 것이 아니라 안정적인 수익을 추구합니다. 트렌드 전략과 달리 동적 균형 전략은 트렌드에 반대합니다. 그러나 동적 균형 전략은 바로 그 반대입니다. 시장이 인기가있을 때 위치를 줄이고 시장이 인기가 없을 때 위치를 확장하는 것이 거시 경제 규제와 유사합니다.
사실, 동적 균형 전략은 예측 불가능한 가격의 개념을 계승하고 동시에 가격 변동을 포착하는 기술이다. 동적 균형 전략의 핵심은 자산 할당 비율을 설정하고 조정하는 것뿐만 아니라 트리거 문턱이다. 길이를 고려하면 기사는 포괄적일 수 없다. 단어 너머에는 마음이 있다는 것을 알아야 한다. 동적 균형 전략의 가장 중요한 부분은 투자 아이디어이다. 이 기사에서 개별 BTC 자산을 블록체인 자산 포트폴리오의 바구니로 대체할 수도 있다.
마지막으로 벤자민 그레이엄의 저서?? 지능형 투자자?? 에서 유명한 단어로 이 기사를 마무리하자: 주식 시장은 가치를 정확하게 측정할 수 있는 "중량 기계"가 아니라 "투표 기계"입니다. 수많은 사람들이 결정하는 것은 합리성과 감수성의 혼합물입니다. 종종 이러한 결정은 합리적인 가치 판단과는 거리가 멀습니다. 투자의 비결은 가격이 본질적 가치보다 훨씬 낮을 때 투자하고 시장 추세가 회복 될 것이라고 믿는 것입니다. 벤자민 그레이엄 똑똑한 투자자