Life is Like a Boat

忘備録や投資日記、プログラミングに関するメモやtipsなど

Dataverseのテーブルレコードが変更された時、変更前と変更後の値が欲しい

例えば、商談テーブルのステータスが何かから「商談成立」に変更になった時、Teamsの全体チャネルに対して「おめでとうございます!」的なお祝いメッセージを送りたい、とします。

Power AppsのCommunityサイトではテーブルのステータス項目とは別に、前の値を保持するための項目を作り、変更されるたびにPower Automateから二つの項目を見て、新しい値で保持用項目を更新というなんとも面倒臭い解決策が提案されていたのですが、この方法を採用すると変更を追いたい項目が2つや3つ増えた時にかなり不便です。

最近、Audit logを見る機会があり、Dataverse Web APIのRetrieveAuditDetails関数を使って前後の値を取得する方法があることを知ったのでその方法をシェアします。

まず、前提としてテーブルのAuditがONになっている必要があります(メッセージにもあるように組織全体のAuditもONになっている必要があります)

次に、Dataverse Web APIを使ってある特定のレコードのAudit Idを取得します。curlコマンドを使っていますが、Power AutomateのHTTPアクションを使って同じことができます。

curl "{Your Org URI}/api/data/v9.2/audits?$filter=_objectid_value%20eq%20{object_id}" \
     -H 'Authorization: Bearer ***** Hidden credentials *****' \
     -H 'Accept: application/json' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -H 'Odata-Version: 4.0' \
     -H 'OData-MaxVersion: 4.0' 

filter=_objectid_value eq {object_id}

でOData filterを使ってObject Idを指定する必要があります。 レスポンスにAudit Idが含まれています。変更履歴が複数ある場合(通常複数あると思います)、最も最新のAudit Idを取得するようにします。

さらに、肝心の変更内容を取得するにはRetrieveAuditDetails関数を使ってこのように取得します。

curl "{Your Org URI}/api/data/v9.2/audits({audit_id})/Microsoft.Dynamics.CRM.RetrieveAuditDetails()" \
     -H 'Authorization: Bearer ***** Hidden credentials *****' \
     -H 'Accept: application/json' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -H 'Odata-Version: 4.0' \
     -H 'OData-MaxVersion: 4.0'

NewValueとOldValueをキーにしたJSONのレスポンスが来るはずです。(スクリーンショットでは変更前はブルボン、変更後がカルビーとなっています。お菓子のことを考えていたからですw)

サンプルで使ったレコードは商談テーブルではないのですが、このやり方で「NewValueが『商談成立』の場合のみに」という条件を作ることができました。

PythonからMicrosoft Dataverseに直接アクセスする方法

