SBCZ80ルーズキットの製作(改造編)

2020/09/21

 以下の改造には、組立前に基板の箔カットが必要になりますので、ご注意ください。


①DRAM容量アップ(48KB)


uPD41464(64kx4bit)を使用しました。M5M4416とピン互換ですが、4倍の容量があります。

改造ポイントは、


・CPUメモリアドレスデコーダの拡張


・アドレスマルチプレクサの拡張


・NMI信号の生成とZ80のNMIへの接続


Z80は、通常2mS/128リフレッシュしかサポートしていませんが、A7は、出力されますので、NMIで補完すると、4mS/256が実現できます。NMI信号の生成は、後述のPIC12F1822で行い、Z80のNMIに接続します。



・GRANTBAS、ZPTB、Universal Monitor Z80のRAM領域の変更および、NMIハンドラの追加(diff結果


②クロック高速化(8MHz)


Z80クロック信号の生成は、PIC12F822で行います。


③シリアル速度自動設定(9.6kbps~115kbps)


シリアル速度自動設定は、PIC12F822で行います。


下記は、PIC12F822周りの改造回路です。IC11に実装しましたので、回路図は、IC11のピン番号になっています。


以下は、PIC12F822の仕様です。



①SCLK: SIOクロック(2PIN)


電源投入後2後~30秒までの間に、SIOのRXD端子からCRコードを検出して自動速度設定を行います。57.6kbpsと115.2kbpsでは、偏差が大きいので、使用できない場合があります。

検出速度   実測周波数
9.6kbps 153.6kHz
19.2bps 307.2kHz
38.4kbps 614.5kHz
57.6kbps 914.5kHz
115.2kbps 1937kHz


②CLK: Z80のクロック(3PIN)


デフォルトは、4MHzにしていますが、PIC12F1822のプログラム切替で、2/4/8MHzの選択が可能です。


③PWR: 抵抗を介して、リセット用のCR回路に接続します。(4PIN)


④~NMI:DRAM 4mS/256リフレッシュ用割り込み(7PIN)


Z80のNMIに接続します。下記は、NMI割り込み処理で、Z80のRレジスタ更新を2mS毎に行います。ROMに埋め込む必要があります。

;	NMI HANDLER
; TARGET: SBCZ80
; ASSEMBLER: ARCPIT XZ80.EXE
;
NMI EQU 0066H ;NMI HANDLER ADDRESS
;
; NMI HANDLER
ORG NMI
PUSH AF
LD A,R
XOR 80H
LD R,A
POP AF
RETN


⑤~RST: Z80のリセット信号です。PWRのリセット用CR回路の電圧を監視しています。(6PIN)


~NMIは、このリセット信号解除に同期し、1mS後から出力されます。


⑥RXD: SIOのRXDA端子に接続します。シリアル自動速度設定に使用します。(5PIN)


最後に、以前の改造と同じように、ROMアドレス切替も行い、32KBのEEPROMを16KB+8KB+8KBに区切り、GRANTBAS、ZPTB、Universal Monitor Z80を切り替えて使用できるようにしました。同じくリセットCR回路のダイオードを電圧検出器に交換しています。追って、PIC12F822のソースコードを公開します。


下記は、改造後の基板の様子です。ジャンパが多くなってしましました。次は、8MHzも試してみる予定です。




立ち上げ画面です。"48766 Bytes free"となっています。


(再クロール更新:2022/12/22)

SBCZ80ルーズキットの製作(リセット不良対策編)

2020/09/20

 以前にZ80高速版を手に入れておいたので、SBCZ80を製作してみました。せっかく製作するので、ついでに下記の改造をしてみました。


①DRAM容量アップ(48KB)

②クロック高速化(8MHz)

③シリアル速度自動設定(9.6kbps~115kbps)


それぞれの内容については、順次紹介していく予定ですが、例のごとく必要な基板の箔カットを行った後、配布されているROMイメージを使って基本動作確認を行ったところ、立ち上げメッセージが出てきませんでした。


CPU周りの波形解析すると、CPUリセット後、SIOの初期設定が行われていましたが、RTSがアクティブになりませんでした。プログラムとしては、正常な動作をしているため、回路図、CPU・SIOデーターシートを確認しましたが、特に問題は発見できませんでした。


各部の波形を確認するとCPUのRESET信号が徐々に電圧が上がっていくのが気になり、再度データシートを確認すると、RESET入力は、基本的なTTLレベルの入力信号となっていました。リセット回路は、CPUリとSIOに接続されているので、徐々に立ち上がる入力信号の場合、動作が閾値電圧に左右されることが予想されます。


SBCZ80のリセット回路は、時定数470mSのCRで構成されているので、仮に10mVの閾値電圧の差があると、簡易計算で0.01V/5V*470mS=0.94mS程度の遅延差が発生します。このことは、SIOの閾値電圧が、CPUの閾値電圧に比べ10mV高いと、CPUがSIOを約1mS以内にSIOの初期設定をすると、SIOはリセット中で、初期設定ができないことになります。


確認のため、C15を0.01uFに交換すると、正常にSIOが動き始めました。CPUとSIOはZilog製ですが、たまたま相性が悪かったようです。


相性が悪いCPUとSIOの対策案:


①相性が良いCPUとSIOに交換する(SIOのリセット閾値電圧が、CPUのそれに比べ低い)

②C15を小容量に変更する(0.01uF程度、但し電源SWでのリセットに問題が残ることがある)

③モステックの資料のようにCR回路の後にシュミットトリガー回路を使用する

④CPUリセット後、十分待ってからSIOの初期設定を行う


もし、SBCZ80が動かない場合、②でリセットボタンを押して切り分けをしてはいかがでしょうか。恒久的には、③が良いかもしれません。


下記は、モステックの資料からの転載です。



今回の改造では、PIC12F822で、CPUクロック、CPUリセット、NMI信号、SIOクロックを発生させることにしました。

(再クロール更新:2022/12/22)

AI投資予測へのチャレンジ ~ ロボアドの上を行く投資コース予測

2020/08/28

 プロが、運用実績データを眺めながら、コース変更をすれば、良い結果がでると思いますが、初心者には難しいかもしれません。そこで、AI投資予測(ディープラーニングに代表される機械学習)にチャレンジしてみることにしました。うまくいけば、新しいロボアド(ダイナミック・ロボット・アドバイザー)ができることになるかもしれません。


一度、ディープラーニングに触れてみたいと思っていた中で、投資予測に関して、以前の仕事関係者からディープラーニングでは、予測精度があまり出なかったと聞いたため、戦々恐々でスタートしました。


当初、時系列データ分析で、各コースの基準価格を入力して将来の基準価格を予測させてみましたが、予測された基準価格から有望なコースを判定しようとすると、わずかな差に左右されるようでした。


そこで、文字認識のように8種類(コース)に分類される画像データ(2次元時系列データ)を入力し、8種類各々の確率を推定するモデルを考えました。なんとなく用途実績があり、曖昧な判定をこなす機械学習に向いている気がしました。上記画像データに相当するのは、今回では市場指数の時系列になります。教師データは、各コースの基準価格の騰落率実績に基づき、コースを選択します。


動的なコース選択予測を下記のような条件で検証を行ってみました。市場指数と各コースの運用成績の相関があるだろうとの仮定を立て、日経225、ダウ、ドル円、米国10年債を採用しましたが、教師データにHコースを除外しているため、Hコースに相関がありそうなナスダック指数は、外すことにしました。


①環境:anaconda環境下(python=3.7.7、tensorflow==1.15.3、keras=2.3.1)、

 spyderを使用

②入力データ(25営業日分):日経225、ダウ、ドル円、米国10年債

③教師データ:翌月11~翌々月11日までの最大騰落率のコースが「1」のデータ

 (但し、Hコースは除外)

④モデル構成:隠し層が100あるシンプルなLSTM

⑤学習:日々の入力データに対するコース選択の教師データ

 (設定当初から2020/1/29まで、約900セット)をepochs: 1800で学習

⑥評価:学習したモデルを使い、2020/1/30時点で翌月運用コースを予測

⑦翌月分を追加学習し、2020/28時点で翌月運用コースを予測

⑧同様に、2020/6/29時点まで翌月運用コースを予測


下記は、モデルのサマリーです。

Layer (type)                 Output Shape              Param #   
=================================================================
input_2 (InputLayer) (None, 25, 4) 0
_________________________________________________________________
lstm_2 (LSTM) (None, 100) 42000
_________________________________________________________________
dense_2 (Dense) (None, 8) 808
=================================================================
Total params: 42,808
Trainable params: 42,808
Non-trainable params: 0

各々の予測したい時点より前のデータにより学習し、2020/1~2020/6までを予測した結果、上限理論値騰落率12.20%に対して、予測騰落率9.47%(年率換算16.23%)となり、77.62%の到達率を獲得できました。コロナショックを受けた期間ですが、良い成績を確保できています。ちなみにリスクは大きいが、リターンが大きいコースHの実績騰落率は、-3.99%ですので、13.46%も優れていることになります。

予測日     翌月最適 翌月予測 翌月最適  翌月予測  翌月理論  翌月コースH
コース  コース コース コース 上限 崩落率
崩落率 崩落率 崩落率
2019/12/30 5 7 0.56% 0.54% 0.56% 0.52%
2020/1/30 1 1 -1.97% -2.00% -1.97% -16.10%
2020/2/28 5 7 -1.64% -2.55% -1.61% -17.21%
2020/3/30 7 7 0.45% -0.46% 1.00% -14.61%
2020/4/28 7 7 8.05% 7.15% 9.56% -6.05%
2020/5/29 1 1 8.00% 7.09% 9.50% -6.69%
2020/6/29 7 7 10.37% 9.47% 12.20% -3.99%


※翌月最適コースとは、月間騰落率実績がわかってから選択したコース(コースHを除く)

※翌月予測コースとは、学習したモデルで翌月を予測したコース

※翌月最適コース崩落率とは、翌月最適コースに基づく、2020/1運用開始日からの騰落率

※翌月予測コース崩落率とは、翌月予測コースに基づく、2020/1運用開始日からの騰落率

※翌月理論上限崩落率とは、コースA~Hの月間騰落率実績が高いコースを選んだ最大騰落率、

 2020/1運用開始日からの騰落率

※翌月コースH崩落率とは、コースHを選択した場合、2020/1運用開始日からの騰落率




1か月程度で検証ができことは、tensorflow、kerasのおかげだと、実感しました。経験と試行錯誤は、必要なものの、データと検証方法さえあれば、用途は結構広げられる気がしました。


参考までに、下記は、lossとaccracyの推移で、2016/6~2019/12月末前日の学習の収束状況です。赤が評価データにたいする精度、青は、教師データに対する誤差に相当します。教師データが、「0」と「1」ですので、予測データが教師データをトレースできるまで、収束速度があまり速くありませんが、なんとか収束でき、コース予測精度は悪くありません。



次は、モデルが予想したコース番号(1がコースA、8がコースH)です。



下記は、学習後に求まった予測データに基づく騰落率結果になります。この場合、2020/2以降は、予測精度が落ちるため、解離がありますが、翌月の予測が重要ですので、問題になりません。



モデル構造は、教科書通りにシンプルですが、それなりに苦労した部分は、学習用入力データ、教師データ、検証入力データを作成する部分と本当に必要な月末時点の翌月予測コースの抽出でした。いわゆる前処理と後処理ですが、機械学習には、結構重要なことがわかりました。一旦、学習・評価が回れば、後は、モデル構造・学習段階のチューニングとその評価を効率的にこなせる高性能PCや、NVIDIA Jetson Nanoのような並列マシンがあると、結構効率的にできそうです。


入力データのCSVレイアウト(基準価格と市場指標)は、"Date fund_A fund_B fund_C fund_D fund_E fund_F fund_G fund_H N225 DJ USD USB IXIC"です。すべて公開情報です。決算日の24日前からの日々市場データと日々コース別基準価格を用意する必要があります。このデータから、市場データに対応する将来騰落率を計算し、それに基づく最適コース選択を行いました。

実際に予測したい月末データだけでは、学習に必要な件数が不足してしまうため、日々の学習データに対する将来騰落率を用意し、件数を増やすことにしました。月末前日の営業日入力データに対する翌月運用コースの予測が実際のコース選択に使用できることになります。

ちなみに、RNNの種類としてsimple_RNN、GRU、LSTMを使ってみましたが、LSTMが最も良い結果が出ました。また、2ヶ月先の予測は、あまり精度がよくない傾向がありましたが、翌月の予測は、そこそこです。


今後、精度アップのため、モデル構造・設定項目のチューニングができたらと考えていますが、まだ定かではありません。


いずれにしても、AI技術がなければ、アマチュア(素人?)では効率的な翌月のコース選択は、難しいと思いました。今回は、コースA~Gの選択範囲で過去7か月の実データ検証を行いましたが、下落局面の予測に優れ、コロナショックにもめげず良いパフォーマンスが達成できたことから、ラップ口座の弱点をカバーできそうです。実際の運用に活かしてみたいと思います。運用結果が良ければ、再度紹介するかもしれません。(今回は、内容的に難解な部分もありますが、興味ある方は、参考にしていただければと思います。)

(再クロール更新:2022/12/22)