加了(not (Filled < Filled[1]))//不允許有庫存時賣出後又立即訊號買進
為何庫存賣出後又觸發買入?
if position >=0
and condition1
and (not (Filled < Filled[1]))//不允許有庫存時賣出後又立即訊號買進
then SetPosition(1,close);
Filled < Filled[1] 是否改為Position < Position[1] 就可避免?
加了(not (Filled < Filled[1]))//不允許有庫存時賣出後又立即訊號買進
為何庫存賣出後又觸發買入?
if position >=0
and condition1
and (not (Filled < Filled[1]))//不允許有庫存時賣出後又立即訊號買進
then SetPosition(1,close);
Filled < Filled[1] 是否改為Position < Position[1] 就可避免?
我是用日K頻率逐筆洗價,,Position 不是應該隨逐筆而變化?
GPT:
var LastSellTick = 0;
if position < position[1] then LastSellTick = CurrentTick; // 記錄賣出時刻
if position >= 0
and condition1
and CurrentTick > LastSellTick + 2 // 至少等 2 個 Tick 才允許買回
then SetPosition(1, close);
✅ 如果 position[1] 是逐筆更新,那 position < position[1] 應該可以即時反映減碼,但仍可能因 Tick 內快速變化而導致「剛賣就買」。
✅ 如果 position[1] 來自 K 棒級別,就需要用 LastPos 或 Delay 機制來防止誤判。
✅ 可以增加 Filled 或 Delay 條件,確保減碼後不會立即買回,防止洗價影響策略執行。
你可以先測試方法 1,如果還是出現問題,再試方法 2 或 3 🚀
建議期待XQ, 整理出XS編寫問題的處理對策資料, 方便用戶查詢除錯的參考。
以下程式碼該如何修正? 是否有其他錯誤或疏忽之處?
程式交易的設計需求是
1. 設定實際庫存量允許的最大值
2. 商品最大部位不超過所設定的實際庫存量下交易
3. 依觸發訊號一張一張買進(最好能指定加碼次數),但不允許賣出後的商品又立即買進 (設計由第6個需求來執行)
4. 若庫存股有獲利如3%,則一張一張賣出(最好能指定減碼次數)
5.若是今日才買入的而有獲利,但該商品已有庫存時,只沖銷今日買的這張價位
6.若庫存股獲利後賣出,有回跌如2%則當沖買回
//訊號觸發買進
var: IntraBarPersist B1Pod(False); //尚未委買
if position <= position[1] then B1Pod=False;
if FilledAtBroker <=2 //控制各策略合計庫存總數量
and B1Pod=False //尚未委買
and position >=0 //目前部位 >=0
and Condition1 //觸發條件
and (not (Position < Position[1]))//不允許賣出後又立即訊號買進
then
begin
SetPosition(minlist(position+1,2),MinList2(value2,value3,GEtField("收盤價", "Tick")),label:="訊號觸發買進");
B1p=MinList2(value2,value3,GEtField("收盤價", "Tick")); //觸發取次低價格
B1Pod=true; //已經委買
BIT=Getfield("時間","Tick"); //觸發的時間
alert("B1P觸發",NumToStr(B1P,1),"Position",NumToStr(Position,1),"Position[1]",NumToStr(Position[1],1),"Filled",NumToStr(Filled,1),
"Filled[1]",NumToStr(Filled[1],1));
end;
//獲利後賣出------------------------------------------------------------------------------------------
var:
intraBarPersist ord1(False), //下單狀態切換確認 未下賣單
intraBarPersist Sod1(B1p*1.03); //預計賣出的價格 為避免抓錯資料改初始B1p測試
if Position >= Filled then ord1=False; //目標部位 >= 實際部位
if B1P <>0 then Sod1= B1P*1.03;
//庫平均 未新買入時舊庫存獲利會出場,未出場前若有新買入成本平均會異動
if Position > 0 and Filled > 0 //目前有庫存
and ord1=False //尚未下單
and GetField("收盤價", "Tick") > FilledAvgPrice*B1A //賣帳號內均價
then
begin
Setposition(maxList(Position-1,0),market,label:="庫獲利後賣出");
{if Filled < Filled[1] then} Sod1=GetField("收盤價", "Tick");//紀錄賣出的價位
{if Filled < Filled[1] then } ord1=True; //已下單賣出
alert("庫獲利觸發",NumToStr(Sod1,1),"Position",NumToStr(Position,1),"Position[1]",NumToStr(Position[1],1),"Filled",NumToStr(Filled,1),
"Filled[1]",NumToStr(Filled[1],1));
end;
//今日買沖(賣) 避免上未出場前若有新買入成本平均會異動,只針對新買入的價格做獲利出場
if Filled > 1 and Filled > Filled[1] //有庫存時有再買進
and ord1=False //尚未下賣單
and B1P > 10
and GetField("收盤價", "Tick") > B1P*B1A //賣今日買的
//B1p似乎會抓錯資料暫不執行
then
begin
Setposition(maxList(Position-1,0),market,label:="再買獲利後賣出");
Sod1=GetField("收盤價", "Tick");//紀錄賣出價位
alert("再買獲利觸發",NumToStr(Sod1,1),"Position",NumToStr(Position,1),"Position[1]",NumToStr(Position[1],1),"Filled",NumToStr(Filled,1),
"Filled[1]",NumToStr(Filled[1],1));
if Filled < Filled[1] then ord1=True; //已下單賣出
end;
//"賣出後當沖買回" 因有兩種賣出情況 以下買回可能會有狀況-------------------------------------------------------------
var: intraBarPersist Brd1(False); //未下單買回 狀態切換
if Filled >=0 and Filled < Filled[1] then Brd1=False;
if ord1=True //已獲利下單
and Brd1=False //未下單買回
and Sod1 > 10 and GetField("收盤價", "Tick") < Sod1*0.98 //價格回檔低於賣出價
and condition1 //須仍有支撐及上漲空間才買回
then
begin
Print("賣沖F","日期",currentDate,"FIlled",NumToStr(FIlled,1),"B1P",NumToStr(B1P,1),
"Sod1",NumToStr(Sod1,1),"Brd1",Brd1);
setposition(Position+1,market,label:="賣出後當沖買回");
alert("賣出後當沖獲利觸發",NumToStr(GetField("收盤價", "Tick"),1),"Position",NumToStr(Position,1),"Position[1]",NumToStr(Position[1],1),"Filled",NumToStr(Filled,1),
"Filled[1]",NumToStr(Filled[1],1));
if Position > Position[1]
then
begin
Brd1=True; //已下單買回
Print("賣沖","日期",currentDate,"FIlled",NumToStr(FIlled,1),"B1P",NumToStr(B1P,1),
"Sod1",NumToStr(Sod1,1),"Brd1",Brd1);
end;
End;
//position恢復原來部位時的判斷
// 狀態重置
if currentTime >= 090000 and currentTime <=140000 and Position = position[1]
then
begin
ord1 = False;
Brd1 = False;
// 重置賣出與買回標記
end;
若 如先指定value55= -1
若觸發賣出後紀錄
value55= GetField("SeqNo", "Tick");
再將and (not (Filled < Filled[1]))//不允許有庫存時賣出後又立即訊號買進
這一段改為
and value55 = -1 //不允許有庫存時賣出後又立即訊號買進
5 評論