MQL5 EAのObject lifecycleを実コードで解説|OnDeinit cleanupを最小化する理由
MQL5でEAを開発していると、チャート上に表示したラインやラベル、パネル部品などのObject管理が問題になることがあります。
EAを削除した時にラインが残る、時間足変更後に表示が重くなる、再セット後に古いラインを参照してしまう、OnDeinitでObjectDeleteを大量に実行してフリーズする。このような問題は、売買ロジックとは別に、Object lifecycleとして設計する必要があります。
この記事では、MQL5 EAのObject lifecycleを、学習用に一般化したコード断片で解説します。完成EAソース全文、外部シート制御、認証、endpoint、token、URL、実運用set値、中核エントリー条件は公開しません。
扱うのは、OnDeinitで広範囲cleanupをしない理由、起動時に残存Objectを監査するstartup audit、危険な残存Objectを実ロジックから除外するresidual ignore、表示専用Objectと実ロジック参照Objectの分離です。
- この記事で扱う範囲
- EA削除時に起きやすいObject問題
- OnDeinitで広範囲cleanupをしない理由
- Objectが残ることとEAが異常終了することのリスク差
- visual-only objectとlogic-reference objectの違い
- startup auditとは
- residual ignoreとは
- current session objectだけ採用する考え方
- 実コード断片1:Object種別を分類する
- 実コード断片2:startup auditで残存Objectを監査する
- 実コード断片3:residual ignoreで古いObjectを使わない
- 実コード断片4:OnDeinitを最小化する
- 再セット時に確認するOBJECT_AUDITログ
- よくある失敗例
- 長時間稼働EAでのObject更新方針
- 問い合わせ前に確認するポイント
- 開発依頼前に整理する情報
- 公開しない情報
- FAQ
- 関連ページ
- まとめ
この記事で扱う範囲
| 項目 | この記事で扱う内容 | 扱わない内容 |
|---|---|---|
| 目的 | EA削除・再セット・時間足変更時にObject起因の不安定化を防ぐ設計 | 売買ロジック、利益を狙う条件、エントリー判断 |
| Object管理 | visual-only、logic-reference、startup audit、residual ignore | 管理ラインの具体的な売買条件、TrailやNanpinの中核判定 |
| OnDeinit | 終了時処理を最小化する考え方 | OnDeinitで全Objectを強制削除する実装 |
| コード例 | 学習用に簡略化した短い疑似コード | 完成EAソース全文、実運用コード全文 |
| 確認対象 | Expertsログ、OBJECT_AUDIT、CLEANUP_PLAN、RESIDUAL_IGNORE | 認証、外部制御、実運用set値、口座管理情報 |
EA削除時に起きやすいObject問題
チャート上にラインやラベルを描画するEAでは、削除時や再セット時に次のような問題が起きることがあります。
| 現象 | 原因になりやすい設計 | 改善方針 |
|---|---|---|
| EA削除時にMT5が重くなる | OnDeinitで全Objectを走査・削除している | OnDeinitの責務を最小化する |
| ラインが残る | 削除対象の整理が不足している | 残ること自体より、再セット時に誤参照しないことを優先する |
| 再セット後に古いラインを使ってしまう | 残存Objectを現在セッションのObjectと区別していない | session tag、startup audit、residual ignoreを使う |
| 手動ラインや他EAのObjectを消してしまう | prefixやownerを見ずにObjectDeleteしている | owner prefix、kind、side、sessionを確認して対象を限定する |
| 長時間稼働で表示が重くなる | 毎tickで全削除・全再作成している | 固定Objectの差分更新、throttle、OnTimer分離へ寄せる |
Object管理では、見た目を完全に整理することよりも、EA本体が異常終了しないこと、売買判定が古いObjectを誤参照しないことを優先します。
OnDeinitで広範囲cleanupをしない理由
EA削除時にチャート上のObjectをすべて消したくなる場合があります。しかし、OnDeinitで広範囲のObject走査や大量削除を行うと、かえって不安定化することがあります。
特に避けたいのは、次のような処理です。
- OnDeinit内でObjectsTotalを使って全Objectを走査する
- prefixが曖昧なObjectをまとめて削除する
- 手動ラインや他EAのObjectまで削除対象に含める
- 削除失敗時に再試行ループする
- ポジション状態に依存した重い処理をOnDeinitで行う
- 削除と再描画を同じ終了処理内で実行する
OnDeinitは、EAの終了時に呼ばれる処理です。ここで重い処理や不安定な処理を詰め込むと、EA削除時のフリーズ、チャートブラックアウト、Abnormal termination、再セット不能などの原因になります。
そのため、OnDeinitでは、Commentのクリア、timer停止、indicator handle解放、軽量な自EAステータスObjectの整理など、最小限の終了処理に寄せます。
Objectが残ることとEAが異常終了することのリスク差
Object管理では、次の2つを分けて考える必要があります。
| 状態 | リスク | 優先度 |
|---|---|---|
| 表示ラインが残る | 見た目が残る。再セット時に監査できれば致命傷ではない | 中 |
| EA削除時に異常終了する | EAやチャートが不安定化し、再現性も落ちる | 高 |
| 残存ラインを実ロジックへ使う | 古いObjectを基準に判定してしまう | 高 |
| 手動ラインを消す | 利用者の作業内容を壊す | 高 |
| 表示専用Objectを残す | 監査ログで残存扱いにできれば許容しやすい | 低〜中 |
重要なのは、Objectが残ることをすべて悪としないことです。残ってもよいObjectと、実ロジックへ誤って使ってはいけないObjectを分け、再セット時に安全側で監査します。
visual-only objectとlogic-reference objectの違い
Object lifecycleを設計する時は、チャートObjectを用途別に分類します。
| 分類 | 例 | 扱い |
|---|---|---|
| visual-only | 平均価格ライン、TP目安ライン、Trail開始ライン、説明ラベル | 表示専用。残存しても実ロジックへ使わない |
| logic-reference | Trail SLライン、仮想ライン、Skipラインなど | 実ロジックに影響し得るため、残存時は無条件採用しない |
| panel-control | ボタン、入力欄、タブ、ステータス枠 | パネルlifecycleで管理する |
| overlay-only | MA、BB、矢印、補助表示 | best-effort。失敗してもEA本体を止めない |
| manual / external | 手動ライン、他EAが作成したObject | 原則削除しない |
たとえば、平均価格ラインやTP目安ラインは表示補助として扱いやすい一方で、Trail SLや仮想ラインのように実ロジックの参照候補になり得るObjectは、起動前から残っていたものをそのまま採用すると危険です。
startup auditとは
startup auditとは、EAをチャートへセットした時に、すでに残っている管理Objectを確認し、どのObjectを表示専用として扱うか、どのObjectを実ロジックから除外するかをログに残す処理です。
startup auditで確認する主な項目です。
| 確認項目 | 意味 |
|---|---|
| Object名 | 自EAの管理Objectかどうかを判断する |
| kind | AVG、TP、TRAIL_SL、KASOU_LINE、SKIP_LINEなどの分類 |
| side | BUY側、SELL側、方向なしを分ける |
| price | 表示価格を確認する |
| action | VISUAL_ONLY、IGNORE_FOR_LOGIC、LOG_ONLYなどの扱い |
| reason | なぜ削除しないか、なぜ無視するか |
この監査により、EA削除時に無理にObjectを消さなくても、再セット時に「古いObjectとして検出し、実ロジックには使わない」という安全設計ができます。
residual ignoreとは
residual ignoreとは、再セット前から残っていたObjectを、現在のEAセッションで作られたObjectではないものとして扱い、実ロジックから除外する考え方です。
特に、次のようなObjectはresidual ignoreの対象になりやすいです。
- Trail SLライン
- 仮想ライン
- Skipライン
- sideやsessionが現在状態と一致しない管理ライン
- 現在セッションのsession tagが付いていないObject
残存Objectを消すのではなく、色や線種を変えて「古いライン」として表示し、ExpertsログにもRESIDUAL_IGNOREとして残すと、調査時に分かりやすくなります。
current session objectだけ採用する考え方
Objectを実ロジックへ使う場合は、「このObjectは現在セット中のEAが生成したものか」を確認する必要があります。
考え方は次の通りです。
| 判定 | 扱い |
|---|---|
| 現在セッションのtagがある | 実ロジック参照候補として扱える |
| 現在セッションのtagがない | 起動前残存として無視する |
| visual-only分類 | 表示専用として扱い、実ロジックへ使わない |
| logic-reference分類 | current sessionでなければIGNORE_FOR_LOGIC |
| owner不明 | 削除しない。監査または無視に留める |
この設計にすると、EA削除時のcleanupを重くしなくても、再セット時に安全側で状態を作り直せます。
実コード断片1:Object種別を分類する
以下は、実際のEAで使う考え方を学習用に簡略化したコード例です。完成EAのソース全文ではなく、構造を理解するための抜粋です。
// 学習用に一般化したObject分類例です。
// 実運用EAの完成ソースではありません。
string ResolveObjectKind(string name)
{
if(StringFind(name, "Logic") != 0)
return "NONE";
if(StringFind(name, "-Avg") >= 0)
return "AVG";
if(StringFind(name, "-TpLine") >= 0)
return "TP";
if(StringFind(name, "-TrailStart") >= 0)
return "TRAIL_START";
if(StringFind(name, "-TrailSl") >= 0)
return "TRAIL_SL";
if(StringFind(name, "-VirtualLine") >= 0)
return "VIRTUAL_LINE";
if(StringFind(name, "-Skip") >= 0)
return "SKIP_LINE";
return "NONE";
}
bool IsLogicReferenceKind(string kind)
{
return (kind == "TRAIL_SL" ||
kind == "VIRTUAL_LINE" ||
kind == "SKIP_LINE");
}実際のEAでは、認証、外部制御、口座条件、エラー処理、ログ出力などを分けて設計します。この記事では、公開できる範囲の構造だけを取り上げています。
このコードの役割
| 処理 | 役割 |
|---|---|
| ResolveObjectKind | Object名から管理ラインの種類を分類する |
| AVG / TP / TRAIL_START | 主に表示補助として扱いやすい分類 |
| TRAIL_SL / VIRTUAL_LINE / SKIP_LINE | 実ロジック参照に影響し得る分類 |
| IsLogicReferenceKind | 残存時に無条件採用してはいけないObjectを判定する |
この段階では、まだObjectを削除しません。まず「何のObjectか」を分類し、次に「現在セッションのObjectか」を確認します。
実コード断片2:startup auditで残存Objectを監査する
以下は、起動時に残っているObjectを監査し、危険な残存Objectを実ロジックから除外する考え方を簡略化した例です。
// 学習用に一般化したstartup audit例です。
// 実運用EAの完成ソースではありません。
string g_sessionTag = "";
void InitObjectSessionTag()
{
g_sessionTag = "SESSION:" + TimeToString(TimeLocal(), TIME_DATE | TIME_SECONDS);
}
void PrintObjectAudit(string side, string eventName, string detail)
{
Print("DIAG/OBJECT_AUDIT: side=", side,
" event=", eventName,
" detail=", detail);
}
void AuditStartupObjects()
{
int found = 0;
int ignored = 0;
for(int i = ObjectsTotal(0, 0, OBJ_HLINE) - 1; i >= 0; i--)
{
string name = ObjectName(0, i, 0, OBJ_HLINE);
string kind = ResolveObjectKind(name);
if(kind == "NONE")
continue;
found++;
string action = "VISUAL_ONLY";
if(IsLogicReferenceKind(kind))
{
action = "IGNORE_FOR_LOGIC";
ignored++;
}
double price = ObjectGetDouble(0, name, OBJPROP_PRICE);
PrintObjectAudit("NONE", "STARTUP_FOUND",
"name=" + name +
" kind=" + kind +
" action=" + action +
" price=" + DoubleToString(price, _Digits));
}
PrintObjectAudit("NONE", "STARTUP_SUMMARY",
"found=" + IntegerToString(found) +
" ignored=" + IntegerToString(ignored) +
" policy=NO_DEINIT_CLEANUP");
}実際のEAでは、認証、外部制御、口座条件、エラー処理、ログ出力などを分けて設計します。この記事では、公開できる範囲の構造だけを取り上げています。
このコードの役割
| 処理 | 役割 |
|---|---|
| InitObjectSessionTag | 現在EAセット用のsession tagを作る |
| AuditStartupObjects | 起動時に残存Objectを確認する |
| STARTUP_FOUND | 検出したObjectを1件ずつ記録する |
| IGNORE_FOR_LOGIC | 実ロジック参照から除外する |
| STARTUP_SUMMARY | 検出数と無視数を要約する |
この設計では、EA削除時にすべてを消すのではなく、再セット時に残存Objectを見つけて安全側で扱います。
実コード断片3:residual ignoreで古いObjectを使わない
以下は、現在セッションのObjectだけを実ロジックで参照し、それ以外を残存Objectとして無視する考え方の例です。
// 学習用に一般化したresidual ignore例です。
// 実運用EAの完成ソースではありません。
bool IsCurrentSessionObject(string name)
{
if(ObjectFind(0, name) < 0)
return false;
string tag = ObjectGetString(0, name, OBJPROP_TOOLTIP);
return (tag == g_sessionTag);
}
void StampCurrentSessionObject(string name)
{
if(ObjectFind(0, name) < 0)
return;
ObjectSetString(0, name, OBJPROP_TOOLTIP, g_sessionTag);
}
bool CanUseObjectForLogic(string name)
{
string kind = ResolveObjectKind(name);
if(kind == "NONE")
return false;
if(!IsLogicReferenceKind(kind))
return true;
if(IsCurrentSessionObject(name))
return true;
PrintObjectAudit("NONE", "RESIDUAL_IGNORE",
"name=" + name +
" kind=" + kind +
" reason=NOT_CURRENT_SESSION");
return false;
}実際のEAでは、認証、外部制御、口座条件、エラー処理、ログ出力などを分けて設計します。この記事では、公開できる範囲の構造だけを取り上げています。
このコードの役割
| 処理 | 役割 |
|---|---|
| StampCurrentSessionObject | 現在EAが作成・更新したObjectにsession tagを付ける |
| IsCurrentSessionObject | そのObjectが現在セッションのものか確認する |
| CanUseObjectForLogic | 実ロジックで参照してよいObjectか判定する |
| RESIDUAL_IGNORE | 古いObjectを使わず、ログに理由を残す |
このようにしておくと、古いTrailラインや仮想ラインが残っていても、現在セッションで作られたObjectでなければ実ロジックから除外できます。
実コード断片4:OnDeinitを最小化する
以下は、OnDeinitで広範囲cleanupを行わず、終了時の責務を最小化する考え方を示した学習用コード例です。
// 学習用に一般化したOnDeinit最小化例です。
// 実運用EAの完成ソースではありません。
void ReleaseIndicatorHandles()
{
// 実際は使用中のhandleだけを個別に解放します。
}
void DeleteStatusObjectsOnly()
{
// EAステータス表示など、軽量で自EA所有が明確なObjectだけを対象にします。
}
void OnDeinit(const int reason)
{
Comment("");
EventKillTimer();
DeleteStatusObjectsOnly();
// 広範囲のObject走査・全削除は行わない。
// Avg / TP / Trail / Virtual / Skip などは、
// 再セット時のstartup auditとresidual ignoreで扱う。
ReleaseIndicatorHandles();
Print("DIAG/DEINIT: event=MINIMAL_CLEANUP reason=", reason);
}実際のEAでは、認証、外部制御、口座条件、エラー処理、ログ出力などを分けて設計します。この記事では、公開できる範囲の構造だけを取り上げています。
このコードの役割
| 処理 | 役割 |
|---|---|
| Comment(“”) | チャート左上コメントを消す |
| EventKillTimer | timer処理を止める |
| DeleteStatusObjectsOnly | 自EA所有が明確で軽量なステータスObjectだけ整理する |
| ReleaseIndicatorHandles | インジケーターハンドルを解放する |
| 全Object削除をしない | 削除時の不安定化を避ける |
OnDeinitでは、「消せるものを全部消す」のではなく、「終了時に安全にできることだけを行う」と考える方が安定します。
再セット時に確認するOBJECT_AUDITログ
Object lifecycle設計では、チャート上の見た目だけでなく、Expertsログを確認することが重要です。
再セット時には、次のようなログを確認します。
DIAG/OBJECT_AUDIT: side=NONE event=STARTUP_FOUND detail=name=... kind=TRAIL_SL action=IGNORE_FOR_LOGIC
DIAG/OBJECT_AUDIT: side=NONE event=RESIDUAL_IGNORE detail=name=... kind=SKIP_LINE reason=NOT_CURRENT_SESSION
DIAG/OBJECT_AUDIT: side=NONE event=STARTUP_SUMMARY detail=found=3 ignored=2 policy=NO_DEINIT_CLEANUP
DIAG/OBJECT_AUDIT: side=NONE event=CLEANUP_PLAN detail=action=LOG_ONLY reason=CLEANUP_DISABLED| ログ | 見るポイント |
|---|---|
| STARTUP_FOUND | 残存Objectを検出しているか |
| VISUAL_ONLY | 表示専用として扱っているか |
| IGNORE_FOR_LOGIC | 実ロジックへ使わないObjectを分けているか |
| RESIDUAL_IGNORE | 現在セッション外のObjectを無視しているか |
| CLEANUP_PLAN | 削除ではなく計画・ログ確認に留めているか |
| STARTUP_SUMMARY | 検出数・無視数・方針が要約されているか |
ログで「古いObjectを検出したが、実ロジックには使っていない」と確認できれば、Objectが残っていても安全側に整理できています。
よくある失敗例
失敗1:OnDeinitで全Objectを削除する
最も避けたいのは、OnDeinitでチャート上のObjectを広範囲に走査し、まとめて削除する処理です。自EA以外のObjectを巻き込むリスクがあり、削除時の不安定化にもつながります。
失敗2:Object名だけで現在状態を判断する
Object名が同じでも、前回セット時の残存Objectである可能性があります。名前だけでなく、現在セッションのtagや監査結果を使って判断する必要があります。
失敗3:表示Objectを実ロジックの真実として使う
ラインやラベルは、表示更新の失敗、残存、再描画遅延の影響を受けます。実ロジックの基準はruntime stateで管理し、Objectは表示補助として扱う方が安全です。
失敗4:表示専用Objectとロジック参照Objectを混ぜる
平均価格ラインやTP目安ラインと、Trail SLや仮想ラインを同じ削除・採用方針で扱うと危険です。用途ごとに分類し、扱いを分ける必要があります。
失敗5:削除失敗時に再試行ループする
ObjectDeleteに失敗した場合、OnDeinit内で何度も再試行すると不安定化します。削除失敗はログ化し、次回起動時のauditやmanual確認へ回す方が安全です。
長時間稼働EAでのObject更新方針
長時間稼働を前提にするEAでは、Objectの作り直し回数を減らすことも重要です。
| 避ける処理 | 推奨する処理 |
|---|---|
| 毎tickでObjectDeleteとObjectCreateを繰り返す | 既存Objectの価格・テキスト・色だけ差分更新する |
| 毎tickでObjectsTotalを全走査する | OnTimerや低頻度maintenanceへ分離する |
| 全Objectを同じprefixで雑に扱う | owner、kind、side、sessionを分ける |
| 表示失敗でEA本体を止める | 表示はbest-effortにし、売買処理と分離する |
| Objectを判定truthとして使う | runtime stateを判定truthにし、Objectは表示補助にする |
表示は利用者にとって重要ですが、表示失敗がそのまま発注・決済・リスク管理に波及する構造は避けるべきです。
問い合わせ前に確認するポイント
EA削除時や再セット時に表示が残る、重い、フリーズする場合は、問い合わせ前に次の情報を整理してください。
| 確認項目 | 内容 |
|---|---|
| 発生タイミング | EA削除時、時間足変更時、再セット時、MT5再起動時のどれか |
| 残っているObject | 平均ライン、TPライン、Trailライン、仮想ライン、ラベル、ボタンなど |
| Expertsログ | OBJECT_AUDIT、STARTUP_FOUND、RESIDUAL_IGNORE、CLEANUP_PLANの有無 |
| 異常終了 | Abnormal terminationやチャートブラックアウトの有無 |
| ポジション状態 | フラット時か、ポジション保有中か |
| 再現手順 | どの操作で再現するか |
| スクリーンショット | チャート上の残存ObjectとExpertsログの画面 |
不具合相談前の整理は、次のページも参考にしてください。
開発依頼前に整理する情報
EA開発を依頼する場合、Object lifecycleの方針を最初に決めておくと、長時間稼働や販売後サポートが楽になります。
- チャートに表示するObjectの種類
- 表示専用Objectと実ロジック参照Objectの分類
- OnDeinitで削除するObjectと残すObject
- 再セット時にstartup auditを行うか
- 残存Objectを実ロジックから除外するか
- cleanupは手動・dry-run・flat時限定にするか
- Object関連ログをどの粒度で出すか
- 問い合わせ時にどのログを送ればよいか
仕様書、setファイル、ログ、スクリーンショットを整理する場合は、次のページも確認してください。
MT5開発依頼前に用意する資料まとめ|仕様書・setファイル・ログ・スクリーンショット
公開しない情報
この記事では、MQL5のObject lifecycleを学ぶために、公開可能な範囲だけを一般化して解説しています。以下は公開しません。
- 完成EAソース全文
- 外部シート参照による動作制御ロジック
- 外部シートCSV取得、解析、時間枠、方向制御ロジック
- 認証、口座許可判定、購入者管理ロジック
- endpoint、token、URL、Google Sheet ID、Webhook URL、GAS URL
- APIキー、認証トークン、口座番号、サーバー名
- 実運用set値
- 中核エントリー条件
- 中核Trail / Nanpin判定
- 独自優位性のある売買判定式
- 利益保証、勝率保証、推奨ロット、推奨銘柄、推奨エントリー
本記事は、投資判断や売買指示ではなく、MQL5開発におけるObject lifecycleと検証手順を理解するための技術解説です。
FAQ
EAを削除した時にラインが残るのは不具合ですか?
必ずしも不具合とは限りません。ポジション保有中や安全性を優先する設計では、ラインを消さずに残す場合があります。重要なのは、再セット時にその残存ラインを実ロジックへ誤って使わないことです。
OnDeinitで全Objectを削除した方がきれいではありませんか?
見た目はきれいになりますが、広範囲cleanupはEA削除時の不安定化や他Objectの巻き込みにつながる場合があります。終了時は最小化し、再セット時に監査する設計の方が安全な場面があります。
residual ignoreとは何ですか?
再セット前から残っていたObjectを、現在セッションのObjectではないものとして扱い、実ロジックから除外する考え方です。ExpertsログではRESIDUAL_IGNOREのような形で確認できるようにします。
Objectが残っていても売買に影響しませんか?
表示専用Objectであれば、売買判定へ使わない設計にできます。Trail SLや仮想ラインのように実ロジックへ影響し得るObjectは、current session確認やresidual ignoreで誤参照を防ぎます。
どのログを確認すればよいですか?
OBJECT_AUDIT、STARTUP_FOUND、RESIDUAL_IGNORE、CLEANUP_PLAN、STARTUP_SUMMARYなどを確認します。Objectが検出されたか、表示専用扱いか、実ロジックから除外されたかを見ます。
このコードは完成EAとして使えますか?
いいえ。この記事のコード例は、Object lifecycleの考え方を理解するために簡略化した学習用コードです。完成EAとしてそのまま使うことは想定していません。
実際のEAソース全文は公開されていますか?
公開していません。完成EAソース全文、外部シート制御、認証、endpoint、token、URL、実運用set値、中核エントリー条件は公開対象外です。
表示Objectの不具合は売買ロジックの不具合と同じですか?
同じではありません。表示Objectの更新失敗と、発注・決済・リスク管理の不具合は分けて確認します。表示系はbest-effort、判定系はruntime stateで管理する設計が重要です。
関連ページ
| ページ | 確認できること |
|---|---|
| MQL5ログファースト設計を実コードで解説 | OBJECT_AUDITなどのログ設計とreason管理 |
| MT5のログ確認方法|Experts・Journalの見方 | ExpertsログとJournalログの基本確認 |
| MT5開発依頼前に用意する資料まとめ|仕様書・setファイル・ログ・スクリーンショット | 開発相談前に整理する資料 |
| 不具合報告・調査依頼について | 不具合相談前に送る情報 |
| 開発・改修の相談ページを見る | EA・インジケーター開発や既存改修の相談導線 |
| よくある質問 | 導入、確認、相談前のFAQ |
| 免責事項 | 投資判断、損益、利用上の注意に関する確認 |
| 投資助言を行わない方針 | 売買助言ではなく技術支援として扱う方針 |
まとめ
MQL5 EAのObject lifecycleでは、OnDeinitで全Objectを消すことよりも、EA本体を異常終了させず、再セット時に残存Objectを安全に扱うことが重要です。
特に、次の4点を分けておくと、長時間稼働や販売後サポートで確認しやすくなります。
- visual-only:表示専用Object。実ロジックへ使わない
- logic-reference:実ロジックへ影響し得るObject。残存時は無条件採用しない
- startup audit:再セット時に残存Objectを監査する
- residual ignore:現在セッション外のObjectを実ロジックから除外する
EA削除時にObjectが残ること自体よりも、古いObjectを現在の判定へ誤って使うこと、手動ラインや他EAのObjectを消してしまうこと、OnDeinitで重いcleanupをしてEAが不安定になることの方が大きなリスクです。
Object lifecycleをログファーストで設計しておくと、表示残り、再セット、時間足変更、長時間稼働時の問題を、Expertsログとチャート表示の両方から切り分けやすくなります。

