In diesem Artikel werden zwei Lösungen beschrieben. Die andere Lösung am Ende des Artikels ist einfacher (empfohlen).
Viele Entwickler, die Python zum Schreiben von Strategien verwenden, möchten die Strategiecodedateien lokal speichern, sind jedoch um die Sicherheit der Strategien besorgt. AlsFMZ API
Eine im Dokument vorgeschlagene Lösung:
Richtliniensicherheit Entwickeln Sie Strategien auf der Inventor Quantitative Trading-Plattform. Strategien sind nur für Inhaber eines Inventor Quantitative-Kontos sichtbar. Darüber hinaus kann der Strategiecode auf der Inventor Quantitative Trading Platform vollständig lokalisiert werden. Beispielsweise kann die Strategie in ein Python-Paket gekapselt und in den Strategiecode geladen werden, wodurch eine Strategielokalisierung erreicht wird. https://www.fmz.com/api#%E7%AD%96%E7%95%A5%E5%AE%89%E5%85%A8%E6%80%A7
Eigentlich besteht hierüber kein Grund zur Sorge, aber da es eine solche Lösung gibt, wird ein vollständiges Implementierungsbeispiel bereitgestellt.
Lassen Sie uns eine einfache Python-Strategie zur Demonstration finden, mit dem klassischenDual Thrust
Strategie, Strategieadresse: https://www.fmz.com/strategie/21856
Wir bemühen uns, keinen Teil des Strategiecodes zu ändern und kapseln die Strategie in eine Datei, die vom Strategiecode auf der FMZ-Plattform aufgerufen werden kann. Das Ausführungsergebnis ist genau dasselbe wie bei der direkten Ausführung der Strategie. Das größte Problem bei der Kapselung besteht darin, dass auf die globalen Objekte, globalen Funktionen und konstanten Werte, die vom Strategiecode auf der FMZ-Plattform aufgerufen werden, in unseren gekapselten Dateien nicht zugegriffen werden kann. Daher müssen wir einen Weg finden, diese Objekte, Funktionen und Variablen zu übergeben und Konstanten zum gekapselten Dokument. Dann werden wir es Schritt für Schritt abarbeiten.
Fügen Sie es in die im lokalen Editor geöffnete Datei testA ein.
# 函数、对象
exchanges = None
exchange = None
Log = None
Sleep = None
TA = None
Chart = None
LogProfitReset = None
LogStatus = None
_N = None
_C = None
LogProfit = None
# 策略参数
ContractTypeIdx = None
MarginLevelIdx = None
NPeriod = None
Ks = None
Kx = None
AmountOP = None
Interval = None
LoopInterval = None
PeriodShow = None
# 常量
ORDER_STATE_PENDING = 0
ORDER_STATE_CLOSED = 1
ORDER_STATE_CANCELED = 2
ORDER_STATE_UNKNOWN = 3
ORDER_TYPE_BUY = 0
ORDER_TYPE_SELL = 1
PD_LONG = 0
PD_SHORT = 1
def SetExchanges(es):
global exchanges, exchange
exchanges = es
exchange = es[0]
def SetFunc(pLog, pSleep, pTA, pChart, pLogStatus, pLogProfitReset, p_N, p_C, pLogProfit):
global Log, Sleep, TA, Chart, LogStatus, LogProfitReset, _N, _C, LogProfit
Log = pLog
Sleep = pSleep
TA = pTA
Chart = pChart
LogStatus = pLogStatus
LogProfitReset = pLogProfitReset
_N = p_N
_C = p_C
LogProfit = pLogProfit
def SetParams(pContractTypeIdx, pMarginLevelIdx, pNPeriod, pKs, pKx, pAmountOP, pInterval, pLoopInterval, pPeriodShow):
global ContractTypeIdx, MarginLevelIdx, NPeriod, Ks, Kx, AmountOP, Interval, LoopInterval, PeriodShow
ContractTypeIdx = pContractTypeIdx
MarginLevelIdx = pMarginLevelIdx
NPeriod = pNPeriod
Ks = pKs
Kx = pKx
AmountOP = pAmountOP
Interval = pInterval
LoopInterval = pLoopInterval
PeriodShow = pPeriodShow
Die Hauptfunktion des obigen Codes besteht darin, die in der aktuellen Datei verwendeten globalen Funktionen und Variablen zu deklarieren. Reservieren Sie dann die Schnittstelle für den Import dieser FunktionenSetExchanges
,SetParams
,SetFunc
. Die Strategien auf der FMZ-Plattform rufen diese Funktionen auf und geben einige verwendete Funktionen, Objekte usw. weiter.
Die Startstrategie ist ganz einfach und lautet wie folgt:
Auf der FMZ-Plattform sind nur wenige Codezeilen geschrieben. Es ist zu beachten, dass die Parameter dieser Startstrategie mit denen unserer gekapselten Strategie identisch sind.Python-Version von Dual Thrust OKCoin FuturesEs ist genau dasselbe. Tatsächlich können Sie die Strategie „Python-Version von Dual Thrust OKCoin Futures“ direkt kopieren, dann den Strategiecode löschen und einfügen
import sys
# 这里我写的是自己放置testA文件的路径,具体我替换为xxx了,简单说就是设置自己的testA文件路径就可以了
sys.path.append("/Users/xxx/Desktop/pythonPlayground/")
import testA
def main():
# 传递交易所对象
testA.SetExchanges(exchanges)
# 传递全局函数 SetFunc(pLog, pSleep, pTA, pChart, pLogStatus, pLogProfitReset, p_N, p_C, pLogProfit)
testA.SetFunc(Log, Sleep, TA, Chart, LogStatus, LogProfitReset, _N, _C, LogProfit)
# 传递策略参数 SetParams(pContractTypeIdx, pMarginLevelIdx, pNPeriod, pKs, pKx, pAmountOP, pInterval, pLoopInterval, pPeriodShow)
testA.SetParams(ContractTypeIdx, MarginLevelIdx, NPeriod, Ks, Kx, AmountOP, Interval, LoopInterval, PeriodShow)
# 执行封装的testA文件中的策略主函数
testA.main()
Auf diese Weise kapseln wir den Richtlinienlogikkörper in der Datei testA und platzieren ihn lokal auf dem Gerät des Hosts. Auf der FMZ-Plattform müssen wir nur eine Startrichtlinie speichern. Der Roboter, der diese Startrichtlinie erstellt, kann unsere lokale Datei direkt laden und führen Sie es lokal auf dem Host aus. .
Laden Sie die Datei direkt zur Ausführung. Dieses Mal bereiten wir eine TestB-Datei vor, um den Code der Strategie „Python-Version von Dual Thrust OKCoin Futures“ zu platzieren.
import time
class Error_noSupport(BaseException):
def __init__(self):
Log("只支持OKCoin期货!#FF0000")
class Error_AtBeginHasPosition(BaseException):
def __init__(self):
Log("启动时有期货持仓! #FF0000")
ChartCfg = {
'__isStock': True,
'title': {
'text': 'Dual Thrust 上下轨图'
},
'yAxis': {
...
Die Strategie ist zu lang, daher wird sie weggelassen und der Strategiecode muss überhaupt nicht geändert werden. Bereiten Sie dann die „Python-Version von Dual Thrust OKCoin Futures (starten Sie die Strategie und führen Sie die Datei testB direkt aus)“ vor, die unsere Strategie auf der FMZ-Plattform ist, erstellen Sie einen Roboter, laden Sie die Datei testB direkt und führen Sie sie direkt aus. Es ist zu beachten, dass die Startstrategie auch dieselben Strategieparametereinstellungen (Strategieschnittstellenparameter) wie die Originalversion von „Python-Version Dual Thrust OKCoin Futures“ haben muss.
if __name__ == '__main__':
Log("run...")
try:
# 文件路径做了处理,可以写入自己testB文件放置的实际路径
f = open("/Users/xxx/Desktop/pythonPlayground/testB.py", "r")
code = f.read()
exec(code)
except Exception as e:
Log(e)
So führen Sie einen Backtest durch:
Die Backtest-Ergebnisse stimmen mit den obigen Tests überein.
Offensichtlich ist die zweite Methode oben einfacher und empfehlenswert. Wenn es eine bessere Methode gibt, können Sie gerne eine Nachricht hinterlassen.