В процессе загрузки ресурсов... загрузка...

Научить вас, чтобы инкапсулировать стратегию Python в локальном файле

Автор:Доброта, Создано: 2020-07-09 10:21:31, Обновлено: 2023-10-28 15:28:00

img

Многие разработчики, которые пишут стратегии в Python, хотят разместить файлы кода стратегии локально, беспокоясь о безопасности стратегии.

Безопасность стратегии

Стратегия разрабатывается на платформе FMZ, и стратегия видна только владельцам учетной записи FMZ. А на платформе FMZ код стратегии может быть полностью локализован, например, стратегия инкапсулируется в пакет Python и загружается в код стратегии, чтобы локализация стратегии была реализована.

Дополнительная информация:https://www.fmz.com/api

На самом деле, такой беспокойства не нужно, но поскольку есть такие потребности, мы предоставим полный пример осуществления.

Составить стратегию

Давайте найдем простую стратегию Python для демонстрации, используя классическийDual ThrustСтратегия, адрес стратегии:https://www.fmz.com/strategy/21856Мы стремимся не изменять какую-либо часть кода стратегии, инкапсулировать стратегию в файл, который может быть вызван кодом стратегии на платформе FMZ, и результат выполнения точно такой же, как прямое выполнение стратегии.

img

Вставить в файлtestAОткрыт местным редактором.

img

Добавить некоторое коды, и сохранить стратегию кода часть скопирована и вставлена нетронутыми

# Function, object
exchanges = None
exchange = None
Log = None
Sleep = None
TA = None
Chart = None
LogProfitReset = None
LogStatus = None
_N = None
_C = None 
LogProfit = None  


# Strategy parameters
ContractTypeIdx = None
MarginLevelIdx = None
NPeriod = None
Ks = None
Kx = None
AmountOP = None
Interval = None
LoopInterval = None
PeriodShow = None  

# constant
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

Основная функция вышеуказанного кода заключается в объявлении глобальных функций и переменных, используемых в текущем файле.SetExchanges, SetParams, SetFuncСтратегии на платформе FMZ вызывают эти функции и передают некоторые используемые функции и объекты.

Стартап-стратегия на платформе FMZ

Стратегия запуска очень простая:

img

Есть только несколько строк кода, написанных на платформе FMZ. Следует отметить, что параметры этой стратегии стартапа точно такие же, как и наша упакованная стратегияВерсия Python кода фьючерсной стратегии Dual Thrust OKCoinНа самом деле, вы можете прямо скопироватьВерсия Python кода фьючерсной стратегии Dual Thrust OKCoinСтратегия, затем просто очистите код стратегии, вставьте его.

import sys
# Here I wrote the path where I put the testA file myself. I replaced it with xxx. To put it simply, I set the path of my testA file.
sys.path.append("/Users/xxx/Desktop/pythonPlayground/")
import testA

def main():
    # Passing Exchange Object
    testA.SetExchanges(exchanges)
    # Pass global function SetFunc(pLog, pSleep, pTA, pChart, pLogStatus, pLogProfitReset, p_N, p_C, pLogProfit)
    testA.SetFunc(Log, Sleep, TA, Chart, LogStatus, LogProfitReset, _N, _C, LogProfit)
    # Passing strategy parameters SetParams(pContractTypeIdx, pMarginLevelIdx, pNPeriod, pKs, pKx, pAmountOP, pInterval, pLoopInterval, pPeriodShow)
    testA.SetParams(ContractTypeIdx, MarginLevelIdx, NPeriod, Ks, Kx, AmountOP, Interval, LoopInterval, PeriodShow)
    # Execute the main strategy function in the encapsulated testA file
    testA.main()

Таким образом, мы обобщаем основную часть логики стратегии вtestAна платформе FMZ, нам нужно только сохранить стратегию запуска. робот, который создает эту стратегию запуска, может напрямую загрузить наш локальный файл и запустить его локально.

Сравнение с обратным тестированием

  • НагрузкаtestAфайл локально для backtest

img

  • Первоначальная стратегия, обратный тест на публичном сервере

img

Еще один простейший способ

Загрузить файл прямо для исполнения. На этот раз мы готовимtestBфайл с кодом дляВерсия Python кода фьючерсной стратегии Dual Thrust OKCoin strategy.

import time
class Error_noSupport(BaseException):
    def __init__(self):
        Log("Only OKCoin futures are supported!#FF0000")

class Error_AtBeginHasPosition(BaseException):
    def __init__(self):
        Log("There is a futures position at startup!#FF0000")

ChartCfg = {
    '__isStock': True,
    'title': {
        'text': 'Dual Thrust Top and bottom rail map'
    },
    'yAxis': {

...

Если стратегия слишком длинная, ее исключают, и кодекса стратегии вообще не нужно менять.

Тогда приготовься.Версия Python кода фьючерсной стратегии Dual Thrust OKCoin(запустить стратегию, непосредственно осуществитьtestBфайл), что является нашей стратегией на платформе FMZ, создать робота, напрямую загрузитьtestBСледует отметить, что стратегия запуска также должна иметь точно такие же параметры параметров стратегии (параметры интерфейса стратегии), как и первоначальная версияВерсия Python кода фьючерсной стратегии Dual Thrust OKCoin.

img

if __name__ == '__main__':
    Log("run...")
    try:
        # The file path is processed, you can write the actual path of your testB file
        f = open("/Users/xxx/Desktop/pythonPlayground/testB.py", "r")
        code = f.read()
        exec(code)
    except Exception as e:
        Log(e)

Выполнить обратный тест:

img

Результат обратного испытания соответствует результатам вышеуказанного испытания.

Очевидно, что второй метод выше проще, его рекомендуется использовать.


Больше