
Cet article présente deux solutions. L’autre solution, à la fin de l’article, est plus simple (recommandée).
De nombreux développeurs qui utilisent Python pour écrire des stratégies souhaitent stocker les fichiers de code de stratégie localement, mais ils sont préoccupés par la sécurité des stratégies. CommeFMZ APIUne solution proposée dans le document :
Politique de sécurité Développez des stratégies sur la plateforme de trading quantitative Inventor. Les stratégies ne sont visibles que pour les détenteurs de comptes Inventor Quantitative. De plus, le code de stratégie peut être entièrement localisé sur la plateforme de trading quantitatif Inventor. Par exemple, la stratégie peut être encapsulée dans un package Python et chargée dans le code de stratégie, ce qui permet de localiser la stratégie. https://www.fmz.com/api#%E7%AD%96%E7%95%A5%E5%AE%89%E5%85%A8%E6%80%A7
En fait, il n’y a pas lieu de s’inquiéter à ce sujet, mais comme il existe une telle solution, un exemple d’implémentation complet est fourni.
Trouvons une stratégie Python simple à démontrer, en utilisant le classiqueDual ThrustStratégie, adresse de la stratégie : https://www.fmz.com/strategy/21856
Nous nous efforçons de ne modifier aucune partie du code de la stratégie et d’encapsuler la stratégie dans un fichier qui peut être appelé par le code de la stratégie sur la plateforme FMZ. Le résultat de l’exécution est exactement le même que celui de l’exécution directe de la stratégie. Le plus gros problème avec l’encapsulation est que les objets globaux, les fonctions globales et les valeurs constantes appelées par le code de stratégie sur la plate-forme FMZ ne sont pas accessibles dans nos fichiers encapsulés, nous devons donc trouver un moyen de transmettre ces objets, fonctions, variables , et des constantes au document encapsulé. Ensuite, nous procéderons étape par étape.

Collez dans le fichier testA ouvert dans l’éditeur local.

# 函数、对象
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
La fonction principale du code ci-dessus est de déclarer les fonctions et variables globales utilisées dans le fichier courant. Réservez ensuite l’interface pour importer ces fonctionsSetExchanges,SetParams,SetFunc. Les stratégies sur la plateforme FMZ appellent ces fonctions et transmettent certaines fonctions, objets, etc. utilisés.
La stratégie de démarrage est très simple, comme suit :

Il n’y a que quelques lignes de code écrites sur la plateforme FMZ. Il convient de noter que les paramètres de cette stratégie de démarrage sont les mêmes que la stratégie que nous encapsulons.Version Python de Dual Thrust OKCoin FuturesC’est exactement la même chose. En fait, vous pouvez copier directement la stratégie « Version Python de Dual Thrust OKCoin Futures », puis effacer le code de la stratégie et le coller
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()
De cette façon, nous encapsulons le corps de la logique de la politique dans le fichier testA et le plaçons localement sur le périphérique de l’hôte. Sur la plateforme FMZ, nous n’avons besoin d’enregistrer qu’une seule politique de démarrage. Le robot qui crée cette politique de démarrage peut charger directement notre fichier local et l’exécuter localement sur l’hôte. .


Charger directement le fichier pour exécution. Cette fois, nous préparons un fichier testB pour placer le code de la stratégie « Version Python de Dual Thrust OKCoin Futures ».
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': {
...
La stratégie est trop longue, elle est donc omise et le code de stratégie n’a pas besoin d’être modifié du tout. Préparez ensuite la « version Python de Dual Thrust OKCoin Futures (démarrez la stratégie et exécutez directement le fichier testB) », qui est notre stratégie sur la plateforme FMZ, créez un robot, chargez directement le fichier testB et exécutez-le directement. Il convient de noter que la stratégie de démarrage doit également avoir les mêmes paramètres de stratégie (paramètres d’interface de stratégie) que la version originale de « Python version Dual Thrust OKCoin Futures ».

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)
Pour effectuer un backtest :

Les résultats du backtest sont cohérents avec les tests ci-dessus.
Bien évidemment, la deuxième méthode ci-dessus est plus simple et recommandée. S’il existe une meilleure méthode, n’hésitez pas à laisser un message.