![]() |
在這個頁面顯示本主題全部的 3 個文章 |
奇狐社區論壇 (http://www.chiefox.com.tw/bbs/index.php)
- 應用交流 (http://www.chiefox.com.tw/bbs/forumdisplay.php?forumid=33)
-- 如何用飛狐連結 80x86 Macro Assembly程式語言 (http://www.chiefox.com.tw/bbs/showthread.php?threadid=4744)
如何用飛狐連結 80x86 Macro Assembly程式語言
學習或會用80x86 Macro Assembly程式語言的朋友幾乎沒有,但還是發帖供飛狐軟體的設計者參考
C++程式語言的編譯器是Microsoft Visual C++6.0
編譯步驟大致如下
一, 用Borland公司的”tasm32” macro assembly compiler 編譯pow10.asm 成pow10.obj,即 To compile,use the following command "tasm32 /ml pow10.asm"
二, 用Microsoft Visual C++6.0編譯foxfunc.cpp,做成my1.dll
簡單流程如下
在Microsoft Visual C++6.0環境中
file - - > new - -> projects - ->win32 dynamic-Link Library - -> 打入projectname,例如”my1” - ->empty project - ->OK
把.cpp及.H檔或其他相關檔全部複製到”my1”目錄
project - ->add to projects - -> files - - >找到foxfunc.cpp檔
project - ->add to projects - -> files - - >找到ppow10.obj檔
build - -> build my1.dll
原碼:
// FoxFunc.H #ifndef __FOXFUNC_H_INCLUDE #define __FOXFUNC_H_INCLUDE /* /////////////////////// 飛狐交易師“C語言介面”擴展程式調用介面規範V3.0 1.本規範適用於飛狐交易師V3.x公式系統. 2.擴展函數用於實現系統函數不能實現的特殊演算法. 3.擴展函數用windows 32位元動態連接庫實現,建議使用Microsoft Visual C++編程. 4.調用時在公式編輯器中寫"動態庫名稱@函數名稱"(參數表)即可,例如下面函數可以寫為"FOXFUNC@MYMACLOSE"(5) 5.動態連接庫名稱和函數名稱可以自己定義. 6.使用時必須將動態庫拷貝到飛狐交易師安裝目錄下的FmlDLL子目錄下使用. */ #ifdef __cplusplus extern "C" { #endif //__cplusplus /////////// //分析週期 enum DATA_TYPE { TICK_DATA=2, //分筆成交 MIN1_DATA, //1分鐘線 MIN5_DATA, //5分鐘線 MIN15_DATA, //15分鐘線 MIN30_DATA, //30分鐘線 MIN60_DATA, //60分鐘線 DAY_DATA, //日線 WEEK_DATA, //周線 MONTH_DATA, //月線 YEAR_DATA, //年線 MULTIDAY_DATA, //多日線 MULTIMIN_DATA //多分鐘線 }; /////////////// //基本資料 typedef struct tagSTKDATA { time_t m_time; //時間,UCT float m_fOpen; //開盤 float m_fHigh; //最高 float m_fLow; //最低 float m_fClose; //收盤 float m_fVolume; //成交量 float m_fAmount; //成交額 WORD m_wAdvance; //上漲家數 僅大盤有效 WORD m_wDecline; //下跌家數 僅大盤有效 } STKDATA; ///////////擴展資料,用於描述分筆成交資料的買賣盤 typedef union tagSTKDATAEx { struct { float m_fBuyPrice[3]; //買1--買3價 float m_fBuyVol[3]; //買1--買3量 float m_fSellPrice[3]; //賣1--賣3價 float m_fSellVol[3]; //賣1--賣3量 }; float m_fDataEx[12]; } STKDATAEx; ////////// //除權數據 typedef struct tagSPLITDATA { time_t m_time; //時間,UCT float m_fHg; //紅股 float m_fPg; //配股 float m_fPgj; //配股價 float m_fHl; //紅利 } SPLITDATA; ///////// /*財務資料順序(m_pfFinData內容) 序號 內容 0 總股本(萬股), 1 國家股, 2 發起人法人股, 3 法人股, 4 B股, 5 H股, 6 流通A股, 7 職工股, 8 A2轉配股, 9 總資產(千元), 10 流動資產, 11 固定資產, 12 無形資產, 13 長期投資, 14 流動負債, 15 長期負債, 16 資本公積金, 17 每股公積金, 18 股東權益, 19 主營收入, 20 主營利潤, 21 其他利潤, 22 營業利潤, 23 投資收益, 24 補貼收入, 25 營業外收支, 26 上年損益調整, 27 利潤總額, 28 稅後利潤, 29 淨利潤, 30 未分配利潤, 31 每股未分配, 32 每股收益, 33 每股淨資產, 34 調整每股淨資, 35 股東權益比, 36 淨資收益率 */ /////////// //調用參數項結構 typedef struct tagCALCPARAM { union { const float* m_pfParam; //序列參數,指向一個浮點型陣列 const float m_fParam; //數值參數 }; const int m_nParamStart; //序列參數有效起始位置 }CALCPARAM; ///////////////////// //調用介面資訊資料結構 typedef struct tagCALCINFO { const DWORD m_dwSize; //結構大小 const DWORD m_dwVersion; //調用軟體版本(V2.10 : 0x210) const DWORD m_dwSerial; //調用軟體序列號 const char* m_strStkLabel; //股票代碼 const BOOL m_bIndex; //大盤 const int m_nNumData; //資料數量(pData,pDataEx,pResultBuf資料數量) const STKDATA* m_pData; //常規資料,注意:當m_nNumData==0時可能為 NULL const STKDATAEx* m_pDataEx; //擴展資料,分筆成交買賣盤,注意:可能為 NULL const int m_nParam1Start; //參數1有效起始位置 const float* m_pfParam1; //調用參數1 const float* m_pfParam2; //調用參數2 const float* m_pfParam3; //調用參數3 const float* m_pfParam4; //調用參數3 float* m_pResultBuf; //結果緩衝區 const DWORD m_dataType; //資料類型 const float* m_pfFinData; //財務資料 //以上與分析家相容,所以沿用其結構和名稱 //以下為飛狐交易師擴展 const DWORD m_dwReserved; // 保留 const int m_nNumParam; // 調用參數數量 const CALCPARAM* m_pCalcParam; // 調用參數陣列 const DWORD m_dwReservedEx[4]; // 保留 char* m_strStkName; //股票名稱 SPLITDATA* m_pSplitData; //除權數據 int m_nNumSplitData; //除權次數 } CALCINFO; /* 注1: (與分析家相容) 1.函數調用參數由m_pfParam1--m_pfParam4帶入,若為NULL則表示該參數無效. 2.當一個參數無效時,則其後的所有參數均無效. 如:m_pfParam2為NULL,則m_pfParam3,m_pfParam4一定為NULL. 3.參數1可以是常數參數或序列數參數,其餘參數只能為常數參數. 4.若m_nParam1Start<0, 則參數1為常數參數,參數等於*m_pfParam1; 5.若m_nParam1Start>=0,則參數1為序列數參數,m_pfParam1指向一個浮點型陣列, 陣列大小為m_nNumData,資料有效範圍為 m_nParam1Start 至 m_nNumData-1. 在時間上m_pData[x] 與 m_pfParam1[x]是一致的 注2: (飛狐交易師擴展) 1.該擴展結構使調用參數在技術上可以是無限數目的,且每個參數都可為數值或序列,由公式中實際的調用參數決定。 2.CALCPARAM結構用於帶入參數資訊和實際資料,m_pCalcParam陣列大小為m_nNumParam,資料有效範圍為 0 至 m_nNumParam-1. 3.按參數的順序,m_pCalcParam[0]為第一個參數的資料,m_pCalcParam[1]為第二個參數的資料...,為了保持相容,原m_nParam1Start、m_pfParam1等5個屬性依然有賦值。 4.若 i位置的參數為數值,取用m_pCalcParam[i].m_fParam. 5.若 i位置的參數為序列,取用m_pCalcParam[i].m_pfParam,陣列大小為m_nNumData,資料有效範圍為m_pCalcParam[i].m_nParamStart 至 m_nNumData-1. 若m_pCalcParam[i].m_nParamStart<0, 則此陣列中無有效資料。 6.由於可以調用多個序列,許多序列的計算可以先在公式中進行,然後作為調用的參數即可。 7.經此擴展,對分析家的DLL依然可以調用、相容。 */ //////////// /* 函數輸出 __declspec(dllexport) int xxxxxxxx(CALCINFO* pData); 1.函數名稱需全部大寫. 2.函數必須以上述形式聲明,請用實際函數名稱替代xxxxxxxx; 對於C++程式還需包括在 extern "C" { } 括弧中. 3.函數計算結果用pData->m_pResultBuf帶回. 4.函數返回-1表示錯誤或全部資料無效,否則返回第一個有效值位置,即: m_pResultBuf[返回值] -- m_pResultBuf[m_nNumData-1]間為有效值. 5.函數名稱長度不能超過15位元組,動態連接庫檔案名不能超過9位元組(不包括副檔名),動態庫名稱不能叫SYSTEM,EXPLORER */ //示例函數,使用時用實際名稱替換 __declspec(dllexport) int WINAPI MYMACLOSE(CALCINFO* pData); __declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData); __declspec(dllexport) int WINAPI MYBBI(CALCINFO* pData); #ifdef __cplusplus } #endif //__cplusplus #endif //__FOXFUNC_H_INCLUDE
原碼:
// FoxFunc.cpp : Defines the entry point for the DLL application. // #include <string.h> #include <stdio.h> #include <io.h> #include <math.h> #include <iostream.h> #include "stdafx.h" #include "FoxFunc.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } //計算收盤價的均價,一個常數參數,表示計算週期 //調用方法: // "FOXFUNC@MYMACLOSE"(5) extern "C" double ppow10(double,double); // !!!!!!!! use "C" for Microsoft visual C++ compiler // !!!!!!!! use "C" for Microsoft visual C++ compiler __declspec(dllexport) int WINAPI MYMACLOSE(CALCINFO* pData) { if ( pData->m_pfParam1 && //參數1有效 pData->m_nParam1Start<0 && //參數1為常數 pData->m_pfParam2==NULL ) //僅有一個參數 { float fParam = *pData->m_pfParam1; int nPeriod = (int)fParam; //參數1 if(nPeriod>0) { float fTotal; int i, j; int ndata = pData->m_nNumData; float yy[5000][1]; for ( i = nPeriod-1; i < pData->m_nNumData; i++ )//計算nPeriod週期的均線,資料從nPeriod-1開始有效 { fTotal = 0.0f; double lngth=2.0; float yy1[5000][1]; for ( j = 0; j < nPeriod; j++ ) //累加 fTotal += pData->m_pData[i-j].m_fClose; pData->m_pResultBuf[i] = fTotal/nPeriod; //平均 pData->m_pResultBuf[i]=ppow10(pData->m_pResultBuf[i],lngth); } return nPeriod-1; } } return -1; } //計算均價,2個參數,參數1為待求均線的資料,參數2表示計算週期 //調用方法: // "FOXFUNC@MYMAVAR"(CLOSE-OPEN,5) __declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData) { if(pData->m_pfParam1 && pData->m_pfParam2 && //參數1,2有效 pData->m_nParam1Start>=0 && //參數1為序列數 pData->m_pfParam3==NULL) //有2個參數 { const float* pValue = pData->m_pfParam1; //參數1 int nFirst = pData->m_nParam1Start; //有效值起始位 float fParam = *pData->m_pfParam2; //參數2 int nPeriod = (int)fParam; if( nFirst >= 0 && nPeriod > 0 ) { float fTotal; int i, j; for ( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ ) { fTotal = 0.0f; for ( j=0; j < nPeriod; j++ ) //累加 fTotal += pValue[i-j]; pData->m_pResultBuf[i] = fTotal/nPeriod;//平均 pData->m_pResultBuf[i] = ppow10(pData->m_pResultBuf[i],2.0); } return nFirst+nPeriod-1; } } return -1; } //計算多個序列的均值,5個參數,參數1-4為待求多個序列,參數5用於舉例說明數值參數的用法,實際在此例中無需該參數 /* 調用方法: MA1:=MA(CLOSE,3); MA2:=MA(CLOSE,6); MA3:=MA(CLOSE,12); MA4:=MA(CLOSE,24); MYBBI: "FOXFUNC@MYBBI"(MA1, MA2, MA3, MA4, 4); */ __declspec(dllexport) int WINAPI MYBBI(CALCINFO* pData) { if ( pData->m_pCalcParam[0].m_nParamStart >= 0 && pData->m_pCalcParam[1].m_nParamStart >= 0 && pData->m_pCalcParam[2].m_nParamStart >= 0 && pData->m_pCalcParam[3].m_nParamStart >= 0 ) //4個序列都含有效數值 { //計算返回的序列的第一個有效值位置 int nFirst = pData->m_pCalcParam[3].m_nParamStart; //已知返回的序列的第一個有效值位置與第4個序列一致 //若不知,則 /* int nFirst = pData->m_pCalcParam[0].m_nParamStart; if ( nFirst < pData->m_pCalcParam[1].m_nParamStart ) nFirst = pData->m_pCalcParam[1].m_nParamStart; if ( nFirst < pData->m_pCalcParam[2].m_nParamStart ) nFirst = pData->m_pCalcParam[2].m_nParamStart; if ( nFirst < pData->m_pCalcParam[3].m_nParamStart ) nFirst = pData->m_pCalcParam[3].m_nParamStart; */ const float* pValue1 = pData->m_pCalcParam[0].m_pfParam; const float* pValue2 = pData->m_pCalcParam[1].m_pfParam; const float* pValue3 = pData->m_pCalcParam[2].m_pfParam; const float* pValue4 = pData->m_pCalcParam[3].m_pfParam; int nNum = (int)(pData->m_pCalcParam[4].m_fParam); //實際上該例中已知nNum=4,在此用於說明數值參數的用法 for( int i = nFirst; i < pData->m_nNumData; i++ ) { pData->m_pResultBuf[i] = (pValue1[i] + pValue2[i] + pValue3[i] + pValue4[i])/nNum; } return nFirst; } return -1; }
原碼:
; ******************************************************* ; * * ; * Delphi Runtime Library * ; * * ; * Copyright (c) 1996,98 Inprise Corporation * ;*-------------------------------------------------------------------------- ; * To compile,give "tasm32 /ml ow10.asm" * ;*-------------------------------------------------------------------------- ; ******************************************************* ; INCLUDE SE.ASM .386 .MODEL flat PUBLIC _ppow10 .CODE ; FUNCTION _Ppow10( double val, double pow: ) : Extended; _ppow10 PROC near fp_power EQU QWORD PTR [ebp+16] fp_val EQU QWORD PTR [ebp+8] val EQU QWORD PTR [eBP-8] ; USE STACK power EQU QWORD PTR [eBP-16] ; USE STACK pow10 EQU QWORD PTR [eBP-24] ; USE STACK FPower10: push ebp mov ebp,esp sub esp,24 MOV EAX,8 MOV EDX,8 ; fldpi fld fp_val ;st(0)=val fstp val fld fp_power ;st(0)=power fstp power fld val ;st(0)=val fmul power ;st(0)=val*power fmul power ;st(0)=val*power*power ; fadd st,st(0) ; fmul qword ptr [ebp+16] ;st(0)=power ; fadd st,st(0) mov esp,ebp pop ebp RET ;return value = st(0) _ppow10 ENDP END
原碼:
oooq:"MY1@MYMAVAR"(c,5),linethick2;
| 全部時間均為台灣時間, 現在時間為12:58 | 在這個頁面顯示本主題全部的 3 個文章 |
Powered by: vBulletin Version 2.3.0 - Copyright©2000-, Jelsoft Enterprises Limited.
簡愛洋行 製作 Copyright 2003-. All Rights Reserved.