skyler
發表於 14-6-14 21:35
kilroy 發表於 14-6-14 20:59 static/image/common/back.gif
Hi,
日圓
感謝您的熱心分享~~
skyler
發表於 14-6-15 19:36
K大您好昨天在做MC的功課時
看到一句話"每根K棒結束都執行程式一次"
因此想請教一個關於回測的問題
AB是否也是如此,在K棒結束後執行程式一次
判斷是否有進出場條件
用以下的程式當範例
MA5_P1 = Ref( MA( C, 5 ), -1 );
MA5_P2 = Ref( MA( C, 5 ), -2 );
Cond_MA5_Buy = MA5_P1 > MA5_P2;
Cond_MA5_Sell = MA5_P1 < MA5_P2;
Cross5_Buy =Cross ( Ref( C, -1 ), MA5_P1 );
Cross5_Sell = Cross ( MA5_P1, Ref( C, -1 ) );
Buy = Cond_MA5_Buy AND Cross5_Buy ;
Sell = Cross5_Sell;
Short = Cond_MA5_Sell AND Cross5_Sell ;
Cover = Cond_MA5_Buy ;
Buy = ExRem( Buy, Short );
Short = ExRem( Short, Buy );
Cover = ExRem( Cover , Sell );
Sell = ExRem( Sell , Cover );
BuyPrice = CoverPrice = O;
ShortPrice = SellPrice = O;
以上的程式
再回測上不會有問題
但在實際SCAN上
由於是K棒結束後才去執行判斷是否進場
假設
當K棒結束後BUY的條件成立
以該K棒OPEN價格進場
由於K棒已經結束了
除非K棒CLOSE價格等於或小於OPEN價格
不然根本買不到
也就是即使SCAN時有條件成立
但實際上很可能無法成交
不知我的理解對不對?!
若真如此
以上面這段範例
應該如何修改才對
感謝您的回覆
謝謝
kilroy
發表於 14-6-15 21:37
skyler 發表於 14-6-15 19:36 static/image/common/back.gif
K大您好昨天在做MC的功課時
看到一句話"每根K棒結束都執行程式一次"
因此想請教一個關於回測的問題
在條件裡加上這行
barcomplete = BarIndex() < LastValue(BarIndex());
或是 buy=ref(...,-1);
skyler
發表於 14-6-15 21:59
所以
這段程式碼在回測是OK
但實際執行上會有問題
我的理解上是沒有錯的嗎?
kilroy
發表於 14-6-15 22:47
skyler 發表於 14-6-15 21:59 static/image/common/back.gif
所以
這段程式碼在回測是OK
但實際執行上會有問題
Hi,
這段 AFL 裡
回測沒問題
SCAN 模式下,會在當根K開始時判斷是否符合買賣條件
符合的話會送單出去了
---
順帶一提
用 scan 的方式
不能用 buy=flip(buy,sell); 這類的語法
參考看看了
skyler
發表於 14-6-15 22:52
本帖最後由 skyler 於 14-6-15 22:53 編輯
kilroy 發表於 14-6-15 22:47 static/image/common/back.gif
Hi,
這段 AFL 裡
所以會在當根K棒開始時判斷
這樣子的話
假設計算速度很快當BUY訊號成立時
那這段AFL下出去以OPEN價的多單
應該都會成立囉?
(PS:不管滑價問題)
所以這就跟MC 是在K棒結束後才判斷
是有所不同囉?
另外我不太懂這個
buy=flip(buy,sell);
的含意?
感謝指導~
kilroy
發表於 14-6-15 23:15
本帖最後由 kilroy 於 14-6-15 23:16 編輯
skyler 發表於 14-6-15 22:52 static/image/common/back.gif
所以會在當根K棒開始時判斷
這樣子的話
假設計算速度很快當BUY訊號成立時
Hi,
可以丟 open 價的 limit 單
但不能保證一定會成交,因為你的單子還得排隊
scan 的方式和 chart 的方式,當根K開盤符合條件後丟市價單,可以在兩點以內成交
可是像 HO(熱燃油) 之類的商品,掛單(ask/bid)較散的時候,成交的價位會與你回測的價位有較大的差距
---
SCAN 會依照原本回測的位置去丟單
ex. 回測 6/04 開盤丟單,那你 SCAN recent 1 bar 是在當天(6/4) 會有訊號
假設這個訊號是多單且持續 (open long) 到6/16
可是 6/16 並不會再出現一次多單的訊號
而 flip 會延續這個 open long 的訊號,並在 6/16 再次丟出多單 order
簡單來說 flip 會在當根K依照 open long/short 的部位再次送單
---
若使用在 chart 的方式,就不會有這個問題
詳細的使用可以參考一些範例
大概會用到的用途是類似
same bar entry/exit
但這類用法很容易有 bug 而且也不好抓
所以不建議使用 flip
參考看看了
greg
發表於 14-6-16 00:10
kilroy 發表於 14-6-1 22:49 static/image/common/back.gif
Hi,
1.
謝謝K 大, 過去兩個星期 我已經不斷嘗試了無數次, K大的語法都用上, 但都無法做到我希望的結果
請大大再幫忙, 看看我的語法要怎樣修改才可以:
1. 設定 "Sell" 只會出現在 "Buy" 成立了之後
2. 把 trailling stop 的語法寫進策略裡
假設以下是一個10分k 策略
AutoTradingParam = True; //ParamToggle("AutoTrading","Off|On",0);
SubmitOrders = True; //ParamToggle("Create or Transmit","Create Only|Create and Transmit",False);
Tracing = False;
BaseRiskPcnt = 1.00; // Percent of account risk per trade
AccountCutout = 75000;// Stop trading if account falls to $X
// Function to provide voice warning whenever any new trades are created
function SayNotTooOften( text, Minperiod )
{
elapsed=GetPerformanceCounter()/1000;
Lastelapsed = Nz( StaticVarGet("lastsaytime") );
if( elapsed - Lastelapsed > Minperiod )
{
StaticVarSet("lastsaytime", elapsed );
Say( text );
}
}
// Interactive Brokers ticker symbols may have unwanted characters for our static variable names. Remove them.
ABName = StrMid(Name(),0,3) + StrMid(Name(),4,3);
IBName = Name();
AutoTrading = StaticVarGet("AutoTrading"+ABName);
if( IsNull( AutoTrading ) )
StaticVarSet("AutoTrading"+ABName,0);
if ( AutoTrading==0 && AutoTradingParam )
{
// About to start AutoTrading after it's been off, so clear all order statuses.
StaticVarSetText("OrderID"+ABName,"");
StaticVarSetText("OrderIDLMT"+ABName,"");
StaticVarSetText("OrderIDSTP"+ABName,"");
StaticVarSetText("OrderStatus"+ABName,"");
StaticVarSetText("OrderLMTStatus"+ABName,"");
StaticVarSetText("OrderStatusSTP"+ABName,"");
}
if ( AutoTrading && AutoTradingParam==0 )
{
// About to stop AutoTrading after it's been on, so clear all order statuses.
StaticVarSetText("OrderID"+ABName,"");
StaticVarSetText("OrderIDLMT"+ABName,"");
StaticVarSetText("OrderIDSTP"+ABName,"");
StaticVarSetText("OrderStatus"+ABName,"");
StaticVarSetText("OrderLMTStatus"+ABName,"");
StaticVarSetText("OrderStatusSTP"+ABName,"");
}
if (AutoTradingParam)
StaticVarSet("AutoTrading"+ABName,1);
else
StaticVarSet("AutoTrading"+ABName,0);
AutoTrading = StaticVarGet("AutoTrading"+ABName);
Filename = _DEFAULT_NAME();
// Your trading conditions here////////////////////////////////////////////////
TimeFrameSet( 30 * in1Minute );
BuySignal1 = C < MA (C, 15);
TimeFrameRestore();
BuySignal = C> Ref(C,-1);
sellSignal = Ref(C,-1) >C;
TimeFrameRestore();
Buy = BuySignal & TimeFrameExpand(BuySignal1 , N*in1Minute) ;
Sell =sellSignal& TimeFrameExpand(BuySignal2 , N*in1Minute);
Short = Cover=0;
// Following variables for exits are mostly for backtesting. Not all are used in Autotrading.
ISLARC=3;// Initial Stop Loss multiplier x ATR. Set as appropriate for your trading rules.
ISL=ATR(20)*ISLARC;
TSLARC=ISLARC;// Trailing Stop Loss multiplier x ATR. Set as appropriate for your trading rules.
TSL=ATR(20)*TSLARC;
PSLARC=10000;// Take Profit multiplier x ATR. Set as appropriate for your trading rules.
PSL=ATR(20)*PSLARC;
nBars = 15;// Exit after n Bars. Set as appropriate for your trading rules.
ShortISLPrice=ShortPrice+Ref(ISL,-1);
ShortPSLPrice=ShortPrice-Ref(PSL,-1);
BuyISLPrice=BuyPrice-Ref(ISL,-1);
BuyPSLPrice=BuyPrice+Ref(ISL,-1);////////******************
// Set some variables for the right edge of the chart for the Auto-Trading code.
LastShortPrice=LastValue(ShortPrice);
LastBuyPrice=LastValue(BuyPrice);
LastShortISLPrice=LastValue(ShortISLPrice);
LastShortPSLPrice=LastValue(ShortPSLPrice);
LastBuyISLPrice=LastValue(BuyISLPrice);
LastBuyPSLPrice=LastValue(BuyPSLPrice);////////////////*******************;
LastATR=LastValue(Ref(ATR(20),-1));
/////////////////// Automation Code //////////////////
// First check if we've just started a new bar. THIS CODE RELIES ON PREFERENCES/INTRADAY SET TO START OF INTERVAL.
PrevDT = StaticVarGet("DateTime"+ABName);
DT = LastValue(DateTime());
NewBar = DT != PrevDT;
StaticVarSet("DateTime"+ABName,DT);
if( NewBar )
{
// Clear all status so we can place a new order on each bar. Later, the status variables are checked to ensure
// that we place no more than 1 order on each bar.
StaticVarSetText("OrderID"+ABName,"");
StaticVarSetText("OrderIDLMT"+ABName,"");
StaticVarSetText("OrderIDSTP"+ABName,"");
StaticVarSetText("OrderStatus"+ABName,"");
StaticVarSetText("OrderLMTStatus"+ABName,"");
StaticVarSetText("OrderStatusSTP"+ABName,"");
}
LastBuy = LastValue(Buy);
LastSell = LastValue(Sell);
LastShort = LastValue(Short);
Filter=Buy OR Sell;
IBPosSize=0;
ibc = GetTradingInterface("IB");
IBcStatus = ibc.IsConnected();
IBcStatusString = WriteIf(IBCStatus==0,"TWS Not Found",
WriteIf(IBCStatus==1,"Connecting to TWS",
WriteIf(IBCStatus==2,"TWS OK",
WriteIf(IBCStatus==3,"TWS OK (msgs)",""))));
// Work out how much money there is and adjust risk size
CashBalanceStr = ibc.GetAccountValue("NetLiquidationByCurrency");
if (CashBalanceStr == "")
CashBalance = 0;
else
CashBalance = StrToNum(CashBalanceStr);
// Note CashBalance is in AUD for my account, so following calculations are all in AUD.
// If trading instruments denominated in multiple currencies, e.g. FX, you will need to adjust this code.
// It is possible to dynamically lookup the IB FX price
// but too extensive for me to include the code here
PositionRisk = BaseRiskPcnt/100*CashBalance;
PositionSize = PositionRisk / Ref(ISL,-1);
IBOrderSize = int(LastValue(PositionSize)/10000)*10000;// Round to nearest $10k - designed for FX ************
OldOrderID = StaticVarGetText("OrderID"+ABName);
if (AutoTrading == 0 && OldORderID == "" && (LastBuy || LastSell))
{
// If there would have been an order during Autotrading, then create a dummy OID to test all other code paths
// e.g. logging, explore output etc.
StaticVarSetText("OrderID"+ABName,"DUMMY");
}
if( IBcStatus AND AutoTrading AND (CashBalance > AccountCutout))
{
OrderID = StaticVarGetText("OrderID"+ABName);
OrderIDLMT = StaticVarGetText("OrderIDLMT"+ABName);
OrderIDSTP = StaticVarGetText("OrderIDSTP"+ABName);
IBPosSize = ibc.GetPositionSize( IBName );
// Only enter once the price moves in my desired direction, otherwise wait until next run of the exploration
// and check again, and again., ...
if( LastBuy AND OrderID == "" )
{
OID = ibc.PlaceOrder( IBName, "Buy", 1, "MKT", 0, TickSize,
"DAY", submitorders, TickSize/0.0001, "outsideRTH" );
// _TRACE("# Pos: 0, PrevOID: "+OrderID+", Buy 1, NewOID: "+OID);
for (dummy=0; dummy<40; dummy++)
ibc.Sleep(50);//Usually takes up to about a second for TWS to get acknowledgement from IB
StaticVarSetText("OrderID"+ABName,OID);
SayNotTooOften("There is an order to be checked",30);
if (SubmitOrders)
{
for (dummy=0; dummy<40; dummy++)
ibc.Sleep(50);//Usually takes up to about a second for TWS to get acknowledgement from IB
// Wait until order actually PreSubmitted - this will prevent submitting another order too quickly
// hopefully stops TWS/IB getting in a knot
tradetime=GetPerformanceCounter()/1000;
while ((GetPerformanceCounter()/1000 - tradetime) < 5) // give up after 5 seconds
{
ibc.Reconnect();//Refreshes ibc, and gets accurate status
ORderStatus = ibc.GetStatus( OID, True);
if (ORderStatus == "PreSubmitted" || ORderStatus == "Submitted" || ORderStatus == "Filled")
break;
}
}
}
else if( LastSell AND OrderID == "" )
{
OID = ibc.PlaceOrder( IBName, "Sell", 1, "MKT", 0, TickSize,
"DAY", SubmitOrders, TickSize/0.0001, "outsideRTH" );
for (dummy=0; dummy<40; dummy++)
ibc.Sleep(50);//Usually takes up to about a second for TWS to get acknowledgement from IB
StaticVarSetText("OrderID"+ABName,OID);
SayNotTooOften("There is an order to be checked",30);
if (SubmitOrders)
{
for (dummy=0; dummy<40; dummy++)
ibc.Sleep(50);//Usually takes up to about a second for TWS to get acknowledgement from IB
// Wait until order actually PreSubmitted - this will prevent submitting another order too quickly
// hopefully stops TWS/IB getting in a knot
tradetime=GetPerformanceCounter()/1000;
while ((GetPerformanceCounter()/1000 - tradetime) < 5) // give up after 5 seconds
{
ibc.Reconnect();//Refreshes ibc, and gets accurate status
ORderStatus = ibc.GetStatus( OID, True);
if (ORderStatus == "PreSubmitted" || ORderStatus == "Submitted" || ORderStatus == "Filled")
break;
}
}
}
// Only enter once the price moves in my desired direction, otherwise wait until next run of the exploration
// and check again, and again., ...
else if( LastShort AND OrderID == "" AND (LastValue(C) >= (LastShortPrice)))
{
OID = ibc.PlaceOrder( IBName, "Sell", IBOrderSize, "TRAIL", 0, TickSize,
"DAY", False, TickSize/0.0001, "outsideRTH" );
// _TRACE("# Pos: 0, PrevOID: "+OrderID+", Sell 1, NewOID: "+OID);
OIDLMT = ibc.PlaceOrder( IBName, "Buy", IBOrderSize, "LMT", LastShortPSLPrice, 0,
"GTC", False, TickSize/0.0001, "outsideRTH", OID);
OIDSTP = ibc.PlaceOrder( IBName, "Buy", IBOrderSize, "STP", 0, LastShortISLPrice,
"GTC", SubmitOrders, TickSize/0.0001, "outsideRTH", OID);
for (dummy=0; dummy<40; dummy++)
ibc.Sleep(50);//Usually takes up to about a second for TWS to get acknowledgement from IB
StaticVarSetText("OrderID"+ABName,OID);
StaticVarSetText("OrderIDLMT"+ABName,OIDLMT);
StaticVarSetText("OrderIDSTP"+ABName,OIDSTP);
SayNotTooOften("There is an order to be checked",30);
if (SubmitOrders)
{
//Usually takes about a second for TWS to get acknowledgement from IB, so delay for 2 secs for safety
for (dummy=0; dummy<40; dummy++)
ibc.Sleep(50);
// Wait until order actually PreSubmitted - this will prevent submitting another order too quickly
// hopefully stops TWS/IB getting in a knot
tradetime=GetPerformanceCounter()/1000;
while ((GetPerformanceCounter()/1000 - tradetime) < 5) // give up after 5 seconds
{
ibc.Reconnect();//Refreshes ibc, and gets accurate status
ORderStatus = ibc.GetStatus( OID, True);
if (ORderStatus == "PreSubmitted" || ORderStatus == "Submitted" || ORderStatus == "Filled")
break;
}
}
}
// Note LastOrderID will remain "" while waiting for price improvement so we may skip entering for the whole of the bar
LastOrderID = StaticVarGetText("OrderID"+ABName);
LastOrderIDLMT = StaticVarGetText("OrderIDLMT"+ABName);
LastOrderIDSTP = StaticVarGetText("OrderIDSTP"+ABName);
ORderStatus = ibc.GetStatus( LastOrderID , True );
if( ORderStatus != "" ) StaticVarSetText("OrderStatus"+ABName,ORderStatus);
ORderLMTStatus = ibc.GetStatus( LastOrderIDLMT , True );
if( ORderLMTStatus != "" ) StaticVarSetText("OrderLMTStatus"+ABName,ORderLMTStatus);
ORderSTPStatus = ibc.GetStatus( LastOrderIDSTP , True );
if( ORderSTPStatus != "" ) StaticVarSetText("OrderStatusSTP"+ABName,ORderSTPStatus);
}
else IBPosSize = 0;
LastOrderID = StaticVarGetText("OrderID"+ABName);
ORderStatus = StaticVarGetText("OrderStatus"+ABName);
LastOrderIDLMT = StaticVarGetText("OrderIDLMT"+ABName);
ORderLMTStatus = StaticVarGetText("OrderLMTStatus"+ABName);
LastOrderIDSTP = StaticVarGetText("OrderIDSTP"+ABName);
ORderSTPStatus = StaticVarGetText("OrderSTPStatus"+ABName);
skyler
發表於 14-6-16 08:37
kilroy 發表於 14-6-15 23:15 static/image/common/back.gif
Hi,
可以丟 open 價的 limit 單
OK~
了解了!
感謝您熱心的回答
謝謝~
skyler
發表於 14-6-17 14:26
本帖最後由 skyler 於 14-6-17 14:27 編輯
k大
請問一下您這段話
這是您用 AutoIt 自己做的嗎?!
--------------------------
另外自己遇到
同樣的資料
例如您提供的 6A #F
分別匯入至AB 與 MC 中
但AB與MC所計算出的指標數值不同
而影響策略的進出場
又以群益MC去查群益所提供的 AD1 澳幣連續月報價
結果資料上又與 6A #F 有所差異
使得指標計算出的結果不同
而影響進出場
結果就是
AB 吃 6A #F 資料 回策績效成功
MC 吃 6A #F 資料 回策績效 失敗
群益MC 吃群益AD1資料 回策績效 失敗
而自己的策略在AB上
以您之前在另一篇文所提供的資料
加上在這串討論文中跟您索取的4種商品
共16種商品
結果都是呈現正向的結果
搞的自己心煩意亂
想詢問一下您的見解
kilroy
發表於 14-6-17 14:35
greg 發表於 14-6-16 00:10 static/image/common/back.gif
謝謝K 大, 過去兩個星期 我已經不斷嘗試了無數次, K大的語法都用上, 但都無法做到我希望的結果
請大大再 ...
Hi,
我有空會寫一個範例,可以自設停損(包含IB TWS 送單)
kilroy
發表於 14-6-17 14:45
skyler 發表於 14-6-17 14:26 static/image/common/back.gif
k大
請問一下您這段話
這是您用 AutoIt 自己做的嗎?!
Hi,
圖示裡,是 AB 作者提供的 IB Controller 對應 IB TWS
可以取得 IB TWS 的一些資訊,如 帳戶權益、目前持單部位、送單結果等
請參閱 http://www.amibroker.com/at/
或許國內券商 API 也有提供函數可以取得資訊,但那要自己寫程式
AB 作者提供這個下單介面(還開放原始碼),真的是解決一個大關卡
---
群益提供的歷史資料我有測過
但不知道他是電子盤還是人工、還是人工+電子
所以還是比較建議你直接使用 eSignal 的資料即可
會比較有差別的地方是換月 (rollover)
我是將 eSignal 報價直接與 IB 報價比對的,請安心使用
參考看看了
skyler
發表於 14-6-17 15:05
本帖最後由 skyler 於 14-6-17 15:12 編輯
kilroy 發表於 14-6-17 14:45 http://www.coco-in.net/static/image/common/back.gif
Hi,
圖示裡,是 AB 作者提供的 IB Controller 對應 IB TWS
謝謝 k大您的回覆與幫忙
目前已經打算走
eSignal + AB + IB 的路了
雖然沒有那麼多資金能操盤
因此打算先匯10000 USD 開了IB戶頭後
再出金部份回來
算了一下
以券商的MC 每個月最少要1000
再加上 一口來回的手續費 6.5 X2 = 13 USD
比起 IB來回約為 5 USD 中間差了 8USD
一個月來回平均 50口 中間差的錢足夠接eSignal還有找了
為什麼您沒有單純想說
直接接IB的報價
而又要另外申請eSignal 呢?
-----------------------------
另外您上線前有用IB模擬帳戶測試過嗎?!
kilroy
發表於 14-6-17 15:18
本帖最後由 kilroy 於 14-6-17 15:25 編輯
skyler 發表於 14-6-17 15:05 static/image/common/back.gif
謝謝 k大您的回覆與幫忙
目前已經打算走
eSignal + AB + IB 的路了
Hi,
申請 eSignal 可以到這個網站
http://chinafinpipe.com/
會比美國 eSignal 便宜一些,且可以接台灣期貨報價
申請很簡單,加會員開通就可以了
每個月自動從信用卡扣款,或是一次買一年
下 CME Group 的商品,只需訂閱
1. eSignal Premier
2. Extended Intraday History
3. CME Group Fee-Waived Globex Data
這樣一個月是 $155 / 上面那個網站可以到 $138
---
IB TWS 本身的報價 (market data) 我覺得不夠穩,有時還會斷線(但不影響 placing order)
為求報價穩定,就訂閱 eSignal 了
---
IB 的 paper account 非常讚
幾乎與真實帳戶一樣,也是測試你 AB 下單到 IB TWS 非常好的平台
在 paper account 測試好自動下單,無誤就可以安心下到 real account 了
參考看看
skyler
發表於 14-6-17 16:06
kilroy 發表於 14-6-17 15:18 static/image/common/back.gif
Hi,
申請 eSignal 可以到這個網站
k大請問一下
我沒記錯的話 YM ZC ZS ZW 這四種
是在CBOT吧
那我要加訂那一項?
感謝~