Como desenhar uma participação, cadeias de propriedade e calcular as participações de CFC

Na prática jurídica dos advogados de empresas, há relativamente pouco tempo (há vários anos), tornou-se necessária a elaboração e apresentação de notificações sobre sociedades estrangeiras controladas (CFCs) nos termos do art. 25.13 do Código Tributário da Federação Russa. A essência desta obrigação é redigir e apresentar um documento que refletirá todas as conexões da empresa na holding ao longo das cadeias da LLC (JSC) atual na Federação Russa ao proprietário residente fiscal do CFC da Federação Russa. Simplificando, se o offshore for de propriedade de um russo (residente fiscal da Federação Russa), e o offshore de uma LLC russa (mesmo através da cerca de LLCs intermediárias) for superior a 25%, haverá uma notificação. O destaque é que é necessário submeter a todas as LLCs (JSCs) em que esta situação é observada e enviar informações sobre propriedade de mais de 25% e alterações subsequentes na participação de propriedade em tempo hábil, caso contrário multas (100.000 rublos para cada empresa na cadeia - Art. 129.6 Código Tributário da Federação Russa).Como a holding (conjunto de pessoas jurídicas) é um organismo vivo e as mudanças constantes nas participações acionárias são inevitáveis, é necessário monitorar de alguma forma tudo isso para não cobrar multas. Como simplificar o trabalho nessa direção, automatizá-lo, este artigo é dedicado. O artigo também será interessante do ponto de vista da apresentação gráfica de estruturas relacionadas, por exemplo, sociais. redes.







Neste artigo, não nos deteremos nos aspectos jurídicos das notificações enviadas sobre um CFC, sobre a participação em um CFC, consideraremos o lado técnico da questão.



Sem dúvida, se a holding em questão se apresenta como estruturas simples do tipo LLC-> KIK-> Russo, então é impraticável construir algo aqui com o envolvimento de uma máquina, é outra questão se a estrutura se ramifica, dobra e não há número desses entrelaçamentos.



Vamos dar uma olhada em várias soluções gráficas existentes que tornarão seu trabalho mais fácil.

Para facilitar a visualização, o notebook jupyter e o ambiente python serão usados.



Networkx



Esta solução é a mais antiga das apresentadas e não pode orgulhar-se da sua interactividade. Existe o mesmo artigo antigo sobre este pacote no Habré.



Porém, o antigo não significa ruim, e esta opção é uma das mais bem-sucedidas tanto em termos de desenho quanto de computação.



Instale e importe o módulo via jupyter:



!pip install networkx
import networkx as nx


Também importamos outros anúncios. módulos que o ajudarão a desenhar formas:



from matplotlib import pyplot as plt
%matplotlib inline
plt.rcParams.update({
    'figure.figsize': (7.5, 7.5),
    'axes.spines.right': False,
    'axes.spines.left': False,
    'axes.spines.top': False,
    'axes.spines.bottom': False})


Vamos construir a primeira rede usando networkx:



from pathlib import Path
data_dir = Path('.') / 'data'
# Read edge list
G = nx.read_edgelist('example.edgelist')
# Draw network
#pos = nx.spring_layout(G)
pos = nx.spectral_layout(G)
#pos = nx.planar_layout(G)
nx.draw_networkx(G, pos)
plt.gca().margins(0.15, 0.15)


Eis o que aconteceu:







como você pode ver, Ivanov possui dois CFCs, que, por sua vez, possuem entidades legais russas. por pessoas.



Vamos analisar o código acima.



Importamos o módulo e especificamos onde leremos os dados no disco de:



from pathlib import Path
data_dir = Path('.') / 'data'


O diretório atual foi considerado 'example.edgelist':



G = nx.read_edgelist('example.edgelist')


* example.edgelist é um arquivo de texto simples como este:



# source target
 1
 2
1 2
1 _
2 _


Os valores são registrados por alguém com um espaço entre eles.



Em seguida, determinamos como será a aparência da rede:



pos = nx.spectral_layout(G)


Se mudarmos para pos = nx.spring_layout (G), então ele assumirá a forma:







E este arranjo, curiosamente, é mais adequado para estruturas maiores.



