代码拉取完成,页面将自动刷新
package services
import (
"gitee.com/quant1x/engine/cache"
"gitee.com/quant1x/engine/config"
"gitee.com/quant1x/engine/factors"
"gitee.com/quant1x/engine/market"
"gitee.com/quant1x/engine/models"
"gitee.com/quant1x/engine/realtime"
"gitee.com/quant1x/engine/storages"
"gitee.com/quant1x/engine/trader"
"gitee.com/quant1x/exchange"
"gitee.com/quant1x/gox/api"
"gitee.com/quant1x/gox/logger"
"gitee.com/quant1x/gox/num"
"gitee.com/quant1x/gox/runtime"
"slices"
"strings"
)
// 任务 - 卖出117
func jobOneSizeFitsAllSales() {
updateInRealTime, status := exchange.CanUpdateInRealtime()
if updateInRealTime && IsTrading(status) {
cookieCutterSell()
} else if runtime.Debug() {
cookieCutterSell()
}
}
// 一刀切卖出
func cookieCutterSell() {
sellStrategyCode := models.ModelOneSizeFitsAllSells
// 1. 获取117号策略(卖出)
sellRule := config.GetStrategyParameterByCode(sellStrategyCode)
if sellRule == nil {
return
}
// 2. 判断是否可以指定自动卖出
if !sellRule.IsCookieCutterForSell() {
return
}
// 3. 判断是否交易日
if !exchange.DateIsTradingDay() {
return
}
// 3.1 判断是否交易时段
if !sellRule.Session.IsTrading() {
return
}
// 4. 查询持仓可卖的股票
positions, err := trader.QueryHolding()
if err != nil {
return
}
// 5. 确定持股到期的个股列表
finalCodeList := checkoutCanSellStockList(sellStrategyCode)
// 6. 遍历持仓
direction := trader.SELL
strategyName := sellRule.QmtStrategyName()
for _, position := range positions {
orderRemark := sellRule.Flag
isNeedToSell := false
// 6.1 如果持仓可卖数据小于1, 继续下一条持仓记录
if position.CanUseVolume < 1 {
continue
}
// 6.2 对齐证券代码, 检查黑白名单
stockCode := position.StockCode
securityCode := exchange.CorrectSecurityCode(stockCode)
if !trader.CheckForSell(securityCode) {
// 禁止卖出, 则返回
logger.Infof("%s[%d]: %s ProhibitForBuying", sellRule.Name, sellRule.Id, securityCode)
continue
}
// 6.3 获取快照
snapshot := models.GetTickFromMemory(securityCode)
if snapshot == nil {
continue
}
// 6.4 现价
lastPrice := num.Decimal(snapshot.Price)
// 昨日收盘
lastClose := num.Decimal(snapshot.LastClose)
// 6.5 计算涨停价
limitUp, _ := market.PriceLimit(securityCode, lastClose)
// 6.6 如果涨停, 则不出
if lastPrice >= limitUp {
logger.Infof("%s[%d]: %s LimitUp, skip", sellRule.Name, sellRule.Id, securityCode)
continue
}
// 6.7 持仓成本
avgPrice := position.OpenPrice
// 6.8 盈亏比
floatProfitLossRatio := num.NetChangeRate(avgPrice, lastPrice)
// 6.9 确定是否规则内最后一天持股
isFinal := slices.Contains(finalCodeList, securityCode)
todayLastSession := sellRule.Session.IsTodayLastSession()
logger.Infof("%s[%d]: %s, profit-loss-ratio=%.02f, last-day=%t, last-session=%t", sellRule.Name, sellRule.Id, securityCode, floatProfitLossRatio, isFinal, todayLastSession)
// 117. 最后一天持股, 且是最后一个交易时段, 则卖出
if isFinal && todayLastSession {
// 卖出
isNeedToSell = true
orderRemark = "LASTDAY:P"
if floatProfitLossRatio > 0 {
orderRemark = orderRemark + ">0"
} else if floatProfitLossRatio == 0 {
orderRemark = orderRemark + "=0"
} else {
orderRemark = orderRemark + "<0"
}
}
// 6.10 股价高于前面一天最高价,且大于等于5日线,如果是获利的,卖出
if !isNeedToSell {
// 6.10.1 获取历史特征数据
history := factors.GetL5History(securityCode)
if history == nil {
continue
}
// 6.10.2 计算5日均线
ma5 := realtime.IncrementalMovingAverage(history.MA4, 5, lastPrice)
// 风险收益比(Risk/Reward Ratio)
orderRemark = "RISK:P"
// 6.10.3 股价高于前一天最高价, 且站上5日线以及盈利的情况下
if lastPrice > history.HIGH && lastPrice >= ma5 && floatProfitLossRatio > 0 {
// 卖出
isNeedToSell = true
orderRemark += ">H>MA5>0"
} else {
//6.11 如果股价触及止盈比例, 则卖出
if sellRule.Session.CanTakeProfit() && floatProfitLossRatio > sellRule.TakeProfitRatio {
isNeedToSell = true
// 止盈
orderRemark += ">TPR"
} else if sellRule.Session.CanStopLoss() && floatProfitLossRatio < sellRule.StopLossRatio {
isNeedToSell = true
// 止损
orderRemark += "<SLR"
}
}
}
// 18168
if !isNeedToSell {
continue
}
// 成本价
//costPrice := position.OpenPrice
orderPrice := lastPrice
orderVolume := position.CanUseVolume
// 卖出
order_id, err := trader.DirectOrder(direction, strategyName, orderRemark, securityCode, trader.LATEST_PRICE, orderPrice, orderVolume)
if err != nil {
continue
}
_ = order_id
}
}
// 获得T+HoldingPeriod的具体日期
func getEarlierDate(period int) string {
dates := exchange.LastNDate(exchange.LastTradeDate(), period)
earlier_date := exchange.FixTradeDate(dates[0], cache.CACHE_DATE)
return earlier_date
}
// 获取所有挂接了指定的卖出策略ID的交易规则
func getStrategyParameterList(sellStrategyId int) []config.StrategyParameter {
traderConfig := config.TraderConfig()
var list []config.StrategyParameter
for _, v := range traderConfig.Strategies {
if v.Flag == models.OrderFlagSell || v.SellStrategy != sellStrategyId {
continue
}
list = append(list, v)
}
return list
}
// 捡出T+HoldingPeriod日的股票列表
func checkoutCanSellStockList(sellStrategyId int) []string {
var list []string
tradeRules := getStrategyParameterList(sellStrategyId)
if len(tradeRules) == 0 {
return list
}
for _, v := range tradeRules {
date := getEarlierDate(v.HoldingPeriod)
qmtStrategyName := v.QmtStrategyName()
codes := storages.FetchListForFirstPurchase(date, qmtStrategyName, trader.BUY)
logger.Infof("sell strategy[%d]: from %d, last-day codes=%s", sellStrategyId, v.Id, strings.Join(codes, ","))
if len(codes) == 0 {
continue
}
list = append(list, codes...)
}
list = api.Unique(list)
return list
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。