GnuHomot 發表於 11-7-28 10:04

我轉換時間字串的函數寫錯了
now(4)回傳的是數字,我以為是字串=___=

GnuHomot 發表於 11-7-28 10:06

貼上修改過的function。太菜了,居然會犯這種錯{:4_623:}

function newDateTimeStr()
{

      newNowDateTime=Now(0);

      sYear=StrLeft(Now(1),4);
      //_TRACE("sYear: "+sYear);

      sDate=StrRight(Now(1),StrLen(Now(1))-5);
      //_TRACE("sDate: "+sDate);

      iMonth=StrToNum(sDate);
      if(iMonth<10)
      sMonth="0"+NumToStr(iMonth,1.0);
      else
      sMonth=NumToStr(iMonth,1.0);
      //_TRACE("sMonth: "+sMonth);


      if(iMonth<10)
      sDay=StrMid(sDate,2,2);
      else
      sDay=StrMid(sDate,3,2);

      iDay=StrToNum(sDay);
      if(iDay<10)
      sDay="0"+NumToStr(iDay,1.0);
      else
      sDay=NumToStr(iDay,1.0);
      //_TRACE("sDay: "+sDay);

      sTime=StrFormat("%g",Now(4));
      if(StrLen(sTime)<6)
      sTime="0"+sTime;
      
newNowDateTime=sYear+"/"+sMonth+"/"+sDay+" "+sTime;
//_TRACE("newNowDateTime: "+newNowDateTime);

return newNowDateTime;
}

GnuHomot 發表於 11-8-1 19:48

繼續來報告這幾天測試的結果

一樣是參考ashell兄的範例http://coco-in.net/viewthread.php?tid=6771&extra=page%3D2

不過其中有幾個是我已知的問題:
1.OMComAPI.GoOrder("FTX","","NowDateTime",Nowposition,Nowclose);
其中"NowDateTime"應該要改為NowDateTime,因為這樣子是輸出一個叫做NowDateTime的字串,而不是真正的時間字串。
2.當下的K棒在接收資料的時候其實是不斷的變動,如果你是檢查最後一根K棒來決定要不要進出,會發現訊號會不斷的送出。譬如說如果是黃金交叉買進的策略,在1分K的圖上面,有可能會出現12:00:01時因為出現交叉向上而送出訊號,但是12:00:05過後,因為下跌又沒有交叉了,所以最後的結果你是看不到這個交叉訊號的,但是下單大師已經收到你的買訊。
所以這邊我改成檢查倒數第二根K棒來決定是否要進場。

3.因為一旦AB跟下單大師都關掉的話,GetNowPosition()也無法問到目前的倉位,所以必需要把倉位記錄起來存在硬碟,這裡是參考http://www.amibroker.org/userkb/2007/04/24/persistent-variables/

4.原先ashell兄是用if (Buy==True)來檢查是否進場,但我發現有時候我居然滾動視窗都會觸發訊號,讓我對BarCount這個值非常懷疑,所以我參考http://www.amibroker.com/at/,改成用LastValue去做。

5.最後一個問題,也是打擊我最大的問題就是,我這樣子做的方向是錯的{:4_660:}


這樣子寫出來的程式碼,是利用Chart更新(預設是每秒更新一次)來檢查是否有產生訊號,但是前提是你必需該Chart要打開XDDD
也就是說如果你切換到別的Sheet就不會有作用了。


後來我才查到應該用AA中run every XXX time的作法來做才對,http://www.coco-in.net/viewthread.php?tid=1446&extra=,這部份就以後再說了{:4_622:}


總而言之,如果願意讓視窗保持完全不動的情況下,那麼我這個程式碼已經是可以發出正確的訊號,但是記得下單大師那邊一定要設定成用Current類的訊號,不然...後果可能很嚴重。


這是我今天測試的結果,http://imm.io/7Ldr
圖上的訊號在下單大師都有正確的接收到。

接下來要來研發策略了。

GnuHomot 發表於 11-8-1 19:51

請參考。

