#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); } |