恥は/dev/nullへ by 初心者

プログラミング素人がのろのろと学んだことをつづっています♪

LibreOfficeのフォント選択リストの縦幅(行数)を短くする

古いPCでLibreOffice Calcを使ったところ、解像度が低いせいかフォントを選択するドロップダウンリストが画面からはみ出しており、リストの下の方にあるフォントが(画面内に)表示されていませんでした。

ネット検索してみたら、ドロップダウンリストの行数を変更する方法が分かったので、ここにメモしておきます。

1.「ツール」→「オプション」→「LibreOffice」→「詳細」→「上級者向け設定を開く」

2.新たに登場したウィンドウの上部にある検索欄に「ListBoxMaximumLineCount」と入力

3.「検索」ボタンを押すと登場する画面で、「ListBoxMaximumLineCount」行を選択

4.「編集」ボタンを押して、行数を変更
(デフォルトは25になっている。この値を少なくする)


現在LibreOfficeの最新バージョンは7.6.xですが、この記事はバージョン7.5.2を元にして書いています。

robocopyでバックアップ

過去にもrobocopyに関する備忘録を書きましたが、フォルダをバックアップする話のみで、ファイルをバックアップするケースについては触れていませんでした。

最近、特定のファイル1つをバックアップすることにしたので、ファイルのコピーも含めたrobocopyの使用例をメモしておくことにしました。

@REM "行頭の@は、コマンドそのものを画面に表示しないようにするためのもの"
@REM "echo.は空白行を画面に表示するためのもの"
@REM "ファイルをコピーする場合は少し記法が異なる"

@chcp 65001
@echo.

@echo フォルダ Downloads をバックアップしています...
@robocopy C:\Users\name\Downloads\ D:\Backup\Downloads\ /MIR /R:3 /W:3 /NP /NDL /UNILOG:D:\Backup\robocopy_Downloads.log

@echo ファイル hoge.txt をバックアップしています...
@robocopy C:\Users\name\Documents D:\Backup hoge.txt /R:3 /W:3 /NP /NDL /UNILOG:D:\Backup\hoge_txt.log

こんな風にrobocopyコマンドを記述してcmdファイルとして使用しています。

最終行がファイルのコピーに関する部分です。

[コピー元フォルダ] [コピー先フォルダ] [ファイル名]

となっています。なお、失敗談を1つ書きますと、ファイル1つをコピーする時にうっかり/MIRオプションを付けて実行したら(当たり前ですが)2つのフォルダをミラーリングし始め、目的とは違う動作になってしまいました。というわけで、1つのファイルをコピーする場合には/MIRを付けていません。

MQL5のArrayReverse関数

MQL5のヘルプを眺めていたらArrayReverseという関数が目に留まりました。使ったことがなかったので、以下のコードで動作確認をしてみました。

void OnStart()
{
    int hoge[4] = {3, 5, 7, 9};
    for(int i = 0; i < 4; i++)
        printf("hoge[%d] = %d", i, hoge[i]);
    
    ArrayReverse(hoge);
    Print("ArrayReverse実行");

    for(int i = 0; i < 4; i++)
        printf("hoge[%d] = %d", i, hoge[i]);
}


実行結果は以下のとおりです。

hoge[0] = 3
hoge[1] = 5
hoge[2] = 7
hoge[3] = 9
ArrayReverse実行
hoge[0] = 9
hoge[1] = 7
hoge[2] = 5
hoge[3] = 3


使う場面が余り思い浮かばないのですが・・・、私のようにMQL4に慣れた人(チャートの右端にあるローソク足を0本目と数える人)がCopyBufferでインジ領域から配列にデータをコピーした場合に使うかもしれないなとぼんやり思いました。

ArraySetAsSeries関数との違い

ArraySetAsSeries関数との違いについては、ArrayReverse関数のヘルプに以下の記述がありました。

ArraySetAsSeries()関数は物理的に配列要素を移動するものではありません。代わりに、要素へのアクセスを時系列同様に変更するために、インデックスの方向を逆方向に変更するだけです。ArrayReverse()関数は、配列が「反転」されるように物理的に配列要素を移動します。

MT5のストップレベル(StopLevel)とは何か?

ストップレベル(StopLevel)とは?

MT5でバックテスト中、注文に失敗しました。「TRADE_RETCODE_INVALID_STOPS」というリターンコードが返ってきており、原因はストップレベル違反でした。

ストップレベル違反とは「TP(利確価格)やSL(損切価格)を指定する場合、基準となる価格(AskまたはBid)から一定以上離れていなくてはならないのに、そうなっていない」ということです。

この「一定以上」という部分がストップレベルです。たとえば、買い注文が約定してポジションを持った時に、Bidが1.09060だったとします。この時、ストップレベルが10ポイントだとしたら、SLは1.09050以下に設定しなくてはなりません。一方、TPは1.09070以上に設定しなくてはなりません。

基準となる価格はAskかBidか?