function newDateTimeStr()
{
        newNowDateTime=Now(0);

        sYear=StrLeft(Now(1),4);
        //_TRACE("sYear: "+sYear);

        sDate=StrRight(Now(1),StrLen(Now(1))-5);
        //_TRACE("sDate: "+sDate);

        iMonth=StrToNum(sDate);
        if(iMonth<10)
        sMonth="0"+NumToStr(iMonth,1.0);
        else
        sMonth=NumToStr(iMonth,1.0);
        //_TRACE("sMonth: "+sMonth);


        if(iMonth<10)
        sDay=StrMid(sDate,2,2);
        else
        sDay=StrMid(sDate,3,2);

        iDay=StrToNum(sDay);
        if(iDay<10)
        sDay="0"+NumToStr(iDay,1.0);
        else
        sDay=NumToStr(iDay,1.0);
        //_TRACE("sDay: "+sDay);

        sTime=StrFormat("%g",Now(4));
        if(StrLen(sTime)<6)
        sTime="0"+sTime;

newNowDateTime=sYear+"/"+sMonth+"/"+sDay+" "+sTime;
//_TRACE("newNowDateTime: "+newNowDateTime);

return newNowDateTime;
}
//***********************************************//

function PersistentVarSet( VarName, Number )
{
global PersistentPath;
String = NumToStr(Number);
fh = fopen( PersistentPath+VarName+".pva","w" );
if( fh )
{
fputs( String, fh );
fclose( fh );
}
return fh;
}

function PersistentVarGet( VarName )
{
global PersistentPath;
fh = fopen( PersistentPath+VarName+".pva","r" );
if( fh )
{
String = fgets( fh );
fclose( fh );
Number = StrToNum(String);
}
else Number = Null;
return Number;
}

//***********************************************//
//The Above are Functions

PersistentPath =ParamStr("Save Path","C:\\AB_PVA\\");//must create folder first, or "fopen" will return false.
IDstr=ParamStr("ID String","ABTW");

SMA=Param("SMA", 3, 2, 20);
LMA=Param("LMA", 10, 10, 200);

OMComAPI = CreateStaticObject("OMSignAPI.OMCOMAPI");
NowPostion=0;
NowPosition=OMComAPI.GetNowPosition(IDstr);
if(NowPosition>99990)
{
if(PersistentVarGet( IDstr )==Null)
{
NowPosition=0;
PersistentVarSet(IDstr, NowPosition);
}
else
{
NowPosition=PersistentVarGet( IDstr );
//PersistentVarSet(IDstr, NowPosition);
_TRACE("Get Persistent Var First Call: "+IDstr);
}
}
//_TRACE(PersistentPath);
//_TRACE("NowPosition: "+NumToStr(NowPosition));

OMComAPI.IniDllAndPosition(IDstr, NowPosition);

//stradegy here
up=Cross(MA(C,SMA),MA(C,LMA));
down=Cross(MA(C,LMA),MA(C,SMA));
Buy = up;
Sell = down OR TimeNum()>134000;//force to exit after 13:40:00
Buy =ExRem(Buy,Sell);
Sell=ExRem(Sell,Buy);

//if(NowPosition<1) //avoid repeat buy at every updating chart
if (LastValue(Ref(Buy,-1)) )
{
NowDateTime=newDateTimeStr();
NowPosition = 1;
NowClose=LastValue(Ref(Close,-1));//LastValue(Close);
OMComAPI.GoOrder(IDstr,"",NowDateTime,Nowposition,Nowclose);
_TRACE("Buy"+NumToStr(NowPosition,1.0)+"@"+NumToStr(Nowclose,1.0)+"@"+NowDateTime);
PersistentVarSet(IDstr, NowPosition);
}

//if(NowPosition>0)
if (LastValue(Ref(Sell,-1)) )
{
NowDateTime=newDateTimeStr();
NowPosition = 0;
NowClose=LastValue(Ref(Close,-1));//LastValue(Close);
OMComAPI.GoOrder(IDstr,"",NowDateTime,NowPosition,NowClose);
_TRACE("Sell"+NumToStr(NowPosition,1.0)+"@"+NumToStr(Nowclose,1.0)+"@"+NowDateTime);
PersistentVarSet(IDstr, NowPosition);
}

Plot(MA(C,SMA),"SMA"+NumToStr(SMA,1.0),colorRed,styleLine);
Plot(MA(C,LMA),"LMA"+NumToStr(LMA,1.0),colorBlue,styleLine);
//PlotShapes(IIf(Buy , shapeSmallUpTriangle, shapeNone) ,colorYellow, 0,L,-50);
//PlotShapes(IIf( Sell, shapeSmallDownTriangle, shapeNone) ,colorBlue, 0,H,-45);
PlotShapes(Buy * shapeSmallUpTriangle ,colorRed, 0,L,-50);
PlotShapes(Sell * shapeSmallDownTriangle ,colorGreen, 0,H,-45);

dist=1.5*ATR(10);
for( i = 1; i < BarCount; i++ )
{
if( Buy ) PlotText( "Buy\n@" + C[ i-1 ], i, L[ i ]-dist, colorRed );
if( Sell ) PlotText( "Sell\n@" + C[ i-1 ], i, H[ i ]+dist, colorGreen );
}


