Benjamin Graham, Warren Buffett's Mentor, hat in seinem Buch "The Intelligent Investor" einen dynamischen Handelsmodus für Aktien und Anleihen erwähnt.
Der Handelsmodus ist sehr einfach: - 50% der Mittel in Aktienfonds und die restlichen 50% in Anleihenfonds investieren. - je nach festgelegten Intervallen oder Marktveränderungen eine Vermögensüberwachung durchführen, um den Anteil der Aktien- und Anleihenvermögenswerte auf den ursprünglichen Wert von 1:1 wiederherzustellen. Dies ist die Logik der gesamten Strategie, einschließlich wann und wie viel zu kaufen und zu verkaufen.
Bei dieser Methode ist die Volatilität von Anleihenfonds sehr gering, viel niedriger als die Volatilität von Aktien, so dass Anleihen hier als "Referenzanker" verwendet werden, d.h. um zu messen, ob die Aktien durch Anleihen zu stark oder zu wenig gestiegen sind. Wenn der Marktwertverhältnis der beiden überschreitet den gesetzten Schwellenwert, wird die Gesamtposition angepasst, die Aktien werden verkauft, und die Anleihen werden gekauft, so dass das Marktwertverhältnis der Aktien und Anleihen auf das ursprüngliche 1:1 zurückkehrt. Im Gegenteil, wenn der Aktienkurs sinkt, wird der Marktwert der Aktie kleiner sein als der Marktwert der Anleihen. Wenn das Marktwertverhältnis der beiden den festgelegten Schwellenwert überschreitet, wird die Gesamtposition angepasst, Aktien gekauft und Anleihen verkauft, so dass das Marktwertverhältnis von Aktien und Anleihen auf das ursprüngliche 1:1 zurückkehrt. Auf diese Weise können wir die Früchte des Aktienwachstums genießen und die Volatilität von Vermögenswerten reduzieren, indem wir den Anteil zwischen Aktien und Anleihen dynamisch ausgleichen.
Dynamische Bilanzstrategie in Blockchain-Asset BTC
Strategie Logik
Auf diese Weise halten wir, egal ob BTC ansteigt oder abwertet, den Kontostand und BTC
Wir nehmen die FMZ Quant Trading Plattform als Beispiel, werfen wir zunächst einen Blick auf das Strategie-Framework:
// 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
}
}
Das gesamte Strategie-Rahmenwerk ist eigentlich sehr einfach, einschließlich einer Hauptfunktion, einer OnTick-Order-Funktion, einer CancelPendingOrders-Funktion und der notwendigen Parameter.
// 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
}
Die Logik des Auftragshandels ist gut organisiert, und alle Kommentare wurden in den Code geschrieben.
Der Hauptprozess ist wie folgt:
// 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
}
}
}
}
Das Auszahlungsmodul ist einfacher und umfasst folgende Schritte:
// 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
}
}
Außenparameter
Als nächstes testen wir diese einfache dynamische Ausgleichsstrategie, um zu sehen, ob sie funktioniert.
Umgebung für Backtests
Backtestleistung
Kurve der Rückprüfung
Während der Backtest-Periode ist BTC auch mit einem maximalen Rückgang von mehr als 70% bis zu 8 Monate weiter gesunken, was dazu führte, dass viele Anleger das Vertrauen in Blockchain-Assets verloren haben. Die kumulative Rendite dieser Strategie beträgt bis zu 160%, und die jährliche Rendite-Risiko-Ratio übersteigt 5. Für eine so einfache Anlagestrategie hat die Rendite der Anlage die der meisten Menschen, die in einer vollen Position sind, übertroffen.
Der Quellcode der Strategie wurde auf der offiziellen Website von FMZ Quant veröffentlicht:https://www.fmz.com/strategy/110545Es gibt keine Notwendigkeit zu konfigurieren, Sie können Backtesting online direkt.
Die Dynamic Balance Strategy in diesem Artikel hat nur einen Kernparameter (Schwelle), der eine sehr einfache Anlagemethode ist. Was sie verfolgt, ist keine überschüssige Rendite, sondern eine stetige Rendite. Im Gegensatz zur Trendstrategie ist die Dynamic Balance Strategy gegen den Trend. Aber die Dynamic Balance Strategy ist genau das Gegenteil. Wenn der Markt beliebt ist, reduziert die Position, während der Markt unbeliebt ist, skaliert die Position, was der makroökonomischen Regulierung ähnelt.
In der Tat ist die dynamische Balance-Strategie ein Handwerk, das das Konzept von unvorhersehbaren Preisen erbt und gleichzeitig Preisschwankungen erfasst. Der Kern der dynamischen Balance-Strategie besteht darin, das Vermögensverteilungsverhältnis sowie die Auslöserschwelle festzulegen und anzupassen. Angesichts der Länge kann ein Artikel nicht umfassend sein. Sie sollten wissen, dass jenseits der Worte ein Herz ist. Der wichtigste Teil der dynamischen Balance-Strategie ist die Anlageidee. Sie können die einzelnen BTC-Assets in diesem Artikel sogar durch einen Korb Blockchain-Assetportfolios ersetzen.
Schließlich schließen wir diesen Artikel mit den berühmten Worten von Benjamin Graham aus dem Buch