先述の文章に登場した「基準となる価格(AskまたはBid)」は買い注文をしたか売り注文をしたかによって異なります。

トレード時の注文から決済までの流れを「買い注文」を例にして見てみましょう。

買い注文の場合、Askで購入してBidで決済することになります。「Askが1.09068 Bidが1.09064」の時にMT5の「BUY」ボタンを押すと、1.09068でポジションを持ちます(購入価格は1.09068)。その後、「Askが1.09067 Bidが1.09063」の時に決済したら、決済価格は 1.09063です。

この例から分かるように、Askは注文時に関与するだけで、ポジションを持った後の主役はBidです。なぜなら、そのポジションに利益が出るか損失が出るかはBidが上がるか下がるかで決まるからです。

いま述べた「主役」が、ストップレベルに関わる「基準となる価格」です。この例では、Bidが主役でした。よって、SLやTPはBidを基準にストップレベルを考慮して決めることになります。

簡単にまとめると次のようになります。

買い注文(成行) → Bidからストップレベル以上離れた所にSLやTPを置く
売り注文(成行) → Askからストップレベル以上離れた所にSLやTPを置く


ストップレベルの情報源

MQL5用のページではありませんが、ストップレベルに関しては以下のページを参考にしました。

https://book.mql4.com/appendix/limits

このページにある表で「成行買い注文」に関する行を見るとSLとTPに関して次のように書かれています。

Order Type     Open Price                      StopLoss (SL)            TakeProfit (TP)
-------------------------------------------------------------------------------------------
Buy            Modification is prohibited      Bid-SL ≥ StopLevel      TP-Bid ≥ StopLevel


これを見ると、SLの位置はBidからStopLevel分以上安くなければならないと分かります。同様に、TPの位置はBidからStopLevel分以上高い価格でなければならないと分かります。

他の注文タイプについても引用しておきます。

Order Type     Open Price                      StopLoss (SL)                 TakeProfit (TP)
-------------------------------------------------------------------------------------------
Buy            Modification is prohibited      Bid-SL ≥ StopLevel           TP-Bid ≥ StopLevel
Sell           Modification is prohibited      SL-Ask ≥ StopLevel           Ask-TP ≥ StopLevel
BuyLimit       Ask-OpenPrice ≥ StopLevel       OpenPrice-SL ≥ StopLevel     TP-OpenPrice ≥ StopLevel
SellLimit      OpenPrice-Bid ≥ StopLevel       SL-OpenPrice ≥StopLevel      OpenPrice-TP ≥ StopLevel
BuyStop        OpenPrice-Ask ≥ StopLevel       OpenPrice-SL ≥ StopLevel     TP-OpenPrice ≥ StopLevel
SellStop       Bid-OpenPrice ≥ StopLevel       SL-OpenPrice ≥ StopLevel     OpenPrice-TP ≥ StopLevel


ストップレベルの調べ方

ストップレベルをコードで調べる場合、以下のようにします。

SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL)


ただし、これを使う場合にはPoint数にする必要があります。

SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL) * _Point


これもストップレベル違反

私のアホな失敗事例を1つ書いておきます。ショートエントリーの実験コードを書いた折、おかしなTP価格を設定してサーバーに売り注文を送信しました。その結果、TRADE_RETCODE_INVALID_STOPSが返ってきました(この時のストップレベルは 0 でした)。

具体的な価格は以下のとおりです。

SL  1.06784
TP  1.06736

Ask 1.06702
Bid 1.06701


売り注文なので、SLはAsk価格よりも高く、TPはAsk価格よりも低くなければいけません。しかし、AskよりもTPの方が高いというおかしな内容になっています。

これもストップレベル違反に該当します。先に引用した表の一部を見てみましょう。

Order Type    Open Price                     StopLoss (SL)           TakeProfit (TP)
-------------------------------------------------------------------------------------------
Sell          Modification is prohibited     SL-Ask ≥ StopLevel     Ask-TP ≥ StopLevel


この表にあるとおり、成行の売り注文においてTPは「Ask - TP」が StopLevel以上でなくてはなりません。しかし、私の失敗事例では

StopLevel = 0

Ask - TP = 1.06702 - 1.06736 = -0.00034

となっており、「Ask - TP」の方がStopLevelよりも小さくなっていました。

VOBファイルを結合したり変換したり

VOBファイルの結合

複数のVOBファイルを1つに結合する方法を調べてみたところ、catコマンドであっさりと実現できるようです。

たとえば、次のようにします。

cat file1.VOB file2.VOB file3.VOB > banana.VOB

これで、banana.VOBの出来上がりです。

VOBファイルをMP4ファイルに変換する

Windows上で、VOBファイルを特定の時刻(たとえば、動画の先頭から10秒経ったところ)から特定の時刻まで再生したい場合、VLC Playerを操作するcmdファイルを使っています。

具体的には、次のような内容を記述したcmdファイルを用意して、それをクリックしています。

"C:\Program Files\VideoLAN\VLC\vlc.exe" .\hoge.vob --start-time=10 --stop-time=35 --zoom=2.2