_SECTION_BEGIN("Price1");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorBlack ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_SECTION_END();

kilroy 發表於 11-8-1 20:17

HI 大大

請問您用下單大師萬用API

和文字檔下單,感覺上,下單速度會差很多嗎

感謝 {:5_260:}

GnuHomot 發表於 11-8-1 20:50

我不是大大{:4_96:}。
我目前只有測試到下單大師的模擬單而已,還沒實測過。
我也只有試過萬用API,我看AB輸出的訊號時間到下單大師接收時間,幾乎都在同一秒內,我想這樣子應該已經夠快了吧??

kilroy 發表於 11-8-1 21:25

我不是大大。
我目前只有測試到下單大師的模擬單而已,還沒實測過。
我也只有試過萬用API,我看AB ...
GnuHomot 發表於 11-8-1 08:50 PM http://www.coco-in.net/images/common/back.gif

好像不ˊ賴 {:5_256:}

GnuHomot 發表於 11-8-3 20:53

繼續來報告,參考這篇的作法
http://www.coco-in.net/viewthread.php?tid=1446&extra=

發現要改其實沒那麼難,主要就是利用
if( Status("action") == actionScan)
來判斷是否有滿足發動下單條件。

而在Automatic Analysis中
把預設5min改為1sec(視個人需求),將Run Every打勾,按下Scan。
如此一來Amibroker就會以一秒Scan一次去檢查,目前的商品是否有滿足下單條件。

這樣的作法跟之前比起來,最大的差別有兩個:
1.不用停留在視窗上,就算切換視窗也沒問題,訊號一樣會發出。
2.可以選擇多商品來交易,達成[單一策略多商品交易]的目的。

另外我又參考
http://www.amibroker.com/guide/h_alerts.html
設定滿足條件時,由Amibroker發出Alert。
如此一來,當Amibroker要送出訊號時,會寄一封信到Gmail,而下單大師收到訊號時,同時也會寄一封信到Gmail。

信箱就可以收到這樣的信
http://imm.io/7QnZ
第一封是Amibroker第一次啟動Scan時所通知,就可以知道Amibroker啟動了。
第二封是Scan到滿足下單條件由Amibroker送出,第三封是下單大師收到訊號後寄的。

整個要自動化下單的架構應該就是這樣了。

希望有遺漏的地方請前輩多多指教。

GnuHomot 發表於 11-8-3 20:54

function newDateTimeStr()
{
        newNowDateTime=Now(0);

        sYear=StrLeft(Now(1),4);
        //_TRACE("sYear: "+sYear);

        sDate=StrRight(Now(1),StrLen(Now(1))-5);
        //_TRACE("sDate: "+sDate);

        iMonth=StrToNum(sDate);
        if(iMonth<10)
        sMonth="0"+NumToStr(iMonth,1.0);
        else
        sMonth=NumToStr(iMonth,1.0);
        //_TRACE("sMonth: "+sMonth);


        if(iMonth<10)
        sDay=StrMid(sDate,2,2);
        else
        sDay=StrMid(sDate,3,2);

        iDay=StrToNum(sDay);
        if(iDay<10)
        sDay="0"+NumToStr(iDay,1.0);
        else
        sDay=NumToStr(iDay,1.0);
        //_TRACE("sDay: "+sDay);

        sTime=StrFormat("%g",Now(4));
        if(StrLen(sTime)<6)
        sTime="0"+sTime;

newNowDateTime=sYear+"/"+sMonth+"/"+sDay+" "+sTime;
//_TRACE("newNowDateTime: "+newNowDateTime);

return newNowDateTime;
}
//***********************************************//

function PersistentVarSet( VarName, Number )
{
global PersistentPath;
String = NumToStr(Number);
fh = fopen( PersistentPath+VarName+".pva","w" );
if( fh )
{
fputs( String, fh );
fclose( fh );
}
return fh;
}

function PersistentVarGet( VarName )
{
global PersistentPath;
fh = fopen( PersistentPath+VarName+".pva","r" );
if( fh )
{
String = fgets( fh );
fclose( fh );
Number = StrToNum(String);
}
else Number = Null;
return Number;
}

//***********************************************//
//The Above are Functions

PersistentPath =ParamStr("Save Path","C:\\AB_PVA\\");//must create folder first, or "fopen" will return false.
IDstr=ParamStr("ID String","ABTW");

SMA=Param("SMA", 3, 2, 20);
LMA=Param("LMA", 10, 10, 200);

