میں اکثر موجد پلیٹ فارم پر گھومتا ہوں اور ہمیشہ خزانے تلاش کرتا ہوں۔ آج مجھے ایک 21 سالہ ملارجحان کی حکمت عملی، میں اصل مصنف کے شاندار اور کامل کوڈ ڈھانچے کی تعریف کرتا ہوں، اور اس میں اعلی لچک ہے۔ اصل حکمت عملی جے ایس ورژن ہے، جسے ازگر کے دوستوں کی سہولت کے لیے دوبارہ لکھا گیا ہے۔
ایمانداری سے، بہت سے ابتدائی افراد پہلے مقداری تجارت میں داخل ہونے پر بہت سے راستے اختیار کرتے ہیں۔ وہ اکثر ناکام آرڈرز، ناقص رسک مینجمنٹ سے ہونے والے نقصانات، اور حکمت عملی کو دوبارہ شروع کرنے کے بعد ڈیٹا کے نقصان جیسے مسائل کا سامنا کرتے ہیں۔ بعد میں، مجھے آہستہ آہستہ ایک اچھے فریم ورک کی اہمیت کا احساس ہوا، جس سے ہمیں بہت سے نقصانات سے بچنے میں مدد مل سکتی ہے۔ یہ رجحان کی حکمت عملی کا فریم ورک اتنا قیمتی ٹول ہے۔ یہ صرف ایک سادہ تجارتی حکمت عملی سے زیادہ ہے؛ یہ ایک ٹول باکس کی طرح ہے، جو آپ کو بنیادی لیکن اہم افعال جیسے آرڈر پلیسمنٹ، سٹاپ لوس آرڈرز، اور ڈیٹا مینجمنٹ فراہم کرتا ہے۔ آپ کو صرف “کب خریدنا ہے” اور “کب بیچنا ہے” کے بنیادی سوالات پر توجہ مرکوز کرنے کی ضرورت ہے۔ مزید برآں، فریم ورک بہت کھلا ہے، جس سے آپ آسانی سے MACD، RSI، یا کسی دوسرے اشارے کے لیے EMA کو تبدیل کر سکتے ہیں جسے آپ ترجیح دیتے ہیں۔ رجحانات کی پیروی کرنا چاہتے ہیں؟ کوئی مسئلہ نہیں۔ مطلب کی تبدیلی کی کوشش کرنا چاہتے ہیں؟ یہاں تک کہ ایک سے زیادہ اشارے کو یکجا کرنا چاہتے ہیں؟ بالکل۔ یہ لچک ناقابل یقین حد تک مفید ہے۔ آپ مختلف آئیڈیاز کے ساتھ تجربہ کرنے کے لیے ایک ہی کوڈ میں ترمیم کر سکتے ہیں۔
میں آج اس فریم ورک کا اشتراک کر رہا ہوں، امید ہے کہ یہ مقداری سرمایہ کاری کی تلاش کرنے والوں کے لیے مددگار ثابت ہوگا۔ ذیل میں اس فریم ورک کے ہر جزو کا تفصیلی تعارف ہے، جو مجھے یقین ہے کہ آپ کو کارآمد ثابت ہوگا۔
ملٹی کموڈٹی ٹریڈنگ فریم ورک میں استعمال ہونے والے متعدد آزاد افعال کے مقابلے میں، یہ فریم ورک کلاس فارمیٹ کا استعمال کرتے ہوئے حکمت عملی کے مختلف حصوں کو منظم اور منظم کرنے کی کوشش کرتا ہے۔ یہ آبجیکٹ اورینٹڈ ڈیزائن نہ صرف کوڈ کو برقرار رکھنے اور اسکیل ایبلٹی کو بہتر بناتا ہے بلکہ حکمت عملی کے اجزاء کو مزید ماڈیولر بناتا ہے، جس سے بعد میں ہونے والی ایڈجسٹمنٹ اور اصلاح کی سہولت ملتی ہے۔ فریم ورک بنیادی طور پر درج ذیل حصوں پر مشتمل ہوتا ہے، ہر ایک اپنے مخصوص فنکشن کے ساتھ، حکمت عملی کی لچک اور عملییت کو یقینی بناتا ہے۔
init فنکشن
__init__یہ فنکشن حکمت عملی کلاس کا ابتدائی طریقہ ہے، جو حکمت عملی کی بنیادی ترتیب ترتیب دینے، متغیرات کو شروع کرنے، اور مارکیٹ کی معلومات حاصل کرنے کے لیے ذمہ دار ہے۔ یہ فنکشن اس بات کو یقینی بناتا ہے کہ حکمت عملی کے چلنے سے پہلے مطلوبہ پیرامیٹرز ترتیب دیے گئے ہیں، اس بات کو یقینی بناتے ہوئے کہ بعد میں ہونے والی تجارتی کارروائیوں کو آسانی سے انجام دیا جا سکتا ہے۔initDatas فنکشن
saveStrategyRunTime فنکشن
سیٹ اسٹریٹجی رن ٹائم فنکشن
_Gفنکشن پاس شدہ ٹائم اسٹیمپ کو مقامی طور پر محفوظ کرتا ہے۔getDaysFromTimeStamp فنکشن
saveUserDatasLocal فنکشن
_Gفنکشن مقامی طور پر ڈیٹا کو محفوظ کرتا ہے۔readUserDataLocal فنکشن
clearUserDataLocal فنکشن
_Gفنکشن مقامی ڈیٹا کو صاف کرتا ہے۔runCmd فنکشن
آرڈر براہ راست کام کرتا ہے
اوپن لانگ فنکشن
orderDirectlyفنکشن خرید آپریشن کرتا ہے۔اوپن شارٹ فنکشن
orderDirectlyفنکشن سیل آپریشن کرتا ہے۔coverLong تقریب
orderDirectlyفنکشن سیل آپریشن کرتا ہے۔coverShort فنکشن
orderDirectlyفنکشن خرید آپریشن کرتا ہے۔getRealOrderSize فنکشن
getSinglePositionMargin فنکشن
getSinglePositionProfit فنکشن
calculateForcedPrice فنکشن
getMaxOrderSize فنکشن
getAccountAsset فنکشن
منافع کی تقریب کا حساب لگائیں۔
isEnoughAssetToOrder فنکشن
runInKLinePeriod فنکشن
Trueدوسری صورت میں، واپسFalse。ٹرینڈججمنٹ فنکشن (بنیادی ٹرینڈ ججمنٹ ماڈیول)
stopLoss تقریب
takeProfit فنکشن
ٹریکنگ ٹیک پرافٹ فنکشن
آرڈر کی تقریب
ٹرینڈ اسٹریٹجی فنکشن
پرنٹ لاگ اسٹیٹس فنکشن
LogStatusفنکشن ٹیبل ڈیٹا کو اسٹیٹس بار میں آؤٹ پٹ کرتا ہے۔اہم تقریب
یہ فریم ورک نہ صرف ڈیجیٹل کرنسی مارکیٹ پر لاگو ہوتا ہے، بلکہ اس میں بھی استعمال کیا جا سکتا ہے۔trendJudgmentمختلف تجارتی حکمت عملی کی ضروریات کے مطابق ڈھالنے کے لیے فنکشن میں فریم ورک کو بڑھایا جا سکتا ہے۔ اس کے علاوہ، فریم ورک کو خاص طور پر اسپاٹ مارکیٹ یا کثیر قسم کے معاہدوں کے لیے بھی تبدیل کیا جا سکتا ہے، جس میں اعلی لچک اور توسیع پذیری ہے۔
ایک جامع اور انتہائی لچکدار خودکار تجارتی نظام کے طور پر، یہ فریم ورک کرپٹو کرنسی مارکیٹ میں ٹرینڈ ٹریڈنگ کے لیے موزوں ہے۔ مسلسل اصلاح اور توسیع کے ذریعے، یہ مستقبل میں کریپٹو کرنسی کے تاجروں کے لیے ایک قابل قدر ٹول بننے کی امید ہے، جس سے انہیں اپنی مقداری حکمت عملیوں کو بہتر طریقے سے تیار کرنے میں مدد ملے گی۔ “Cryptocurrency Trend Strategy Trading Framework” ایک جامع ڈھانچہ پر فخر کرتا ہے۔ کوڈ میں نسبتاً بڑا ہونے کے باوجود، یہ بنیادی طور پر حقیقی دنیا کے تجارتی نقطہ نظر سے ٹرینڈ ٹریڈنگ کے لیے درکار بنیادی فنکشنل ماڈیولز کا احاطہ کرتا ہے۔ لہٰذا، یہ فریم ورک تجارتی حکمت عملی سیکھنے اور عملی اطلاق دونوں کے لیے اہم حوالہ قدر اور عملی اہمیت رکھتا ہے۔ اس کی جامع فعالیت اور لچک اسے مضبوط سپورٹ فراہم کرتے ہوئے متنوع مارکیٹ کے ماحول کے مطابق ڈھالنے کے قابل بناتی ہے۔
موجد پلیٹ فارم مقداری تجارتی علم اور حکمت عملیوں کا ایک خزانہ ہے، ہر ایک اپنے ڈویلپرز کی حکمت اور تجربے کو مجسم کرتا ہے۔ ہم یہاں قیمتی تجارتی حکمت عملیوں اور تکنیکوں کو دریافت کرنے کے لیے ہر کسی کو خوش آمدید کہتے ہیں۔ ہمارے تمام اختراعی اور اشتراک کرنے والے صارفین کا شکریہ۔ یہ آپ کے تعاون کی بدولت ہے کہ یہ پلیٹ فارم مقداری تجارت میں سیکھنے اور تبادلے کے لیے ایک اہم مقام بن گیا ہے، جس سے ہر ایک کو اپنی مہارت اور مہارت کو بہتر بنانے میں مدد ملتی ہے۔
”`python “‘backtest start: 2024-11-26 00:00:00 end: 2024-12-03 00:00:00 period: 1d basePeriod: 1d exchanges: [{“eid”:“Futures_Binance”,“currency”:“BTC_USDT”}] “’
import json, talib import numpy as np
class TrendStrategy: def init(self): # 基本设置 self._Currency = TradeCurrency self._Interval = Interval self._UseQuarter = UseQuarter self._UseContract = TradeCurrency + (‘.swap’ if self._UseQuarter else ‘.quarter’) self._OnlyTrendJudgment = OnlyTrendJudgment self._EnableMessageSend = EnableMessageSend # 趋势判断 self._RunInKLinePeriod = RunInKLinePeriod self._KLinePeriod = KLinePeriod self._EmaLength = EmaLength self._EmaCoefficient = EmaCoefficient self._UseStddev = UseStddev self._UseRecordsMiddleValue = UseRecordsMiddleValue self._StddevLength = StddevLength self._StddevDeviations = StddevDeviations # 下单设置 self._MarginLevel = MarginLevel self._OrderSize = OrderSize self._OrderByMargin = OrderByMargin self._OrderMarginPercent = OrderMarginPercent self._PricePrecision = None self._AmountPrecision = None self._OneSizeInCurrentCoin = None self._QuarterOneSizeValue = None # 止盈止损 self._UseStopLoss = UseStopLoss self._StopLossPercent = StopLossPercent self._UseTakeProfit = UseTakeProfit self._TakeProfitPercent = TakeProfitPercent self._UseTrackingTakeProfit = UseTrackingTakeProfit self._UsePositionRetracement = UsePositionRetracement self._TakeProfitTriggerPercent = TakeProfitTriggerPercent self._CallBakcPercent = CallBakcPercent
# 策略变量
self._LastBarTime = 0
self._TrendWhenTakeProfitOrStopLoss = 0
self._HadStopLoss = False
self._TriggeredTakeProfit = False
self._PeakPriceInPosition = 0
self._HadTakeProfit = False
self._PriceCrossEMAStatus = 0
# 统计变量
self._InitAsset = 0
self._ProfitLocal = 0
self._TakeProfitCount = 0
self._TradeCount = 0
self.StrategyRunTimeStampString = "strategy_run_time"
self._StrategyDatas = {"start_run_timestamp": 0, "others": ""}
self._UserDatas = None
# 相对固定参数
self._MaintenanceMarginRate = 0.004
self._TakerFee = 0.0005
self._IsUsdtStandard = False
# 获取合约信息
ticker = _C(exchange.GetTicker, self._UseContract)
marketInfo = exchange.GetMarkets()[self._UseContract]
Log('获取市场信息:', marketInfo)
self._PricePrecision = marketInfo['PricePrecision']
self._AmountPrecision = marketInfo['AmountPrecision']
self._OneSizeInCurrentCoin = marketInfo['CtVal']
self._QuarterOneSizeValue = marketInfo['CtVal']
exchange.SetCurrency(self._Currency)
exchange.SetMarginLevel(self._UseContract, self._MarginLevel)
exchange.SetPrecision(self._PricePrecision, self._AmountPrecision)
# 初始化数据
def initDatas(self):
self.saveStrategyRunTime()
self.readUserDataLocal()
self._InitAsset = self._UserDatas["init_assets"]
self._ProfitLocal = self._UserDatas["profit_local"]
self._TakeProfitCount = self._UserDatas["take_profit_count"]
self._TradeCount = self._UserDatas["trade_count"]
if self._OrderByMargin:
self.getRealOrderSize(-1, self._OrderSize)
Log("已经重新计算下单张数:", self._OrderSize)
if self._UseTakeProfit and self._UseTrackingTakeProfit:
raise Exception("止盈和回调止盈不能同时使用!")
# 设置合约
def setContract(self):
self._IsUsdtStandard = "USDT" in self._Currency
exchange.SetCurrency(self._Currency)
if self._UseQuarter:
exchange.SetContractType("quarter")
else:
exchange.SetContractType("swap")
# 保存程序起始运行时间 秒级时间戳
def saveStrategyRunTime(self):
local_data_strategy_run_time = _G(self.StrategyRunTimeStampString)
if local_data_strategy_run_time is None:
self._StrategyDatas["start_run_timestamp"] = Unix()
_G(self.StrategyRunTimeStampString, self._StrategyDatas["start_run_timestamp"])
else:
self._StrategyDatas["start_run_timestamp"] = local_data_strategy_run_time
# 设置程序起始运行时间 秒级时间戳
def setStrategyRunTime(self, timestamp):
_G(self.StrategyRunTimeStampString, timestamp)
self._StrategyDatas["start_run_timestamp"] = timestamp
# 计算两个时间戳之间的天数,参数是秒级时间戳
def getDaysFromTimeStamp(self, start_time, end_time):
if end_time < start_time:
return 0
return (end_time - start_time) // (60 * 60 * 24)
# 保存数据到本地
def saveUserDatasLocal(self):
self._UserDatas = {
"init_assets": self._InitAsset,
"profit_local": self._ProfitLocal,
"take_profit_count": self._TakeProfitCount,
"trade_count": self._TradeCount
}
# 存储到本地
_G(exchange.GetLabel(), self._UserDatas)
Log("已把所有数据保存到本地.")
# 读取用户本地数据,程序启动时候运行一次
def readUserDataLocal(self):
user_data = _G(exchange.GetLabel())
if user_data is None:
self._InitAsset = self.getAccountAsset(_C(exchange.GetPosition), _C(exchange.GetAccount), _C(exchange.GetTicker))
self._UserDatas = {
"init_assets": self._InitAsset,
"profit_local": 0,
"take_profit_count": 0,
"trade_count": 0
}
else:
self._UserDatas = user_data
# 清除用户本地数据,交互按钮点击运行
def clearUserDataLocal(self):
_G(exchange.GetLabel(), None)
Log(exchange.GetLabel(), ":已清除本地数据.")
# 策略交互
def runCmd(self):
cmd = GetCommand()
if cmd:
# 检测交互命令
Log("接收到的命令:", cmd, "#FF1CAE")
if cmd.startswith("ClearLocalData:"):
# 清除本地数据
self.clearUserDataLocal()
elif cmd.startswith("SaveLocalData:"):
# 保存数据到本地
self.saveUserDatasLocal()
elif cmd.startswith("ClearLog:"):
# 清除日志
log_reserve = cmd.replace("ClearLog:", "")
LogReset(int(log_reserve))
elif cmd.startswith("OrderSize:"):
# 修改下单张数
if self._OrderByMargin:
Log("已经使用保证金数量来下单,无法直接修改下单数量!")
else:
order_size = int(cmd.replace("OrderSize:", ""))
self._OrderSize = order_size
Log("下单张数已经修改为:", self._OrderSize)
elif cmd.startswith("OrderMarginPercent:"):
# 修改下单保证金百分比
if self._OrderByMargin:
order_margin_percent = float(cmd.replace("OrderMarginPercent:", ""))
self._OrderMarginPercent = order_margin_percent
Log("下单保证金百分比:", self._OrderMarginPercent, "%")
else:
Log("没有打开根据保证金数量下单,无法修改下单保证金百分比!")
# 交易函数
def orderDirectly(self, distance, price, amount):
tradeFunc = None
if amount <= 0:
raise Exception("设置的参数有误,下单数量已经小于0!")
if distance == "buy":
tradeFunc = exchange.Buy
elif distance == "sell":
tradeFunc = exchange.Sell
elif distance == "closebuy":
tradeFunc = exchange.Sell
else:
tradeFunc = exchange.Buy
exchange.SetDirection(distance)
return tradeFunc(price, amount)
def openLong(self, price, amount):
real_amount = self.getRealOrderSize(price, amount)
return self.orderDirectly("buy", price, real_amount)
def openShort(self, price, amount):
real_amount = self.getRealOrderSize(price, amount)
return self.orderDirectly("sell", price, real_amount)
def coverLong(self, price, amount):
return self.orderDirectly("closebuy", price, amount)
def coverShort(self, price, amount):
return self.orderDirectly("closesell", price, amount)
# 重新计算下单数量
def getRealOrderSize(self, price, amount):
real_price = price if price != -1 else _C(exchange.GetTicker).Last
if self._OrderByMargin:
if self._IsUsdtStandard:
self._OrderSize = _N(self._InitAsset * (self._OrderMarginPercent / 100) / real_price * self._MarginLevel / self._OneSizeInCurrentCoin, self._AmountPrecision) # u本位数量(杠杆放大数量)
else:
self._OrderSize = _N(self._InitAsset * (self._OrderMarginPercent / 100) * self._MarginLevel * real_price / self._QuarterOneSizeValue, self._AmountPrecision) # 币本位数量(杠杆放大数量)
else:
self._OrderSize = amount
return self._OrderSize
# 获取单个持仓占用保证金
def getSinglePositionMargin(self, position, ticker):
position_margin = 0
if len(position) > 0:
if self._IsUsdtStandard:
position_margin = position[0].Amount * self._OneSizeInCurrentCoin * ticker.Last / self._MarginLevel
else:
position_margin = position[0].Amount * self._QuarterOneSizeValue / ticker.Last / self._MarginLevel
return position_margin
# 获取单向持仓的收益和收益%
def getSinglePositionProfit(self, position, ticker):
if len(position) == 0:
return [0, 0]
price = ticker.Last
position_margin = self.getSinglePositionMargin(position, ticker)
position_profit_percent = (price - position[0].Price) / position[0].Price * self._MarginLevel if position[0].Type == PD_LONG else (position[0].Price - price) / position[0].Price * self._MarginLevel
position_profit = position_margin * position_profit_percent
return [position_profit, position_profit_percent]
# 计算强平价格
def calculateForcedPrice(self, account, position, ticker):
position_profit = 0
total_avail_balance = 0
forced_price = 0
position_margin = self.getSinglePositionMargin(position, ticker)
[position_profit, position_profit_percent] = self.getSinglePositionProfit(position, ticker)
if self._IsUsdtStandard:
total_avail_balance = account.Balance + position_margin + account.FrozenBalance - position_profit if position_profit > 0 else account.Balance + position_margin + account.FrozenBalance
if position[0].Type == PD_LONG:
forced_price = ((self._MaintenanceMarginRate + self._TakerFee) * self._MarginLevel * account.FrozenBalance - total_avail_balance) / self._OneSizeInCurrentCoin + (position[0].Amount * position[0].Price) / (position[0].Amount - (self._MaintenanceMarginRate + self._TakerFee) * position[0].Amount)
else:
forced_price = ((self._MaintenanceMarginRate + self._TakerFee) * self._MarginLevel * account.FrozenBalance - total_avail_balance) / self._OneSizeInCurrentCoin - (position[0].Amount * position[0].Price) / (-1 * position[0].Amount - (self._MaintenanceMarginRate + self._TakerFee) * position[0].Amount)
else:
total_avail_balance = account.Stocks + position_margin + account.FrozenStocks - position_profit if position_profit > 0 else account.Stocks + position_margin + account.FrozenStocks
if position[0].Type == PD_LONG:
forced_price = (self._MaintenanceMarginRate * position[0].Amount + position[0].Amount) / (total_avail_balance / self._QuarterOneSizeValue + position[0].Amount / position[0].Price)
else:
forced_price = (self._MaintenanceMarginRate * position[0].Amount - position[0].Amount) / (total_avail_balance / self._QuarterOneSizeValue - position[0].Amount / position[0].Price)
if forced_price < 0:
forced_price = 0
return forced_price
# 计算最大可下单张数
def getMaxOrderSize(self, margin_level, ticker, account):
max_order_size = 0
if self._IsUsdtStandard:
max_order_size = account.Balance * margin_level / (self._OneSizeInCurrentCoin * ticker.Last)
else:
max_order_size = account.Stocks * ticker.Last / self._QuarterOneSizeValue * margin_level
return _N(max_order_size, self._AmountPrecision)
# 获取账户资产
def getAccountAsset(self, position, account, ticker):
# 计算不同情况下的账户初始资产
account_asset = 0
position_margin = self.getSinglePositionMargin(position, ticker)
if self._IsUsdtStandard:
if len(position) > 0:
account_asset = account.Balance + account.FrozenBalance + position_margin
else:
account_asset = account.Balance + account.FrozenBalance
else:
if len(position) > 0:
account_asset = account.Stocks + account.FrozenStocks + position_margin
else:
account_asset = account.Stocks + account.FrozenStocks
return account_asset
# 收益统计
def calculateProfit(self, ticker):
# 重新获取一下账户持仓与资产
position = _C(exchange.GetPosition)
account = _C(exchange.GetAccount)
# 当前总收益 - 上一次总收益 = 本次的收益
current_profit = (self.getAccountAsset(position, account, ticker) - self._InitAsset) - self._ProfitLocal
self._ProfitLocal += current_profit
if current_profit > 0:
self._TakeProfitCount += 1
self._TradeCount += 1
LogProfit(_N(self._ProfitLocal, 4), " 本次收益:", _N(current_profit, 6))
self.saveUserDatasLocal()
# 是否还够资金下单
def isEnoughAssetToOrder(self, order_size, ticker):
is_enough = True
account = _C(exchange.GetAccount)
if self._IsUsdtStandard:
if account.Balance < order_size * ticker.Last * self._OneSizeInCurrentCoin / self._MarginLevel:
is_enough = False
else:
if account.Stocks < order_size * self._QuarterOneSizeValue / ticker.Last / self._MarginLevel:
is_enough = False
return is_enough
# 按照K线周期运行策略核心
def runInKLinePeriod(self, records):
bar_time = records[-1].Time
if self._RunInKLinePeriod and self._LastBarTime == bar_time:
return False
self._LastBarTime = bar_time
return True
# 趋势判断模块(可编辑具体指标)
def trendJudgment(self, records):
# 检查价格是否穿过均线
def checkPriceCrossEma(price, ema_value):
if self._PriceCrossEMAStatus == 0:
if price <= ema_value:
self._PriceCrossEMAStatus = -1
else:
self._PriceCrossEMAStatus = 1
elif (self._PriceCrossEMAStatus == -1 and price >= ema_value) or (self._PriceCrossEMAStatus == 1 and price <= ema_value):
self._PriceCrossEMAStatus = 2 # 完成穿过
# EMA的多空判断
ema_long = False
ema_short = False
price = records[-2].Close # 已经收盘的K线的收盘价格
ema = TA.EMA(records, self._EmaLength)
ema_value = ema[-2] # 收盘K线对应ema值
ema_upper = ema_value * (1 + self._EmaCoefficient)
ema_lower = ema_value * (1 - self._EmaCoefficient)
checkPriceCrossEma(price, ema_value)
if price > ema_upper:
ema_long = True
elif price < ema_lower:
ema_short = True
# 标准差判断
in_trend = False
if self._UseStddev:
records_data = []
for i in range(len(records)):
records_data.append((records[i].High + records[i].Low) / 2 if self._UseRecordsMiddleValue else records[i].Close)
records_data = np.array(records_data) # 将 list 转换为 np.array
stddev = np.std(records_data, ddof=1) # 使用 numpy 计算标准差
if stddev > self._StddevDeviations:
in_trend = True
else:
in_trend = True
# 趋势判断
long = in_trend and ema_long
short = in_trend and ema_short
if long:
Log("当前趋势为:多", self._EnableMessageSend and "@" or "#00FF7F")
elif short:
Log("当前趋势为:空", self._EnableMessageSend and "@" or "#FF0000")
else:
Log("当前趋势为:震荡", self._EnableMessageSend and "@" or "#007FFF")
return [long, short]
# 止损
def stopLoss(self, position, ticker):
stop_loss_price = 0
price = ticker.Last
if len(position) == 1 and self._UseStopLoss:
if position[0].Type == PD_LONG:
stop_loss_price = position[0].Price * (1 - self._StopLossPercent / 100)
if price < stop_loss_price:
self.coverLong(-1, position[0].Amount)
self.calculateProfit(ticker)
self._TrendWhenTakeProfitOrStopLoss = 1
self._HadStopLoss = True
Log("多单止损。止损价格:", _N(stop_loss_price, 6), ", 持仓价格:", _N(position[0].Price), self._EnableMessageSend and "@" or "#FF1CAE")
elif position[0].Type == PD_SHORT:
stop_loss_price = position[0].Price * (1 + self._StopLossPercent / 100)
if price > stop_loss_price:
self.coverShort(-1, position[0].Amount)
self.calculateProfit(ticker)
self._TrendWhenTakeProfitOrStopLoss = -1
self._HadStopLoss = True
Log("空单止损。止损价格:", _N(stop_loss_price, 6), ", 持仓价格:", _N(position[0].Price), self._EnableMessageSend and "@" or "#FF1CAE")
# 止盈
def takeProfit(self, position, ticker):
take_profit_price = 0
price = ticker.Last
if len(position) == 1 and self._UseTakeProfit:
if position[0].Type == PD_LONG:
take_profit_price = position[0].Price * (1 + self._TakeProfitPercent / 100)
if price > take_profit_price:
self.coverLong(-1, position[0].Amount)
self.calculateProfit(ticker)
self._TrendWhenTakeProfitOrStopLoss = 1
self._HadTakeProfit = True
Log("多单止盈。止盈价格:", _N(take_profit_price, 6), ", 持仓价格:", _N(position[0].Price), self._EnableMessageSend and "@" or "#FF1CAE")
elif position[0].Type == PD_SHORT:
take_profit_price = position[0].Price * (1 - self._TakeProfitPercent / 100)
if price < take_profit_price:
self.coverShort(-1, position[0].Amount)
self.calculateProfit(ticker)
self._TrendWhenTakeProfitOrStopLoss = -1
self._HadTakeProfit = True
Log("空单止盈。止盈价格:", _N(take_profit_price, 6), ", 持仓价格:", _N(position[0].Price), self._EnableMessageSend and "@" or "#FF1CAE")
# 回调止盈
def trackingTakeProfit(self, position, ticker):
take_profit_price = 0
trigger_price = 0
price = ticker.Last
if len(position) > 0 and self._UseTrackingTakeProfit:
if position[0].Type == PD_LONG:
# 多单持仓
if self._TriggeredTakeProfit:
# 已达到触发价格,监控是否止盈
self._PeakPriceInPosition = price if price > self._PeakPriceInPosition else self._PeakPriceInPosition # 更新价格高点
if self._UsePositionRetracement:
take_profit_price = self._PeakPriceInPosition - (self._PeakPriceInPosition - position[0].Price) * (self._CallBakcPercent / 100) # 计算回调的止盈价格
else:
take_profit_price = self._PeakPriceInPosition * (1 - self._CallBakcPercent / 100) # 计算回调的止盈价格
if price < take_profit_price:
self.coverLong(-1, position[0].Amount) # 平多
self.calculateProfit(ticker)
self._TriggeredTakeProfit = False # 复位触发标记
self._TrendWhenTakeProfitOrStopLoss = 1 # 记录止盈时候的趋势
self._HadTakeProfit = True # 记录发生了止盈
Log("多单回调止盈:持仓中价格高点:", _N(self._PeakPriceInPosition, 6), ", 止盈价格:", _N(take_profit_price, 6), ", 当前价格:", _N(price, 6),
", 持仓价格:", _N(position[0].Price, 6), self._EnableMessageSend and "@" or "#FF1CAE")
else:
# 监控是否达到回调止盈的触发价格
trigger_price = position[0].Price * (1 + self._TakeProfitTriggerPercent / 100)
if price > trigger_price:
self._TriggeredTakeProfit = True # 触发回调止盈
self._PeakPriceIn