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:}