avatar of 发明者量化-小小梦 发明者量化-小小梦
Suivre Messages privés
4
Suivre
1271
Abonnés

Je vous apprends étape par étape à encapsuler une stratégie Python dans un fichier local

Créé le: 2020-06-30 10:48:18, Mis à jour le: 2024-12-10 20:27:04
comments   3
hits   3310

Je vous apprends étape par étape à encapsuler une stratégie Python dans un fichier local

Je vous apprends étape par étape à encapsuler une stratégie Python dans un fichier local

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.

Encapsuler une stratégie

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.

Je vous apprends étape par étape à encapsuler une stratégie Python dans un fichier local

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

Je vous apprends étape par étape à encapsuler une stratégie Python dans un fichier local

  • Ajoutez du code et conservez la partie du code de stratégie que vous avez copiée et collée intacte
  # 函数、对象
  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 fonctionsSetExchangesSetParamsSetFunc. Les stratégies sur la plateforme FMZ appellent ces fonctions et transmettent certaines fonctions, objets, etc. utilisés.

Stratégie de lancement sur la plateforme FMZ

La stratégie de démarrage est très simple, comme suit :

Je vous apprends étape par étape à encapsuler une stratégie Python dans un fichier local

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. .

Comparaison des backtests

  • Charger le fichier testA localement pour le backtesting

Je vous apprends étape par étape à encapsuler une stratégie Python dans un fichier local

  • Stratégie originale, backtestée sur un serveur public

Je vous apprends étape par étape à encapsuler une stratégie Python dans un fichier local

Une autre façon plus simple

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 ».

Je vous apprends étape par étape à encapsuler une stratégie Python dans un fichier local

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 : Je vous apprends étape par étape à encapsuler une stratégie Python dans un fichier local

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.