MicrosoftのPower PlatformにはPower BIというBIツールがあります。解説本やチュートリアルも豊富に出ていて、株クラのPowerBIマスターの方が以前に株価データ配信のKabuPlusと組み合わせたPowerBIダッシュボードを作成されていて(https://twitter.com/yustock)、アイデア次第でなんでも表現できるな〜と思った次第です。

ただ、すでにPythonを使った分析基盤がある場合にわざわざPower BIの使い方を学んでPython側で溜まった知見の移行をする。。。というのは手が出づらいものです。

それぞれに良さがあり、活用シーンが異なります。すでにPandas+Jupyter資産があり、アドホックな分析をやりたい場合には慣れている方を使った方が良いでしょう。

ここでは、Power PlatformのDataverseに顧客データや営業データが既に溜まっていて、Pandas+Jupyter Notebookを使ってデータ分析するケースを考えたいと思います。

方法その1

一番手軽なやり方は、Power Automateの"When a HTTP request is received"トリガーを使うことです。

数ステップを組み合わせたこちらのPower Automate フローで取引先テーブルを全部返すGETメソッドのエンドポイントができてしまいます。一度のリクエストで最大5000行という制限がありますが、@odata.nextLinkで次の5000件が取れそうな感じなので(検証してません)、回避する方法はググれば探せると思います。

エンドポイントにアクセスしてレスポンスをDataframeにすることができます。 f:id:nerimplo:20211110115209p:plain

方法その2

方法2はOdataプロトコルとRestful APIを使ってDataverseのレコードを取得する方法です。

スクショ付きで説明したいと思います。

まず、Azure Active DirectoryでAppを登録します。ここで言うAppはOAuth認証を使用してDataverse環境に接続できるアプリケーションです。 f:id:nerimplo:20211115162429p:plain

Appによろしく名前をつけて、Single Tenantを選び次へ。 f:id:nerimplo:20211115162507p:plain

client secretを作ります。この値は後で使うので必ずコピーします。値が表示されるのは作成時のみなので、ここでコピーしないとまた作り直す必要があります。 f:id:nerimplo:20211115162602p:plain

Power Platform admin centerに移動します。設定からアプリケーションユーザーを作成します。 f:id:nerimplo:20211115162648p:plain

Appユーザの追加ボタンを押し、右パネルから先程Azure ADで作ったApp名を選び追加します。 f:id:nerimplo:20211115162831p:plain

この後、セキュリティロールをアサインする必要があるのですが、App用に個別のロールを作り、適切な権限を与えることを強く推奨します。特にデータ分析だけに使うのであればRead権限だけで十分なはずです。

ここまでで下準備は完了です。

あとはアクセストークンを取得して、取引先レコードを取得するためのDataverse Web APIのエンドポイントに対してリクエストするだけです。以下サンプルコードです。

import requests
import pandas as pd

LOGIN_URL = 'https://login.microsoftonline.com/{0}/oauth2/token'
TENANT_ID = 'YOUR_TENANT_ID'
APP_ID = 'YOUR_APP_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
GRANT_TYPE = 'client_credentials'
RESOURCE = 'https://YOUR_ENV.crm7.dynamics.com/'
DATAVERSE_DATA_URL = '{0}/api/data/v9.1/'.format(RESOURCE)

response = requests.post(LOGIN_URL.format(TENANT_ID), data = {
    'tenant_id': TENANT_ID,
    'client_id': APP_ID,
    'client_secret': CLIENT_SECRET,
    'grant_type': GRANT_TYPE,
    'resource': RESOURCE
})

access_token = response.json().get('access_token')
token_type = response.json().get('token_type')

ACCOUNTS_DATA_URL = f'{DATAVERSE_DATA_URL}accounts'
accounts = requests.get(ACCOUNTS_DATA_URL, headers = {'Authorization': f'{token_type} {access_token}'})

df = pd.DataFrame(accounts.json().get('value'))

解説するポイントとしては、取引先レコードを取得するエンドポイントACCOUNTS_DATA_URLの最後が/accountsと複数形になっている点くらいです。これ結構ハマりポイントだと思いますw https://xxxxx.dynamics.com/api/data/v9.1/accounts

レスポンスに含まれるDataverseレコードはJSON形式になっていますので、これをPandasのDataframeにしてあげればあとはこっちのものです。

さらにOdataプロトコルを使うことでアドホックなクエリを作ることができます。

/accounts?$filter=Name eq 'ABC CORP'

とすると取引先名がABC CORPという会社のレコードを取得することができます。

ちなみにSQL脳の人がODataプロトコルのクエリを作る際にこのチートシートがめちゃくちゃ役立ちますw ぜひ使ってみてください。

skyvia.com

西側諸国が今豊かなのは中世の教会がいとこ同士の結婚を禁じたから

投資理論家であり歴史研究家や神経内科医でもあるウィリアム・バーンスタイン氏がBloomberg RadioのPodcast「Master in Business」で話していたのですが、氏が最近読んで感銘を受けた本として"The Weirdest People in the World"をあげています。

この本でいうweirdは「変な」を意味する形容詞ではなく、Western Educated Industrialized, Rich and Democraticの頭字語だそうです。同書はJoseph Henrich氏という文化人類学者によって書かれ、彼の論題は、西側諸国がなぜ今豊かなのか、その理由として中世の教会がいとこ同士の結婚を禁じたからだ、というのです。

なぜある国は裕福で、ある国は貧乏なのかというのは経済学の長く続く議論の一つですが、これには結構Freaknomics的な驚きを感じます。

教会はいとこ婚だけでなく場合によってはひいひいひいひい爺ちゃんが共通の人(Fifth cousin)との結婚も禁じたとのこと。ここまでくると事実上、生まれ育った町を離れ、結婚相手を探さなければなりません。

数世紀にわたるこの制度は欧州社会の親族関係の構造を根本的に変えていきます。伝統的な親族関係では年長者に従う道徳的価値がありました。しかし、教会が親族以外との結婚を定めたことで、個人主義、不適合、仲間内への偏見のなさなどの新しい価値観が生まれたと言います。このPodcastバーンスタイン氏は“radius of trust”と表現していましたが、中世の教会がいとこ同士の結婚を禁じたことで、この半径が大きくなった社会、つまり見知らぬ人を信頼するようになった社会が豊かな現代社会の性質だといいます。経済的にも政治的にも制度的にも劣っていて、信頼の半径が非常に小さい社会はうまくいっていない傾向があります。例えば、北イタリアと南イタリアでは前者は信頼半径は非常に高く、後者は非常に低くなっています。

「trust」の崩壊が幾たびもの金融危機を引き起こしました。一方で「trust」は不確実性や取引コストを削減し、交換の効率を高め、専門化を促進し、アイデアや人的・物的資本への投資を促す役割があるでしょう。その広がりは中世の教会によるルールが要因だったという下りに、文化人類学的な視点で世の中を見る面白さを感じました。

Transcriptはこちらです。この「Master in Business」は、投資や経営だけでなく経済学、社会学、危機管理など様々な専門家が話すPodcastなので、視野や視点を広げる意味でもかなりおすすめです。 ritholtz.com

砂糖の世界史

今年の目標で毎月5冊本を読み、1つでもいいのでブログに感想を書くという「決意を新た」にしたのですが、それができず5月のGWになってしまいました\(^o^)/

いわゆる積読本としては10冊近くになっており、この休み期間中に読み進めています。

ところで、経営コンサルタント大前研一によると、

「人間が変わる方法は、時間配分を変える、住む場所を変える、付き合う人を変える」の3つしかない

といいます。さらに、

もっとも意味がないのが『決意を新たにすること』(中神 康議. 経営者・従業員・株主がみなで豊かになる 三位一体の経営 (Japanese Edition) (Kindle Locations 3805-3807). Kindle Edition.)

だそうです\(^o^)/

閑話休題、そんなこんなで手に取ったのが 砂糖の世界史 (岩波ジュニア新書) です。

砂糖の世界史 (岩波ジュニア新書)

この本の魅力は、砂糖という多くの人が好むモノ(著者は世界中の誰もが普遍的に好きなモノということで「世界商品」と言っています)から近代史を見てみよう、という視点で書かれていることです。

誰もが好きで甘く、そして純白の砂糖。

16世紀から19世紀にかけて各国の政治家や実業家はいかにして砂糖の生産を握り、その流通ルートを押さえるか知恵を絞りました。(p.7)

生産するため植民地でプランテーションを作ります。プランテーションでの作付け、収穫、砂糖への加工、運搬、その他維持管理にには人手が必要です。労働力として何千万もの人々をアフリカから強制的に連れてきました。特に、

カリブ海の島々では先住民に代わり、アフリカから連れてこられた黒人奴隷が人口の多くを占めるようになりました。(p.16)

というのが、本書での展開のはじまりなのですが、砂糖の生産から消費までの過程を追う事で世界各地の相互の繋がりが見えてくることに気付かされます。

この本をAmazonでポチったきっかけは、知り合いの教員から勧められたからです。学校推薦の夏休み読書本というわけではないですが、小学校高学年からでも読みやすいと感じます。最近、小中高のカリキュラムで「持続可能な開発目標」を児童生徒に考えて発表させる取り組みが進んでいますので、その副読本にもなるのではないかと思います。

個人的には、高校の世界史の授業でこれを読んでいたら、世界史に興味持ってもっといい点とれたかもwと思います。

最後に、私が大いに共感した著者がこの本のあとがきで述べている下りを引用します。

歴史を学ぶということは、年代や事件や人命をたくさん覚え込むことではありません。いま私たちが生きているこの世界がどのようにしてこんにちの姿になってきたのかを、身近なところから考えてみることなのです。(p. 208)

砂糖の世界史 (岩波ジュニア新書)

砂糖の世界史 (岩波ジュニア新書)

What is it like to work for Elon Musk

"What is it like to work for Elon Musk"というタイトルでSpaceXイーロン・マスクと共に働いた元NASA技術者のGarrett Reisman氏がJoe Rogan氏の番組でこう答えています。

  • イーロンの意思決定は、その決定によって人類が火星で持続可能なコロニーを作れる日を早めるか遅くなるかに基づいている
  • イーロンはスティーブ・ジョブズのように人々の生活に劇的なインパクトを与えるというレガシーを残したい。
  • (Reisman氏は)自分は今まで多くの超超優秀な人と仕事をしたが、大抵彼らは一つの事柄に対して超超優秀なものだ。イーロンは我々(SpaceX)のトップ技術者とソフトウェアについて議論しているかと思えば、製造技術者ととても難解な溶接の方法について議論している。イーロンの知識の幅には本当に感銘を受ける。

www.youtube.com

決算後ギャンブルメモ

大抵この時期の決算シーズンは発表社数でみて

  • 1月中旬の小波
  • 1月最終週の木金の中波
  • 2月第一週後半から第二週の大波

という感じなのですが、今週はちょうどその谷間でたまった発表分をぽちぽち見ながら業績の趨勢をみる感じでした。

決算ギャンブルは業績発表前にポジションを持ち、発表後に反対売買する事なのですが、決算発表日の翌日終値で買い、5営業日に売るパターンをした場合を調べてみました。

これは決算後ギャンブルと名付ければ良いかわかりませんが、

の2パターンあると思います。

まず、決算発表日翌営業日に前日終値比でプラスになった銘柄数は354社中140社。そのうち、5営業日後もさらに上昇を続けた銘柄は81あります。これらはポジティブサプライズがモメンタムになって上昇が続いたと解釈されると思います。そのトップ10を抽出してみました。 f:id:nerimplo:20210124134458p:plain

つぎに、決算発表翌営業日が前日比でマイナス、5営業日後の終値でプラスリターンになっている銘柄数は99でした。直後に売られたが日が経つにつれ戻ったパターンです。その上位10を表示しています。 f:id:nerimplo:20210124125922p:plain

うち、リターン別でソートして1位になったJESCOの1時間足をみると、 f:id:nerimplo:20210124130633p:plain

発表翌日のオープンで売られ、その翌日のオープンで下ひげを付けています。自分だったらその翌日の下ひげ近辺で損切りしてそうです。

それぞれのパターンを表にまとめてみました。

t5>t1 t5=<t1
t1+ 81 59
t1- 91 123

t1が決算発表の翌営業日、t5が5営業日後です。決算発表日の翌営業日(t1)の終値が前日比プラス、かつ5営業日終値(t5)がt1を上回っている銘柄数は81です。

2020年を振り返る - 投資編

激動の一年が終わりました。 年間の日本株PFのパフォーマンスを計算したところ、年初来で28.9%増。米株PFは12/30時点で80.2%増となりました。

自分のTwilogを読み返しつつ今年を振り返りたいと思います。

1-2月

思い返せばイラン司令官殺害のニュースなど中東情勢の悪化懸念から始まった2020年。東京オリンピックを控えて年前半のGWにかけては波乱含みの展開、年後半から上向くイメージでいました。

1月5日には武漢新型コロナウイルス患者が発生したと発表(NHKスペシャルによると感染はそれより前に始まっていて、武漢の海鮮市場は初期クラスターの一部だったようです)。

当局は専用病棟を速攻で建てているし、

強権的なロックダウン措置をとる対応が中国発のニュースで流れていました。

とはいえ、この時点で自分は大阪でのMicrosoftのイベントに行っていましたし、正直対岸の火事程度に思っていて、まぁ豚インフルの頃と同じになるやろ、くらいの構えでした。

それでも、プットオプションを保険目的で買ってました。中国ニュースを追っていると武漢では秀吉もびっくりな一夜城で病院建てるくらいの大騒動なのに、株式市場は2月第3週まで、特に日経平均はそれほど影響を受けておらず、このウイルスの脅威は実はそれ程なくて、間違っているのは(心配し過ぎなのは)自分じゃないか、と思うようになりました。そうであれば、ここは少しでも利益乗ってるプットオプション外して様子を見よう、と判断したのが2/20です。後から振り返ってこの判断がいかに愚かだったのか思い知ることになります。 f:id:nerimplo:20201230170641p:plain

歴史的下落の3月

自分は社会人になってからリーマンショックと2011年3月大震災を経験したのですが、その頃は運用額も今より少なく、銘柄数も多くなかったので、今回体感する下落の恐怖は今までで最大でした。 株式PFの下落を少しでも回避するため、信用ポジは徹底的に損切り、少しでも利益が乗っている現物は長期保有候補であってもとにかく売りました。キャッシュポジションはPFの8割近くになりました。

米株ではNYダウのサーキットブレイクという、ものすごいプライスアクションを経験しました。「Frozen III」なんてジョークよく言えたよなと今振り返って思います。

おそらく、想定を超えるプライスアクションを経験した人は笑いしか出てこないんじゃないか。

3月末時点では年初来-35%でした。

金融/財政総動員

3月15日、FRBは臨時の会合を開き、パウエル議長は危機対応を表明。事実上のゼロ金利政策と大量の国債などを買い入れる量的緩和の再開を決定しました。 www3.nhk.or.jp

その後通常の失業保険にさらに600ドル/週を上乗せするなど、政府が国民のポケットに金を突っ込む平時であれば考えられない政策を含むCARES法案が米議会で合意。 www.washingtonpost.com

これらの政策により市中のマネーはM1/M2を見ると判るように急拡大。 f:id:nerimplo:20201230172930j:plainf:id:nerimplo:20201230172941j:plain

経済学史に深く刻まれる出来事でしょう。

急回復の春

4月、5月は大きく回復し、特に5月の月間確定損益は過去最高となりました。 スクリーニングに出てくるバリュエーションを気にせずとにかく平時に普通に戻ればある程度稼げる時価総額大きめの優良企業を現物で買い始めました。 5月に月間で過去最大の確定利益となった要因としては、3月末から4月にかけて建てた信用買いポジの貢献が大きいと自己分析してます。

ヨコヨコの夏/秋

その後7-8月の利確と損切りの夏を過ごし、一進一退の秋になり、10月中旬の新興市場ピークアウトの余波を受けました。 この頃、AI Insideが大きく貢献した一方、決算ギャンブルをしたパソナ空売りポジションが決算発表後に見事に逆サイドに行くS高となり大きな損失となりました。

8月以降は海運セクターのポジションを初めて作りました。郵船と川崎汽です。読み通りどちらの業績も市況の回復を享受し、株価はそれに反応した形となりました。

大統領選後

大統領選から12月にかけて時価総額上位のバリュー/クオリティのカムバックを享受できました。シクリカルの機械や化学セクターにうまく乗れました。特に12月にかけてYH水準で推移できたのは夏頃にポジション作ったレノバです。エネルギー政策関連として注目される事は当初は全く考えてなかったのですが、自前で発電所を建てられる優位性と今後の投資額、売電設備の着実な積み上がりを期待して5-7年のスパンで考えての投資でした。ポジション量も現物としては多めだったので、現物PFのパフォーマンスに大きく貢献しました。ちなみに同株は12月後半で全株利確しました。

振り返ってみると、急落→急回復→ヨコヨコ→上昇とPFとマーケットは大方同じように推移しました。地合いに助けられた1年だったと思います。

来年のビュー

COVID19については現在の第3波をやり過ごす過程でモデルナやファイザーのmRNAワクチン、アストラゼネカの安価なワクチンが世界的に普及していくことでしょう。順調にいけばアメリカは来秋にも集団免疫を獲得することになり、消費や設備投資の回復、失業率の下落、COVID19により生じたスラック解消による賃金増と好調なマクロ経済環境に戻ると予想しています。

来年1-3月は、平時の経済環境でうまくキャッシュを稼げそうな企業の押し目を狙う戦略でいくつもりです。全体的なマーケットの雰囲気を把握するために使っている25日移動平均線を上回る銘柄の割合を見つつ、信用枠ではシクリカルなセクターやテーマ株投資で上手く回していこうと思っています。