久しぶりにこれをやろうとしたところ、問題が発生しました。VOBファイルの時刻がずれているのか、、、cmdファイルで指定した時刻とは違うところから再生されました。ネット情報によると、VOBファイルの再生時刻がおかしいケースがしばしばあるようです。

その後、ファイルをMP4形式に変換することにより再生時刻が修正されたという記事を読んだので、ffmpegを使ってMP4に変換してみました。

   ffmpeg -i hoge.VOB hoge.mp4

これでMP4ファイルが完成しました。

それから次のcmdファイルを実行してみたところ、無事に10秒~35秒部分を再生することができました。

"C:\Program Files\VideoLAN\VLC\vlc.exe" .\hoge.mp4 --start-time=10 --stop-time=35 --zoom=2.2

/etc/apt/sources.list(Debian12)

Debian12(Bookworm)がリリースされて1ヶ月以上経ったので、自分もDebian12に移行しました。それに伴い、aptに使用するsources.listを少し修正しました。

/etc/apt/sources.list (Debian 12)

# Security updates
deb http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware
deb-src http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware

# Stable repository
deb http://ftp.riken.jp/Linux/debian/debian bookworm main contrib non-free non-free-firmware
deb-src http://ftp.riken.jp/Linux/debian/debian bookworm main contrib non-free non-free-firmware

# Stable updates
deb http://ftp.riken.jp/Linux/debian/debian bookworm-updates main contrib non-free non-free-firmware
deb-src http://ftp.riken.jp/Linux/debian/debian bookworm-updates main contrib non-free non-free-firmware

# Stable backports
deb http://ftp.riken.jp/Linux/debian/debian bookworm-backports main contrib non-free non-free-firmware
deb-src http://ftp.riken.jp/Linux/debian/debian bookworm-backports main contrib non-free non-free-firmware


変更点

Debian12リリース前は、上記sources.listにある non-free-firmware がありませんでした。Debian 12になってから、従来 non-free だったものが、non-free と non-free-firmware に分割されたようです。

少し迷ったこと

Security updatesのURLについて少し迷いました。といいますのも、以下の2つのページに載っていた記述例が少し違っていたからです。

(1) https://www.debian.org/security/index.html
(2) https://wiki.debian.org/SourcesList

(1)の方に載っていた記述例

deb http://security.debian.org/debian-security bookworm-security main contrib non-free non-free-firmware


(2)の方に載っていた記述例

deb http://deb.debian.org/debian-security/ bookworm-security main contrib non-free


(1)ではsecurity.debian.org、(2)ではdeb.debian.orgとなっていますね。

何となく誰でも編集できるWikiよりは(1)の情報に従っておこうと思い、(1)の記述例を踏襲しました(ちなみに、両方のリポジトリを見ましたが、素人目には同じように見えました)。

Vimの正規表現メモ

Vim正規表現が良く分からなかったので、必要になったものを少し調べてみました。

目次


最短一致でマッチ

最短一致に使う正規表現をネット検索したら以下のものがありました。

Vimの正規表現における最短一致     \{-}


sakana inu sakana kuma sakana

という3つのsakanaを含むテキストを使って実験してみました。

上記テキストのうち2つ目のsakanaまでをマッチさせたい場合は次のようにします。

sakana.\{-}sakana


こうすると最短一致となり、

sakana inu sakana

にマッチします。

ちなみに、Vim以外では *? を最短一致に使います。これを鬼車で試したところ、次の書き方で最短一致ができました。

sakana.*?sakana     


失敗例も書いておきます。

sakana.*sakana

この書き方だと最長一致になるので

sakana inu sakana kuma sakana

という風に3つ目のsakanaまで含まれてしまいます。

ダブルクォーテーションの内側だけにマッチ

ダブルクォーテーションの中にあるテキストだけをマッチさせる場合(ダブルクォーテーションは含まない)、次のようにします。

"\@<=..*"\@=


ダブルクォーテーションも含める場合は、上の例から先読みと後読みに関する部分を除去するだけです。

"..*"


行をまたいでマッチ(複数行マッチ)

""
aaaaaaaaaaaaaa
bbbbbbbbbb
ccccccccccccccccc
""
ddddd
""

というテキストがあったとして、1行目の""から5行目の""までを最短一致でマッチさせるなら

""\_.\{-}""

とします。最短一致なので、dddd以下はマッチしません。

空行にマッチ

空行をマッチさせるのにどうやるのか少し悩みましたが、^$ であっさりとマッチしました。if文で使うとしたら

let line_content = getline(line('.'))               " 現在行の内容をline_contentに代入
if line_content =~ '^$' || line_content =~ '^  *'   " 空行 OR 半角spaceのみ
    echo '空行 or 半角spaceのみ'
endif

という感じです。

ファイル末尾にマッチ

ファイル末尾(EOF)は

\%$

で表現できます。

参考にしたサイト

https://qiita.com/kawaz/items/d0708a4ab08e572f38f3