2024.09
林貴晴/AMSER Inc.
読みやすく、シンプルなソースコードは、可読性が高くなり、バグが少なく、効率的に動作します。しかし、ソースコードを他者に提供する必要がある場合でも、ロジックは知られたくないことがあります。そこで、本記事ではソースコードの難読化手法について説明します。
以下のようなシンプルなコードがあります。
このような条件式を、二次方程式を使って難読化する方法を紹介します。
if(Hour() == 9 || Hour() == 10) // 発注処理
Hour()をxと置き換えて考えます。
if(x == 9 || x == 10)//発注処理
これは以下のように変形できます。
if((x - 9) == 0 || (x - 10) == 0)//発注処理
次に、この条件を数学的な二次方程式の形式に変換します。
(x - 9)(x - 10) = 0
この方程式を展開します。
x² - 19x + 90 = 0
90を移項して右辺に移し、xでくくります。
x * (x - 19) = -90
これをMQL5のコードに適用すると、次のように書き換えることができます。
if(Hour() * (Hour() - 19) == -90) // 発注処理
理屈は単純ですが、このような変形を理解していない人にとっては、非常に読みにくいコードとなります。
MQL5の列挙型には、それぞれ数値が割り振られています。たとえば、ポジションの売り買いを示すPOSITION_TYPE_BUYは0、POSITION_TYPE_SELLは1です。この性質を利用して、以下のようなコードを難読化します。
long TYPE = PositionGetInteger(POSITION_TYPE); if(TYPE == POSITION_TYPE_BUY && RSI > 70) // 決済処理 if(TYPE == POSITION_TYPE_SELL && RSI < 30) // 決済処理
上記のコードを次のように変換できます。
double TYPE = (PositionGetInteger(POSITION_TYPE) - 0.5) * 2; if(TYPE * RSI < (50 - 20 * TYPE) * TYPE) // 決済処理
この難読化のロジックは、BUYとSELLの条件判断を1つのコードにまとめています。
PositionGetInteger(POSITION_TYPE)は0を返します。
これにより、次の式になります。
TYPE = (0 - 0.5) * 2; // TYPEには-1が入ります。
この値を代入すると2行目は次のように計算されます。
-1 * RSI < (50 - 20 * -1) * -1
これを、簡単にまとめます。
-RSI < -70
両辺に-1を掛けるとRSI > 70となり、元のソースコードと同じ条件になります。
PositionGetInteger(POSITION_TYPE)は1を返します。
TYPE=(1-0.5)*2;// TYPE には +1が入ります。
この値を2行目に代入すると、次の式になります。
1 * RSI < (50 - 20 * 1) * 1
これを簡単にすると、RSI < 30となり、こちらも元のソースコードと同じ条件となります。
コードの難読化は、MQL5プログラマーがロジックを保護するための有効な手段です。二次方程式や列挙型を利用した方法は、ソースコードの解読を困難にし、トレーディングロジックを守るのに役立ちます。特に、EAを外部に提供する場合や、逆コンパイルのリスクがある場合に効果を発揮します。
しかし、難読化には注意すべき点もあります。難読化されたコードは作成者自身にとっても理解が難しくなり、将来の修正や機能追加が困難になる可能性があります。さらに、エラーが発生した際のデバッグも複雑になります。
難読化は有効なツールですが、それ単独ではなく、総合的なアプローチの一部として活用することが賢明です。
林 貴晴(AMSER株式会社代表取締役)
内資系薬品会社で約10年勤務の後、
外資系製薬会社(現IQVIA及びGSK)で合計約10年を勤務
その後EA AMSERを開発し、その成績を評価され、株式会社ゴゴジャンの部長として抜擢。
現在はAMSER株式会社代表取締役。