104 lines
4.1 KiB
MQL5
104 lines
4.1 KiB
MQL5
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| KronosBench.mq5 |
|
||
|
|
//| MMQ — Muhammad Minhas Qamar |
|
||
|
|
//| www.mql5.com |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#property copyright "MMQ — Muhammad Minhas Qamar"
|
||
|
|
#property link "https://www.mql5.com"
|
||
|
|
#property version "1.00"
|
||
|
|
#property script_show_inputs
|
||
|
|
#property strict
|
||
|
|
|
||
|
|
#include <Kronos\KronosInference.mqh>
|
||
|
|
|
||
|
|
#define KR_TOK_DIR "kronos_weights\\tokenizer\\"
|
||
|
|
#define KR_PRED_DIR "kronos_weights\\predictor\\"
|
||
|
|
|
||
|
|
input string InpRefDir = "kronos_refs\\"; // reuse x_norm/x_stamp for input
|
||
|
|
input int InpLookback = 64; // context bars
|
||
|
|
input int InpPredLen = 4;
|
||
|
|
input int InpSampleCount = 1;
|
||
|
|
input bool InpGreedy = true;
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Read a [rows,cols] float32 .bin into a matrix(double). |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool LoadF32Matrix(const string fname, ulong rows, ulong cols, matrix &out)
|
||
|
|
{
|
||
|
|
int h = FileOpen(fname, FILE_READ | FILE_BIN);
|
||
|
|
if(h == INVALID_HANDLE)
|
||
|
|
{
|
||
|
|
PrintFormat("open fail %s (%d)", fname, GetLastError());
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
ulong n = rows * cols;
|
||
|
|
float buf[];
|
||
|
|
ArrayResize(buf, (int)n);
|
||
|
|
uint got = FileReadArray(h, buf, 0, (int)n);
|
||
|
|
FileClose(h);
|
||
|
|
if(got != n)
|
||
|
|
{
|
||
|
|
PrintFormat("short read %s", fname);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
out = matrix::Zeros(rows, cols);
|
||
|
|
for(ulong r = 0; r < rows; r++)
|
||
|
|
for(ulong c = 0; c < cols; c++)
|
||
|
|
out[r][c] = (double)buf[r*cols+c];
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Script entry point. |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OnStart()
|
||
|
|
{
|
||
|
|
const int L = InpLookback, P = InpPredLen;
|
||
|
|
Print("============ Kronos benchmark ============");
|
||
|
|
PrintFormat("config: lookback=%d pred_len=%d sample_count=%d greedy=%s",
|
||
|
|
L, P, InpSampleCount, (InpGreedy ? "true" : "false"));
|
||
|
|
|
||
|
|
//--- input: take the first L rows of the reference x_norm window (already normalized)
|
||
|
|
matrix x_norm_full, x_stamp_full;
|
||
|
|
if(!LoadF32Matrix(InpRefDir + "x_norm.bin", 256, KR_NFEAT, x_norm_full))
|
||
|
|
return;
|
||
|
|
if(!LoadF32Matrix(InpRefDir + "x_stamp.bin", 256, 5, x_stamp_full))
|
||
|
|
return;
|
||
|
|
if(L > 256)
|
||
|
|
{
|
||
|
|
Print("lookback>256 not available from refs");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
matrix x_norm = matrix::Zeros((ulong)L, KR_NFEAT);
|
||
|
|
for(int i = 0; i < L; i++)
|
||
|
|
for(int j = 0; j < KR_NFEAT; j++)
|
||
|
|
x_norm[i][j] = x_norm_full[i][j];
|
||
|
|
|
||
|
|
matrix full_stamp = matrix::Zeros((ulong)(L + P), 5);
|
||
|
|
for(int i = 0; i < L; i++)
|
||
|
|
for(int j = 0; j < 5; j++)
|
||
|
|
full_stamp[i][j] = x_stamp_full[i][j];
|
||
|
|
//--- reuse last context stamp for the horizon (timing only, values irrelevant)
|
||
|
|
for(int i = 0; i < P; i++)
|
||
|
|
for(int j = 0; j < 5; j++)
|
||
|
|
full_stamp[L + i][j] = x_stamp_full[L - 1][j];
|
||
|
|
|
||
|
|
CKronosModel model;
|
||
|
|
uint t0 = GetTickCount();
|
||
|
|
if(!model.Init(KR_TOK_DIR, 4, 4, 256, 4, 512, KR_PRED_DIR, 8, 512, 8, 1024, 512))
|
||
|
|
{ Print("Init failed"); return; }
|
||
|
|
PrintFormat("weight load: %u ms", GetTickCount() - t0);
|
||
|
|
|
||
|
|
//--- one full path (greedy, 1 sample)
|
||
|
|
uint t1 = GetTickCount();
|
||
|
|
matrix pred;
|
||
|
|
int g1[], g2[];
|
||
|
|
if(!model.GeneratePathNorm(x_norm, full_stamp, P, 1.0, 0, 1.0, InpGreedy, pred, g1, g2))
|
||
|
|
{ Print("GeneratePathNorm failed"); return; }
|
||
|
|
uint dt = GetTickCount() - t1;
|
||
|
|
PrintFormat("ONE path (L=%d, P=%d): %u ms -> ~%.1f ms/step", L, P, dt, (double)dt / P);
|
||
|
|
PrintFormat("=> full forecast at sample_count=%d would be ~%u ms", InpSampleCount, dt * InpSampleCount);
|
||
|
|
Print("==========================================");
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|