#resource "Python/model.onnx" as uchar ExtModel[]// 자원으로서의 모델
#define TESTS 10000 // 테스트 데이터세트의 수
/+------------------------------------------------------------------+
//| 프로그램 시작 함수 스크립트 |
/+------------------------------------------------------------------+
int OnStart()
{
//--- 모델 생성
long session_handle=OnnxCreateFromBuffer(ExtModel,ONNX_DEBUG_LOGS);
if(session_handle==INVALID_HANDLE)
{
Print("Cannot create model. Error ",GetLastError());
return(-1);
}
//--- 입력 텐서 크기가 모델에 대해 정의되어 있지 않으므로 명시적으로 지정합니다.
//--- 첫 번째 인덱스는 배치 크기, 두 번째 인덱스는 시리즈 크기, 세 번째 인덱스는 시리즈 수(OHLC)
const long input_shape[]={1,10,4};
if(!OnnxSetInputShape(session_handle,0,input_shape))
{
Print("OnnxSetInputShape error ",GetLastError());
return(-2);
}
//--- 출력 텐서 크기가 모델에 개해 정의되어 있지 않으므로 명시적으로 지정합니다.
//--- 첫 번째 인덱스는 배치 크기이며 입력 텐서의 배치 크기와 일치해야 합니다.
//--- 두 번째 인덱스는 예상 가격들의 수입니다(여기서는 종가만 예측됨).
const long output_shape[]={1,1};
if(!OnnxSetOutputShape(session_handle,0,output_shape))
{
Print("OnnxSetOutputShape error ",GetLastError());
return(-3);
}
//--- 테스트 실행
vector closes(TESTS); // 검증 가격을 저장할 벡터
vector predicts(TESTS); // 구한 예측들을 저장할 벡터
vector prev_closes(TESTS); // 이어지는 가격들을 저장할 벡터
matrix rates; // OHLC 시리즈를 얻기 위한 행렬
matrixsplitted[2];// 시리즈를 테스트와 검증으로 나누는 두 부분 행렬
ulong parts[]={10,1}; // 나누어진 부분 행렬�l 크기
//--- 이전 바부터 시작
for(int i=1; i<=TESTS; i++)
{
//--- 11개의 바를 얻음
rates.CopyRates("EURUSD",PERIOD_H1,COPY_RATES_OHLC,i,11);
//--- 행렬을 테스트와 검증으로 나눕니다.
rates.Vsplit(parts,splitted);
//--- 유효성 검증 매트릭스에서 종가를 가져옵니다.
closes[i-1]=splitted[1][3][0];
//--- 테스트된 시리즈의 마지막 종가
prev_closes[i-1]=splitted[0][3][9];
//--- 10개의 바의 테스트 매트릭스를 테스팅에 제출
predicts[i-1]=PricePredictionTest(session_handle,splitted[0]);
//--- 런타임 에러
if(predicts[i-1]<=0)
{
OnnxRelease(session_handle);
return(-4);
}
}
//--- 작업 완료
OnnxRelease(session_handle);
//--- 가격 움직임이 올바르게 예측되었는지를 평가
int right_directions=0;
vector delta_predicts=prev_closes-predicts;
vector delta_actuals=prev_closes-closes;
for(int i=0; i<TESTS; i++)
if((delta_predicts[i]>0 && delta_actuals[i]>0) || (delta_predicts[i]<0 && delta_actuals[i]<0))
right_directions++;
PrintFormat("right direction predictions = %.2f%%",(right_directions*100.0)/double(TESTS));
//---
return(0);
}
/+------------------------------------------------------------------+
//| 데이터 준비하고 모델 실행 |
/+------------------------------------------------------------------+
double PricePredictionTest(const long session_handle,matrix& rates)
{
static matrixf input_data(10,4); // 변환된 입력을 위한 행렬
static vectorf output_data(1); // 결과를 받을 벡터
static matrix mm(10,4); //수평 벡터의 행렬 Mean
static matrix ms(10,4); // 수평 벡터의 Std
//--- OHLC 수직 벡터 세트가 모델에 입력되어야 합니다.
matrix x_norm=rates.Transpose();
//--- 가격 정규화
vector m=x_norm.Mean(0);
vector s=x_norm.Std(0);
for(int i=0; i<10; i++)
{
mm.Row(m,i);
ms.Row(s,i);
}
x_norm-=mm;
x_norm/=ms;
//--- 모델 실행
input_data.Assign(x_norm);
if(!OnnxRun(session_handle,ONNX_DEBUG_LOGS,input_data,output_data))
{
Print("OnnxRun error ",GetLastError());
return(0);
}
//--- 출력 값에서 가격을 비정규화
double y_pred=output_data[0]*s[3]+m[3];
return(y_pred);
}
|