if( Status("action") == actionScan)
{
//_TRACE("actionScan");
OMComAPI = CreateStaticObject("OMSignAPI.OMCOMAPI");
NowPostion=0;
NowPosition=OMComAPI.GetNowPosition(IDstr);
if(NowPosition>99990)
{
if(PersistentVarGet( IDstr )==Null)
{
NowPosition=0;
PersistentVarSet(IDstr, NowPosition);
_TRACE("Can't Get Persistent Var then Create: "+IDstr);

}
else
{
NowPosition=PersistentVarGet( IDstr );
//PersistentVarSet(IDstr, NowPosition);
_TRACE("Get Persistent Var First Call: "+IDstr);
}
OMComAPI.IniDllAndPosition(IDstr, NowPosition);
AlertIf(1,"EMAIL", "OrderMaster Initialized: "+NumToStr(NowPosition,1.0), 0);
}
//_TRACE(PersistentPath);
//_TRACE("NowPosition: "+NumToStr(NowPosition));

}//if( Status("action") == actionScan)


//stradegy here
up=Cross(MA(C,SMA),MA(C,LMA));
down=Cross(MA(C,LMA),MA(C,SMA));
Buy = up;
Sell = down OR TimeNum()>133900;//force to exit after 13:40:00
Buy =ExRem(Buy,Sell);
Sell=ExRem(Sell,Buy);


if( Status("action") == actionScan)
{

if(NowPosition<1) //avoid repeat buy at every updating chart
if (LastValue(Ref(Buy,-1)) )
{
NowDateTime=newDateTimeStr();
NowPosition = 1;
NowClose=LastValue(Ref(Close,-1));//LastValue(Close);
OMComAPI.GoOrder(IDstr,"",NowDateTime,Nowposition,Nowclose);
_TRACE("Buy"+NumToStr(NowPosition,1.0)+"@"+NumToStr(Nowclose,1.0)+"@"+NowDateTime);
AlertIf(1,"EMAIL", "Buy"+NumToStr(NowPosition,1.0)+"@"+NumToStr(Nowclose,1.0)+"@"+NowDateTime, 1);
PersistentVarSet(IDstr, NowPosition);
}

if(NowPosition>0)
if (LastValue(Ref(Sell,-1)) )
{
NowDateTime=newDateTimeStr();
NowPosition = 0;
NowClose=LastValue(Ref(Close,-1));//LastValue(Close);
OMComAPI.GoOrder(IDstr,"",NowDateTime,NowPosition,NowClose);
_TRACE("Sell"+NumToStr(NowPosition,1.0)+"@"+NumToStr(Nowclose,1.0)+"@"+NowDateTime);
AlertIf(1,"EMAIL", "Sell"+NumToStr(NowPosition,1.0)+"@"+NumToStr(Nowclose,1.0)+"@"+NowDateTime, 2);
PersistentVarSet(IDstr, NowPosition);
}

}//if( Status("action") == actionScan)


Plot(MA(C,SMA),"SMA"+NumToStr(SMA,1.0),colorRed,styleLine);
Plot(MA(C,LMA),"LMA"+NumToStr(LMA,1.0),colorBlue,styleLine);
//PlotShapes(IIf(Buy , shapeSmallUpTriangle, shapeNone) ,colorYellow, 0,L,-50);
//PlotShapes(IIf( Sell, shapeSmallDownTriangle, shapeNone) ,colorBlue, 0,H,-45);
PlotShapes(Buy * shapeSmallUpTriangle ,colorRed, 0,L,-50);
PlotShapes(Sell * shapeSmallDownTriangle ,colorGreen, 0,H,-45);

dist=1.5*ATR(10);
for( i = 1; i < BarCount; i++ )
{
if( Buy ) PlotText( "Buy\n@" + C[ i-1 ], i, L[ i ]-dist, colorRed );
if( Sell ) PlotText( "Sell\n@" + C[ i-1 ], i, H[ i ]+dist, colorGreen );
}


_SECTION_BEGIN("Price1");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorBlack ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_SECTION_END();

GnuHomot 發表於 11-8-3 20:56

不知道有沒有前輩知道要如何做多策略??

難不成要把所有策略都寫到同一個AFL裡面,有點怪怪的{:4_144:}

GnuHomot 發表於 11-8-3 21:18

順便說明一下我目前規劃的流程
1.Run DDE2TickQuote.exe (ABTW)
2.Run Amibroker
3.Automatic Analysis => Run Every => Scan
4.Run OrderMaster下單大師 =>開始下單