Por fim, desenhamos a rede, marcando os recuos:



nx.draw_networkx(G, pos)
plt.gca().margins(0.15, 0.15)


É fácil salvar uma imagem:



plt.savefig('plot.png')


Como desenhar um segmento em networkx



#
H = G.subgraph(['', '1', '_'])
plt.subplot(212) 
print(":") 
nx.draw_networkx(H)


Não







recuamos aqui, e os nomes "à esquerda": Networkx opera com os conceitos de nós e links entre eles. Em nossa situação, os nós são Ivanov, KIK1, KIK2, Romashka_OOO, Bucket_AO. E os links são os que estão no arquivo example.edgelist.



Você pode ver os dois simplesmente referindo-se aos métodos G.nodes e G.edges:







Gráfico direcional em networkx (lista de arestas direcionadas)



Vamos esclarecer um pouco a rede construída, adicionar setas:



# Read edge list
G = nx.read_edgelist(
    str('example.edgelist'),
    create_using=nx.DiGraph)
pos = nx.spectral_layout(G)
# Draw network
nx.draw_networkx(G, pos, arrowsize=20)
plt.gca().margins(0.15, 0.15)


Pequenas mudanças tornaram possível pintar uma imagem mais clara de quem é o dono de quem:



No código, como você pode ver, as mudanças são mínimas.



O próximo passo é construir um gráfico onde o tamanho dos pacotes de propriedade será visível.



Para fazer isso, você precisa se familiarizar com o conceito de peso (peso) é o terceiro parâmetro principal com o qual o networkx pode trabalhar. Para incluí-lo no trabalho, você precisa adicionar esses mesmos pesos a um arquivo de texto, por exemplo:



# source target
 1 100
 2 100
1 2 50
1 _ 100
2 _ 100


Agora vamos reconstruir a rede usando os pesos e designá-los no gráfico:



# Read edge list
G = nx.read_weighted_edgelist(
    str('example2.edgelist'))
# Extract weights
weights = [d['weight'] for s, t, d in G.edges(data=True)]
nx.draw_networkx(G,pos)
labels = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels)
plt.gca().margins(0.15, 0.15)


* example2.edgelist é o arquivo gerado acima com pesos.



Temos a seguinte imagem:







Quem possui quem e como, networkx



Agora, como advogados-programadores, precisamos entender em que sequência e em que quantidade Ivanov possui, por exemplo, Bucket_AO, e se ele o possui. Isso é necessário para determinar o fato da propriedade na holding ramificada e todas as cadeias para o LLC alvo (JSC), para que posteriormente essas cadeias possam ser registradas na notificação CFC.



Com o networkx, você pode fazer isso da seguinte maneira:



list(nx.all_simple_paths(G,'', '_'))


O primeiro argumento é o nó proprietário, o segundo é o nó para o qual construiremos caminhos.



Usando este método, você pode ver que Bucket_AO de Ivanov pertence às seguintes cadeias:



[['', '1', '2', '_'], ['', '2', '_']]


Isso é confirmado graficamente.



Você pode descobrir a parcela de propriedade multiplicando os pesos entre os nós correspondentes: 1 * 0,5 * 1 = 0,5, 1 * 1 = 1. Participação de mais de 25%, notificação deve ser enviada.



No código, a multiplicação é feita com as seguintes muletas (um método mais elegante ainda não foi encontrado):



x=0
b=0
c=[]
for i in list(nx.all_simple_paths(G,'', '_')):    
    for a in i:        
        if x>len(i)-2:
            pass                        
        else:            
            b=int(nx.bidirectional_dijkstra(G, i[x],i[x+1])[0])#                        
            x+=1
            c.append(b/100)              
print(c)
import numpy as np
print(np.prod(c))


x=0
b=0
c=[]
for i in list(nx.all_shortest_paths(G,'', '_')):
    for a in i:        
        if x>len(i)-2:
            pass                      
        else:            
            b=int(nx.bidirectional_dijkstra(G, i[x],i[x+1])[0])#                        
            x+=1
            c.append(b/100)              
print(c)
import numpy as np
print(np.prod(c))


