The resource loading... loading...

Handshake teaches you how to wrap a Python policy in a cost-effective document.

Author: Inventors quantify - small dreams, Created: 2020-06-30 10:48:18, Updated: 2024-12-10 20:27:04

手把手教你把一个Python策略封装成本地文件

Handshake teaches you how to wrap a Python policy in a cost-effective document.

This article discusses two options, the other one at the end of the article is simpler (recommended).

There are many developers who use Python to write policies and want to keep their policy code files locally, because of security concerns.FMZ APIOne of the proposals in the document is:

Strategic security Inventor Quantified Trading Platforms, the policies are only visible to the inventor's account holders. Inventor Quantified Trading Platforms, the policy code can be fully localized, for example, by wrapping the policy in a Python package and loading it into the policy code.https://www.fmz.com/api#%E7%AD%96%E7%95%A5%E5%AE%89%E5%85%A8%E6%80%A7

This concern is unnecessary, but a solution is a perfect example of how it can be implemented.

Package a policy

We're looking for a simple Python strategy to demonstrate, using the classicDual ThrustThis is the first time I have seen this kind of thing.https://www.fmz.com/strategy/21856We strive not to change any part of the policy code, to wrap the policy in a file that can be called by the policy code on the FMZ platform, and the execution results are perfectly consistent with the direct execution of the policy. The biggest problem with wrapping is that the global objects, global functions, and constant values that are called by the policy code on the FMZ platform are not accessible in our wrapped file, so we have to find a way to pass these objects, functions, variables, and constants to the wrapped file.

手把手教你把一个Python策略封装成本地文件

Paste the testA file opened in the local editor.

手把手教你把一个Python策略封装成本地文件

  • Added some code to keep the original package intact for the copy-paste policy code portion
  # 函数、对象
  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

The main function of the above code is to declare the global functions, variables used in the current file; then reserve the interface for importing these functions.SetExchangesSetParamsSetFuncThe policy on the FMZ platform calls these functions and passes some of the functions, objects, etc. that are used.

Launch strategy on the FMZ platform

It's easy to get started, as follows:

手把手教你把一个Python策略封装成本地文件

The only code written on the FMZ platform is just these lines, and it's important to note that the parameters for this startup policy are to wrap it with the policy that we're wrapping.Python version of Dual Thrust OKCoin futuresSimilarly, you can directly copy the "Python version Dual Thrust OKCoin futures" policy, and then just clear the policy code and paste it on the screen.

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()

In this way, we wrap the policy logic object in the testA file and place it locally on the device where the host is located, and on the FMZ platform, the bot that created this startup policy can directly load our local file and run it locally on the host.

Re-test the contrast

  • Locally load testA file to retrieve

手把手教你把一个Python策略封装成本地文件

  • The original policy, retested on the public server

手把手教你把一个Python策略封装成本地文件

The other, simpler way.

The file can be loaded directly into the executable. This time, we prepared a testB file that put the code for the "python version Dual Thrust OKCoin futures" policy.

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': {

...

If the policy is too long, it is omitted and the policy code is not changed at all. Then prepare the "python Dual Thrust OKCoin futures", which is our strategy on the FMZ platform, create a bot, directly load the testB file, and execute it directly. Note that the "start policy" must have the same set of policy parameters as the original Python Dual Thrust OKCoin futures ("strategy interface parameters").

手把手教你把一个Python策略封装成本地文件

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)

Do the retest:手把手教你把一个Python策略封装成本地文件

The results of the retest are consistent with the above test.

The second method is obviously simpler, and I recommend using it, if there is a better way, welcome to the message.


Related

More

qq89520I was inspired to think that selenium could be used for many other things.

qq89520Learning

Inventors quantify - small dreamsHa ha, any ideas that you can come up with, let's discuss it together.