附上很簡陃的AutoIt的程式碼,小弟只是AutoIt的初學者,有錯請前輩多多指教。
接下來可以利用Windows的工作排程器,排定每天早上8:45去執行AutoIt編譯好的執行檔做這些動作。

收盤後再利用下單大師的關機流程把這些程式都關掉,和把電腦關閉。





#cs ----------------------------------------------------------------------------

AutoIt Version: 3.3.6.1
Author:         GnuHomot

Script Function:
        Template AutoIt script.

#ce ----------------------------------------------------------------------------

; Script Start - Add your code below here

ShellExecute("C:\ABTW\DDE2TickQuote.exe", "-auto","C:\ABTW")
;run("C:\ABTW\DDE2TickQuote.exe","C:\ABTW")
WinWait("DDE2TickQuote")

ControlClick("Note","", "")

WinActivate("DDE2TickQuote")
WinWaitActive("DDE2TickQuote","", 5)

;enter password
WinWait("群益DLL連線設定")
ControlClick("群益DLL連線設定","", 1)

Sleep(3000);

;;close Form
;WinActivate("DDE2TickQuote")
;WinWaitActive("DDE2TickQuote")
;ControlClick("DDE2TickQuote","", 2)


run("C:\Program Files (x86)\AmiBroker\Broker.exe","C:\Program Files (x86)\AmiBroker")
WinWait("","",5)

Sleep(15000);//wait for ABTW loading data into Amibroker

WinActivate("Note")
;WinWaitActive("Note")
ControlClick("Note","", "")

;Run AA every run in 1sec
WinMinimizeAll()
WinSetState("","",@SW_MAXIMIZE)
WinActivate("")
$rtn=WinWaitActive("","", 5)
Send("^q");go Amibroker to set customize hot-key to call "Automatic Analysis"
WinWaitActive("","",5)
ControlSend("","", "", "^a")
ControlSend("","", "", "1sec")
ControlCommand("","", "", "Check")
ControlClick("","", "")


;Run OrderMaster
run("C:\Program Files (x86)\OrderMaster\OrderMaster.exe","C:\Program Files (x86)\OrderMaster")

WinWait("")
;WinActivate("")
;WinWaitActive("")
Sleep(10000);
ControlClick("","", "")
;MouseClick("left", 1366, 345)


Exit

kilroy 發表於 11-8-3 21:47

順便說明一下我目前規劃的流程
1.Run DDE2TickQuote.exe (ABTW)
2.Run Amibroker
3.Automatic Analysis =>...
GnuHomot 發表於 11-8-3 09:18 PM http://www.coco-in.net/images/common/back.gif

大大 請問 autoit 要怎麼寫

開啟 amiBroker 之後


進入 file -> import wizard

pick files -> (進入我指定的目錄之後,選擇我指定的數個檔案)

自動選好格式YMD, time底下選 comma or space

---
這個對我來說好難阿 {:9_582:}{:9_580:}

kilroy 發表於 11-8-3 21:55

另外我又參考
http://www.amibroker.com/guide/h_alerts.html
設定滿足條件時,由Amibroker發出Alert。
GnuHomot 發表於 11-8-3 08:53 PM http://www.coco-in.net/images/common/back.gif

   這個厲害~ 小弟還沒玩過 {:4_113:}

GnuHomot 發表於 11-8-3 22:00

大大 請問 autoit 要怎麼寫

開啟 amiBroker 之後


進入 file -> import wizard

pick files -> (進 ...
kilroy 發表於 11-8-3 09:47 PM http://coco-in.net/images/common/back.gif

沒寫過,不會{:4_140:}

GnuHomot 發表於 11-8-4 10:01

本帖最後由 GnuHomot 於 11-8-4 10:03 AM 編輯

沒想到這麼快又來要報告了,因為我發現bug{:4_87:}

原來程式中
if(PersistentVarGet( IDstr )==Null)
這個條件式是無用的>"<
因為雖然PersistentVarGet()會回傳Null,但是就是沒辦法跟Null做比較,我也不知道為什麼。

這行要改成
if(NumtoStr(PersistentVarGet(IDstr) == {EMPTY})
利用NumtoStr轉Null後會變成"{EMPTY}"字串來做比較

這樣子就可以了

另外
單一策略多商品交易確定這個方法也行
程式碼稍微修改後,不同商品發出不同的辨識碼給下單大師,下單大師那邊也同時設定好,在AA中選All Symbols就可以了。
我在網路上還是沒找到要怎麼做自動交易 多策略單一商品 或是多策略多商品的方法{:4_93:}
頁: 1 [2] 3 4 5 6
查看完整版本: Amibroker接下單大師測試