No primeiro caso, ele exibirá uma fração de 0,5, no segundo 1.



Que outras opções de visualização estão disponíveis? Por exemplo, Netwulf.



Netwulf



A documentação está aqui .



A própria rede é interativa, esta é sua principal vantagem. Depois de instalar o pacote python, vamos construir a rede:



import netwulf as nw
plt.figure(figsize=(200,200))
G = nx.read_weighted_edgelist(str('example2.edgelist'),create_using=nx.DiGraph)
pos = nx.spring_layout(G)
nw.visualize(G)


Após executar o código, o jupyter congela e em uma janela adicional do navegador que se abre, você pode ver o resultado:







No lado direito do painel, você pode ver as opções, alterando o que afeta a rede construída online.



A desvantagem deste pacote é que ainda não é possível mostrar os pesos e setas entre os nós, mas os autores prometeram refiná-lo.



* para voltar ao jupyter você precisa clicar na opção "postar para python":







Outra boa opção para tal visualização para python é o projeto webweb jovem.



Webweb



A documentação está aqui .



A rede é construída de maneira semelhante:



from webweb import Web
web = Web(title='kitchen_sink')

web.display.networkName = 'tree'
web.display.networkLayer = 2
web.display.colorBy = 'ring'
web.display.sizeBy = 'degree'
web.display.gravity = .3
web.display.charge = 30
web.display.linkLength = 15
web.display.colorPalette = 'Greens'
web.display.scaleLinkOpacity = False
web.display.scaleLinkWidth = True

from pathlib import Path
data_dir = Path('.') / 'data'
# Read edge list
G = nx.read_edgelist('example.edgelist',create_using=nx.DiGraph)
plt.figure(figsize=(200,200))
# Draw network
pos = nx.spring_layout(G)
Web(list(G.edges)).show()






Das vantagens claras sobre o netwulf: a capacidade de destacar nós-chave com cores, pesquisa de texto para nós com destaque na rede: Em







resumo, podemos dizer que os descendentes em desenvolvimento de networkx - netwulf e webweb são bons para construir uma imagem rápida da estrutura de uma pequena propriedade. Ambos os módulos têm um modo de congelamento para congelar nós que ficam juntos em uma pilha devido à interatividade do gráfico. Porém, mesmo utilizando-os, não é fácil trabalhar com estruturas de grande escala onde o número de nós é superior a 200.



"Pedestal" do Ministério das Finanças, propriedade cruzada e anelar



Tudo seria muito bom na construção de tais estruturas, se não fosse por uma coisa que estraga o quadro todo. Isto, no entanto, reside no facto de as participações da empresa serem proprietárias através de outras pessoas jurídicas. faces e isso é chamado de propriedade cruzada ou anel.



Nas fotos em cartas do Ministério das Finanças (por exemplo, de 02.07.2013 -4-13 / 11912) é assim.



Propriedade cruzada: em forma de anel







:







Vamos ver como o networkx define os links para o esquema de propriedade cruzada da participação de D em B.



Vamos criar um edgelist com links:



# source target
D B 45
B A 40
A B 55
E A 60


Tendo construído uma rede com pesos, você pode ver que o feedback entre A e B não é refletido:







Pode ser visto se você construir uma rede sem pesos, com setas:







E quanto aos cálculos? Qual é a participação cumulativa de D em B?



Tudo parece transparente aqui, 45%



E o networkx dá a lista de comandos (nx.all_simple_paths (G, 'D', 'B')):

[['D', 'B']]

Mas nem tudo é tão simples.



O Ministério da Fazenda afirma que a participação total de D em B é determinada pela fórmula:







E será de 57,69%.



O que fazer? networkx é impotente?



De forma alguma, o networkx revelará tais situações, mas a fórmula de cálculo será diferente, de acordo com a “letra da lei”.



Este problema pode ser parcialmente resolvido adicionando entradas

AA

BB ao edgelist

Além disso, com a lista de comandos (nx.nodes_with_selfloops (G)), você pode ver os nós com participação neles, mas isso ainda não é levado em consideração ao determinar os caminhos de D para B.



download do notebook jupyter - aqui .



All Articles