相關標簽:
?
? 發布一個Python網格交易策略
?
?
?
#老聽說金字塔支持Python了,而且很牛X,一直想了解一下,就邊學邊玩,寫了一個網格交易的策略,經過驗證,還不錯,
#金字塔的Python版用于算法交易還是可以,從交易下單,到成交過程訂單狀態的回報,都很準確。
#相對于VBA使用對象的方式來調用,Python更直觀,簡潔。
#
#需要增強的地方(可能我還沒學會):
#1、希望增加對INI文件讀寫的功能,我使用import ConfigParser不支持
#2、希望增加對界面方面的支持,Python有支持圖形的庫
#--------------------------------------------------------------
?
# 本Python代碼主要用于策略交易
# 可以自己import我們平臺支持的第三方python模塊,比如pandas、numpy等。
from PythonApi import *
import time
from decimal import Decimal
?
#? 參數定義區,這里定義的參數可以直接在context對象中獲取。--(選擇實現)
def parameter():
? ? settimer(GridTrade,200000)? ? ? ? #200秒執行一次? ? ? ??
? ? input_par("lastbuy",0,0,9,1)? ? #末次買入開倉單號
? ? input_par("lastsell",0,0,9,1)? ? #末次賣出開倉單號
? ? input_par("lastbuyping",0,0,9,1)? ? #末次平多單單號
? ? input_par("lastsellping",0,0,9,1)? ? #末次平空單單號
? ? input_par("jiange",2,0,5,1)? ? #間隔
? ? input_par("vol",1,0,9,1)? ? #每檔手數
? ? input_par("firstvol",1,0,9,1)? ? #初始手數
? ? input_par("fx",1,1,2,1)? ? #交易方向 1-多 2-空
? ? input_par("maxvol",1,0,9,1)? ? #最大手數
?
#? 在這個方法中編寫任何的初始化邏輯。context對象將會在你的算法策略的任何方法之間做傳遞。--(必須實現)
?
def init(context):
? ? settimer(GridTrade,10000)? ? ? ? #10秒執行一次
? ? # 在context中保存全局變量
? ? context.s1 = "SQFU00"? ?#交易代碼
? ? #settimer(GridTrade,20000)? ? ? ? #2秒執行一次
? ? #引用PEL指標公式"my_test"的ma5日均線指標值。PEL指標必須提前存在或者構建。
? ? context.price = int( history_bars(context.s1,1,\'1m\',\'open\') )? ? ? ? ? ?
? ? context.priceO = int( history_bars(context.s1,1,\'1m\',\'open\') )? ? ? ? ? ?
? ? context.priceH = int( history_bars(context.s1,1,\'1m\',\'high\') )
? ? context.priceL = int( history_bars(context.s1,1,\'1m\',\'low\') )
? ? context.priceC = int( history_bars(context.s1,1,\'1m\',\'close\') )? ??
?
? ? print("T0 D+K/策略啟動/"+context.s1+\'/參考價=\'+str(context.price)+\'/價O=\'+str(context.priceO)+\'/價H=\'+str(context.priceH)+\'/價L=\'+str(context.priceL)+\'/價C=\'+str(context.priceC))
? ? log_debug_info(\'C:\\T0DK.txt\',"T0 D+K/策略啟動/"+context.s1+\'/參考價=\'+str(context.price)+\'/價O=\'+str(context.priceO)+\'/價H=\'+str(context.priceH)+\'/價L=\'+str(context.priceL)+\'/價C=\'+str(context.priceC))
? ? ? ??
def setorderid(context):
? ? settimer(GridTrade,20000)? ? ? ? #20秒執行一次? ??
? ? #檢查未成交訂單,將單號賦值給全局變量,避免啟動策略時變量的值為0
? ? #print("獲取未成交訂單編號")
? ? log_debug_info(\'C:\\T0DK.txt\',"獲取未成交訂單編號")
? ??
? ? Orders=get_orders(context.s1,0)? ? #取未成交單
? ? context.lastbuy=0
? ? context.lastbuyping=0
? ? context.lastsell=0
? ? context.lastsellping=0
? ? if not(Orders == None):
? ? ? ? for order in Orders:
? ? ? ? ? ? orderID=order.order_id? ? #委托單號
? ? ? ? ? ? sBuySell=order.side? ? ? ? ? ? ? ? #買賣
? ? ? ? ? ? sKp=order.position_effect? ? ? ? #開平
? ? ? ? ? ? sStatus=order.status? ? ? ? ? ? ?#狀態
? ? ? ? ? ??
? ? ? ? ? ? #print(str(orderID)+\',\'+sBuySell+\',\'+sKp+\',\'+sStatus)
? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',str(orderID)+\',\'+sBuySell+\',\'+sKp+\',\'+sStatus)? ?
? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? if context.lastbuy==0 and sBuySell=="buy" and sKp=="open" and sStatus=="submitted":
? ? ? ? ? ? ? ? context.lastbuy=order.order_id? ? #單號
? ? ? ? ? ? if context.lastsell==0 and sBuySell=="sell" and sKp=="open" and sStatus=="submitted":
? ? ? ? ? ? ? ? context.lastsell=order.order_id? ? #單號
? ? ? ? ? ? if context.lastbuyping==0 and sBuySell=="sell" and sKp=="close" and sStatus=="submitted":
? ? ? ? ? ? ? ? context.lastbuyping=order.order_id? ? #單號
? ? ? ? ? ? if context.lastsellping==0 and sBuySell=="buy" and sKp=="close" and sStatus=="submitted":
? ? ? ? ? ? ? ? context.lastsellping=order.order_id? ? #單號
? ? ? ? ? ??
? ? ? ? #print(\'開多:\'+str(context.lastbuy)+\',平多:\'+str(context.lastbuyping)+\',開空:\'+str(context.lastsell)+\',平空:\'+str(context.lastsellping))
? ? ? ? log_debug_info(\'C:\\T0DK.txt\',\'開多:\'+str(context.lastbuy)+\',平多:\'+str(context.lastbuyping)+\',開空:\'+str(context.lastsell)+\',平空:\'+str(context.lastsellping))
?
#網格交易主程序? ? ?
def GridTrade(context):
? ? settimer(GridTrade,60000)? ? ? ? #60秒執行一次? ? ? ??
? ? nAmount0=get_account(53)? ? #帳戶有效檢查
? ? if nAmount0==False:
? ? ? ??
? ? ? ? #print(\'賬戶=\'+str(nAmount0)+\'登陸推出了,退出交易。\')
? ? ? ? log_debug_info(\'C:\\T0DK.txt\',\'賬戶\'+str(nAmount0)+\'登陸推出了,退出交易。\')
? ? ? ? return
? ? ? ??
? ? if istradertime(context.s1)==False:? ? #不在交易時間,不進入交易段
? ? ? ??
? ? ? ? #print("不在交易時間,不進入交易段")
? ? ? ? log_debug_info(\'C:\\T0DK.txt\',"不在交易時間,不進入交易段")
? ? ? ? return
? ??
? ? setorderid(context)? ? ? ? ? ?#獲取未成交訂單號,保存到全局變量
? ??
? ? nAmount=get_account(19)? ? #可用資金
? ? if nAmount<=0:
? ? ? ? print(\'賬戶可用資金\'+str(nAmount)+\'低于0了/登陸推出了,退出交易。\')
? ? ? ? log_debug_info(\'C:\\T0DK.txt\',\'賬戶可用資金低于0了,退出交易。\')
? ? ? ? return
? ? ? ? ? ??
? ? portfolio=get_portfolio(context.s1,0)? ? #獲取持倉量
? ? if context.fx==1:
? ? ? ? iDuoTotal=portfolio.buy_quantity
? ? ? ? DTnCurOrdPrice = round(context.priceH - ((iDuoTotal -context.firstvol) * context.jiange) / context.vol, 1)
?
? ? if context.fx==1:
? ? ? ? iKongTotal=portfolio.sell_quantity
? ? ? ? KTnCurOrdPrice = round(context.priceL - ((context.firstvol - iKongTotal) * context.jiange) / context.vol, 1)
? ? ? ??
? ? #print(\'檔位價:\'+str(nCurOrdPrice)+\',開多:\'+str(context.lastbuy)+\',平多:\'+str(context.lastbuyping)+\',開空:\'+str(context.lastsell)+\',平空:\'+str(context.lastsellping))
? ? log_debug_info(\'C:\\T0DK.txt\',\'空檔位價:\'+str(KTnCurOrdPrice)+\'多檔位價:\'+str(DTnCurOrdPrice)+\',開多:\'+str(context.lastbuy)+\',平多:\'+str(context.lastbuyping)+\',開空:\'+str(context.lastsell)+\',平空:\'+str(context.lastsellping))? ? ? ? ? ??
?
? ? nPrice = get_dynainf (context.s1,7)? ? #獲取最新價
? ? if context.fx==1:? ? #做多
? ? ? ? if (context.lastbuy==0 and iDuoTotal<context.maxvol):
? ? ? ? ? ? DTnOrdPrice=DTnCurOrdPrice-context.jiange
? ? ? ? ? ? context.lastbuy=buy_open(context.s1,"Limit",DTnOrdPrice,context.vol)
? ? ? ? ? ? #print(\'檔位價:\'+str(nCurOrdPrice)+\',委托價:\'+str(nOrdPrice)+\',開多\')
? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',\'檔位價:\'+str(DTnCurOrdPrice)+\',委托價:\'+str(DTnOrdPrice)+\',開多\')
? ? ? ? ? ??
? ? ? ? if (context.lastbuyping==0 and iDuoTotal>0):
? ? ? ? ? ? DTnOrdPrice=DTnCurOrdPrice+context.jiange
? ? ? ? ? ? context.lastbuyping=sell_close(context.s1,"Limit",DTnOrdPrice,context.vol)
? ? ? ? ? ? #print(\'檔位價:\'+str(nCurOrdPrice)+\',委托價:\'+str(nOrdPrice)+\',平多\')
? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',\'檔位價:\'+str(DTnCurOrdPrice)+\',委托價:\'+str(DTnOrdPrice)+\',平多\')
? ? ? ? ? ??
? ? if context.fx==1: #and iKongTotal<context.maxvol:? ? #做空
? ? ? ? if (context.lastsell==0 and iKongTotal<context.maxvol):
? ? ? ? ? ? KTnOrdPrice=KTnCurOrdPrice+context.jiange
? ? ? ? ? ? context.lastsell=sell_open(context.s1,"Limit",KTnOrdPrice,context.vol)
? ? ? ? ? ? #print(\'檔位價:\'+str(nCurOrdPrice)+\',委托價:\'+str(nOrdPrice)+\',開空\')
? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',\'檔位價:\'+str(KTnCurOrdPrice)+\',委托價:\'+str(KTnOrdPrice)+\',開空\')
? ? ? ? ? ??
? ? ? ? if (context.lastsellping==0 and iKongTotal>0):
? ? ? ? ? ? KTnOrdPrice=KTnCurOrdPrice-context.jiange
? ? ? ? ? ? context.lastsellping=buy_close(context.s1,"Limit",KTnOrdPrice,context.vol)
? ? ? ? ? ? #print(\'檔位價:\'+str(nCurOrdPrice)+\',委托價:\'+str(nOrdPrice)+\',平空\')
? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',\'檔位價:\'+str(KTnCurOrdPrice)+\',委托價:\'+str(KTnOrdPrice)+\',平空\')
? ? ? ? ? ??
# before_trading此函數會在每天基準合約的策略交易開始前被調用,當天只會被調用一次。--(選擇實現)
def before_trading(context):
? ? pass
?
?
# 你選擇的品種的數據更新將會觸發此段邏輯,例如日或分鐘歷史數據切片或者是實時數據切片更新。--(必須實現)
def handle_bar(context):
? ? # 開始編寫你的主要的算法邏輯。
? ? pass
? ??
? ??
# after_trading函數會在每天交易結束后被調用,當天只會被調用一次。 --(選擇實現)
def after_trading(context):
? ? pass?
? ??
# order_status當委托下單,成交,撤單等與下單有關的動作時,該方法就會被調用。---(選擇實現)
def order_status(context,order):
? ? #print(\'訂單成交\')
? ? log_debug_info(\'C:\\T0DK.txt\',\'訂單成交\')
? ? #print(order.order_book_id)
? ? log_debug_info(\'C:\\T0DK.txt\',order.order_book_id)
? ? #print(str(order.order_id)+\',\'+order.status+\',\'+order.order_book_id)
? ? log_debug_info(\'C:\\T0DK.txt\',str(order.order_id)+\',\'+order.status+\',\'+order.order_book_id)
? ? #print(\'開多:\'+str(context.lastbuy)+\',平多:\'+str(context.lastbuyping)+\',開空:\'+str(context.lastsell)+\',平空:\'+str(context.lastsellping))
? ? log_debug_info(\'C:\\T0DK.txt\',\'開多:\'+str(context.lastbuy)+\',平多:\'+str(context.lastbuyping)+\',開空:\'+str(context.lastsell)+\',平空:\'+str(context.lastsellping))
? ? #如果是成交,將對應的委托單撤銷
? ? log_debug_info(\'C:\\T0DK.txt\',"如果是成交,將對應的委托單撤銷")
? ??
? ? if (order.status=="tradeing" and order.order_book_id==context.s1):
? ? ? ? #print(str(order.order_id)+\'全部成交\')
? ? ? ? log_debug_info(\'C:\\T0DK.txt\',str(order.order_id)+\'全部成交\')
? ? ? ??
? ? ? ? if order.order_id==context.lastbuy:? ? ? ? #買入成交
? ? ? ? ? ? if context.lastbuyping!=0:
? ? ? ? ? ? ? ? cancel_order (context.lastbuyping)
? ? ? ? ? ? ? ? #print("買入成交之后撤平倉單,"+str(context.lastbuyping))
? ? ? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',"買入成交之后撤平倉單,"+str(context.lastbuyping))
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? context.lastbuyping=0
? ? ? ? if order.order_id==context.lastbuyping:? ? #平多成交
? ? ? ? ? ? if context.lastbuy!=0:
? ? ? ? ? ? ? ? cancel_order (context.lastbuy)
? ? ? ? ? ? ? ? #print("平多成交之后撤開倉單,"+str(context.lastbuy))
? ? ? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',"平多成交之后撤開倉單,"+str(context.lastbuy))
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? context.lastbuy=0
? ? ? ? if order.order_id==context.lastsell:? ? ? ? #賣出成交
? ? ? ? ? ? if context.lastsellping!=0:
? ? ? ? ? ? ? ? cancel_order (context.lastsellping)
? ? ? ? ? ? ? ? #print("賣出成交之后撤平倉單,"+str(context.lastsellping))
? ? ? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',"賣出成交之后撤平倉單,"+str(context.lastsellping))
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? context.lastsellping=0
? ? ? ? ? ? ? ??
? ? ? ? if order.order_id==context.lastsellping:? ? #平空成交
? ? ? ? ? ? if context.lastsell!=0:
? ? ? ? ? ? ? ? cancel_order (context.lastsell)
? ? ? ? ? ? ? ? #print("平空成交之后撤開倉單,"+str(context.lastsell))
? ? ? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',"平空成交之后撤開倉單,"+str(context.lastsell))
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? context.lastsell=0
? ??
? ? #如果是撤單,將對應的變量設置為0?
? ? log_debug_info(\'C:\\T0DK.txt\',"如果是撤單,將對應的變量設置為0 ")? ? ? ? ? ? ? ?
?
? ? if (order.status=="cancelled" and order.order_book_id==context.s1):
? ? ? ? if order.order_id==context.lastbuy:? ? ? ? #買入撤單
? ? ? ? ? ? #print("買入開倉撤單,"+str(context.lastbuy))
? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',"買入開倉撤單,"+str(context.lastbuy))
? ? ? ? ? ??
? ? ? ? ? ? context.lastbuy=0
? ? ? ? if order.order_id==context.lastbuyping:? ? #平多撤單
? ? ? ? ? ? #print("平多單撤單,"+str(context.lastbuyping))
? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',"平多單撤單,"+str(context.lastbuyping))
? ? ? ? ? ??
? ? ? ? ? ? context.lastbuyping=0
? ? ? ? if order.order_id==context.lastsell:? ? ? ?#賣出撤單
? ? ? ? ? ? #print("賣出開倉撤單,"+str(context.lastsell))
? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',"賣出開倉撤單,"+str(context.lastsell))
? ? ? ? ? ??
? ? ? ? ? ? context.lastsell=0
? ? ? ? if order.order_id==context.lastsellping:? ?#平空撤單
? ? ? ? ? ? #print("平空單撤單,"+str(context.lastsellping))
? ? ? ? ? ? log_debug_info(\'C:\\T0DK.txt\',"平空單撤單,"+str(context.lastsellping))
? ? ? ? ? ??
? ? ? ? ? ? context.lastsellping=0
?
# order_action當查詢交易接口信息時返回的通知---(選擇實現)
#注意:該事件函數僅在融資融券、新股申購操作刷新動作時才會觸發,一般賬戶無效。
#def order_action(context):
? ??
? ? #pass
?
# exit函數會在測評結束或者停止策略運行時會被調用。---(選擇實現)
def exit(context):
? ??
? ? #獲得品種的浮動盈虧,(多空同時存在時,為多空浮動盈虧之和)
? ? zhan_bzj = get_account(28)
? ? #print(\'占用保證金總額\'+str(zhan_bzj))
? ? log_debug_info(\'C:\\T0DK.txt\', \'占用保證金總額\'+str(zhan_bzj))
? ??
? ? #獲得帳戶平倉盈虧
? ? pingcang_win_long = get_account(30)
? ? #print(\'帳戶平倉盈虧\'+str(pingcang_win_long))
? ? log_debug_info(\'C:\\T0DK.txt\', \'帳戶平倉盈虧\'+str(pingcang_win_long))
? ??
? ? #獲得帳戶浮動盈虧
? ? fudong_win_long = get_account(4)
? ? #print(\'帳戶浮動盈虧\'+str(fudong_win_long))
? ? log_debug_info(\'C:\\T0DK.txt\', \'帳戶浮動盈虧\'+str(fudong_win_long))
? ??
? ? #獲得帳戶手續費
? ? shouxufei = get_account(31)
? ? #print(\'帳戶手續費\'+str(shouxufei))
? ? log_debug_info(\'C:\\T0DK.txt\', \'帳戶手續費\'+str(shouxufei))
? ??
? ? #盈虧率和成本比計算
? ? #fudong_ykl = get_account(4)/get_account(28)*100
? ? #chengbenbi = get_account(30)/get_account(31)
? ? #log_debug_info(\'C:\\T0DK.txt\', \'浮動盈虧率\'+str(fudong_ykl)+\'/平倉成本比\'+str(chengbenbi))
? ? ? ??
? ? killtimer(GridTrade)? ? #終止計時器
? ? print("終止計時器")
? ? log_debug_info(\'C:\\T0DK.txt\', \'終止計時器\')
? ? return
?
?
#type參數 (get_account函數)?
# type? ? 說明
#1? ? 該函數返回常數,返回當前交易帳戶ID(該函數返回字符串類型數值)
#2? ? 賬戶類型,0 盈透 1 CTP 2 金仕達期貨 3FIX接口 4恒生期貨 5子賬戶 6其他柜臺 255 無效賬戶
#3? ? 現金余額
#5? ? 浮動盈虧
#6? ? 當前交易帳戶中的動態權益/資產值
#19? ? 當前可用資金
#20? ? 當前流動資產
#26? ? 上次結算準備金/期初余額
#27? ? 結算準備金/期初余額
#28? ? 占用保證金/證券市值
#29? ? 可取資金
#30? ? 平倉盈虧數額/回報賣出金額/融券盈虧
#31? ? 手續費
#32? ? 入金金額/利息積數/融資市值
#33? ? 出金金額/當前余額
#34? ? 上次信用額度
#35? ? 上次質壓
#36? ? 質壓金額
#37? ? 信用額度
#38? ? 凍結保證金/禁取資產
#39? ? 凍結手續費/回報買入金額/融資盈虧
#40? ? 保底資金
#41? ? 多頭保證金率(期貨專有)
#42? ? 空頭保證金率(期貨專有)
#43? ? 返回交易網關名稱,該函數返回字符串常數
#44? ? 融券市值
#45? ? 融券費用
#46? ? 融券利息
#47? ? 融資余額
#48? ? 融券余額
#49? ? 可用保證金
#50? ? 已用融資額
#51? ? 已用融券額
#52? ? 融資負債
#53? ? 返回當前交易賬戶是否處于有效狀態。建議對賬戶持倉或資金進行讀取時首先調用該函數對賬戶有效性進行判斷,以免出現誤操作。(對IB外盤無效,僅限國內)
?
# 本Python代碼主要用于策略交易
# 可以自己import我們平臺支持的第三方python模塊,比如pandas、numpy等。
#from PythonApi import *
?
#? 參數定義區,這里定義的參數可以直接在context對象中獲取。--(選擇實現)
#def parameter():
#? ? input_par("myvalues1",5,1,20,1)
#? ? input_par("myvalues2",10,1,20,1)
?
?
#? 在這個方法中編寫任何的初始化邏輯。context對象將會在你的算法策略的任何方法之間做傳遞。--(必須實現)
#def init(context):
? ? # 在context中保存全局變量
? ? #context.s1 = "SZ000001"? ?#平安銀行股票
? ??
? ? # print("策略啟動") #調試打印輸出
? ??
?
# before_trading此函數會在每天基準合約的策略交易開始前被調用,當天只會被調用一次。--(選擇實現)
#def before_trading(context):
#? ? pass
?
?
# 你選擇的品種的數據更新將會觸發此段邏輯,例如日或分鐘歷史數據切片或者是實時數據切片更新。--(必須實現)
#def handle_bar(context):
? ? # 開始編寫你的主要的算法邏輯。
? ??
? ? #使用buy_open、sell_close等方法下單
? ? #下單示例:
? ? #buy_open(context.s1, "Market", volume = 100)? ? #? 市價開多
? ? #buy_open(context.s1, "Limit", 25.45, 100)? ? ? ?#? 限價開多
#? ? pass
? ??
? ??
# after_trading函數會在每天交易結束后被調用,當天只會被調用一次。 --(選擇實現)
#def after_trading(context):
#? ? pass
? ??
? ??
# order_status當委托下單,成交,撤單等與下單有關的動作時,該方法就會被調用。---(選擇實現)
#def order_status(context,order):
#? ? pass
?
# order_action當查詢交易接口信息時返回的通知---(選擇實現)
#def order_action(context,type, account, datas)
#? ? ? ?pass
?
# exit函數會在測評結束或者停止策略運行時會被調用。---(選擇實現)
#def exit(context):
#? ? pass
?
{別忘了將本網告訴您身邊的朋友,向朋友傳達有用資料,也是一種人情,你朋友會感謝你的。}
?