ウォーレン・バフェットのメンターである ベンジャミン・グラハムは 本"The Intelligent Investor"で 株式と債券のダイナミック・バランス・トレーディングモードについて言及しています
取引の仕方はとてもシンプルです - 資金の50%を株式基金に,残りの50%を債券基金に投資する.つまり,株と債券は,半分を互いに占めています. - 固定期間や市場変動に応じて,資産の再バランスを取って,株式資産と債券資産の比率を元の1:1に戻す. 購入・販売のタイミングや 購入・販売の金額など 簡単です!
この方法では,債券ファンドの変動は 実際には非常に小さく,株式の変動よりもはるかに低いので,債券はここで"参照アンカー"として使用されます.
株価が上昇すると,株価の市場価値は債券の市場価値より大きくなります.両者の市場価値比が設定された
ブロックチェーン資産BTCにおける動的バランス戦略
戦略の論理
この方法で,BTCが値上げするか減価するかに関わらず,私たちは常に口座残高とBTCの市場価値を動的に等しく保っています.BTCが値下げした場合,私たちは購入し,再び上昇した場合,残高のように,いくつか販売します.
FMZ Quant Trading Platform を例として,まず戦略の枠組みを見てみましょう.
// 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
}
}
戦略の枠組み全体が非常にシンプルで,メイン機能,オンティックオーダー配置機能,キャンセル待ちオーダー機能,必要なパラメータを含む.
// 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. 設定する必要はありません,あなたは直接オンラインバックテストすることができます.
この記事のダイナミックバランス戦略には,非常に単純な投資方法である1つのコアパラメータ (しきい値) しかありません.それは過剰な収益ではなく,安定した収益を追求しています.トレンド戦略とは異なり,ダイナミックバランス戦略はトレンドに反しています.しかしダイナミックバランス戦略はちょうど逆です.市場は人気のあるとき,ポジションを減らす,市場は人気がないとき,ポジションをスケールする,これはマクロ経済規制に似ている.
実際,ダイナミックバランス戦略は,予測不可能な価格の概念を継承し,同時に価格変動を捉える工夫である.ダイナミックバランス戦略の核は,資産配分比率,トリガースロージックを設定し調整することです.長さを考えると,記事は包括的になることはできません.言葉を超えて,心があることを知っておくべきです.ダイナミックバランス戦略の最も重要な部分は投資アイデアです.この記事で個々のBTC資産をブロックチェーン資産ポートフォリオのバスケットに置き換えることもできます.
最後に,本文をベンジャミン・グラハムの著書"The Intelligent Investor"の有名な言葉で締めくくりましょう. 株式市場は,価値を正確に測定できる"計測機"ではなく",投票機"です. 無数の人が取る決断は,理性と感覚の混合物です. 多くの場合,これらの決定は理性的な価値判断から遠いものです. 投資の秘訣は,価格が本質的な価値よりもはるかに低いときに投資し,市場のトレンドが回復すると信じることです. ベンジャミン・グラハム 賢明な投資家